What you are looking for is the ParseInt method. Instead of using read
in a loop and constructing your number, Serial.ParseInt
does exactly that for you.
The correct code would be:
#include <Servo.h>
Servo myservo;
int pin = 9;
void setup() {
myservo.attach(9);
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
Serial.setTimeout(100);
Serial.begin(9600);
}
void loop() {
int number;
if (Serial.available()) {
number = Serial.parseInt();
myservo.write(number);
delay(0.5);
}
}
Notice that I set the serial timeout period to 100ms. This is to prevent parseInt
to wait too much before deciding that it has read an entire int; otherwise when receiving a value (say, 42) it waits for about 1 second waiting for some other digits.
The Python script also has a problem or two. First, you should wait for a bit after establishing the connection because every time the serial is opened the Arduino resets, so it won't read the first couple of values. You could also get a cleaner solution by printing some string from the Arduino when ready (as the last instruction of the setup
function, for example) and wait for it in the Python script with readLine
.
Secondly, arduinoData.write
takes a byte array as input, whereas you pass an int. You need to encode such int in bytes, first converting it to a string with str
and then encoding it with encode
.
I got the following program working:
import serial
import time
import random
arduinoData = serial.Serial('/dev/ttyUSB0',9600)
# Let Arduino some time to reset
time.sleep(2)
while True:
low = 0; high = 180
ran_number = random.randint(low, high)
print(ran_number)
arduinoData.write(str(ran_number).encode())
time.sleep(1)