Cách gửi số tới Arduino UNO qua Python 3 và mô-đun nối tiếp


9

Tôi chưa quen với Arduino (và lập trình máy tính nói chung), vì vậy tôi xin lỗi nếu câu hỏi này có vẻ ngớ ngẩn.

Khi tôi thiết lập kết nối arduino-LED cơ bản, tôi gặp vấn đề khi gửi INTEGERS tới arduino thông qua cổng nối tiếp. Tôi có thể dễ dàng gửi các ký tự như 'm', 'o', v.v. Tuy nhiên, nếu tôi gửi một số thì có vẻ như đơn giản là nó không nhận được.

Đây là mã Arduino, lý tưởng là nó sẽ nhận được một giá trị từ cổng usb thông qua python hoặc màn hình nối tiếp và sau đó điều chỉnh độ sáng của đèn LED theo giá trị. (giá trị phải nằm trong phạm vi [0,255]).

LƯU Ý: Tôi đang sử dụng ARDUINO UNO và PYTHON 3

// --------------------------

int LED = 10;
int number;

void setup(){

pinMode(LED,OUTPUT);
Serial.begin(9600);
}

void loop(){

number = Serial.read();
Serial.print(number);
Serial.print('\n');
if(number == -1){
number = 0;
}

else if(number > 255){

number = 255;

}

else if(number < 0){

number = 0;
}

analogWrite(LED,number);
delay(1000);
}

Tuy nhiên, khi tôi nhập một giá trị vào cổng Nối tiếp hoặc thông qua Python, ví dụ 0, nó cho tôi 48 câu trả lời (điều thú vị là mã ASCII cho 0!) Và bật đèn LED không phải là điều nên xảy ra vì ở 0 đèn LED sẽ tắt !! Tôi đang thiếu một cái gì đó nhưng tôi không thể tìm thấy những gì ... Bạn có thể vui lòng cho tôi biết những gì sai?

Đây là mã tôi sử dụng trong Python:

import serial
import time
try:
    arduino = serial.Serial(port,speed)
    time.sleep(2)
    print("Connection to " + port + " established succesfully!\n")
except Exception as e:
    print(e)

#Note: for characters such as 'a' I set data = b'a' to convert the data in bytes
#However the same thing does not work with numbers...
data = 0
data = arduino.write(valueToWrite)
time.sleep(2)
arduino.close()

Tôi đang làm gì sai hay hiểu lầm? Cảm ơn bạn.


1
Hãy thửarduino.write(chr(valueToWrite))
Gerben

Giải pháp này không hoạt động ngay cả đối với các ký tự .. Hơn nữa, khi có liên quan đến các ký tự, nó hoạt động tốt chỉ cần gửi chúng dưới dạng byte như: b'm '. Dù sao, cảm ơn câu trả lời.
mickkk

Câu trả lời:


6

Phân tích cú pháp trên Arduino có thể chậm và tốn thời gian (điều này rất tệ nếu bạn sử dụng chế độ đặt trước đồng hồ hoặc có các nhiệm vụ quan trọng về thời gian), vì vậy hãy thực hiện bằng Python.

Vấn đề là bạn đang gửi các số dưới dạng ASCII trong khi bạn cần gửi chúng dưới dạng nhị phân thô. Đây là nơi structđến.

3>> import struct
3>> print(struct.pack('>B', 0))
b'\x00'
3>> print(struct.pack('>B', 255))
b'\xff'
3>> print(struct.pack('>2B', 255, 0))
b'\xff\x00'
3>> print(struct.pack('>H', 9000))
b'#('

Vì vậy, những gì bạn thực sự muốn là:

data = arduino.write(struct.pack('>B', valueToWrite))

Hoặc một cái gì đó để có hiệu lực.


Cảm ơn rât nhiều! Điều này thật đúng với gì mà tôi đã tìm kiếm!
mickkk

Mặc dù hộp bình luận trống rỗng có nội dung màu xám nói, tôi sẽ nói cảm ơn! Đã cố gắng ghi một luồng bit (tệp chương trình FPGA .bin) vào chip flash SPI bằng cách sử dụng Teensy 3.2 với Arduino làm PC -> giao diện flash và đây là chìa khóa để làm cho nó hoạt động trên đầu PC.
KyranF

1

Serial.read()chỉ đọc MỘT ký tự từ cổng nối tiếp và trả về giá trị ASCII của nó, điều này giải thích những 48gì bạn có.

Để đọc một số hoàn chỉnh, bạn có 2 tùy chọn:

  1. Sử dụng Serial.parseInt()đọc càng nhiều ký tự nếu cần và thực hiện chuyển đổi trước khi trả về số đã đọc dưới dạng int. Hãy tiếp tục kiểm tra các tài liệu tham khảo ở đây.
  2. Bạn đọc từng ký tự trong một vòng lặp (với Serial.read()) cho đến ký tự cuối cùng, đặt từng ký tự đọc vào một bộ đệm ( charmảng) sau đó chuyển đổi chuỗi kết quả thành một số có hàm C tiêu chuẩn atoi.

Tất nhiên, tùy chọn đầu tiên là dễ nhất nhưng nó sẽ trả về 0nếu không có gì được đọc sau khi hết thời gian 1 giây (có thể định cấu hình với Serial.setTimeout()).


Câu trả lời này không chính xác như những gì tôi đã yêu cầu, tuy nhiên nó rất hữu ích và tôi sẽ sử dụng nó! Cảm ơn bạn rất nhiều vì sự giúp đỡ!
mickkk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.