Hello Guys,
I need your help a little bit. I have been reading a lot in the recent weeks about non-blocking codes and other stuff to understand how to build up my code. But, I am still struggling.
I am trying to move a stepper motor and read a load cell simultaneously. The idea is to move the stepper motor continuously until I interrupt the action through the serial connection. I do not need very quick acquisition rate, 10 Hz is more than enough. So, the load cell's circuit (HX711) is not the issue.
My issue is probably is that I am sending data through the terminal "frequently". Here is the loop():
void loop(){
if (Serial.available() > 0) {
char cin = Serial.read(); //read in the command letter
if(cin == 's'){ //if the command is 's' = START
cin1 = Serial.parseFloat(); //value for speed from the terminal
while (Serial.read() != 'n') { //while we dont STOP through the serial this loop will run.
if (micros() > time_now1 + cin1)
{
counter++; //counter for the steps
divider = 1000000/(cin1*counter); //the divider will tell the number of samples per second. more samples will slow down the arduino.
time_now1 = micros();
if (divider == 1) //div = 4, 4 samples / second. this is still OK for serial and stepper.
{
if(scale.is_ready() == true){
dataAdc = scale.read();}
Serial.print(micros());
Serial.print('\t');
//Serial.write(scale.get_units());
Serial.print(dataAdc);
counter = 0;
Serial.print('\n');
}
digitalWrite(stepper, HIGH);
}
if (micros() > time_now2 + cin1) {
//counter2++;
time_now2 = micros();
digitalWrite(stepper, LOW);
}
}
}//end of WHILE 'n' loop
}//end of IF 's' loop
So, as you can see, the Arduino is waiting for a command, a letter (s) through the terminal, and an integer to start the inner while loop. Then, while an other (n) letter is not coming through the terminal, the stepper motor (driven by and EasyDriver) is running based on cin1 which is basically the delay between a digitalWrite. During the run of the motor, I want to get periodic readouts from the HX711 circuit, for example at every 5000th cycle. I made a "divider" where I manually calculated my desired values and I check if I get that value. In this case, I have a "magic number", 1000000, so, when the speed (cin1) is at 200, I will get a readout at every 5000th step of the motor which is 1 value/second. . Based on this number, I can tell the program to enter a small sub-loop to send some data to my PC through the serial.
The problem comes here. When I send something through serial while the motor is running, there will be a small, periodic "knocking" noise coming from the motor. Since my delay (cin1) is in us, and the 4 serial.print takes roughly 1200 us, I suspect that the motor skips or stops for a short time, so the normal rhythm of the rotation gets interrupted for a very short time which will cause the noise.
I think this can be problematic, because if I run the the motor for a long time, I might have some problems with my accuracy due to the accumulated delays caused by the printing.
I tried to print on the second part of the stepping, to make the delays symmetric, but the problem is the order of magnitude time difference between the delays for the motor and the delay caused by the serial communication. I commented out the serial.print() part and ran the motor just as it is, without sending anything through the terminal, and there was no noise. I also tried to send some random characters, but NOT reading the hx711, and the noise was still there. So I suspect that the serial somehow blocks my motor.
I need to run this motor relatively fast, thus the microsecond region for delay is unavoidable. (I am using the stepper motor with a 1:100 gear setup, because I need torque, a lot.)
Is there anything that can be improved with my code (of course yes) and make the serial communication more efficient? I don't need very high speeds, 10 Hz is enough, but at slower speeds of the motor, even 1-2 Hz is OK.
Thank you for your help, and please let me know if you want me to provide more details.