วิธีส่งตัวเลขไปยัง Arduino UNO ผ่าน Python 3 และอนุกรมโมดูล


9

ฉันยังใหม่กับ Arduino (และการเขียนโปรแกรมคอมพิวเตอร์ทั่วไป) ดังนั้นฉันต้องขออภัยถ้าคำถามนี้ดูโง่

เมื่อฉันตั้งค่าการเชื่อมต่อ arduino-LED พื้นฐานฉันมีปัญหาในการส่ง INTEGERS ไปยัง arduino ผ่านพอร์ตอนุกรม ฉันสามารถส่งตัวอักษรเช่น 'm', 'o' และอื่น ๆ ได้อย่างง่ายดาย .. อย่างไรก็ตามถ้าฉันส่งหมายเลขดูเหมือนว่ามันจะไม่ได้รับ

นี่คือรหัส Arduino ที่ควรจะได้รับค่าจากพอร์ต usb ผ่าน python หรือจอภาพอนุกรมแล้วปรับความสว่างของ LED ตามค่า (ค่าต้องอยู่ในช่วง [0,255])

หมายเหตุ: ฉันกำลังใช้ ARDUINO UNO และ 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);
}

อย่างไรก็ตามเมื่อฉันป้อนค่าลงในพอร์ตอนุกรมหรือผ่าน Python เช่น 0 มันให้คำตอบที่ 48 (ซึ่งน่าสนใจคือรหัส ASCII สำหรับ 0!) และสว่างขึ้น LED ซึ่งไม่ใช่สิ่งที่ควรจะเกิดขึ้นตั้งแต่ ที่ 0 LED ควรดับ !! ฉันขาดอะไรบางอย่าง แต่หาอะไรไม่พบ ... คุณช่วยบอกฉันทีว่ามีอะไรผิดปกติได้หรือไม่?

นี่คือรหัสที่ฉันใช้ใน 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()

ฉันทำอะไรผิดหรือเข้าใจผิด ขอบคุณ.


1
ลองarduino.write(chr(valueToWrite))
Gerben

โซลูชันนี้ใช้งานไม่ได้กับตัวละคร .. นอกจากนี้สำหรับตัวอักษรที่เกี่ยวข้องมันใช้งานได้ดีเพียงส่งเป็นไบต์เช่น: b'm ' อย่างไรก็ตามขอบคุณสำหรับคำตอบ
mickkk

คำตอบ:


6

การแยกวิเคราะห์บน Arduino อาจช้าและใช้เวลานาน (ซึ่งไม่ดีถ้าคุณใช้การตั้งค่านาฬิกาล่วงหน้าหรือมีภารกิจที่สำคัญต่อเวลา) ดังนั้นลองทำใน Python

ปัญหาคือคุณกำลังส่งตัวเลขเป็น ASCII ในขณะที่คุณต้องส่งเป็นไบนารีแบบดิบ นี่คือที่structมา

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'#('

ดังนั้นสิ่งที่คุณต้องการคือ:

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

หรือบางสิ่งบางอย่างกับผลกระทบนั้น


ขอบคุณมาก! นี่คือสิ่งที่ฉันกำลังมองหา!
mickkk

แม้จะมีสิ่งที่กล่องข้อความว่างข้อความสีเทากล่าวว่าฉันจะบอกว่าขอบคุณ! พยายามเขียนบิตสตรีม (ไฟล์โปรแกรม FPGA .bin) ไปยังชิปแฟลช SPI โดยใช้ Teensy 3.2 พร้อม Arduino เป็นพีซี -> อินเตอร์เฟสแฟลชและนี่คือกุญแจสำคัญในการทำให้พีซีทำงานได้ในตอนท้าย
KyranF

1

Serial.read()อ่านเพียงหนึ่งตัวอักษรจากพอร์ตอนุกรมและส่งกลับค่า ASCII ของมันซึ่งอธิบายถึง48คุณได้รับ

หากต้องการอ่านตัวเลขทั้งหมดคุณมี 2 ตัวเลือก:

  1. การใช้งานที่อ่านเป็นตัวละครมากที่สุดเท่าที่จำเป็นและดำเนินการแปลงก่อนที่จะกลับจำนวนการอ่านเป็นSerial.parseInt() intโปรดตรวจสอบข้อมูลอ้างอิงเพิ่มเติมที่นี่
  2. คุณอ่านตัวอักษร eachn ในวง (มีSerial.read()) จนกว่าคนสุดท้ายที่ใส่แต่ละ charcater อ่านเป็นบัฟเฟอร์ ( charอาร์เรย์) atoiแล้วแปลงสตริงส่งผลไปยังหมายเลขที่มีฟังก์ชั่นมาตรฐาน

แน่นอนตัวเลือกแรกเป็นตัวเลือกที่ง่ายที่สุด แต่จะกลับมา0ถ้าไม่มีการอ่านหลังจากหมดเวลา 1s (กำหนดด้วยSerial.setTimeout())


คำตอบนี้ไม่ตรงกับที่ฉันขอ แต่มันมีประโยชน์มากและฉันจะใช้มัน! ขอบคุณมากสำหรับความช่วยเหลือ!
mickkk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.