Search code examples
pythonarduinoservo

arduino auto servo movement signal from python


how do i change the if statement in arduino in order to move the servo the same degrees as whats randomized in python?

First he's the python code:

import serial
import time
import random

arduinoData = serial.Serial('com4',9600)     
while True:
    low = 0; high = 180
    ran_number = random.randint(low, high)
    print ran_number
    time.sleep(1)

    arduinoData.write(ran_number) 

python code is fine works with other things.

Now the arduino code, fix this:

#include <Servo.h>
Servo myservo;

int data;
int pin=9;
int pos = 0;

void setup() { 
  myservo.attach(9);
  pinMode(pin, OUTPUT); 
  digitalWrite (pin, LOW);
  Serial.begin(9600);
}

void loop() {
while (Serial.available()){
  data = Serial.read();
}
if statement here.....                       
  }              
}

Solution

  • 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)