Arduino UNO stops running after several minutes/hours

I am currently working on a wireless monitoring system using a Arduino UNO, Arduino Mega, a CH340 Arduino Mega and LoRa (Ra-02) Modules. I've used the Arduino Mega as master node, UNO as Node 1 and CH340 Mega as node 2. I am testing LoRa Nodes sending and requesting packets and I've notice that UNO suddenly stops sending replies and when I click the reset button , it works again and after several minutes or hours, it stops working again and needed reset (note: the two mega works perfectly fine). Is it my Arduino UNO that has problem or can I improve it in codes?

I am new in coding Arduino and only rely on youtube and online forums. Thank you for your help!!

Here's the Codes I am using

//Master Node
//Arduino Mega

#include <SPI.h>            
#include <LoRa.h>

const int csPin = 53;
const int resetPin = 9;
const int irqPin = 8;
 
byte MasterNode = 0xFF;     
byte Node1 = 0xBB;
byte Node2 = 0xCC; 

String SenderNode = "";
String outgoing;              // outgoing message

byte msgCount = 0;            // count of outgoing messages

// Tracks the time since last event fired
unsigned long previousMillis=0;
unsigned long int previoussecs = 0; 
unsigned long int currentsecs = 0; 
unsigned long currentMillis = 0;
int interval= 1 ; // updated every 1 second
int Secs = 0; 


void setup() {
  Serial.begin(9600);                   // initialize serial

  LoRa.setPins(csPin, resetPin, irqPin);

  if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }

  Serial.println("LoRa init succeeded.");
}

void loop() {


currentMillis = millis();
   currentsecs = currentMillis / 1000; 
    if ((unsigned long)(currentsecs - previoussecs) >= interval) {
     Secs = Secs + 1;
     //Serial.println(Secs);
     if ( Secs >= 11)
    {
      Secs = 0; 
    }
    if ( (Secs >= 1) && (Secs <= 5) )
    {
     
    String message = "34"; 
    sendMessage(message,MasterNode, Node1);
    }

        if ( (Secs >= 6 ) && (Secs <= 10))
    {
     
    String message = "55"; 
    sendMessage(message,MasterNode, Node2);
    }
    
   previoussecs = currentsecs;
    }

  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
    
  }


void sendMessage(String outgoing, byte MasterNode, byte otherNode) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(otherNode);              // add destination address
  LoRa.write(MasterNode);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  LoRa.write(outgoing.length());        // add payload length
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}

void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  // read packet header bytes:
  int recipient = LoRa.read();          // recipient address
  byte sender = LoRa.read();            // sender address
  if( sender == 0XBB )
  SenderNode = "Node1:";
  if( sender == 0XCC )
  SenderNode = "Node2:";
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = LoRa.read();    // incoming msg length

  String incoming = "";

  while (LoRa.available()) {
    incoming += (char)LoRa.read();
  }

  if (incomingLength != incoming.length()) {   // check length for error
    //Serial.println("error: message length does not match length");
    ;
    return;                             // skip rest of function
  }

  // if the recipient isn't this device or broadcast,
  if (recipient != Node1 && recipient != MasterNode) {
   // Serial.println("This message is not for me.");
    ;
    return;                             // skip rest of function
  }

  if (recipient != Node2 && recipient != MasterNode) {
   // Serial.println("This message is not for me.");
    ;
    return;                             // skip rest of function
  }

  Serial.print("Received data " + incoming);
  Serial.print(" from 0x" + String(sender, HEX));
  Serial.println(" to 0x" + String(recipient, HEX));
  Serial.println("RSSI: " + String(LoRa.packetRssi()));
  Serial.println("Snr: " + String(LoRa.packetSnr()));
  Serial.println();

}
//Node 1
//Arduino Uno

#include <SPI.h>              
#include <LoRa.h>

const int csPin = 10;
const int resetPin = 9;
const int irqPin = 8;

int count = 0;
int mess = 0;

String outgoing;              // outgoing message

byte msgCount = 0;            // count of outgoing messages
byte MasterNode = 0xFF;     
byte Node1 = 0xBB;


void setup() {
  Serial.begin(9600);                   // initialize serial

  LoRa.setPins(csPin, resetPin, irqPin);

  while (!Serial);

  Serial.println("LoRa Duplex");



  if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }

  Serial.println("LoRa init succeeded.");
}

void loop() {


  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
}

void sendMessage(String outgoing, byte MasterNode, byte otherNode) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(MasterNode);              // add destination address
  LoRa.write(Node1);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  LoRa.write(outgoing.length());        // add payload length
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}

void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  // read packet header bytes:
  int recipient = LoRa.read();          // recipient address
  byte sender = LoRa.read();            // sender address
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = LoRa.read();    // incoming msg length

  String incoming = "";

  while (LoRa.available()) {
    incoming += (char)LoRa.read();
  }

  if (incomingLength != incoming.length()) {   // check length for error
   // Serial.println("error: message length does not match length");
   ;
    return;                             // skip rest of function
  }

  // if the recipient isn't this device or broadcast,
  if (recipient != Node1 && recipient != MasterNode) {
    //Serial.println("This message is not for me.");
    ;
    return;                             // skip rest of function
  }
    Serial.println(count++);
    int Val = incoming.toInt();
    if(Val == 34)
    { 
    String message = String(mess++); 
    sendMessage(message,MasterNode,Node1);
    delay(100);
    }
  
}
//Node 2
//Arduino Mega CH340

#include <SPI.h>              // include libraries
#include <LoRa.h>

const int csPin = 53;
const int resetPin = 9;
const int irqPin = 8;

int count = 0;
int mess = 0;

String outgoing;              // outgoing message

byte msgCount = 0;            // count of outgoing messages
byte MasterNode = 0xFF;     
byte Node2 = 0xCC;


void setup() {
  Serial.begin(9600);                   // initialize serial

  LoRa.setPins(csPin, resetPin, irqPin);

  while (!Serial);

  Serial.println("LoRa Duplex");



  if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }

  Serial.println("LoRa init succeeded.");
}

void loop() {


  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
}

void sendMessage(String outgoing, byte MasterNode, byte otherNode) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(MasterNode);              // add destination address
  LoRa.write(Node2);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  LoRa.write(outgoing.length());        // add payload length
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}

void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  // read packet header bytes:
  int recipient = LoRa.read();          // recipient address
  byte sender = LoRa.read();            // sender address
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = LoRa.read();    // incoming msg length

  String incoming = "";

  while (LoRa.available()) {
    incoming += (char)LoRa.read();
  }

  if (incomingLength != incoming.length()) {   // check length for error
   // Serial.println("error: message length does not match length");
   ;
    return;                             // skip rest of function
  }

  // if the recipient isn't this device or broadcast,
  if (recipient != Node2 && recipient != MasterNode) {
    //Serial.println("This message is not for me.");
    ;
    return;                             // skip rest of function
  }
    Serial.println(count++);
    int Val = incoming.toInt();
    if(Val == 55)
    { 
    String message = String(mess++); 
    sendMessage(message,MasterNode,Node2);
    delay(100);
    }
  
}

notice your UNO code is using String - it is not recommend to use C++ objects on small microcontrollers such as the UNO as memory can become fragmented and the crash the program
if you replace the UNO with a Mega does it fix the problem?
replace the String with a char[] array?

1 Like

I've read about that too, the memory leak thing. They suggests to replace String into cstring but I didn't know how and can get much examples. I am not familiar in c++ and any other programming language. Can you help me convert my code or at least give me example? Thank you so much for responding I really appreciate it!

serial-input-basics shows examples of reading characters from serial input stream and storing into arrays

1 Like

Thank you! I'll read that too.

attempted to convert Uno code from String to char[]


//Node 1
//Arduino Uno

#include <SPI.h>              
#include <LoRa.h>

const int csPin = 10;
const int resetPin = 9;
const int irqPin = 8;

int count = 0;
int mess = 0;

char outgoing[100];              // outgoing message
int outIndex=0;

byte msgCount = 0;            // count of outgoing messages
byte MasterNode = 0xFF;     
byte Node1 = 0xBB;


void setup() {
  Serial.begin(9600);                   // initialize serial

  LoRa.setPins(csPin, resetPin, irqPin);

  while (!Serial);

  Serial.println("LoRa Duplex");



  if (!LoRa.begin(433E6)) {             // initialize ratio at 915 MHz
    Serial.println("LoRa init failed. Check your connections.");
    while (true);                       // if failed, do nothing
  }

  Serial.println("LoRa init succeeded.");
}

void loop() {


  // parse for a packet, and call onReceive with the result:
  onReceive(LoRa.parsePacket());
}

void sendMessage(char outgoing[], byte MasterNode, byte otherNode) {
  LoRa.beginPacket();                   // start packet
  LoRa.write(MasterNode);              // add destination address
  LoRa.write(Node1);             // add sender address
  LoRa.write(msgCount);                 // add message ID
  LoRa.write(strlen(outgoing));        // add payload length
  LoRa.print(outgoing);                 // add payload
  LoRa.endPacket();                     // finish packet and send it
  msgCount++;                           // increment message ID
}

void onReceive(int packetSize) {
  if (packetSize == 0) return;          // if there's no packet, return

  // read packet header bytes:
  int recipient = LoRa.read();          // recipient address
  byte sender = LoRa.read();            // sender address
  byte incomingMsgId = LoRa.read();     // incoming msg ID
  byte incomingLength = LoRa.read();    // incoming msg length

  char incoming[100] = {0};
  int inIndex=0;

  while (LoRa.available()) {
    incoming[inIndex++]= (char)LoRa.read();
  }
  inIndex=0;
  if (incomingLength != strlen(incoming)) {   // check length for error
   // Serial.println("error: message length does not match length");
   ;
    return;                             // skip rest of function
  }

  // if the recipient isn't this device or broadcast,
  if (recipient != Node1 && recipient != MasterNode) {
    //Serial.println("This message is not for me.");
    ;
    return;                             // skip rest of function
  }
    Serial.println(count++);
    int Val = 0;//incoming.toInt();
    sscanf(incoming, "%d", &Val);
    if(Val == 34)
    { 
    char message[100]={0};// = String(mess++); 
    sprintf(message,"%d",mess);
    sendMessage(message,MasterNode,Node1);
    delay(100);
    }
  
}

it compiles OK
hope it helps!

1 Like

Thank you for this and I've tried this but it also stops and need reset to run again. I might consider switching from UNO to Mega instead.

need to isolate where the problem is

i suggest just recognizing that a received packet is available, "flushing" it without processing it to verify that that processing is not causing any problem

1 Like

Hi,
How are you powering the UNO?
Can you please post a circuit diagram of the failing UNO unit?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

1 Like

Sorry I didn't get it what "flushing" are you talking about.

It is just connected in my laptop and the Ra-02 is connected like this (the difference is the yellow wire in my connection is in pin 8 instead of pin 2 and it is configured in the code the irqPin).

just read the bytes to empty the buffer

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.