I am trying to write a code that will allow me to send output to my microcontroller (Sparkfun Redboard) using Python code.
I want to pass different variables (CMJ or SJ) I want the built-in LED to turn on (and stay on) if CMJ is passed and turn off (and stay off) if SJ is passed. I would also like to print("invalid") if anything else is passed.
Here is my python code:
import serial
import time
# Setup serial communication
serialcomm = serial.Serial("COM4", 500000)
serialcomm.timeout = 1
# Define your variable
activity = "CMJ" # Change this to "CMJ" or anything else to test different scenarios
while True:
if activity == "done":
print("finished")
break
elif activity == "CMJ":
command = "on"
elif activity == "SJ":
command = "off"
else:
command = "invalid"
# Send the command to the Arduino
serialcomm.write(('command'+'\n').encode()) # Send command with newline character
# Wait for a moment to ensure the command is processed
time.sleep(0.5)
# Read and print the response from the Arduino
response = serialcomm.readline().decode('ascii').strip()
print(response)
# Close the serial communication when done
serialcomm.close()
and my Arduino code:
String InBytes;
void setup() {
Serial.begin(500000); // Ensure this matches the Python code
pinMode(LED_BUILTIN, OUTPUT); // Set the LED pin as an output
digitalWrite(LED_BUILTIN, LOW); // Ensure the LED is off initially
}
void loop() {
if (Serial.available() > 0) {
InBytes = Serial.readStringUntil('\n'); // Read the incoming string until newline
InBytes.trim(); // Remove any leading or trailing whitespace/newline characters
// Debugging output
Serial.print("Received command: ");
Serial.println(InBytes);
if (InBytes == "on") {
digitalWrite(LED_BUILTIN, HIGH); // Turn the LED on
Serial.write("Led on"); // Send a response back
} else if (InBytes == "off") {
digitalWrite(LED_BUILTIN, LOW); // Turn the LED off
Serial.write("Led off"); // Send a response back
} else {
Serial.write("Invalid"); // Handle invalid commands
}
}
}
The result is that the LED just blinks away for a sec no matter what variable I pass (CMJ, SJ, or anything else. There must be something wrong with the code but cannot figure out.
Taking a closer look at your code, the bug is that you are using ('command'+'\n').encode()
. In this case, the Arduino will get the string "command\n"
.
To fix it, use this on the Python side:
# Setup serial communication
serialcomm = serial.Serial("COM4", 500000)
serialcomm.timeout = 1
# Define your variable
activity = "CMJ" # Change this to "CMJ" or anything else to test different scenarios
while True:
try:
if activity == "done":
print("finished")
break
elif activity == "CMJ":
command = "on"
elif activity == "SJ":
command = "off"
else:
command = "invalid"
command += "\n"
serialcomm.write(command.encode()) # Send command with newline character
time.sleep(0.5)
response = serialcomm.readline().decode('ascii').strip()
print(response)
except KeyboardInterrupt:
print("Goodbye!")
serialcomm.close()
break
Notice that I added a try:except
statement, like this, the loop will continue until someone uses cntrl+c
, at which point the script will end the serialcomm
will be closed.
Hope this helps.
Also the "proof" on my side:
Note: make sure that the Arduino/microcontroller board is not accessed by any other program or process than your Python script (f.e. don't use the Arduino IDE's Serial Monitor). Otherwise, the serial port is "open"/in use by another program and trying to access it in python will throw a permission error. Also check which COM port number you need to use before trying to access a port as well!