Cara mengirim nomor ke Arduino UNO melalui Python 3 dan serial modul

9

Saya baru mengenal Arduino (dan pemrograman komputer secara umum), jadi saya minta maaf jika pertanyaan ini terlihat konyol.

Setelah saya mengatur koneksi arduino-LED dasar, saya memiliki masalah dalam mengirim INTEGERS ke arduino melalui port serial. Saya dapat dengan mudah mengirim karakter seperti 'm', 'o' dan seterusnya .. Namun jika saya mengirim nomor sepertinya tidak mendapatkannya.

Berikut adalah kode Arduino, idealnya harus mendapatkan nilai dari port usb melalui python atau monitor serial dan kemudian menyesuaikan kecerahan LED sesuai dengan nilainya. (nilai harus dalam kisaran [0,255]).

CATATAN: Saya menggunakan ARDUINO UNO dan 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);
}

Namun, ketika saya memasukkan nilai ke port Serial atau melalui Python, misalnya 0, itu memberi saya 48 sebagai jawaban (yang, menariknya, adalah kode ASCII untuk 0!) Dan menyalakan LED yang bukan yang seharusnya terjadi karena pada 0 LED harus dimatikan !! Saya kehilangan sesuatu tetapi saya tidak dapat menemukan apa ... Bisakah Anda memberi tahu saya apa yang salah?

Berikut adalah kode yang saya gunakan dalam 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()

apa yang saya lakukan salah atau kesalahpahaman? Terima kasih.

mickkk
sumber
1
Cobaarduino.write(chr(valueToWrite))
Gerben
Solusi ini tidak berfungsi bahkan untuk karakter .. Selanjutnya, sejauh menyangkut karakter, berfungsi dengan baik hanya mengirim mereka sebagai byte seperti: b'm '. Bagaimanapun, terima kasih atas jawabannya.
mickkk

Jawaban:

6

Mem-parsing pada Arduino bisa lambat dan memakan waktu (yang buruk jika Anda menggunakan prescaling jam atau memiliki tugas-tugas penting), jadi mari kita lakukan dengan Python.

Masalahnya adalah Anda mengirim nomor sebagai ASCII sedangkan Anda harus mengirimnya sebagai biner mentah. Di sinilah structmasuk.

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

Jadi yang Anda inginkan adalah:

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

atau sesuatu untuk efek itu.

Ignacio Vazquez-Abrams
sumber
Terima kasih banyak! Ini persis apa yang saya cari!
mickkk
Terlepas dari apa yang dikatakan kotak abu-abu kotak komentar kosong, saya akan mengucapkan terima kasih! Sedang mencoba untuk menulis bit-stream (file program FPGA .bin) ke chip flash SPI menggunakan Teensy 3.2 dengan Arduino sebagai PC -> antarmuka flash, dan ini adalah kunci untuk membuatnya bekerja pada ujung PC.
KyranF
1

Serial.read()hanya membaca SATU karakter dari port serial dan mengembalikan nilai ASCII-nya, yang menjelaskan apa yang 48Anda dapatkan.

Untuk membaca angka lengkap, Anda memiliki 2 opsi:

  1. Gunakan Serial.parseInt()yang membaca karakter sebanyak yang diperlukan dan melakukan konversi sebelum mengembalikan nomor baca sebagai int. Silakan periksa referensi lebih lanjut di sini.
  2. Anda membaca setiap karakter dalam satu lingkaran (dengan Serial.read()) hingga yang terakhir, menempatkan setiap karakter baca ke dalam buffer ( chararray) kemudian mengubah string yang dihasilkan ke angka dengan fungsi C standar atoi.

Tentu saja, opsi pertama adalah yang paling mudah tetapi akan kembali 0jika tidak ada yang dibaca setelah batas waktu 1s (dapat dikonfigurasi dengan Serial.setTimeout()).

jfpoilpret
sumber
Jawaban ini tidak persis apa yang saya minta, namun sangat berguna dan saya akan menggunakannya! Terima kasih banyak atas bantuannya!
mickkk