Como enviar números para o Arduino UNO via Python 3 e o módulo serial


9

Eu sou novo no Arduino (e na programação de computadores em geral), então peço desculpas se essa pergunta parecer boba.

Depois de configurar uma conexão arduino-LED básica, tenho problemas ao enviar INTEGERS para o arduino através da porta serial. Posso facilmente enviar caracteres como 'm', 'o' e assim por diante. No entanto, se eu enviar um número, parece que ele simplesmente não o entende.

Aqui está o código do Arduino, idealmente, ele deve obter um valor da porta usb através do python ou do monitor serial e, em seguida, ajustar o brilho do LED de acordo com o valor. (o valor deve estar no intervalo [0,255]).

NOTA: Estou 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);
}

No entanto, quando insiro um valor na porta serial ou através do Python, por exemplo 0, ele me fornece 48 como resposta (que, curiosamente, é o código ASCII para 0!) E acende o LED, que não é o que deveria acontecer desde a 0 o LED deve estar apagado !! Estou faltando alguma coisa, mas não consigo encontrar o que ... Você poderia me dizer o que está errado?

Aqui está o código que eu uso no 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()

o que estou fazendo de errado ou mal-entendido? Obrigado.


11
Tentearduino.write(chr(valueToWrite))
Gerben 12/08

Esta solução não funciona mesmo para caracteres. Além disso, no que diz respeito aos caracteres, funciona bem apenas enviando-os como bytes como: b'm '. De qualquer forma, obrigado pela resposta.
Mckkk 12/08

Respostas:


6

A análise no Arduino pode ser lenta e demorada (o que é ruim se você usar a pré-escala do relógio ou tiver tarefas críticas), então vamos fazê-lo no Python.

O problema é que você está enviando os números como ASCII, enquanto você precisa enviá-los como binários brutos. É aqui que structentra.

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

Então, o que você realmente quer é:

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

ou algo nesse sentido.


Muito obrigado! Era exatamente isso que eu estava procurando!
Mckkk 12/08

Apesar do que diz o texto acinzentado da caixa de comentários vazia, vou agradecer! Estava tentando gravar um fluxo de bits (arquivo de programa .GA de FPGA) em um chip flash SPI usando um Teensy 3.2 com Arduino como a interface PC -> flash, e essa era a chave para fazê-lo funcionar no final do PC.
KyranF

1

Serial.read()lê apenas UM caractere da porta serial e retorna seu valor ASCII, o que explica o que 48você obteve.

Para ler um número completo, você tem 2 opções:

  1. Use Serial.parseInt()que leia quantos caracteres forem necessários e realize a conversão antes de retornar o número de leitura como um int. Por favor, verifique a referência aqui.
  2. Você lê cada caractere em um loop (com Serial.read()) até o último, coloca cada caractere de leitura em um buffer ( charmatriz) e converte a sequência resultante em um número com a função C padrão atoi.

Obviamente, a primeira opção é a mais fácil, mas retornará 0se nada for lido após um tempo limite de 1s (configurável com Serial.setTimeout()).


Esta resposta não era exatamente o que eu estava pedindo, no entanto, foi muito útil e eu a usarei! Muito obrigado pela ajuda!
Mckkk 12/08
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.