Come inviare numeri ad Arduino UNO tramite Python 3 e il modulo seriale


9

Sono nuovo di Arduino (e della programmazione per computer in generale), quindi mi scuso se questa domanda sembra sciocca.

Una volta impostato un collegamento arduino-LED di base, ho problemi a inviare INTEGERS ad arduino attraverso la porta seriale. Posso facilmente inviare caratteri come 'm', 'o' e così via .. Tuttavia, se invio un numero sembra che semplicemente non lo capisca.

Ecco il codice Arduino, idealmente dovrebbe ottenere un valore dalla porta USB tramite Python o il monitor seriale e quindi regolare la luminosità del LED in base al valore. (il valore deve essere compreso nell'intervallo [0,255]).

NOTA: sto usando ARDUINO UNO e 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);
}

Tuttavia, quando inserisco un valore nella porta seriale o tramite Python, ad esempio 0, mi dà 48 come risposta (che, cosa interessante, è il codice ASCII per 0!) E illumina il LED che non è ciò che dovrebbe accadere da allora a 0 il LED dovrebbe essere spento !! Mi manca qualcosa ma non riesco a trovare cosa ... Potresti dirmi cosa c'è che non va?

Ecco il codice che uso in 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()

cosa sto facendo di sbagliato o incomprensione? Grazie.


1
Provaarduino.write(chr(valueToWrite))
Gerben,

Questa soluzione non funziona nemmeno per i personaggi .. Inoltre, per quanto riguarda i personaggi, funziona bene semplicemente inviandoli come byte come: b'm '. Comunque, grazie per la risposta.
Mickkk,

Risposte:


6

L'analisi su Arduino può essere lenta e dispendiosa in termini di tempo (il che è negativo se si utilizza il prescaling dell'orologio o si hanno attività critiche in termini di tempo), quindi facciamolo in Python.

Il problema è che stai inviando i numeri come ASCII mentre devi inviarli come binari grezzi. È qui che structentra in gioco.

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

Quindi quello che vuoi davvero è:

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

o qualcosa in tal senso.


Grazie mille! Questo e 'esattamente quello che stavo cercando!
Mickkk,

Nonostante ciò che dice il testo in grigio nella casella di commento vuota, dirò grazie! Stavo cercando di scrivere un bit-stream (file di programma .bin FPGA) su un chip flash SPI usando un Teensy 3.2 con Arduino come interfaccia flash per PC ->, e questa era la chiave per farlo funzionare sul PC.
KyranF,

1

Serial.read()legge solo UN carattere dalla porta seriale e restituisce il suo valore ASCII, il che spiega il risultato 48ottenuto.

Per leggere un numero completo, hai 2 opzioni:

  1. Utilizzare Serial.parseInt()che legge tutti i caratteri necessari ed esegue la conversione prima di restituire il numero letto come int. Si prega di controllare ulteriormente il riferimento qui.
  2. Leggi ogni carattere in un ciclo (con Serial.read()) fino all'ultimo, inserisci ciascun carattere di lettura in un buffer ( charmatrice), quindi converti la stringa risultante in un numero con la funzione C standard atoi.

Naturalmente, la prima opzione è la più semplice, ma tornerà 0se non viene letto nulla dopo un timeout di 1s (configurabile con Serial.setTimeout()).


Questa risposta non era esattamente quello che stavo chiedendo, tuttavia è stata molto utile e la userò! Grazie mille per l'aiuto!
Mickkk,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.