Python 3 ve modül seri üzerinden Arduino UNO'ya numara gönderme


9

Arduino'da (ve genel olarak bilgisayar programlamasında) yeniyim, bu yüzden bu soru aptalca görünüyorsa özür dilerim.

Temel bir arduino-LED bağlantısı kurduktan sonra, seri port üzerinden INTEGERS'ı arduino'ya göndermekte sorun yaşıyorum. Kolayca 'm', 'o' ve benzeri karakterleri gönderebilirim .. Ancak bir numara gönderirsem, anlaşılmaz gibi görünüyor.

İşte Arduino kodu, ideal olarak python veya seri monitör aracılığıyla usb portundan bir değer almalı ve daha sonra LED'in parlaklığını değere göre ayarlamalıdır. (değer [0,255] aralığında olmalıdır).

NOT: ARDUINO UNO ve PYTHON 3 kullanıyorum

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

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);
}

Ancak, Seri bağlantı noktasına veya Python aracılığıyla bir değer girdiğimde, örneğin 0, bana cevap olarak 48 verir (ilginç bir şekilde, 0 için ASCII kodu!) Ve o zamandan beri olması gerekmeyen LED'i yakar. 0'da LED kapalı olmalıdır !! Bir şey eksik ama ne bulamıyorum ... Lütfen neyin yanlış olduğunu söyler misiniz?

İşte Python içinde kullandığım kod:

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

ne yanlış yapıyorum ya da yanlış anlıyorum? Teşekkür ederim.


1
Deneyinarduino.write(chr(valueToWrite))
Gerben

Bu çözüm karakterler için bile işe yaramaz .. Ayrıca, karakterler söz konusu olduğunda, sadece bayt olarak göndermek için iyi çalışır: b'm '. Her neyse, cevap için teşekkürler.
mickkk

Yanıtlar:


6

Arduino'da ayrıştırma yavaş ve zaman alıcı olabilir (saat ölçeklendirme kullanıyorsanız veya zaman açısından kritik görevleriniz varsa kötüdür), bu yüzden Python'da yapalım.

Sorun sayıları ASCII olarak göndermenizdir, oysa onları ham ikili olarak göndermeniz gerekir. Burası devreye structgiriyor.

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

Yani gerçekten istediğiniz şey:

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

ya da bu yönde bir şey.


Çok teşekkür ederim! Tam da aradığım şey buydu!
mickkk

Boş yorum kutusunun gri metin yazmasına rağmen, teşekkür edeceğim! PC -> flash arabirimi olarak Arduino ile Teensy 3.2 kullanarak bir SPI flash çipine bir bit akışı (FPGA .bin program dosyası) yazmaya çalışıyordu ve bu PC ucunda çalışmasını sağlayan anahtardı.
KyranF

1

Serial.read()seri bağlantı noktasından yalnızca BİR karakter okur ve ASCII değerini döndürür 48.

Tam bir sayıyı okumak için 2 seçeneğiniz vardır:

  1. Gerektiği Serial.parseInt()kadar karakter okuyan ve okuma numarasını bir olarak döndürmeden önce dönüştürme işlemini kullanın int. Lütfen referansı buradan kontrol edin .
  2. Her karakter karakterini Serial.read()sonuncusuna kadar bir döngüde (ile ) okur, her bir okuma karakterini bir tampona ( chardizi) koyarsınız ve sonra elde edilen dizeyi standart C işleviyle bir sayıya dönüştürürsünüz atoi.

Tabii ki, ilk seçenek en kolay olanıdır, ancak 01 saniyelik bir zaman aşımından sonra hiçbir şey okunmazsa geri döner (ile yapılandırılabilir Serial.setTimeout()).


Bu cevap tam olarak istediğim şey değildi, ancak çok faydalı oldu ve kullanacağım! Yardımın için çok teşekkür ederim!
mickkk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.