Hello all,
Once I again I am looking to the collective knowledge of this forum for a solution to my problem.
I am communicating between a Raspberry PI (Python 3.4) and an Arduino Uno, or I should say, trying.
Here is what should happen....
I send a command string to the Arduino "F25000,3500" with a new line character. The Uno reads this byte-by-byte and echos it back to the Pi. The Arduino then processes this data further and waits for a new command.
This works perfectly the first time (First run on the PI's program, and from a boot on the Arduino. If I just re-run the program over and over again, everything works fine.
However, when the PI sends Two or more commands to the UNO things get strange. Instead of sending the command - it sends odd characters, possibly more than it should. As with the earlier, the first command is fine, just the second, third and so on commands turn to jiberish.
With the first command always working, it seems as though something goes on between commands that messes with the serial data.
THINGS I HAVE NOTICED
- On first communication, I send 12 bytes and get 12 bytes back (not counting LF)
- Checking the buffer amount is always 12 on first command
- Data being Echoed from UNO is identical to data sent
- On second communication, I send 12 byte and get 18 bytes back
- Checking the buffer amount is always 18 on the second command
- Data being echoed from UNO is jiberish
I HAVE TRIED MANY DIFFERENT THINGS TO NO AVAIL, HOWEVER...
- Assuming it had to do with the serial port and perhaps buffer data on the PI side...
- I tried flushing the buffers - didn't help.
- I tried opening port - sending data - closing port then repeating - didn't help.
- Running without the UNO serial port monitor active - didn't help.
- Running without the UNO connected to a USB on a computer (power adapter instead - no help.
I suspect the problem is on the PI side but just have not been able to pinpoint the issue.
I sure hope someone can help me out on this one.
Thanks in advance,
Chris D
Python 3.4 code on Raspberry Pi 3
# This routine will send a command to the Arduino and it will execute
# It cannot do it repeatedly within a loop
from time import sleep
import serial
import binascii
err_cnt = 0
#Start up code to open the serial port
ser = serial.Serial("/dev/ttyS0",9600, timeout =1)
print("Hello, waiting for data...")
if ser.isOpen():
print(ser.name, "is open")
print(ser)
# Create & send the command to the Arduino
def Send_Command_To_Pi(Command_String, Steps, SPS):
global err_cnt
Command_String = Command_String
ser.write(Command_String.encode('ascii'))
sleep(.2)
Val1 = Steps + ","
ser.write(Val1.encode('ascii'))
sleep(.2)
Val2 = SPS
Check_Val = Command_String + Val1 + Val2
Val2 = Val2 + "\n"
ser.write(Val2.encode('ascii'))
print("Sent")
sleep(.1)
Buffer = ser.inWaiting()
print("Buffer ",Buffer)
try:
indata = bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
indata = indata + bytes.decode(ser.read())
print("S",Check_Val)
print("R",indata)
print("Cmds ",x, " Errors ",err_cnt)
except:
err_cnt += 1
print("ERROR count =",err_cnt)
sleep(1)
#First command sent to Arduino
print("------------------------")
Command_String = "F"
Steps = "25000"
SPS = "3500"
Send_Command_To_Pi(Command_String, Steps, SPS)
#Wait long enough for all activity to be done on Arduino
sleep(20)
#Second command sent to Arduino
print("------------------------")
Command_String = "R"
Steps = "25000"
SPS = "3500"
Send_Command_To_Pi(Command_String, Steps, SPS)
ARDUINO UNO Code (only relevant portions)
...
Serial.begin(9600); // set up Serial library at 9600 bps
...
// Fetch commands from serial port if there are any
if (Serial.available() > 0) {
inByte = Serial.read();
if (inByte != 10 || inByte != 13)
{
Serial.write(inByte); // echo back to pi everything that was sent in this command
}
// only input if a letter, number, =,?,+ are typed!
if ((inByte >= 65 && inByte <= 90) || (inByte >= 97 && inByte <= 122) || (inByte >= 48 && inByte <= 57) || inByte == 44 || inByte == 61 || inByte == 63) {
Serial_Command.concat(inByte);
}// end serial.available
// Process command when NL/CR are entered:
// Handle the incomming commands from the Raspberry Pi
if (inByte == 10 || inByte == 13) {
inByte = 0;
// Respond to a command:
if (Serial_Command.startsWith("F")) //FORWARD MOTION command
{
temp1 = Serial_Command.substring(1, Serial_Command.indexOf(','));
temp2 = Serial_Command.substring(Serial_Command.indexOf(',') + 1);
temp1.toCharArray(carray, 10);
CMD_Steps = atol(carray);
temp2.toCharArray(carray, 10);
Target_SPS = atol(carray);
digitalWrite(LeftWheelDir,L_FWD);
digitalWrite(RightWheelDir,R_FWD);
End_Move_Alert = 1;
Steps = 0;
Target_Steps = CMD_Steps;
Steps_To_Go = CMD_Steps;
ACC_Flag = 1;
Command = 0;
//response to Pi
//Serial.println(Command);
//Serial.println(CMD_Steps);
//Serial.println(Target_SPS);
}
else if (Serial_Command.startsWith("R")) // REVERSE MOTION command
{
temp1 = Serial_Command.substring(1, Serial_Command.indexOf(','));
temp2 = Serial_Command.substring(Serial_Command.indexOf(',') + 1);
temp1.toCharArray(carray, 10);
CMD_Steps = atol(carray);
temp2.toCharArray(carray, 10);
Target_SPS = atol(carray);
digitalWrite(LeftWheelDir,L_REV);
digitalWrite(RightWheelDir,R_REV);
End_Move_Alert = 1;
Steps = 0;
Target_Steps = CMD_Steps;
Steps_To_Go = CMD_Steps;
ACC_Flag = 1;
Command = 1;
//response to Pi
Serial.println(Command);
Serial.println(CMD_Steps);
Serial.println(Target_SPS);
}
else
{
if (!Serial_Command.equalsIgnoreCase(""))
{
//Serial.println("BAD");
}
}
Serial_Command = "";
}
}