Autor Tema: como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?  (Leído 5331 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
« Respuesta #15 en: 17 de Marzo de 2021, 23:00:45 »
como la idea es aplicar lo que ustedes me enseñan, dejo este codigo, que realiza lo que deseo pero la idea es que sea CCS". (trabaja bien lo dejo por referencia) muestra el arreglo de "14"
 

* captura arduino.png
(71.84 kB, 669x500 - visto 315 veces)

Código: C
  1. // (c) Michael Schoeffler 2018, http://www.mschoeffler.de
  2. #include <SoftwareSerial.h>
  3.  
  4. const int BUFFER_SIZE = 14; // RFID DATA FRAME FORMAT: 1byte head (value: 2), 10byte data (2byte version + 8byte tag), 2byte checksum, 1byte tail (value: 3)
  5. const int DATA_SIZE = 10; // 10byte data (2byte version + 8byte tag)
  6. const int DATA_VERSION_SIZE = 2; // 2byte version (actual meaning of these two bytes may vary)
  7. const int DATA_TAG_SIZE = 8; // 8byte tag
  8. const int CHECKSUM_SIZE = 2; // 2byte checksum
  9.  
  10. SoftwareSerial ssrfid = SoftwareSerial(6,8);
  11.  
  12. uint8_t buffer[BUFFER_SIZE]; // used to store an incoming data frame  //// almacena la cadena
  13. int buffer_index = 0;       // puntero
  14.  
  15. void setup() {
  16.  Serial.begin(9600);
  17.  
  18.  ssrfid.begin(9600); // inicio comunicacion
  19.  ssrfid.listen();     // selecciono este serial
  20.  
  21.  Serial.println("INIT DONE");  //veo que transmita
  22. }
  23.  
  24. void loop() {
  25.   if (ssrfid.available() > 0)// si el puerto esta recibiendo
  26.   {
  27.     bool call_extract_tag = false;   // bandera
  28.    
  29.     int ssvalue = ssrfid.read(); // read  // almaceno el dato entrante en ssvalue
  30.     if (ssvalue == -1) { // no data was read  
  31.       return;
  32.     }
  33.  
  34.     if (ssvalue == 2) { // RDM630/RDM6300 found a tag => tag incoming // tag encontrado
  35.       buffer_index = 0; // coloco puntero en posicion 0
  36.     } else if (ssvalue == 3) { // tag has been fully transmitted       // si llega el 3 ya leyo los 14bits
  37.       call_extract_tag = true; // extract tag at the end of the function call  // llamo la funcion para extraer el tag
  38.     }
  39.  
  40.     if (buffer_index >= BUFFER_SIZE) { // checking for a buffer overflow (It's very unlikely that an buffer overflow comes up!)poco probable que se desborde el buffer
  41.       Serial.println("Error: Buffer overflow detected!");
  42.       return;
  43.     }
  44.     //Serial.println(buffer_index);
  45.     buffer[buffer_index++] = ssvalue; // everything is alright => copy current value to buffer // coloco dato en el buffer [0] incremento puntero
  46.  
  47.     if (call_extract_tag == true)
  48.     {
  49.       if (buffer_index == BUFFER_SIZE) {
  50.         unsigned tag = extract_tag();
  51.       } else { // something is wrong... start again looking for preamble (value: 2)
  52.         buffer_index = 0;
  53.         return;
  54.       }
  55.     }    
  56.   }    
  57. }
  58.  
  59. unsigned extract_tag() {
  60.     uint8_t msg_head = buffer[0];
  61.     uint8_t *msg_data = buffer + 1; // 10 byte => data contains 2byte version + 8byte tag
  62.     uint8_t *msg_data_version = msg_data;
  63.     uint8_t *msg_data_tag = msg_data + 2;
  64.     uint8_t *msg_checksum = buffer + 11; // 2 byte
  65.     uint8_t msg_tail = buffer[13];
  66.  
  67.     // print message that was sent from RDM630/RDM6300
  68.     Serial.println("--------");
  69.  
  70.     Serial.print("Message-Head: ");
  71.     Serial.println(msg_head);
  72.  
  73.     Serial.println("Message-Data (HEX): ");
  74.     for (int i = 0; i < DATA_VERSION_SIZE; ++i) {
  75.       Serial.print(char(msg_data_version[i]));
  76.     }
  77.     Serial.println(" (version)");
  78.     for (int i = 0; i < DATA_TAG_SIZE; ++i) {
  79.       Serial.print(char(msg_data_tag[i]));
  80.     }
  81.     Serial.println(" (tag)");
  82.  
  83.     Serial.print("Message-Checksum (HEX): ");
  84.     for (int i = 0; i < CHECKSUM_SIZE; ++i) {
  85.       Serial.print(char(msg_checksum[i]));
  86.     }
  87.     Serial.println("");
  88.  
  89.     Serial.print("Message-Tail: ");
  90.     Serial.println(msg_tail);
  91.  
  92.     Serial.println("--");
  93.  
  94.     long tag = hexstr_to_value(msg_data_tag, DATA_TAG_SIZE);
  95.     Serial.print("Extracted Tag: ");
  96.     Serial.println(tag);
  97.  
  98.     long checksum = 0;
  99.     for (int i = 0; i < DATA_SIZE; i+= CHECKSUM_SIZE) {
  100.       long val = hexstr_to_value(msg_data + i, CHECKSUM_SIZE);
  101.       checksum ^= val;
  102.     }
  103.     Serial.print("Extracted Checksum (HEX): ");
  104.     Serial.print(checksum, HEX);
  105.     if (checksum == hexstr_to_value(msg_checksum, CHECKSUM_SIZE)) { // compare calculated checksum to retrieved checksum
  106.       Serial.print(" (OK)"); // calculated checksum corresponds to transmitted checksum!
  107.     } else {
  108.       Serial.print(" (NOT OK)"); // checksums do not match
  109.     }
  110.  
  111.     Serial.println("");
  112.     Serial.println("--------");
  113.  
  114.     return tag;
  115. }
  116.  
  117. long hexstr_to_value(char *str, unsigned int length) { // converts a hexadecimal value (encoded as ASCII string) to a numeric value
  118.   char* copy = malloc((sizeof(char) * length) + 1);
  119.   memcpy(copy, str, sizeof(char) * length);
  120.   copy[length] = '\0';
  121.   // the variable "copy" is a copy of the parameter "str". "copy" has an additional '\0' element to make sure that "str" is null-terminated.
  122.   long value = strtol(copy, NULL, 16);  // strtol converts a null-terminated string to a long value
  123.   free(copy); // clean up
  124.   return value;
  125. }
« Última modificación: 17 de Marzo de 2021, 23:13:49 por johenrod »
Si algo parece complicado... es por que esta mal explicado.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
« Respuesta #16 en: 18 de Marzo de 2021, 06:47:08 »
Vale. Ahora ya si lo tengo claro. Son 14 bytes. Para no hacernos un lío si te parece lo tratamos en adelante en hexadecimal.

 El primer byte tiene valor 0x02. Luego vienen 12 bytes con el rfid de la tarjeta y por último tienes valor 0x03 para cerrar la trama.

  El código que te puse entonces debería funcionar.

  Ve probando el hardware, prueba por ejemplo que el pic recibe datos correctamente mediante un echo por ejemplo:

Código: C
  1. printf(“Prueba de echo\r\n”);
  2. while(1) putc(getc);

  Con estas línea en tu main justo después de configurar los puertos y demás conecta el pic a una terminal. Si ves la frase “Prueba de echo” en la terminal significa que el pic envía y que el puerto esta correctamente configurado. Envíale al pic caracteres y comprueba si te los devuelve.

  Si es afirmativo el pic transmite .

 Lo siguiente es conectar el módulo y que el pic te envíe la trama al terminal, te sirve el mismo código anterior:

conecta el TX del módulo al RX del pic y el TX del pic a una terminal.  Lee una tarjeta y mira a ver si el pic te devuelve la trama.

 Si no es así asegúrate que al momento de dar alimentación al módulo de la tarjeta este no te envíe alguna trama inicial de bienvenida tipo: “Rfid reader version 3000 release. “  Ni alguna otra cosa similar por que si eso sucede te colapsa el fifo de recepción del pic (solo tiene un caracter de capacidad) . Si no se atiende una recepción, el pic bloquea la recepción y tienes que resetear la usart. 

  Si este fuese tu caso, una forma de solucionarlo es manejar el bit CREN del registro RCSTA del pic. Con ese bit puedes desactivar la recepción (CREN=0;) al arranque del programa, esperar un tiempo a que el módulo de la tarjeta suelte todo lo que tenga que soltar y entonces activar la recepción. (CREN=1);

  En caso de colapso del fifo en algún momento puedes reactivar la recepción simplemente poniendo CREN a cero y seguidamente a 1 de nuevo.

  Un saludo.

 

« Última modificación: 18 de Marzo de 2021, 06:51:28 por remi04 »

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
« Respuesta #17 en: 18 de Marzo de 2021, 14:12:54 »
Maestro - remi04.. Gracias y cordial saludo.
Algo que no comprendo, se que cualquiera que sea el formato que reciba siempre seran unos y ceros, creeria que se necesita saber en que formato estan codificados para que al recibirlos saber que hacer.
depende del tipo de variable donde se reciban los datos cambian? es decir si los recibo en " int recibe;" seria en entero y "char recibe;" se tranforma en ascci? ( no se si me hice entender)

Aqui el fragmento de codigo y lo que recibo, cuando se pasa la tarjeta se reciben indefinidamentelos mismos datos, no seria mejor que solo reciba una vez y al pasar de nuevo la tarjeta lea de nuevo el codigo?
Código: C
  1. void main()
  2.    {
  3.    RXDTSEL=0;// PIN CON VARIAS FUNCIONES EN 0 FUNCIONA COMO RX
  4.    TXCKSEL=0; // PIN CON VARIAS FUNCIONES EN 0 FUNCIONA COMO TX
  5.    //setup_adc_ports(NO_ANALOGS);
  6.    set_tris_b(0b00000010);
  7.    output_B(0x00);
  8.  
  9.  
  10.    // printf("estoy transmitiendo\r\n");
  11.    // printf("Prueba de echo\r\n");
  12.  
  13.    
  14.    while(TRUE)
  15.    {
  16.  
  17. putc(getc());
  18.    
  19.    }
  20.    }

* trama en hex.png
(105.67 kB, 702x457 - visto 279 veces)
« Última modificación: 18 de Marzo de 2021, 17:47:11 por johenrod »
Si algo parece complicado... es por que esta mal explicado.

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
« Respuesta #18 en: 18 de Marzo de 2021, 17:21:56 »
..hice la siguiente adaptacion en ccs y me muestra "HEX" en el puerto, igual que la imagen anterior.
ya solo me falta fraccionar los datos para guardar lo que necesito en 2 posciciones de la EEPROM. (pues...  si lo que hice esta bien) :shock:
en el siguiente codigo voy mostrando lo que va llegando a la variable auxiliar "rec" y se va guardando en el arreglo,, pero creeria que lo ideal es mostrarlo cuando se llene el arreglo y asi ver, que guardo bien el dato, el ejemplo lo dejo en el segundo codigo.( me muestra el dato igual al anterior)

   
Código: C
  1. void main()
  2.    {
  3.    RXDTSEL=0;// PIN CON VARIAS FUNCIONES EN 0 FUNCIONA COMO RX
  4.    TXCKSEL=0; // PIN CON VARIAS FUNCIONES EN 0 FUNCIONA COMO TX
  5.    //setup_adc_ports(NO_ANALOGS);
  6.    set_tris_b(0b00000010);
  7.    output_B(0x00);
  8.  
  9.     int rfid[14];
  10.     printf("estoy transmitiendo");
  11.    int rec=0;
  12.    
  13.    while(TRUE)
  14.    {
  15.    if(kbhit()>0)
  16.    {
  17.    for (int z = 0 ; z < 14 ; z++) // read the rest of the tag
  18.    {
  19.    rec=(getc());
  20.    rfid[z] = rec;
  21.    putc(rec);
  22.    }
  23.    }  
  24.    }
  25.    }

Código: C
  1. int rfid[14];
  2.     printf("estoy transmitiendo");
  3.    int rec=0;
  4.    int z=0;
  5.    while(TRUE)
  6.    {
  7.    if(kbhit()>0)
  8.    {
  9.    for (z = 0 ; z < 14 ; z++) // read the rest of the tag
  10.    {
  11.    rec=(getc());
  12.    rfid[z] = rec;
  13.    //putc(rfid[z] );
  14.    }
  15.       for (z = 0 ; z < 14 ; z++) // read the rest of the tag
  16.    {
  17.    rec=rfid[z];
  18.  
  19.    putc(rec);
  20.    }
  21.    
  22.    }
  23.      
  24.    }
  25.    }
« Última modificación: 18 de Marzo de 2021, 18:18:28 por johenrod »
Si algo parece complicado... es por que esta mal explicado.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
« Respuesta #19 en: 18 de Marzo de 2021, 18:26:17 »
Maestro - remi04.. Gracias y cordial saludo.
Algo que no comprendo, se que cualquiera que sea el formato que reciba siempre seran unos y ceros, creeria que se necesita saber en que formato estan codificados para que al recibirlos saber que hacer.
depende del tipo de variable donde se reciban los datos cambian? es decir si los recibo en " int recibe;" seria en entero y "char recibe;" se tranforma en ascci? ( no se si me hice entender)

Aqui el fragmento de codigo y lo que recibo, cuando se pasa la tarjeta se reciben indefinidamentelos mismos datos, no seria mejor que solo reciba una vez y al pasar de nuevo la tarjeta lea de nuevo el codigo?
Código: C
  1. void main()
  2.    {
  3.    RXDTSEL=0;// PIN CON VARIAS FUNCIONES EN 0 FUNCIONA COMO RX
  4.    TXCKSEL=0; // PIN CON VARIAS FUNCIONES EN 0 FUNCIONA COMO TX
  5.    //setup_adc_ports(NO_ANALOGS);
  6.    set_tris_b(0b00000010);
  7.    output_B(0x00);
  8.  
  9.  
  10.    // printf("estoy transmitiendo\r\n");
  11.    // printf("Prueba de echo\r\n");
  12.  
  13.    
  14.    while(TRUE)
  15.    {
  16.  
  17. putc(getc());
  18.    
  19.    }
  20.    }
 - Tienes que ingresar para ver archivos adjuntos -


En CCS cuando declaras una variable de tipo char no es ni mas ni menos que un entero de 8 bits. Pero es una forma de tener seguro que declaras eso mismo.

Puedes declarar:

int caracter;
char caracter;
int8 caracter;

    Solo las dos ultimas te aseguran que son variables de 8 bits, las tres pueden almacenar un carácter que a fin de cuenta y como bien dices, no son mas que una secuencia de "n bits" numero de 1,s y 0,s.   El tamaño de la variable "int" depende del compilador y de la arquitectura del microcontrolador que estés usando. Si usas un microcontrolador de 16 bits, determinados compiladores declararan un "int" como una variable de 16 bits.  Es la principal diferencia respecto a las otras dos.

  Respecto a conocer el tipo de dato que te está enviando una terminal, ya te lo expliqué. No es lo mismo recibir en ASCII "12345" que recibir en hex "0x01,0x02,0x03,0x04,0x05". Si no sé qué salida de visualización tienes configurado en el terminal es imposible tratarlos.

  Respecto a que el modulo permanezca enviando las tramas indefinidamente no pasa nada. El modulo es así, así lo han programado y para eso encabezan con un 0x02 al inicio y terminan con un 0x03.  Ten en cuenta que si el modulo solo enviase la trama una vez al insertar la tarjeta, si tu programa en ese momento estaba haciendo algo que demora incluso la ejecución de una interrupción, puede que cuando vayas a leer ya vayas tarde y empieces a leer a partir del tercer carácter. Si tienes la ventaja de que se repetirá la trama pues esperas y pillas la siguiente..  Como el que pierde el tren o el autobús.  Para mi es hasta una ventaja.

   La trama que has puesto ya entiendo que es pasando por el pic con esa linea de código de echo ¿verdad?.

 Saludos.


Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
« Respuesta #20 en: 18 de Marzo de 2021, 18:44:54 »
Maestro - remi04..
te estoy muy agradecido por tu tiempo y enseñanzas.
Citar
La trama que has puesto ya entiendo que es pasando por el pic con esa linea de código de echo ¿verdad?.
exacto lo que buscaba era que estuviese bien la forma en la qhe lo hago, perdon si abuso,,, he tratado de encontrar en los foros una forma algo ilustrativa para separar los datos y lo que he encontardo no me ha servido o mejor, no lo he podido interpretar para realizarlo.
sabes quizas de un link o tema en el foro que pudiera aclaralo.
gracias una vez mas..
« Última modificación: 18 de Marzo de 2021, 18:47:46 por johenrod »
Si algo parece complicado... es por que esta mal explicado.

Desconectado remi04

  • PIC24F
  • *****
  • Mensajes: 657
Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
« Respuesta #21 en: 18 de Marzo de 2021, 18:51:52 »
Pero este código que has puesto no espera por el inicio de trama (0x02) por lo que no es seguro que siempre te vaya a leer una trama perfectamente sincronizada. puede empezar a leer a partir del cuarto byte y aunque va a leerte una trama completa, estará desfasada.

   No es ningún problema, pero entonces luego tendrás que recorrer el array buscando donde está el 0x02 y a partir de ahí ir leyendo los valores hasta el final del array y luego volver al inicio del array para continuar parseando.

  Prueba esto:

Código: C
  1. int rfid[14];
  2.   printf("estoy transmitiendo");
  3.   while(TRUE){
  4.      if(kbhit()){
  5.         if (getc() == 0x02) {             // ¿ El carácter tiene el valor 0x02 ?
  6.           for (int z = 0 ; z < 12 ; z++)   // Lee el resto de la trama "Tag" excepto el caracter numero 13 que sabemos que será 0x03 (fin de trama)
  7.             rfid[z] =getc();
  8.           for (z = 0 ; z < 12 ; z++)   // Muestra el tag recibido excepto el valor final 0x03 que no forma parte del mismo.        
  9.            putc(rfid[z]);
  10.            printf("\r\n”);
  11.           rfid[13] = 0;      // Null de fin de cadena. (Para que el printf de abajo termine en el carácter 13 y no siga imprimiendo "basura" hasta que encuentre un "0".         ​
  12.      ​}
  13.    ​}
  14.  
  15. printf("El RFID de la tarjeta es: %s",rfid);
  16. while(1);                // Fin de programa.
  17. }


« Última modificación: 19 de Marzo de 2021, 18:57:17 por remi04 »

Desconectado johenrod

  • PIC18
  • ****
  • Mensajes: 276
Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
« Respuesta #22 en: 21 de Marzo de 2021, 12:49:41 »
Maestro - remi04.. Cordial saludo,
te había dejado descansar un poco tratando de implementar el código.
Si por favor me despejas algunas dudas..(espero no sean muchas)
según mis consultas ++i no es lo mismo que i++, porque ++i es un pre incremento si la variable se inicia en 0 después que pasa la comparación del for y entra a los corchetes y se incremeta en 1 pero i++ se incrementa al volver a comparar la función. coloque un print para ver si había un cambio pero siempre obtuve un 0 el la primera pasada (yo esperaba que fuera 1 cuando es ++i)  :undecided:
Código: C
  1. for (int i = 0; i < DATA_VERSION_SIZE; ++i)
  2.     {
  3.       Serial.print(i);// es 0
  4.       Serial.print(char(msg_data_version[i]));
  5.     }
Código: C
  1. for (int i = 0; i < DATA_VERSION_SIZE; i++)
  2.     {
  3.       Serial.print(i);// es 0
  4.       Serial.print(char(msg_data_version[i]));
  5.     }
mi otra duda es, he visto que una buena práctica al hacer una matrix de caracteres, se declara una constante del mismo ancho del buffer, para que es esto exactamente?
A esta constante también se le debe agregar un bit mas para el carácter "null"?

Código: C
  1. int const lenbuff=15; // Longitud máxima del buffer
  2.  
  3. ///////////////////////////////////////
  4. // RAM
  5. ///////////////////////////////////////
  6.  
  7. int  xbuff=0x00;     // Índice: siguiente char en cbuff
  8. char cbuff[lenbuff]; // Buffer de recepción
por ultimo me decias que ...
 if (ssvalue==-1) // esto seria 0xff
estuve chequeando  enviando por el puerto serie 0xFF, 255, 128,127 y no entraba al if (se que la variable "int ssvalue" al ser signed cuando llega a 127 provoca un overflow, y que ahí con el complemento a"2" pasa a ser "10000000" (entonces no se por que no entra)
Código: C
  1. if (ssrfid.available() > 0)// si el puerto esta recibiendo
  2.   {
  3.  
  4.    
  5.     int ssvalue = ssrfid.read(); // read  // almaceno el dato entrante en ssvalue
  6.     if (ssvalue == -1) { // no data was read  
  7.       Serial.println(ssvalue);//?????????????????
  8.       return;
  9.     }



« Última modificación: 21 de Marzo de 2021, 13:47:51 por johenrod »
Si algo parece complicado... es por que esta mal explicado.