Arduino Serial1 dropping commands

Hi,

I connected arduino mega serial1 and connected through max485,
and i getting commands from gateway via rs485 serial port with node-red
but it dropping commands
i send 0 and 1
while testing i sent 4x1 but it prints only 3 or 2 times and the same with 0 commands it is not reliable,

any idea what i'm missing

int in12 = 9;
int in13 = 10;
int in14 = 11;
String command;
void setup() {
  Serial1.begin(9600);//Using Serial1 Port
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {
  if(Serial1.available()){ //If Serial Data is available
    
    int c = Serial1.read() - '0';
    Serial.println(c);
    if(c == 1){
       digitalWrite(13,HIGH);
       Serial.println("HIGH");
    }
    else if (c==0){
      digitalWrite(13,LOW);
       Serial.println("LOW");
    }
    else{
       Serial.println("Wrong Command");
    }
    }
}

void parseCommand(String com){
  String part1;
  String part2;

  //valveon_3
  //valveoff_3

  part1 = com.substring(0,com.indexOf("_"));
  part2 = com.substring(com.indexOf("_")+1);
  Serial.println(part1);
  Serial.println(part2);
  if(part1.equalsIgnoreCase("valveon")){
    int pin = part2.toInt();
    digitalWrite(13,HIGH);
  }
  else if (part1.equalsIgnoreCase("valveoff")){
    int pin = part2.toInt();
    digitalWrite(13,LOW);
  }
  else{
    Serial.println("COMMAND NOT FOUND");
  }
}

sending multiple characters at a time has the potential of overflowing the USART buffer if they are not read quickly enough. Serial prints at 9600 take ~1msec.

i use the following. but we BOTH might be better of doing "while (Serial.available())" instead of "if (Serial.available())"

void
pcRead (void)
{
    static int  analogPin = 0;
    static int  val = 13;

    if (Serial.available()) {
        int c = Serial.read ();

        switch (c)  {
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            val = c - '0' + (10 * val);
            break;

        case 'A':
            analogPin = val;
            Serial.print   ("analogPin = ");
            Serial.println (val);
            val = 0;
            break;

        case 'D':
            debug ^= 1;
            break;

        case 'I':
            pinMode (val, INPUT);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" INPUT");
            val = 0;
            break;

        case 'O':
            pinMode (val, OUTPUT);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" OUTPUT");
            val = 0;
            break;

        case 'P':
            pinMode (val, INPUT_PULLUP);
            Serial.print   ("pinMode ");
            Serial.print   (val);
            Serial.println (" INPUT_PULLUP");
            val = 0;
            break;


        case 'a':
            Serial.print   ("analogRead: ");
            Serial.println (analogRead (val));
            val = 0;
            break;

        case 'c':
            digitalWrite (val, LOW);
            Serial.print   ("digitalWrite: LOW  ");
            Serial.println (val);
            val = 0;
            break;

        case 'p':
            analogWrite (analogPin, val);
            Serial.print   ("analogWrite: pin ");
            Serial.print   (analogPin);
            Serial.print   (", ");
            Serial.println (val);
            val = 0;
            break;

        case 'r':
            Serial.print   ("digitalRead: pin ");
            Serial.print   (val);
            Serial.print   (", ");
            Serial.println (digitalRead (val));
            val = 0;
            break;

        case 's':
            digitalWrite (val, HIGH);
            Serial.print   ("digitalWrite: HIGH ");
            Serial.println (val);
            val = 0;
            break;

        case 't':
            Serial.print   ("pinToggle ");
            Serial.println (val);
            pinToggle (val);
            val = 0;
            break;

        case 'v':
            Serial.print ("\nversion: ");
            Serial.println (version);
            break;

        default:
            Serial.print ("unknown char ");
            Serial.println (c,HEX);
            break;
        }
    }
}

I connected arduino mega serial1 and connected through max485,

Connected how ? How have you connected the MAX485 to the MEGA ? Please post a diagram.

How do you know the problem is not on the sending side of the rs485 serial? You say you're getting commands, but how can you be sure?

Deva_Rishi:
Connected how ? How have you connected the MAX485 to the MEGA ? Please post a diagram.

yes using MAX485 and mega, i'll post the diagram and i'' send to u after figure everything out

gcjr:
sending multiple characters at a time has the potential of overflowing the USART buffer if they are not read quickly enough. Serial prints at 9600 take ~1msec.

i use the following. but we BOTH might be better of doing "while (Serial.available())" instead of "if (Serial.available())"

void

pcRead (void)
{
   static int  analogPin = 0;
   static int  val = 13;

if (Serial.available()) {
       int c = Serial.read ();

switch (c)  {
       case '0':
       case '1':
       case '2':
       case '3':
       case '4':
       case '5':
       case '6':
       case '7':
       case '8':
       case '9':
           val = c - '0' + (10 * val);
           break;

case 'A':
           analogPin = val;
           Serial.print   ("analogPin = ");
           Serial.println (val);
           val = 0;
           break;

case 'D':
           debug ^= 1;
           break;

case 'I':
           pinMode (val, INPUT);
           Serial.print   ("pinMode ");
           Serial.print   (val);
           Serial.println (" INPUT");
           val = 0;
           break;

case 'O':
           pinMode (val, OUTPUT);
           Serial.print   ("pinMode ");
           Serial.print   (val);
           Serial.println (" OUTPUT");
           val = 0;
           break;

case 'P':
           pinMode (val, INPUT_PULLUP);
           Serial.print   ("pinMode ");
           Serial.print   (val);
           Serial.println (" INPUT_PULLUP");
           val = 0;
           break;

case 'a':
           Serial.print   ("analogRead: ");
           Serial.println (analogRead (val));
           val = 0;
           break;

case 'c':
           digitalWrite (val, LOW);
           Serial.print   ("digitalWrite: LOW  ");
           Serial.println (val);
           val = 0;
           break;

case 'p':
           analogWrite (analogPin, val);
           Serial.print   ("analogWrite: pin ");
           Serial.print   (analogPin);
           Serial.print   (", ");
           Serial.println (val);
           val = 0;
           break;

case 'r':
           Serial.print   ("digitalRead: pin ");
           Serial.print   (val);
           Serial.print   (", ");
           Serial.println (digitalRead (val));
           val = 0;
           break;

case 's':
           digitalWrite (val, HIGH);
           Serial.print   ("digitalWrite: HIGH ");
           Serial.println (val);
           val = 0;
           break;

case 't':
           Serial.print   ("pinToggle ");
           Serial.println (val);
           pinToggle (val);
           val = 0;
           break;

case 'v':
           Serial.print ("\nversion: ");
           Serial.println (version);
           break;

default:
           Serial.print ("unknown char ");
           Serial.println (c,HEX);
           break;
       }
   }
}

the problem also appears with 1 char, i'll try your code and see

the problem also appears with 1 char,

by this you mean it is also ignored?

but there are times when it is recognized? So sometimes it works and sometimes it doesn't?

gcjr:
by this you mean it is also ignored?

but there are times when it is recognized? So sometimes it works and sometimes it doesn't?

Yes, sometimes it receive the char and sometimes doesn't

for example i sent A then B then A then B

serial monitor shows ABB or sometime AB only or A only etc.

so it looks like the wiring is correct. As aarg asked, how are you sending?

gcjr:
so it looks like the wiring is correct. As aarg asked, how are you sending?

I'm using an iot gateway with node-red installed
And i inject the character to the rs485 serial using the flow and print that character on arduino end , that's all i do for testing

you might try testing what you want to do on the Serial port and send data from the Arduino IDE monitor. Then when it works to your satisfaction, use that same code to process Serial1

gcjr:
you might try testing what you want to do on the Serial port and send data from the Arduino IDE monitor. Then when it works to your satisfaction, use that same code to process Serial1

what i want to do is to control relays from the iot gateway via Serial1 port, so waht i'm trying to figure out now is the issue of dropping some communication to don't drop commands in the future,

maybe it is buffer problem ? how to increase the serial1 buffer and what is the maximum it can take

I think speculation will not get you closer to a solution. You need to narrow down the problem using divide and conquer troubleshooting strategy. If you're not familiar with that, if you have an AB that won't work, design a test for A or B alone. If B fails, break that into two B1 B2 and test those... keep dividing until you see the problem. Reply #10 is an example of that.

Hi,
Following the topic Arduino Serial1 dropping commands i manage to solve the commands problem it seems that it was coding issue, and thank for the replies i solved it
now the issue is with transmit to Serial1 and receive the data on the gateway (with node-red) too.

i tried Serial1.write() and Serial1.send() but on the other end it doesn't receive anything (i monitor it with a serial input node).

i toggled the 30 pin to HIGH to transmit before Serial1.send and also the same problem.

Any help? Thanks

const int pin_LED = 13;
const int pin_485Dir = 30;      // RX Enable RS485
const int RS485Transmit = HIGH;      // TX Enable RS485
const int RS485Receive = LOW;
const int relay1 = 6;
const int relay2 = 7;
const int relay3 = 8;
const int relay4 = 9;
void setup()
{
    Serial.begin(9600);
    Serial1.begin(9600);

    pinMode(pin_LED, OUTPUT);
    pinMode(pin_485Dir, OUTPUT);
    pinMode(relay1, OUTPUT);
    pinMode(relay2, OUTPUT);
    pinMode(relay3, OUTPUT);
    pinMode(relay4, OUTPUT);

}

void loop()
{
    //Set receive mode

    digitalWrite(pin_485Dir, RS485Receive);

    while (Serial1.available()) {
        char ch = Serial1.read();

        Serial.print("RX: ");
        Serial.print(ch);
        Serial.println("");
        switch(ch){
          case 'A': ToggleLED(relay1); break;
          case 'B': ToggleLED(relay2); break;
          case 'C': ToggleLED(relay3); break;
          case 'D': ToggleLED(relay4); break;
        }
    }
}

void ToggleLED(int  rel) {
    digitalWrite(rel, !digitalRead(rel));
}

To better help you, can you post both sketches and your wiring schematic?

Right off the bat I can see that you’re not using any sort of robust serial packet system. You can learn the theory behind serial packets in the tutorials Serial Input Basics and Serial Input Advanced. As for implementing a packet system, you can use SerialTransfer.h to automatically packetize and parse your data for inter-Arduino communication without the headace. The library is installable through the Arduino IDE and includes many examples.

Here are the library’s features:

This library:

  • can be downloaded via the Arduino IDE’s Libraries Manager (search “SerialTransfer.h”)
  • works with “software-serial” libraries
  • is non blocking
  • uses packet delimiters
  • uses consistent overhead byte stuffing
  • uses CRC-8 (Polynomial 0x9B with lookup table)
  • allows the use of dynamically sized packets (packets can have payload lengths anywhere from 1 to 255 bytes)
  • can transfer bytes, ints, floats, and even structs!!

Example TX Arduino Sketch:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  myTransfer.txBuff[0] = 'h';
  myTransfer.txBuff[1] = 'i';
  myTransfer.txBuff[2] = '\n';
  
  myTransfer.sendData(3);
  delay(100);
}

Example RX Arduino Sketch:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  if(myTransfer.available())
  {
    Serial.println("New Data");
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}

Power_Broker:
To better help you, can you post both sketches and your wiring schematic?

Right off the bat I can see that you’re not using any sort of robust serial packet system. You can learn the theory behind serial packets in the tutorials Serial Input Basics and Serial Input Advanced. As for implementing a packet system, you can use SerialTransfer.h to automatically packetize and parse your data for inter-Arduino communication without the headace. The library is installable through the Arduino IDE and includes many examples.

Here are the library’s features:

Example TX Arduino Sketch:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  myTransfer.txBuff[0] = ‘h’;
  myTransfer.txBuff[1] = ‘i’;
  myTransfer.txBuff[2] = ‘\n’;
 
  myTransfer.sendData(3);
  delay(100);
}





Example RX Arduino Sketch:


#include “SerialTransfer.h”

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  if(myTransfer.available())
  {
    Serial.println(“New Data”);
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}

I attached the sketch on the arduino, the mega will work both tx and rx is this possible?

It will receive from serial1 the packet then transmit success to the same serial1, the transmit is the problem now

And the max is wired as
RE-DE 30
R0 Rx1
DI Tx1

What is the transmit problem? Please describe it. Generally, transmit is very straighforward since you control when characters are sent. Realize that serial transmission will block if the transmit buffer is allowed to fill up. So you have to allow time for the characters to be sent, or else use flush() to wait for the buffer to empty.

aarg:
What is the transmit problem? Please describe it. Generally, transmit is very straighforward since you control when characters are sent. Realize that serial transmission will block if the transmit buffer is allowed to fill up. So you have to allow time for the characters to be sent, or else use flush() to wait for the buffer to empty.

The issue is that i don't receive anything on the other end.

Is it the same to use serial write, print, send
Which one to use in this case?

KareemWaheed:
The issue is that i don't receive anything on the other end.

Is it the same to use serial write, print, send
Which one to use in this case?

Write a simple reliable test sketch that transmits a test message. Verify it on a terminal. Then you know the problem is on the receiving, not the transmitting end.

You still have not posted both of your sketches and have not posted a schematic. The problem most definitely lies in one of those pieces, but without them, we can't be much help.