Serial Communication from Raspberry Pi to Arduino Stepper Motor not working

I'm trying to test code through my stepper motor through serial communication, but it is not working. I've tried test cases within the Arduino code and it works perfectly, but even when I try a simple ser.write() function in my Raspberry Pi, it won't turn to the specific point, only a very small turn happens.

I'm using the AccelStepper library, and I plugged my NEMA 23 into the Arduino. Here is the code for Python through a Raspberry Pi:

import serial

ser = serial.Serial('/dev/ttyACM0', 9600)

theta = 54

ser.write(theta)

And here's the code for my Arduino Mega:

#include <AccelStepper.h>

AccelStepper stepper(1,7,6); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

void setup(){  
   Serial.begin(9600);
   stepper.setMaxSpeed(150);
   stepper.setAcceleration(100);
   stepper.setCurrentPosition(0);  
}

void loop() { 
  if(Serial.available() > 0){
    int theta = SerialparseInt.read();
    double theta_to_pulse = theta/1.8;
  stepper.runToNewPosition(theta_to_pulse);
  //stepper.runToNewPosition(0);
  //stepper.run();
}

Is there any advice?

When your Python script opens the serial port, the arduino reboots and the setup takes a bit of time. As you send the angle right away, it’s lost as serial is not ready yet.

Try to delay 3s before sending theta

Side note:
I would suggest to study Serial Input Basics to understand how to correctly deal with the serial port on your arduino

May be not serial, but Serial ?

Sorry, I was pressing undo and went too far. I edited my post. I thought I could use parseInt to simply get the number that I want to send over. The code works within the Arduino but not through the Pi as it moves a very short distance.

I'll try that. Doing that, would I need to include the time library in Python for the delay? Or just simply delay it within the Arduino code?

No, the parseint function is inappropriate for this.
It get number from a string, but you send a byte from Pi
Use Serial.read() instead or change the Pi code

Okay so with incorporating what is recommended, I tried this:

I simply used this code first:

AccelStepper stepper(1,7,6); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

void setup()
{  
   stepper.setMaxSpeed(150);
   stepper.setAcceleration(100);
   stepper.setCurrentPosition(0);  
}

void loop()
{ 
  double theta = 90;
  double theta_to_pulse = theta/1.8;
  stepper.runToNewPosition(theta_to_pulse);
  //stepper.runToNewPosition(0);
  //stepper.run();
}

This moved my stepper motor 90 degrees like how I wanted it to.

Then I tried this code for serial communication:

#include <AccelStepper.h>

AccelStepper stepper(1,7,6); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

void setup(){  
   Serial.begin(9600);
   stepper.setMaxSpeed(150);
   stepper.setAcceleration(100);
   stepper.setCurrentPosition(0);  
}

void loop() { 
  delay(3000)
  if(Serial.available() > 0){
    delay(3000);
    int theta = Serial.read();
    delay(3000);
    double theta_to_pulse = theta/1.8;
    stepper.runToNewPosition(theta_to_pulse);
  //stepper.runToNewPosition(0);
  //stepper.run();
}
}

And my python code is:

import serial

ser = serial.Serial('/dev/ttyACM0', 9600)

theta = 54

ser.write(theta)

When I run this, the motor moves a hair.

My only thought would be possibly that the Arduino is drawing power from the Raspberry Pi to not make it turn, but I'm absolutely stuck.

First, two delays 3 sec each in receiver code should be removed.
And after that - add printing of theta variable to Serial and show the output


These are my two outputs. The first one is from 90 degrees, and the second one is from 150 degrees when I put those numbers into the serial monitor. The numbers pop up as pairs and the motor changes direction each time a pair of numbers is shown. And then the turn isn't close to 90 or 150 degrees.

I'm trying to have my Stepper Motor move a certain direction given code from a Raspberry Pi.

I simply used this code first:

AccelStepper stepper(1,7,6); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

void setup()
{  
   stepper.setMaxSpeed(150);
   stepper.setAcceleration(100);
   stepper.setCurrentPosition(0);  
}

void loop()
{ 
  double theta = 90;
  double theta_to_pulse = theta/1.8;
  stepper.runToNewPosition(theta_to_pulse);
  //stepper.runToNewPosition(0);
  //stepper.run();
}

This moved my stepper motor 90 degrees like how I wanted it to.

Then I tried this code for serial communication:

#include <AccelStepper.h>

AccelStepper stepper(1,7,6); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

void setup(){  
   Serial.begin(9600);
   stepper.setMaxSpeed(150);
   stepper.setAcceleration(100);
   stepper.setCurrentPosition(0);  
}

void loop() { 
  delay(3000)
  if(Serial.available() > 0){
    delay(3000);
    int theta = Serial.read();
    delay(3000);
    double theta_to_pulse = theta/1.8;
    stepper.runToNewPosition(theta_to_pulse);
  //stepper.runToNewPosition(0);
  //stepper.run();
}
}

And my python code is:

import serial

ser = serial.Serial('/dev/ttyACM0', 9600)

theta = 54

ser.write(theta)

When I run this, the motor moves a hair.

My only thought would be possibly that the Arduino is drawing power from the Raspberry Pi to not make it turn, but I'm absolutely stuck.

You can't use delay, especially with those numbers, in an Accelstepper application.

Sorry, I meant to take the first two delays out. I was testing where to put one. I tried to use the serial monitor however, and I got this output when I inserted 90 and 150



The numbers pop up in pairs, and whenever a pair is shown, the motor moves a bit, but not to either of the angles.

You **can't use any such large delays ** together with Accelstepper. It needs to be kicked at as high speed as possible. Else the stepper will freeze, during the delay.
Don't use screen shots like this! You can use the code tags for both code and output listings.

I'm trying to send a value from my Raspberry Pi as an angle value towards my Arduino Mega that is connected to a stepper motor. Here is what I have done so far:

First, I simply tested with manually inputting a value in for the motor to turn:

#include <AccelStepper.h>

AccelStepper stepper(1,7,6); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

void setup(){  

   stepper.setMaxSpeed(150);
   stepper.setAcceleration(100);
   stepper.setCurrentPosition(0);  
}

void loop()
{ 
  double theta = 90;
  double theta_to_pulse = theta/1.8;
  stepper.runToNewPosition(theta_to_pulse);
  //stepper.runToNewPosition(0);
  //stepper.run();
}

It worked perfectly.

Then I tried to incorporate serial commands with this code

#include <AccelStepper.h>

AccelStepper stepper(1,7,6); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

void setup(){  
   Serial.begin(9600);
   stepper.setMaxSpeed(150);
   stepper.setAcceleration(100);
   stepper.setCurrentPosition(0);  
}

void loop() { 
  if(Serial.available() > 0){
    int theta = serial.read();
    double theta_to_pulse = theta/1.8;
    stepper.runToNewPosition(theta_to_pulse);
  //stepper.runToNewPosition(0);
  //stepper.run();
}

When inputting a value like 90 or 150, I would get this in the Serial Monitor:


Each set of two numbers would pop up, and it would rotate at some weird small angle, thus wouldn't work.

Finally, I've been trying to get serial communication from my Raspberry Pi to Arduino to work, but it would move the motor literally a hair and stop:

import serial

ser = serial.Serial('/dev/ttyACM0', 9600)

theta = 54

ser.write(theta)

I'm not sure what the problem is. Could someone help?

raspberry pi serial comm permissions - Search (bing.com)

As I remember, you have some Linux stuff to work on

I have merged your cross-posts @ceowens.

Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting can result in a suspension from the forum.

In the future, please only create one topic for each distinct subject matter. This is basic forum etiquette, as explained in the "How to get the best out of this forum" guide. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

As I said, the Arduino reboots so it’s the Python code that needs waiting until the arduino is ready before sending data

Your topic has been moved to a more suitable location on the forum as this has nothing to do with Avrdude, stk500 or Bootloader.

I don't have time to read through all thiis convoluted thread, but if you are opening the Pi port each time to want to send a value it may be resetting the Arduino. This is a "feature " but a right PITA. There is a hardware fix that involves a capacitor on a couple of pins detailed somewhere. I use a Nano to control a pendulum clock and to update some parameters via the USB port i have a switch that connects the cap for control mode or not for reprogramming. One way to check would be to look at the leds on your Arduino as the Pi starts sending to see if you get8 the characteristic reset pattern.

Test with this code:

void setup(){  
   Serial.begin(9600);
 
}

void loop() { 
  if(Serial.available() > 0){
    int theta = Serial.read();
    Serial.println(theta, HEX);
}
}

and show the output. Don't use screen shots like above!

I hope you understand, that your Raspberry can't connect to the same Serial as Arduino USB (Serial). You should use an other port, such as Serial1, Serial2 etc