Duda comunicacion puerto serie TX y RX

He probado a enviar solo el primer comando, y esto es lo que aparece :

1.Get RF_READER type and product snr
Command code:0x0101
Parameters:NONE
Answer data: RF_READER type and product snr

Recibido comando. CheckSum OK
0000010100442D5468696E6B204D33305A3133342056322E303051

Cuando habla de "snr" se refiere a la fuerza de señal?

Así pudiera entenderse a primera vista, pero más bien supongo que signifique serial number o algo así (¿nùmero de versión?). De todas formas, he pasado esa respuesta a ascii. La conversión:
442D5468696E6B204D33305A3133342056322E3030 (el 51 será el checksum)
D-Think M30Z134 V2.00
En este caso, lo que tiene sentido son los caracteres, en lugar del valor hexadecimal.

Arrea, que listo! Bueno, es buena noticia, por lo menos, sabemos a ciencia cierta que el dispositivo responde, ahora tan solo falta, leer la etiqueta. Sigo haciendo pruebas, se te ocurre algo? Medire la continuidad de la antena, por si hubiera un fallo de fabricacion.

Intentaremos hacer en el loop un sencillo interface para emitir comandos. De esa forma podrás testar mejor.
Dame un ratillo y te cuento.

Vale, muchisimas gracias! Sin prisa, gracias por todo! Sigo haciendo pruebas hasta donde llegan mis cortas entendederas. Estoy probando el segundo comando, la funcion LED.

  1. Manage LED
    Command code: 0x0102
    Parameters:00=LED ON
    01=LED OFF
    Remarks: Power on LED has a short process from light to destroy, then LED commands from outside.
    Answer data: NONE

No aprecio que se ilumine el led en ningun momento, sigo mirando cosillas.

Bueno. Es un método tosco, pero acelerará tus pruebas. Sustituye el setup y loop por estos:

void setup() {
  Serial.begin(9600);
  RFID.begin(9600);
}

void loop() {
  if (Serial.available()) {
    int numero=Serial.parseInt();
    if (numero >= 10) 
      EnviaComando(numero/10,numero%10);
    else
      EnviaComando(numero);
  }
  if (recepcion()) {
    byte *pRespuesta = (byte *) &respuesta.idDispositivo;
    for (int i=0; i<respuesta.longitud; i++){
      if(pRespuesta[i]<0x10) Serial.print(0);
      Serial.print(pRespuesta[i], HEX);
    }
    Serial.println();
  }
}

Luego teclea comandos en el monitor serie de la siguiente forma:
-cifra significativa del comando
-cifra del parámetro
-un separador (por ejemplo una coma).

Por ejemplo:

  • Get RF_Reader: teclea 1,
  • Manage led: teclea 10, o 11,
  • Manage antenna: teclea 30, o 31,
  • Read Id: teclea 4,

Ya me contarás.

Asi, mucho mejor, he descubierto una cosita, por si puede ser de ayuda.

Comando enviado: 3
Parametro: 1
Estado: 0
Estado: 1
Estado: 2
Estado: 2
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Recibido comando. CheckSum OK
000001030002
Comando enviado: 3
Parametro: 0
Estado: 0
Estado: 1
Estado: 2
Estado: 2
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Recibido comando. CheckSum OK
000001030002

Entiendo, que si se envia el comando numero 3 con el parametro 1 deberia aparecer ??

000001030102

en vez de

000001030002

Quieto parado todo el mundo, creo que los comandos estan al reves en el datasheet. Sigo haciendo pruebas, parece que ya lee el tag.

Comando enviado: 4
Parametro: 1
Estado: 0
Estado: 1
Estado: 2
Estado: 2
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Estado: 3
Recibido comando. CheckSum OK
000001040003BD402ABA009C0001000000F6

// 10 Numero de serie
// 20 LED apagado
// 21 LED encendido
// 30 Antena cerrada
// 31 Antena abierta
// 41 Lectura etiqueta

Estos son los comandos correctos. Ya lee las etiquetas, ahi va el resultado.

Recibido comando. CheckSum OK
000001040003BD402ABA009C0001000000F6

Solo falta el ultimo paso, convertir el valor. De mientras, sigo haciendo unas pruebas para terminar de concluir la fase de codigos.

A ver qué sale de aquí.

#include <SoftwareSerial.h>

SoftwareSerial RFID(8,9);

struct ComandoConParam {
  byte cabecera[2];
  unsigned int longitud;
  byte idDispositivo[2];
  byte idComand[2];
  byte parametro;
  byte checkSum;
};

struct ComandoSinParam {
  byte cabecera[2];
  unsigned int longitud;
  byte idDispositivo[2];
  byte idComand[2];
  byte checkSum;
};

union Comando{
  ComandoConParam conP;
  ComandoSinParam sinP;
  } comando = {
    {
      {0xAA,0xBB},
      0x0006,
      {0x00,0x00},
      {0x01,0x04},
      0x00,
      0x03,
    }
  };

  struct Respuesta {
    unsigned int longitud;
    byte idDispositivo[2];
    byte idComand[2];
    byte estado;
  byte parametros[30]; // Dejamos un trozo holgado porque la respuesta get Rf_Reader era más larga que los 12 bytes del id
  } respuesta;

  bool recepcion(){
    enum {AA, BB, Lon, Bloque} static estadoRx=AA;
    static int indice;
    static byte checkSum;
    static byte *pRespuesta;
    if (RFID.available()) {
      switch (estadoRx) {
        case AA:
        if (RFID.read() == 0xAA) estadoRx = BB;
        break;   
        case BB:
        if (RFID.read() == 0xBB) {
          pRespuesta = (byte *) &respuesta;
          indice = 0;
          estadoRx = Lon;
        }
        else
        estadoRx=AA;
        break;   
        case Lon:
        pRespuesta[indice++]=RFID.read();
        if (indice == 2) {
        pRespuesta = (byte *) &respuesta.idDispositivo; // He puesto casting a byte porque no podía simular el cero para el segundo byte
        indice = 0;
        checkSum = 0;
        estadoRx = Bloque;
      }
      break; 
      case Bloque:
      pRespuesta[indice]=RFID.read();
      checkSum ^= pRespuesta[indice];
      indice++; // este es el incremento que se me olvidó
      if (indice == (byte)respuesta.longitud) {
        estadoRx = AA;
        Serial.print ("Recibido comando. CheckSum ");
        Serial.println(checkSum?"error":"OK");
        if (!checkSum) return true;
      }
      break;
    }
  }
  return false;
}



void EnviaComando(byte command) {
  comando.sinP.longitud = 5;
  comando.sinP.idComand[1] = command;
  comando.sinP.checkSum = comando.sinP.idDispositivo[0] ^ comando.sinP.idDispositivo[1] ^ comando.sinP.idComand[0] ^ comando.sinP.idComand[1];
  RFID.write((byte *) &comando, sizeof(ComandoSinParam));
  Serial.print("Comando enviado: ");
  Serial.println(command, HEX);
}

void EnviaComando(byte command, byte param) {
  comando.conP.longitud = 6;
  comando.conP.idComand[1] = command;
  comando.conP.parametro = param;
  comando.conP.checkSum = comando.conP.idDispositivo[0] ^ comando.conP.idDispositivo[1] ^ comando.conP.idComand[0] ^ comando.conP.idComand[1] ^ comando.conP.parametro;
  RFID.write((byte *) &comando, sizeof(ComandoConParam));
  Serial.print("Comando enviado: ");
  Serial.println(command, HEX);
  Serial.print("Parametro: ");
  Serial.println(param, HEX);
}

void setup() {
  Serial.begin(9600);
  RFID.begin(9600);
}

void loop() {
  if (Serial.available()) {
    int numero=Serial.parseInt();
    if (numero >= 10) 
    EnviaComando(numero/10,numero%10);
    else
    EnviaComando(numero);
  }
  if (recepcion()) {
    Serial.print("Comando ");
    for (int i=0; i<2; i++) {
      if (respuesta.idComand[i]<0x10) Serial.print(0);
      Serial.print(respuesta.idComand[i], HEX);
    }
    Serial.println();
    Serial.print("Estado: ");
    Serial.println(respuesta.estado==0? "OK":"ERR");
    Serial.print("Datos texto: ");
    for (int i=0; i<(respuesta.longitud-6); i++) { //la longitud será la total, menos 2 de id, 2 de comando, 1 de status y 1 checksum
      Serial.print(respuesta.parametros[i]);
    }
    Serial.println();
    Serial.print("Datos HEX: ");
    for (int i=0; i<(respuesta.longitud-6); i++) { //la longitud será la total, menos 2 de id, 2 de comando, 1 de status y 1 checksum
      if (respuesta.parametros[i]<0x10) Serial.print(0);
      Serial.print(respuesta.parametros[i], HEX);
    }
    Serial.println();
  }
}

Creo que ya tienes bastantes cosillas sobre las que avanzar; pero si necesitas ayuda puntual, por aquí me tienes.
Saludos

Okey, muchas gracias, mañana con un poquito mas de calma reviso de nuevo el codigo y hago las pruebas. Cuando ya este todo claro y funcionando, subiremos el codigo, las fotografias y la PCB que haga a modo de escudo con la antena directamente en circuito impreso, y asi, que pueda aprovechar el resto de la humanidad tu codigo y esfuerzo.

En estado me aparece error.

Comando enviado: 4
Parametro: 1
Recibido comando. CheckSum OK
Comando 0104
Estado: ERR
Datos texto:
Datos HEX:

El resto de comandos, con sus respectivos parametros, aparecen correctamente y funcionan a la orden.

Sustituye la línea

//Serial.println(respuesta.estado==0? "OK":"ERR");
Serial.println(respuesta.estado, HEX);

Me imagino que será nuestro viejo amigo el error E3 (no tag).

En efecto, error E3, no encuentra la etiqueta.

Comando enviado: 4
Parametro: 1
Recibido comando. CheckSum OK
Comando 0104
Estado: E3
Datos texto:
Datos HEX:

Los demas comandos, funcionan con naturalidad.

Pues me temo que en ese punto no puedo ayudarte, pues parece tener más que ver con el hardware que con el software (aunque tal vez tenga que ver con que debas activar la antena o sacar de sleep al RFID) y no dispongo de ese hardware para probar.
Intenta rememorar qué tocaste cuando te ha dado lecturas sin errores.

Buenas, creo que he descubierto un pequeño error frente al dispositivo, por eso, en algunas ocasiones, vuelca ese error. Tras varias comprobaciones, el ultimo codigo, funciona correctamente, esto es lo que aparece en pantalla. He intentado, desligar de todas las maneras por si fuera un array de datos, pero, sin buenos resultados. No logro comprender muy bien el valor que devuelve en HEX, este es el resultado.

Comando enviado: 4
Parametro: 1
Recibido comando. CheckSum OK
Comando 0104
Estado: 0
Datos texto: 32212772051313217010031
Datos HEX: 20D44DCD8303D9000100001F

El numero que aparece en el blister de la etiqueta es : 985141000822147

Según pone en el datasheet, y traduciendo a decimal cada grupo:

Bytes 1 al 5 (National ID):
20 D4 4D CD 83 ->‭ 141000822147‬

Bytes 6 y 7 (Country ID):
03 D9 -> 985

Byte 8 (Data flag):
00

Byte 9 (Animal flag):
01

Bytes 10 al 12 (additional data)
00 00 1F->31

Como ves, el primer y segundo grupo componen el número que aparece en el blister, sólo que intercambiados.

Muchisimas gracias por todo, ya parece estar resuelto. No tenia en cuenta yo los grupos intercambiados, por eso no lo leia correctamente. Si te parece bien, seguire haciendo unas pequeñas pruebas, y redactare un poco la informacion que hemos obtenido hasta la fecha y si tienes ganas le pegas un vistazo, y asi poder dar el trabajo algo mas documentado, puesto que en el datasheet, aparecen varios errores. Muchas gracias de nuevo.

Hola @Oscar_Sanchez

Yo tambien estoy jugando con el D-Think_M30Z134, intento leer el ID de my perro... no sin mucha dificultad!
Que opina de compartir su codigo (library?) ?

Muchas gracias,