Hello community
Goal:
I tried to let stepper motors move with an Arduino Mega. BecauseI also use a tft touch display and several sensors, the run() function (AccelStepper library) can't fire often enough. Especially reading touch-input from the tft display seems to slow it all down. So I decided to go with a seperate Arduino Uno that is only for letting the stepper motors run. From the Arduino Mega there are two digitals that tells the Arduino Uno with HIGH/LOW which direction is needed. If both are LOW, no movement is needed. On the other hand Arduino Uno should tell the Arduino Mega which position the motors are over serial. Format to send and receive is a long.
So far:
Robin2's plain flagship example from here works. I could send and receive several longs correctly.
Now when I add the AccelStepper library to the code, the output data is getting weird.
Code on the Arduino Uno (controlling stepper motors):
/* Example sketch to control a 28BYJ-48 stepper motor with ULN2003 driver board, AccelStepper and Arduino UNO: continuous rotation. More info: https://www.makerguides.com */
// Include the AccelStepper library:
#include <AccelStepper.h>
// Motor pin definitions:
#define motorsRightPin1 4 // IN1 on the ULN2003 driver
#define motorsRightPin2 5 // IN1 on the ULN2003 driver
#define motorsRightPin3 6 // IN1 on the ULN2003 driver
#define motorsRightPin4 7 // IN1 on the ULN2003 driver
#define motorsLeftPin1 8 // IN1 on the ULN2003 driver
#define motorsLeftPin2 9 // IN1 on the ULN2003 driver
#define motorsLeftPin3 10 // IN1 on the ULN2003 driver
#define motorsLeftPin4 11 // IN1 on the ULN2003 driver
byte relais = 3;
byte megaInputUp = 12;
byte megaInputDown = 13;
// megaOutput is pin 0 (Serial)
unsigned long millisPrev = 0;
unsigned long millisRelais = 0;
byte motorsError = 0;
int motorsSpeedUp = 1700;
int motorsSpeedDown = 2000;
int motorsAccUp = 500;
int motorsAccDown = 500;
long fullDistance = 74532; // 4096 = eine volle Umdrehung / ~75532 = Fensterhöhe
long motorsDistance = 0;
// Define the AccelStepper interface type; 4 wire motor in half step mode:
#define MotorInterfaceType 8
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper library with 28BYJ-48 stepper motor:
AccelStepper motorsLeft = AccelStepper(MotorInterfaceType, motorsLeftPin1, motorsLeftPin3, motorsLeftPin2, motorsLeftPin4);
AccelStepper motorsRight = AccelStepper(MotorInterfaceType, motorsRightPin1, motorsRightPin3, motorsRightPin2, motorsRightPin4);
void setup() {
Serial.begin(9600);
motorsLeft.setCurrentPosition(0);
motorsRight.setCurrentPosition(0);
// RELAIS
pinMode(relais, OUTPUT);
pinMode(megaInputUp, INPUT);
pinMode(megaInputDown, INPUT);
}
void loop() {
// FALLS MILLIS WIEDER VON VORNE BEGINNEN
if (millis() < millisPrev) {
millisRelais = 0;
}
millisPrev = millis();
if (millis() > millisRelais + 120000) {
if (digitalRead(relais) == HIGH) {
digitalWrite(relais, LOW);
motorsError = 1; // IRGENDWAS STIMMT DANN NICHT.
millisRelais = millis();
}
}
// RUN MOTORS
if (motorsError == 0) {
if (digitalRead(megaInputDown)==HIGH && digitalRead(megaInputUp)==LOW && motorsLeft.currentPosition() != fullDistance) { // Soll runterfahren
digitalWrite(relais, HIGH);
motorsLeft.setSpeed(motorsSpeedDown);
motorsRight.setSpeed(motorsSpeedDown);
motorsLeft.setAcceleration(motorsAccDown);
motorsRight.setAcceleration(motorsAccDown);
motorsLeft.moveTo(fullDistance);
motorsRight.moveTo(-fullDistance);
motorsLeft.run();
motorsRight.run();
millisRelais = millis();
} else if (digitalRead(megaInputUp)==HIGH && digitalRead(megaInputDown)==LOW && motorsLeft.currentPosition() != 0) { // Soll rauffahren
digitalWrite(relais, HIGH);
motorsLeft.setSpeed(motorsSpeedUp);
motorsRight.setSpeed(motorsSpeedUp);
motorsLeft.setAcceleration(motorsAccUp);
motorsRight.setAcceleration(motorsAccUp);
motorsLeft.moveTo(0);
motorsRight.moveTo(0);
motorsLeft.run();
motorsRight.run();
millisRelais = millis();
} else {
digitalWrite(relais, LOW);
}
motorsDistance = motorsLeft.currentPosition();
Serial.println(motorsDistance);
}
}
Code on the Arduino Mega (just receiving serial data for now) - congruent to Robin2's example:
// Example 4 - Receive a number as text and convert it to an int
const byte numChars = 32;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;
long dataNumber = 0; // new for this version
void setup() {
Serial1.begin(9600);
Serial.begin(9600);
Serial.println("<Arduino is ready>");
}
void loop() {
recvWithEndMarker();
showNewNumber();
}
void recvWithEndMarker() {
static byte ndx = 0;
char endMarker = '\n';
char rc;
if (Serial1.available() > 0) {
rc = Serial1.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 showNewNumber() {
if (newData == true) {
dataNumber = 0; // new for this version
dataNumber = atol(receivedChars); // new for this version
Serial.print("This just in ... ");
Serial.println(receivedChars);
Serial.print("Data as Number ... "); // new for this version
Serial.println(dataNumber); // new for this version
newData = false;
}
}
The input data in this example should be 0 since motorsLeft.currentPosition() should be 0 as well. But it receives data like '42' '4' 42000' '2' '5' '7'... To me it looks like AccelStepper also sends some data over the serial?!
I hope, someone can help me with this. What am I overlooking?
Best regards, t