RX/TX always on, Serial buffer overflowing?

I am calculating the azimuth and elevation of the ISS relative to me with a python script, which then sends the values, for example: (-22; 330), to an Arduino which then moves a stepper and a servo to that position. The python script transmits the position once per second. Arduino code ( at least the important part, credits to Robin2):

void loop()
{
 recvWithEndMarker();
   if (newData)
   {
      SortData(); 
      moveServo();
      moveStepper();
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\n';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();

      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
      }
   }
}

void SortData()
{
   char *strings[16]; 
   char *ptr = NULL; byte index = 0;
   ptr = strtok(receivedChars, ";");  // delimiters, semicolon
   while (ptr != NULL)
   {
      strings[index] = ptr;
      index++;
      ptr = strtok(NULL, ",");
   }
   
   // convert string to int
   azimuth = atoi(strings[0]);
   elevation = atoi(strings[1]);
   newData = false;
   Serial.print("Azimuth = ");
   Serial.print(azimuth);
   Serial.print("   Elevation = ");
   Serial.println(elevation);
   Serial.println();
}

Everything works fine for about 5-10 minutes, but then the TX and RX LED suddenly turn on and the Arduino can't control the servo and stepper anymore. Is the serial buffer overflowing? And if so, how can I fix this?

Show us your whole code, please. If it's related to Serial, it could be as simple as upping your Baud rate, but hey, we can't tell, 'cause we can't see what you've done...
C

It is a shame that you did not include the part of the sketch that sets the Serial baud rate

How are the stepper and the servo powered ?

How it works, You post a question, we post questions or clarifications, you respond, we respond. Your silence at this point means I wander off into the weeds somewhere, and don't likely return for an hour or two...
Good luck!
C

At a first glance: how do you release from state as:

newData = true;

Not to see where newData is reset (assuming a "side effect" in one of the other functions).

You handle properly the case that your "receivedChars[ndx]" would overflow. You avoid properly to write "behind" the array. Correct.

But you overwrite all the time the same character, at the end even this all the time overwritten characters with '\0' at the end (you would lose for sure the tail of a message).
You do not raise a flag that you have hit the "buffer overflow" case. Could it be, that your receiver buffer is corrupted and does not have anymore the correct received strings?

I cannot imagine that the UART has stopped working. Instead, your code might have reached the "end of buffer" condition (and all corrupted).
Put a single char debug print into the loop, just to see if you still receive via UART (I would think so). Flag an error if you hit the "buffer overflow" condition (and potentially be careful to use a corrupted buffer content).
Potentially, the client side is wrong and sends a too large string (you would not get anymore properly).

Also question: is "numChars" set to 16 (actually 16 +1 for a NUL character)?
Later you process in SortData() but you have just a

char *strings[16]; 

Does it match with the Rx input buffer size "receivedChars[ndx]"?
Or do you hit now the case to write "behind" *strings[16]? (and a memory corruption, FW crashes in a strange behavior)

Thank you all for the answers! Here's the entire code:

#include <Servo.h>
#include <Stepper.h>

Servo servo1;
Stepper stepper1(2038, 11, 9, 10, 8);

const byte numChars = 100;
char receivedChars[numChars];   // an array to store the received data

boolean newData = false;

int azimuth;
int elevation;

void setup()
{
   Serial.begin(115200);
   Serial.println("<Arduino is ready>  Enter Azimuth and Elevation separated with a semicolon (;) ");
   servo1.attach(3);
   stepper1.setSpeed(15);
}

void loop()
{
 recvWithEndMarker();
   if (newData)
   {
      SortData(); 
      moveServo();
      moveStepper();
   }
}

void recvWithEndMarker()
{
   static byte ndx = 0;
   char endMarker = '\n';
   char rc;

   while (Serial.available() > 0 && newData == false)
   {
      rc = Serial.read();

      if (rc != endMarker)
      {
         receivedChars[ndx] = rc;
         ndx++;
         if (ndx >= numChars)
         {
            ndx = numChars - 1;
         }
      }
      else
      {
         receivedChars[ndx] = '\0'; // terminate the string
         ndx = 0;
         newData = true;
      }
   }
}

void SortData()
{
   char *strings[16]; 
   char *ptr = NULL; byte index = 0;
   ptr = strtok(receivedChars, ";");  // delimiters, semicolon
   while (ptr != NULL)
   {
      strings[index] = ptr;
      index++;
      ptr = strtok(NULL, ",");
   }
   
   // convert string to int
   azimuth = atoi(strings[0]);
   elevation = atoi(strings[1]);
   newData = false;
   Serial.print("Azimuth = ");
   Serial.print(azimuth);
   Serial.print("   Elevation = ");
   Serial.println(elevation);
   Serial.println();
}


void moveServo()
{
      if(elevation < 0)
     {
      int pos = -1 * elevation + 90;
      servo1.write(pos);
     }
     else
     {
      int pos = 90 - elevation;
      servo1.write(pos);
     }
}

void moveStepper()
{
  if(azimuth != 0 || azimuth != 359)
  {
    int pos = azimuth * 5.66;
    stepper1.step(pos);
  }
         
}

The stepper and servo are powered by the Arduino directly (without a shield) at 5V. Increasing the baud rate did not help.

If you power the steppermotor and the servo from the 5V pin and your arduino is powered via the input-jack. This means you draw too much current from the arduino 5V regulator.
Your steppermotor and the servo need their own power-supply.

The GND of this power-supply must be connected to the GND of the arduino

best regards Stefan

1 Like

This is not a good idea. The Arduino should not be regarded as a power supply, especially for high current components such as servos and steppers. You may have already damaged your Arduino

1 Like

If not damaged, it, or some portion of it, may be shutting down or otherwise compromised. That would explain running for several minutes, then failing. Not guaranteed, but certainly suspect.
C

1 Like

Ah damn, you guys are right. I should've thought of this earlier, I'll change this. Do you think this might the root of this problem?

Can't hazard a guess, but I certainly wouldn't look under the carpet for bugs until this elephant is dealt with.

2 Likes

If you have been drawing large currents from the Arduino 5V pin then all bets are off

1 Like

As you have discovered, that does not work. Separate power supplies are required for motors and servos. A driver is required for the stepper.

I'm using 28BYJ-48 Stepper Motor with a ULN2003 Driver, what would be a good 5V power supply? A 9v batter would be too much, right?

A 5V phone charger is fine for one small servo and possibly also the 28BYJ-48. Don't forget to connect the negative power supply lead to Arduino ground.

Ah cool, I'll check that out!

If the 9V battery is a PP3 then it is totally unsuitable, not least for the reason that it too cannot supply enough current

1 Like

You should learn some basics about ohms law. What is voltage, current, resistance
and how do they depend on each other.

The microcontroller-world is not superstandardised like USB-devices.
You have to take care of more things than just "does the plug fit into the socket?"

If you want to go on working with this kind of electronics you should have a digital multimeter for measuring voltages, currents and resistance.
And you should have a basic knowledge on how to measure them.

If you have your digital multimeter adjusted for current-measuring and you would connect the DMM like it is done for a voltage-measuring you would do a pure shortcut to the circuit which would burn through the inbuild fuse of the multimeter and maybe damage your circuit.

best regards Stefan

1 Like

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