Atmega 328P RFM95 shows EV_RESET when trying to send data


(Jhenins) #1

Hi folks! :sunglasses:

I built my own node with arduino pro mini (atmega 328P), RFM95 and DS18D20. I don’t use deep sleep mode but TPL5551 (Nano-Power System Timer for Power Gating) by TI. I am using this code from my county member who gave me his code. (This code works for him).

Click here to see code
/*******************************************************************************
   Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman

   Permission is hereby granted, free of charge, to anyone
   obtaining a copy of this document and accompanying files,
   to do whatever they want with them without any restriction,
   including, but not limited to, copying, modification and redistribution.
   NO WARRANTY OF ANY KIND IS PROVIDED.

   This example will send Temperature and Air Pressure
   using frequency and encryption settings matching those of
   the The Things Network. Application will 'sleep' 7x8 seconds (56 seconds)

   This uses ABP (Activation-by-personalisation), where a DevAddr and
   Session keys are preconfigured (unlike OTAA, where a DevEUI and
   application key is configured, while the DevAddr and session keys are
   assigned/generated in the over-the-air-activation procedure).


   Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in
   g1, 0.1% in g2), but not the TTN fair usage policy (which is probably
   violated by this sketch when left running for longer)!

   To use this sketch, first register your application and device with
   the things network, to set or generate an AppEUI, DevEUI and AppKey.
   Multiple devices can use the same AppEUI, but each device has its own
   DevEUI and AppKey.

   Do not forget to define the radio type correctly in config.h.


Adapted by A.Jenerts
 *******************************************************************************/

#include <avr/wdt.h>
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>

#include "LoraEncoder.h"

#include <EEPROM.h>

#include <OneWire.h>
#include <DallasTemperature.h>


const int batteryCheck = A0; // ADC pin that read battery level (3 pin)
const int DONE = 2; // pool this pin HIGH when uplink is done. (2 pin)
const int LedPin = A2; // on board LED

const int DS18B20Pin = 6; //define to what pin temperature sensor is connected

const int counterEEPROMaddress = 0; // adress where counter is store on EEPORM

bool joined = false;
bool done = false;


// LoRaWAN NwkSKey, network session key
static const PROGMEM u1_t NWKSKEY[16] = { 0xF1, 0x4F, 0x27, 0x25, 0x6A, 0x46, 0xBA, 0x85, 0x21, 0x79, 0x3D, 0x9C, 0xD8, 0x52, 0xF4, 0xFC };
static const PROGMEM u1_t APPSKEY[16] = { 0x34, 0x0A, 0x5E, 0x4C, 0x6D, 0xB9, 0xDE, 0xC7, 0x44, 0x66, 0x60, 0x61, 0x99, 0x58, 0x53, 0xD2 };
// LoRaWAN end-device address (DevAddr)
static const u4_t DEVADDR = 26011E62 ; 

// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
// DISABLE_JOIN is set in config.h, otherwise the linker will complain).
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }


static osjob_t sendjob;
static osjob_t initjob;

// Pin mapping is hardware specific.

const lmic_pinmap lmic_pins = {
  .nss = 10,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = 9,
  .dio = {7,8, LMIC_UNUSED_PIN },
};


// setup one wire interface 
OneWire oneWire(DS18B20Pin);
// create temperature sensor object
DallasTemperature TempSens(&oneWire);




void do_send(osjob_t* j) {
  digitalWrite(LedPin, LOW); //pools led low when data reading is started
  
  byte buffer[4]; // buffer for storing values for sending
  LoraEncoder encoder(buffer);

  encoder.writeUint16(analogRead(batteryCheck)); //adds value to buffer

  TempSens.requestTemperatures(); // Send the command to get temperatures

  encoder.writeTemperature(TempSens.getTempCByIndex(0)); // saves temprature from DS18B20 to buffer

  digitalWrite(LedPin, HIGH); // indicated that data has been read and decoded
  
  // Check if there is not a current TX/RX job running
  if (LMIC.opmode & OP_TXRXPEND) {
    Serial.println(F("OP_TXRXPEND, not sending"));
  }

  else {
    // Prepare upstream data transmission at the next possible time.
 
    LMIC_setTxData2(1, buffer, sizeof(buffer), 0);

  }

}



void setup()
{
  Serial.begin(57600);
  TempSens.begin();
  
  pinMode(LedPin, OUTPUT);
  pinMode(DONE, OUTPUT);
  
  
  digitalWrite(LedPin, HIGH);
  // LMIC init
  os_init();
  // Reset the MAC state. Session and pending data transfers will be discarded.
  LMIC_reset();

  // Set static session parameters. Instead of dynamically establishing a session
  // by joining the network, precomputed session parameters are be provided.
  uint8_t appskey[sizeof(APPSKEY)];
  uint8_t nwkskey[sizeof(NWKSKEY)];
  memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
  memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
  LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);

#if defined(CFG_eu868)
  LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI);      // g-band
  LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK,  DR_FSK),  BAND_MILLI);      // g2-band

#elif defined(CFG_us915)
  LMIC_selectSubBand(1);
#endif


/*
  //disable all but one channel
  for (int channel = 1; channel < 8; channel++) {
    LMIC_disableChannel(channel);
  }
*/

  // Disable link check validation
  LMIC_setLinkCheckMode(0);

  // TTN uses SF9 for its RX2 window.
  LMIC.dn2Dr = DR_SF9;

  // Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)
  LMIC_setDrTxpow(DR_SF7, 14);
  LMIC.seqnoUp = EEPROMReadCounter(counterEEPROMaddress);
}


void loop() {   
  do_send(&sendjob);    // Sent sensor values
  while (done == false)
  {
    digitalWrite(LedPin, HIGH);
    os_runloop_once();
  }
  done = false;
  digitalWrite(LedPin, LOW);
  delay(10);

  
  //save new counter 
  EEPROMWriteCounter(counterEEPROMaddress, (EEPROMReadCounter(counterEEPROMaddress) + 1) );
  digitalWrite(LedPin, HIGH);
  delay(30);
  //siganl TPL5111 to de assert DRVn line
  
  digitalWrite(DONE, HIGH);
}



long EEPROMReadCounter(long address)
{
  //Read the 4 bytes from the eeprom memory.
  long four = EEPROM.read(address);
  long three = EEPROM.read(address + 1);
  long two = EEPROM.read(address + 2);
  long one = EEPROM.read(address + 3);

  //Return the recomposed long by using bitshift.
  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

void EEPROMWriteCounter(int address, unsigned long value)
{
  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0XFF);
  byte one = ((value >> 24) & 0xFF);

  EEPROM.write(address, four);
  EEPROM.write(address + 1, three);
  EEPROM.write(address + 2, two);
  EEPROM.write(address + 3, one);
}




void onEvent (ev_t ev) {
  int i, j;
  switch (ev) {
    case EV_SCAN_TIMEOUT:
      Serial.println(F("EV_SCAN_TIMEOUT"));
      break;
    case EV_BEACON_FOUND:
      Serial.println(F("EV_BEACON_FOUND"));
      break;
    case EV_BEACON_MISSED:
      Serial.println(F("EV_BEACON_MISSED"));
      break;
    case EV_BEACON_TRACKED:
      Serial.println(F("EV_BEACON_TRACKED"));
      break;
    case EV_JOINING:
      Serial.println(F("EV_JOINING"));
      break;
    case EV_JOINED:
      Serial.println(F("EV_JOINED"));
      // Disable link check validation (automatically enabled
      // during join, but not supported by TTN at this time).
      LMIC_setLinkCheckMode(0);
      // after Joining a job with the values will be sent.
      joined = true;
      break;
    case EV_RFU1:
      Serial.println(F("EV_RFU1"));
      break;
    case EV_JOIN_FAILED:
      Serial.println(F("EV_JOIN_FAILED"));
      break;
    case EV_REJOIN_FAILED:
      Serial.println(F("EV_REJOIN_FAILED"));
      // Re-init
      os_setCallback(&initjob, initfunc);
      break;
    case EV_TXCOMPLETE:
      done = true;
      if (LMIC.dataLen) {
        // data received in rx slot after tx
        // if any data received, a LED will blink
        // this number of times, with a maximum of 10
        Serial.print(F("Data Received: "));
        Serial.println(LMIC.frame[LMIC.dataBeg], HEX);
        i = (LMIC.frame[LMIC.dataBeg]);
      }
      Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
      delay(50);  // delay to complete Serial Output before Sleeping
      break;
    case EV_LOST_TSYNC:
      Serial.println(F("EV_LOST_TSYNC"));
      break;
    case EV_RESET:
      Serial.println(F("EV_RESET"));
      break;
    case EV_RXCOMPLETE:
      // data received in ping slot
      Serial.println(F("EV_RXCOMPLETE"));
      break;
    case EV_LINK_DEAD:
      Serial.println(F("EV_LINK_DEAD"));
      break;
    case EV_LINK_ALIVE:
      Serial.println(F("EV_LINK_ALIVE"));
      break;
    default:
      Serial.println(F("Unknown event"));
      break;
  }
}

// initial job
static void initfunc (osjob_t* j) {
  // reset MAC state
  LMIC_reset();
  // start joining
  LMIC_startJoining();
  // init done - onEvent() callback will be invoked...
}

Here is my schematical:

Schematic_LoRa-Wan-Atmega-328P-RFM95W-Node.v.1.1.pdf (53.7 KB)

I added my node in TTN aplications by ABP activation mode. When my node tried to send data I have “EV_RESET” and I can’t figure out what is the reason. :frowning:

I don’t change setups at config.h, because default was good for me.


(Afremont) #3

That’s not a lot to go on, but if it resets exactly when it tries to transmit, I’m guessing it might be a power supply issue of it not being able to supply enough current without the voltage sagging. Did you build this circuit, or is a premanufactured board?


(Arinze Izukanne) #4

Hi,
1st, Can you edit your post and make the sketch preformatted text using the icon </>. It is easier to read that way.
2ndly, According to your wiring, you have dio0 – 8 and dio1 – 7. However in your sketch it is reversed.

Rather than jump into a script like this, I would suggest you go step by step. Use the sample ttn-ABP script and try sending a few bytes. If everything works, then modify the sketch to read your temperature sensor and send.


(Jhenins) #5

I built (projected) a pcb and solder all together! I added pictures. Here is Arduino pro mini with 168 atmega, 3v3 version but now I changed it to arduino pro mini 328p 3v3 version. Because 168 don’t have enough space for code. :smile: As power supply I am using 18650 3.7v battery. But I tried to send signal with usb power too, the same problem.

LoRa Wan Atmega 328P TFM95W Node v.1.1.


(Arjan) #6

LMIC’s EV_RESET event is not a hardware reset, but documented as:

EV_RESET

Session reset due to rollover of sequence counters. Network will be rejoined automatically to acquire new session.

So, that might be due to the logic of LMIC.seqnoUp = EEPROMReadCounter(counterEEPROMaddress) and all.

// LoRaWAN end-device address (DevAddr)
static const u4_t DEVADDR = 26011E62 ; 

This defines a (huge) decimal number, in scientific notation with some exponent. It should be hexadecimal:

static const u4_t DEVADDR = 0x26011E62; 

When specifying in decimal format, it would read:

static const u4_t DEVADDR = 637607522; 

(Jhenins) #7

Thank You a lot arjanvanb !

I uploaded simple code for EEPROM. Than I uploaded my node code again. Of course I added 0x before dev adress. Right know all works great.

Where I can have some more information “books” about these things? How You all know about this so much?