Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
239 views
in Technique[技术] by (71.8m points)

python - pyserial communication with arduino (for motor-control)

I would like to send data from python do arduino in order to control motors via relays. Idea is to send a number, in order to identify a motor and a value, to finally move it. Unfortunately im struggling with some problems. Data is getting lost.

So, in this minimal example there is an identifier "n", to indicate that the received data is the variable "number" and an identifier "c" to identify that the received data is a counter. To find out what's wrong, I send the data back to Python and try to read it. This is setup is only working for the first to characters. All other data is getting lost.

Can someone give me a hint? Are those identifiers necessary? Do I have to put some delay(), or maybe another baut-rate?

I guess it's something about the second identifier. The setup is working fine, if I only work with the "counter" for example.

Thank you very much in advance!

Pyhton:

import serial
import time

Port = "/dev/cu.usbserial-A601FZBL"
ser = serial.Serial(Port,9600,timeout=1)

time.sleep(1)

counter = 0

def Test(counter):
    ser.write(b"n")
    ser.write(str(1).encode())
    print("number:", 1)

    get = ser.readline().decode()
    print("get:", get)    


    ser.write(b"c")
    ser.write(str(counter).encode())
    print("counter:", counter)

    get = ser.readline().decode()
    print("get:", get)
    print()


while True:
    Test(counter)
    counter += 1

Arduino:

void setup() {
  Serial.begin(9600);
}

int number;
int counter;

void loop() {
  if (Serial.available() > 0) {
    if (Serial.peek() == 'n') {
      Serial.read();
      number = Serial.parseInt();
      Serial.println(number);

      if (Serial.peek() == 'c') {
        Serial.read();
        counter = Serial.parseInt();
        Serial.println(counter);
      }

      while (Serial.available() > 0) {
        Serial.read();
      }
    }
  }
}

Sorry! Here is my sample-run: (I'm confused, why there are additional blank-lines, beside the print() in the output)

number: 1
get: 1


counter: 0
get: 

number: 1
get: 
counter: 1
get: 

number: 1
get: 
counter: 2
get: 

number: 1
get: 
counter: 3
get: 

number: 1
get: 
counter: 4
get: 

number: 1
get: 
counter: 5
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Thanks for the support. So, finally no data did get lost ;) The problem was: Arduino is creating a blank-line, when sending data back. so "ser.readline()[:-2].decode()" solved this issue. I run into another problem, when sending integers bigger than 9. In order to do so, one has to split the integer into separated chars and encode them. Here is my workaround:

Python:

import serial
import time

Port = "/dev/cu.usbserial-A601FZBL"
ser = serial.Serial(Port,9600,timeout=1)

time.sleep(1)

counter = 0

def Test(counter):
    data = [b"n", b"0", b"c"]
    value = list(str(counter))

    for char in value:
        data.append(char.encode())

    ser.write(data)
    print("write:", "0", counter)

    get_1 = ser.readline()[:-2].decode()
    get_2 = ser.readline()[:-2].decode()
    print("get:  ", get_1, get_2)
    print()

while True:
    Test(counter)
    counter += 1

Arduino:

void setup() {
  Serial.begin(9600);
}

int number;
int counter;

void loop() {
  while (Serial.available() > 0) {
    if (Serial.peek() == 'n') {
      Serial.read();
      number = Serial.parseInt();
      Serial.println(number);

      if (Serial.peek() == 'c') {
        Serial.read();
        counter = Serial.parseInt();
        Serial.println(counter);
      }

      while (Serial.available() > 0) {
        Serial.read();
      }
    }
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...