Enviar múltiples datos desde Python

Hola

Hace un tiempo desarrollé una aplicación en Python que toma datos de un juego como la velocidad, se manda al Arduino y este mueve un servomotor que bien puede servidor como velocímetro. Ahora he querido usarlo en otros juegos pero a la vez mandando mas datos a la vez como la marcha, RPM, etc..... En este foro hay ejemplos como
http://forum.arduino.cc/index.php?topic=212305.0
http://forum.arduino.cc/index.php?topic=8336.0

Pero mi problema es que en el primero los datos se muestran en una aplicación gráfica aparte mientras que el segundo recibe los datos ya listos a través de X-Sim, un software enfocado en los simuladores de movimiento 2DOF. Yo hice una aplicación en Python, obtengo los datos, los meto dentro de un diccionario junto a una llave, por ejemplo, {R: , S: , G: }

Mi gran duda y de la cual he estado preguntando e investigando, en base a un diccionario de datos, hashmap o similar, como mando un array de datos asociativos desde Python y que el Arduino pueda interpretar como en el segundo ejemplo antes dado. ¿Por qué necesito que sea así? porque hay juegos en la cual es imposible obtener ciertos datos porque el juego mismo no los tiene. En simuladores se obtiene la cantidad de combustible, la fuerza G, el estado de los neumaticos, etc...., pero en otros juegos no es posible tener dato de aquello, y mi idea es abarcar la mayor cantidad de juegos y que mi aplicación sea lo mas modular posible en cuanto a datos.

Esta pregunta la he buscado y he preguntado hasta el cansancio en grupos de Facebook e incluso en Reddit. Si bien tiene que ver un tema entre Python y Arduino, como que no tengo otras opciones de busqueda ya que como solución me dicen que reescriba la aplicacion a C/C++, y por experiencia no he podido hacer el salto. Se que no tengo un codigo Arduino para mostrar mi duda pero si les dejo el archivo en Python por el cual estoy obteniendo los datos del juego.

https://github.com/PPastene/pyspeedo/blob/master/dirt3.py

Cabe decir que se imprimen por consola, aun no los manda por serial al Arduino.

Exactamente cuál es tu duda?

Lo que preguntas es cómo recibir una trama para que luego Arduino realice cierta acción basado en ese dato?

PD: al ser datos en tiempo real, puede que sea mejor enviar dichos datos en forma binaria.
No hablo de enviar '1' y '0' como caracteres, sino que -por ejemplo- el valor de las RPM se pueda en enviar con tan solo 2 caracteres/bytes.

No se a que te refieres con trama. De hecho ya he tenido este tipo de tropiezo en donde ni yo logro expresar bien lo que quiero preguntar

Mi duda es, como mando un diccionario, hashmap o array asociativo de datos desde Python al Arduino, para que en el Arduino por ejemplo, si se recibe una R deba ejecutar tal función que deba leer el valor que tiene R, algo así como este código Connecting real car cluster with pc games (X-sim) - Exhibition - Arduino Forum

P-Pablo:
No se a que te refieres con trama.

Llámalo "paquete", "trama", "frame" o como sea.
Hablo de un conjunto de bytes que representan un dato. Ejemplos:

"R1500"
El programa debe interpretarlo como "ajustar las RPM a mostrar, al equivalente a 1500"

"R3000S110"
RPM a 3000, velocidad a 110.

En este último ejemplo se puede apreciar cómo la información se recibirá: todo junto.
Creo que es fácil darse cuenta que cada trama, orden, comando o "tipo de dato"; está separado por un caracter no númerico.

Una implementación binaria del segundo ejemplo sería el siguiente:

0x7F 0x00 0xB8 0x0B 0x7F 0x01 0x6E 0x00

0x7F: inicio del la trama que contiene un dato. El valor es definido por el programador, pero debe ser reconocido por el receptor.
0x00: índice del "tipo de dato"; equivale a las letras R, S o G. El valor es asignado por el programador (hasta 256 diferentes en caso de indexar con un único byte), pero debe ser reconocido por el receptor. Para el ejemplo, supongamos que este valor equivale a 'R' o las RPM. ESTE TIPO DE DATO ASUMIRÁ QUE LOS DOS SIGUIENTES BYTES SON EL VALOR DE ESTE.
0xB8 0x0B: representan el valor de este dato (ahora las RPM). Aquí es donde entra en juego la enorme ventaja del binario: ESTOS BYTES SE PUEDEN COPIAR DIRECTAMENTE A UN VARIABLE, EVITANDO ASÍ EL TEDIOSO PROCESO DE CONVERTIR DESDE TEXTO. Si se copiaran directamente a una variable int, el valor de este sería 3000 (como en el ejemplo).
0x7F: inicio de otra trama que contiene otro dato.
0x01: índice del "tipo de dato". Para el ejemplo, supongamos que este valor equivale a 'S' o velocidad. ESTE TIPO DE DATO ASUMIRÁ QUE LOS DOS SIGUIENTES BYTES SON EL VALOR DE ESTE.
0x6E 0x00: representan el valor de este dato (ahora la velocidad). Si se copiaran directamente a una variable int, el valor de este sería 110 (como en el ejemplo).

P-Pablo:
Mi duda es, como mando un diccionario, hashmap o array asociativo de datos desde Python al Arduino

Asumiendo que ya tienes claro cómo Arduino debe interpretar las órdenes, entonces ya eso es por el lado del emisor.
No conozco mucho de Python (por no decir "nada"), pero la idea base es la siguiente:

Necesito enviar cierto dato, entonces primero le imprimo la letra que lo representa, luego el valor de ese dato.

Más claro ahora?

PD: si Python permite enviar valores numéricos en forma binaria, en serio deberías considerarlo. Estamos hablando de mostrar información en tiempo real, así pues lo más lógico sería entonces que el tiempo de procesamiento sea el menor posible, no crees?

Hola

Primero, feliz navidad algo atrasada, ya después de pasarla en familia escribí un codigo (tanto en python como en arduino) de lo que quiero lograr

bool led1;
bool led2;
bool led3;

char kind_of_data;

void setup() {
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);

  Serial.begin(9600);
}

void loop() {
  while(Serial.available() > 0){
    kind_of_data = Serial.read();
    if(kind_of_data == 'R'){
      led1 = Serial.read();
      digitalWrite(7, led1);
    }
    if(kind_of_data == 'P'){
      led2 = Serial.read();
      digitalWrite(7, led2);
    }
    if(kind_of_data == 'S'){
      led3 = Serial.read();
      digitalWrite(7, led3);
    }
  }
}
import serial
import time

ser = serial.Serial()
ser.port = "COM3"
ser.baudrate=9600
ser.bytesize=serial.EIGHTBITS
ser.timeout=1

datos = {}
ser.open()

while True:
    datos = {'R': False, 'P': False, 'S': False}
    print(datos)
    ser.write(bytes(b'datos'))
    time.sleep(1.0)
    datos = {'R': True, 'P': True, 'S': True}
    print(datos)
    ser.write(bytes(b'datos'))
    time.sleep(1.0)

¿Que hace Python? En un diccionario hay tres elementos: R, P y S, en donde cada 1 segundo va cambiando entre false y true, a la vez de que se envía por serial al Arduino. El arduino tiene que leer la llave del diccionario y dependiendo de lo que se lee es la que ejecuta tal instrucción. El arduino no prende los leds pero en la placa se prende la luz de RX, dando a entender que si está recibiendo los datos pero no los puede leer, y eso es lo que necesito saber. El codigo arduino no está bien escrito pero es a modo de ejemplo de lo que quiero lograr

ser.write(bytes(b'datos'))

No tengo claro qué es exactamente lo que envía.

led1 = Serial.read();
digitalWrite(7, led1);

Esto quiere decir que pin 7 se encenderá siempre y cuando esa lectura retorne un valor diferente de cero. No hablo de cero como '0' (que equivale a 46), sino de un byte con el valor 0x00 ('\0' o terminador de strings).

Se me ocurren tres posibles formatos de cómo los envía:

  • "RfalsePfalseSfalse" (quizá estén separados por un espacio, coma o raya; qué se yo...)
  • "R0P0S0" (quizá estén separados por un espacio, coma o raya; qué se yo...)
  • 0x52, 0x00, 0x50, 0x00, 0x53, 0x00 (descrito en forma binaria)