Serial read is accurate for only 10 loops

I am attempting to make a motor controller that also shows what speed the motor is set to on an lcd, the project is currently on two arduinos, one to run the motor and one for the lcd b/c when they were run on the same arduino the lcd slowed the motor down. I am having issues receiving data on the lcd arduino. The first 10-20 loops are accurate and shows the correct number, but after that the data breaks down and shows the correct numbers in incorrect patterns, i.e. instead of '1023' it returns:
1
1221
30121
321

the tx and rx pins are correctly connected and so are the grounds
I have attached my code below, what am I doing wrong?

Code for motor

#include <AccelStepper.h>

// Define stepper motor connections
#define dirpin 2                // Direction Pin
#define steppin 4               // Stepper Pin
#define motorInterfaceType 1

int potentiometer = A0;         // Potentiometer Pin
int i = 0;                      // Setup Loop variable
int howfast = 0;              // Mapped Speed

AccelStepper stepper = AccelStepper(motorInterfaceType, steppin, dirpin);

void setup() {
  Serial.begin(9600);  // Serial read begin,

  pinMode(potentiometer, INPUT);
  pinMode(steppin, OUTPUT);
  pinMode(dirpin, OUTPUT);
  digitalRead(dirpin);    //direction pin either LOW or HIGH to move in either direction

  // Set the maximum speed in steps per second:
  stepper.setMaxSpeed(3000);
}

void loop() {
  // put your main code here, to run repeatedly:
  senddata();
  for (int i = 0; i < 10; i++)
  {
    // Set the speed in steps per second:
    stepper.setSpeed(howfast);
    // Step the motor with a constant speed as set by setSpeed():
    stepper.runSpeed();
  }
}

void senddata() {
  howfast = analogRead(potentiometer);
  Serial.println(howfast);
  delay(1);
}

Code for lcd (from Serial Input Basics thread)

#include <Wire.h>
#include <LiquidCrystal_I2C.h>  // LCD Library

const byte numChars = 32;
char receivedChars[numChars];   // an array to store the received data
boolean newData = false;
int dataNumber = 0;             // new for this version

LiquidCrystal_I2C lcd(0x27, 16, 2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup() {
  Serial.begin(9600);
  Serial.println("<Arduino is ready>");
  lcd.init();                  // initialize the lcd
  lcd.init();
}

void loop() {
  recvWithEndMarker();
  Serial.println(receivedChars);
  // LCD Screen;
  lcd.backlight();
  //  print out string
  lcd.setCursor(2, 0);
  lcd.print("Motor Speed");
  // print out the value on LCD:
  lcd.setCursor(6, 1);
  lcd.print(receivedChars);
}

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

  if (Serial.available() > 5) {
    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;
    }
  }
}

  for (int i = 0; i < 10; i++)
  {
    // Set the speed in steps per second:
    stepper.setSpeed(howfast);
    // Step the motor with a constant speed as set by setSpeed():
    stepper.runSpeed();
  }

What is the purpose of this for loop ?

I found that the rpm was higher when using the for loop, I am more concerned about the serial read right now

For best reliability, I would change the code to use a start marker as well as end marker.

with two arduinos it's even worse. Now you have the serial receiver that is slowed down and your receive buffer will overrun.
You must not write to the lcd with every loop, and you should only write text that has changed.

That's because now the serial transmission is slowing down the stepper. Serial transmisson is very slow compared to the speed of the processor - especially with 9600 baud.

1 Like

Thanks for the suggestions. How would I alter the lcd code to only write text that has changed?

E.G. this:

is the same in every loop and could be done once in setup

and also this:

is very time consuming and should not be done in every loop.

And you should use a higher baud rate, e.g. 115200.

N.B. The splitting in 2 Arduinos doesn't help. Put it back to one again, If you use your LCD properly ( not writing too often ) it should work. The problems are the same - with one or two Arduinos.

@microbahner your modesty is admirable. Not a word about the MobaTools.

The big advantage of the MobaTools is that this library creates the step-pulses
"in the background" based on a timer-interrupt.
execute a single function-call and the stepper-motor runs

So I will post a WokSim with a demo-code with quite some explaining comments

best regards Stefan

Yes, the MobaTools would tolerate the poor design of the sketch. But the changes mentioned should also be made with MobaTools.

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