I have connected an Arduino to a raspberry pi so that a specific event is triggered when I send a signal(in this case a number). When I send a number with the script and tell it just to print in serial monitor it works, when I try and just have it run the motors on start it works fine, however when combining the two: having it run a specific command if a particular number is received nothing happens. If anyone could point to the flaw here, I would be very grateful. Python Code:
import serial, time
arduino = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
cmd = ''
while cmd != '0':
cmd = input('Enter a cmd ')
arduino.write(cmd.encode('ascii'))
Arduino Code:
#include <Arduino.h>
const byte MOTOR_A = 3; // Motor 2 Interrupt Pin - INT 1 - Right Motor
const byte MOTOR_B = 2; // Motor 1 Interrupt Pin - INT 0 - Left Motor
// Constant for steps in disk
const float stepcount = 20.00; // 20 Slots in disk, change if different
// Constant for wheel diameter
const float wheeldiameter = 66.10; // Wheel diameter in millimeters, change if different
const float gear_ratio = 34;
const float PPR = 12;
// Integers for pulse counters
volatile int counter_A = 0;
volatile int counter_B = 0;
// Motor A
int enA = 10;
int in1 = 9;
int in2 = 8;
// Motor B
int enB = 5;
int in3 = 7;
int in4 = 6;
// Interrupt Service Routines
// Motor A pulse count ISR
void ISR_countA()
{
counter_A++; // increment Motor A counter value
}
// Motor B pulse count ISR
void ISR_countB()
{
counter_B++; // increment Motor B counter value
}
// Function to convert from centimeters to steps
int CMtoSteps(float cm)
{
float circumference = (wheeldiameter * 3.14) / 10; // Calculate wheel circumference in cm
return int(cm * gear_ratio * PPR / circumference);
}
// Function to Move Forward
void MoveForward(int steps, int mspeed)
{
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
// Set Motor A forward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B forward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Go forward until step value is reached
while (steps > counter_A or steps > counter_B) {
if (steps > counter_A) {
analogWrite(enA, mspeed);
} else {
analogWrite(enA, 0);
}
if (steps > counter_B) {
analogWrite(enB, mspeed);
} else {
analogWrite(enB, 0);
}
}
// Stop when done
analogWrite(enA, 0);
analogWrite(enB, 0);
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
}
// Function to Move in Reverse
void MoveReverse(int steps, int mspeed)
{
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
// Set Motor A reverse
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B reverse
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Go in reverse until step value is reached
while (steps > counter_A && steps > counter_B) {
if (steps > counter_A) {
analogWrite(enA, mspeed);
} else {
analogWrite(enA, 0);
}
if (steps > counter_B) {
analogWrite(enB, mspeed);
} else {
analogWrite(enB, 0);
}
}
// Stop when done
analogWrite(enA, 0);
analogWrite(enB, 0);
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
}
// Function to Spin Right
void SpinRight(int steps, int mspeed)
{
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
// Set Motor A reverse
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B forward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Go until step value is reached
while (steps > counter_A && steps > counter_B) {
if (steps > counter_A) {
analogWrite(enA, mspeed);
} else {
analogWrite(enA, 0);
}
if (steps > counter_B) {
analogWrite(enB, mspeed);
} else {
analogWrite(enB, 0);
}
}
// Stop when done
analogWrite(enA, 0);
analogWrite(enB, 0);
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
}
// Function to Spin Left
void SpinLeft(int steps, int mspeed)
{
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
// Set Motor A forward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B reverse
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Go until step value is reached
while (steps > counter_A && steps > counter_B) {
if (steps > counter_A) {
analogWrite(enA, mspeed);
} else {
analogWrite(enA, 0);
}
if (steps > counter_B) {
analogWrite(enB, mspeed);
} else {
analogWrite(enB, 0);
}
}
// Stop when done
analogWrite(enA, 0);
analogWrite(enB, 0);
counter_A = 0; // reset counter A to zero
counter_B = 0; // reset counter B to zero
}
void setup()
{
Serial.begin(9600);
// Attach the Interrupts to their ISR's
pinMode(MOTOR_A,INPUT);
pinMode(MOTOR_B,INPUT);
pinMode(in1,OUTPUT);
pinMode(in2,OUTPUT);
pinMode(in3,OUTPUT);
pinMode(in4,OUTPUT);
pinMode(enA,OUTPUT);
pinMode(enB,OUTPUT);
attachInterrupt(digitalPinToInterrupt (MOTOR_A), ISR_countA, RISING); // Increase counter A when speed sensor pin goes High
attachInterrupt(digitalPinToInterrupt (MOTOR_B), ISR_countB, RISING); // Increase counter B when speed sensor pin goes High
}
void loop()
{
delay(100);
int compareOne = 1;
int compareTwo = 2;
int compareThree = 3;
if (Serial.available() > 0){
String stringFromSerial = Serial.readString();
if (stringFromSerial.toInt() == compareOne){
Serial.println("Forward");
MoveForward(CMtoSteps(50), 255); // Forward half a metre at 255 speed
}
if (stringFromSerial.toInt() == compareTwo){
Serial.println("Spin Right");
SpinRight(CMtoSteps(10), 255); // Right half a metre at 255 speed
}
if (stringFromSerial.toInt() == compareThree){
Serial.println("Spin Left");
SpinLeft(CMtoSteps(10), 255); // Right half a metre at 255 speed
}
else {
Serial.println("Not equal");
}
}
Put whatever you want here!
MoveReverse(CMtoSteps(25.4),255); // Reverse 25.4 cm at 255 speed
}
UPDATE: I have changed the loop
so that it compares ints instead of strings as per @GrooverFromHolland suggestion. Still, nothing happens when I input from python but it is printed in the serial monitor. Why the motors spin when I just trigger it in the loop directly for testing, but not when commanded to via serial monitor is my issue. As well as this, I have discovered that the interrupts are not working for some reason. Any help appreciated.