TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: johenrod en 28 de Febrero de 2021, 16:25:35

Título: como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod en 28 de Febrero de 2021, 16:25:35
Cordial saludo, requiero almacenar datos de tags de tarjetas RFID las  cuales tiene un ancho de 32 bits, se que hay una función que aun no utilizo make8(), make16() y make32() para este fin,
al parecer puedo segmentar los 4 bytes  y guardarlos en la posiciones EEPROM 0,1,2 y 3 hasta aquí todo parece ir bien pero eso es para 1 sola tarjeta, cuando quiera almacenar otras tarjetas, como se donde debo escribir para no sobrescribir en posiciones ya utilizadas y de igual forma cuando vaya a realizar la lectura de una tarjeta ya almacenada (comparar) como se efectuaría la comparación.
Gracias de antemano.
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 en 28 de Febrero de 2021, 18:40:59
Ahí yo haría dos cosas.

  1-  dos funciónes específicas que sean las únicas en todo el programa que tengan acceso a la memoria eeprom.  Una seria de lectura, a la cual le envías el índice de tarjeta que quieres leer y ella te devuelve el rfid de ese índice. 


Código: C
  1. int32 read_rfid_card(int index) {
  2.   return make32(read_eeprom(index*4),read_eeprom((index*4)+1),read_eeprom((index*4)+2),read_eeprom((index*4)+3));
  3. }

Para llamar a esta función:

Código: C
  1. int32 rfid = read_rfid_card(4);   // dame el rfid de la tarjeta número 4





de esa forma tú le mandas el índice de tarjeta, por ejemplo, la tarjeta número 4, y el va a buscarla en las direcciones 4*4,  4*4+1, 4*4+2,  4*4+3, es decir, posiciones: 16,17,18 y 19 respectivas. 

  Nunca hay posibilidad de cruzar ni solapar nada.

  Para grabar una tarjeta le mandas a esta función el código rfid de la misma y el índice de número de tarjeta donde se grabará ese rfid:

Código: C
  1. void write_rfid_card(int32 rfid,int index) {
  2.   write_eeprom(index * 4, make8(rfid,3));
  3.   write_eeprom((index * 4) + 1, make8(rfid,2));
  4.   write_eeprom((index * 4) + 2, make8(rfid,1));
  5.   write_eeprom((index * 4) + 3, make8(rfid,0));
  6. }


La forma de usar la función sería:

Código: C
  1. // int32 rfid = 1234567890;     // rfid que has leído de una tarjeta física.
  2. wtite_rfid_card(rfid,4);     // graba  el código rfid en el índice 4.

Y ya para tener un plus de seguridad extra, implementaría un CRC8.  Reservaria un quinto byte a cada tarjeta.  Cuando vayas a grabar un rfid, le calculas el CRC8 a ese rfid con los 4 bytes que lo componen, y ese CRC8 lo grabas en una quinta posición.

   Entonces en las funciones anteriores tendrías que agregar un quinto byte a cada rfid para calcular y grabar el CRC8 en la que graba y luego leer el CRC8 en la que lee y comprobarlo para validarlo.

  Eso ya te aseguraría que lo que estás leyendo corresponde a un rfid real y no a algo de 4 bytes que se te hayan cruzado.   

  Pero vamos, que sería difícil que con las funciones anteriores se te cruce nada salvo que tengas desbordamiento de dirección por llegar a ocupar toda la eeprom entera. Tienes que agregar control para limitar el índice al número maximo de tarjetas que te caben en la eeprom.

 Saludos.
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod en 28 de Febrero de 2021, 19:06:42
Citar
Ahí yo haría dos cosas.

  1-  dos funciónes específicas que sean las únicas en todo el programa que tengan acceso a la memoria eeprom.  Una seria de lectura, a la cual le envías el índice de tarjeta que quieres leer y ella te devuelve el rfid de ese índice.


Código: C
int32 read_rfid_card(int index) {
  return make32(read_eeprom(index*4),read_eeprom((index*4)+1),read_eeprom((index*4)+2),read_eeprom((index*4)+3));
}
 
remi04
Gracias por tu respuesta..

cuando coloque una tarjeta cualquiera, tendría que explorar toda la eeprom para ir comparando si esta existe?
Eso seria algo demorado o no?
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 en 28 de Febrero de 2021, 19:20:53
Con el CRC8 sería la forma más rápida.

  Si tienes 4 bytes de un rfid seguido de un byte con un CRC8 calculado sobre esos 4 bytes entonces la búsqueda solo la haces en los crc8’s y no en toda la eeprom.

  Por ejemplo:

  Meten una tarjeta. Su rfid es 1234567890.

 Lo que haces es calcular su CRC8, y ahora lanzas la búsqueda en la eeprom de un CRC8 que tenga un valor idéntico.  Así solo tienes que buscar en los bytes 4,9,14,19, sucesivamente que son los que tienen el crc de los 4 bytes que lo preceden y no en toda la eeprom.

 Una vez localizado pues lees el rfid (los 4 bytes anteriores a ese CRC),  y lo comparas con el rfid leído.  Si coincide ya lo tienes.

  Es mucho más rápido.

  Y si quieres que sea aún más rápido, al arranque del programa lees toda la eeprom (solo los crc) y te haces un array donde almacenas los CRC8 por orden que hay en la eeprom. Es un index en ram de todos los rfid que hay en la eeprom.   Así aceleras muchísimo la búsqueda a la hora que metan una tarjeta en el sistema a ver si está o no está puesto que si encuentras su crc por ejemplo en el índice 9, pues usas las funciones anteriores para leer a tiro directo ese rfid en la eeprom y luego lo comparas.   Es muy difícil que te salga un crc duplicado pero puede pasar, por eso siempre que localices, lees el rfid y lo comparas. Si no es, sigues buscando el siguiente crc que coincida ...  es como buscar en un listín.

 
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod en 28 de Febrero de 2021, 20:16:00
Con el CRC8 sería la forma más rápida.

  Si tienes 4 bytes de un rfid seguido de un byte con un CRC8 calculado sobre esos 4 bytes entonces la búsqueda solo la haces en los crc8’s y no en toda la eeprom.

  Por ejemplo:

  Meten una tarjeta. Su rfid es 1234567890. ....



Gracias por tu respuesta, por ultimo antes de tirarme al ruedo,,
lo ideal seria antes de empezar a escribir el la eeprom colocar todo en FF? para saber donde escribí la ultima vez, o que seria lo adecuado para ir escribiendo en orden?
Gracias por la paciencia.
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: Robert76 en 28 de Febrero de 2021, 22:14:23
Hola, pero al trabajar con índices, no necesitas explorar la EEPROM.
Lo 1ro. qué debe hacer el programa una vez detectada una tag, es enviar el índice y esperar los datos. Sí dichos datos vuelven en FF, pues quiere decir que esa tarjeta nunca se usó.
Y ahí es dónde entra la creatividad!
Puedes gestionar arbitrariamente que datos guardar para cada tag.
Por ejem. almacenar además de los 4 octetos que requieres, añadir 1 byte más, indicando los atributos.
Es decir, si dicha tag está habilitada vale 0x01.
Sí está anulada, 0x02, suspendida 0x03, según jerarquía de lugares restringidos 0x04 al 0x20(ejem), etc.
Sí la tarjeta es eliminada, dicho byte vuelve a FF o el valor que tú deseas y bien conoces.
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 en 01 de Marzo de 2021, 07:02:32
Con el CRC8 sería la forma más rápida.

  Si tienes 4 bytes de un rfid seguido de un byte con un CRC8 calculado sobre esos 4 bytes entonces la búsqueda solo la haces en los crc8’s y no en toda la eeprom.

  Por ejemplo:

  Meten una tarjeta. Su rfid es 1234567890. ....



Gracias por tu respuesta, por ultimo antes de tirarme al ruedo,,
lo ideal seria antes de empezar a escribir el la eeprom colocar todo en FF? para saber donde escribí la ultima vez, o que seria lo adecuado para ir escribiendo en orden?
Gracias por la paciencia.

Efectivamente la eeprom la inicializas a FF una sola vez. Por ejemplo, mediante un menú o una opción de inicialización, esto sería “formatear”

 Esto se puede plantear de muchas formas. Yo te sugiero imitar un poco a un sistema de archivos y estructurar la eeprom para trabajar de forma similar.

 
  Puedes hacerlo parecido a como funciona el sistema de archivos FAT32 que usa un sector llamado FSINFO donde almacena entre otros, cuál es la última entrada que ha sido ocupada y por lo tanto, para buscar una entrada libre lo harás a partir de la siguiente que indica fsinfo.  Pues aquí lo puedes hacer igual.  Esto FAT32 lo usa solamente para acelerar la búsqueda de entradas libres en una unidad que puede tener 32 Gb.   Se hace muy necesario. Pero en tu caso en una eeprom que puede tener 255 bytes o 2 Kb no vas a acelerar mucho, pero la idea en este caso no es acelerar nada sino controlar en forma secuencial por orden ascendente el registro y eliminación de tarjetas como explicó más abajo.

  En adelante, llamo “entrada” al conjunto de 5 bytes (4 para tu rfid y 1 para crc o byte de atributos) como sugiere el compañero que es también muy buena idea por que puedes indicar muchísimas cosas en ese byte relativos a la entrada de la que forma parte o al rfid en si o a todo.
 
 Te reservas por ejemplo la última posición o las dos últimas posiciones de la eeprom según la cantidad de eeprom disponible para poner ahí tu “fsinfo”. Cuando grabes una tarjeta nueva, te vienes aquí e indicas el índice de entrada de esa tarjeta entendiendo como índice, el que apunta al quinto byte de la entrada (que es el que contiene el crc o los atributos)  Así siempre sabes donde se grabó la última tarjeta y no tienes que escanear toda la eeprom.

 
Cuando una tarjeta es eliminada, sus 5 bytes pasan a FF.   

  Cuando vas a grabar una nueva consultas tu “fsinfo” para saber por donde se grabó la última y empezar a buscar una entrada libre para la nueva tarjeta.  Cuando fsinfo llegue al final de la eeprom empieza a cero otra vez. 

 Escanear solo los bytes 4,9,14,19 como ya sugerí. Si están en FF significa que esa entrada es posible que esté libre. Aún hay que comprobarlo.

   Ahora tocaría leer la entrada completa, los 5 bytes. ¿Están todos a FF? , entrada libre encontrada. La tomas, la usas y te vas al fsinfo y lo indicas. Ya siempre sabrás a partir de donde empezar a buscar la siguiente vez.

 Como ves, las operaciones de registro y eliminación de tarjetas siempre va a ir en forma secuencial en orden ascendente a lo largo de toda la eeprom  y cuando llegues al final comienza a cero de nuevo.

  Esto presenta de antemano una ventaja, y es que las operaciones de grabación en las entradas disponibles se automatiza. 

  Pero presenta una desventaja, y es que los índices ya no van a estar necesariamente organizados por orden.  Por lo que cuando metes una tarjeta y lees el rfid y obtienes su índice tienes que ir a buscar ese índice en la eeprom.  Escaneando de nuevo los bytes 4,9,14,19,24,29, etc de principio a fin hasta que lo encuentres.

  De nuevo, en el arranque del programa lo podrías indexar. Leyendo todos los índices y haciéndote un array en ram de donden están todos y así la localización es prácticamente instantánea.

  Un saludo.


 
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod en 01 de Marzo de 2021, 13:00:23
Gracias por las respuestas... y por el tiempo dedicado.
Uf... va a estar algo teso pero ya que no soy muy bueno con punteros, pero de eso se trata de ir aprendiendo.
según vaya realizando el código lo voy subiendo  para aceptar mejoras.
 :-)
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod en 15 de Marzo de 2021, 19:13:12
ya voy algo adelantando algo, pero me frene en un problema.
la tarjeta rfid RDM6300 125KHZ su literatura dice que tiene un código HEX que lo convierten a "ASCCI" pero al leerlo en el pic no me lee ni el primero ni el ultimo bit( el primero siempre es 2 y el ultimo siempre un 3) ,en la tabla ascci dice que son comienzo y final de texto sera por esto que no los muestra?
dejo el código que viene en la tarjeta y su representación en "ASCCI" que es lo que recibe el pic
   2,30,39,30,30,36,32,39,39,32,39,44,42,3  >esto a lo interior de la tarjeta y lo envía en ascci asi>
       0  9   0   0   6   2   9   9   2   9  D  B

   Como podría leer los 14 bits que envía la tarjeta?

en arduino lee todo con "temp=Serial.read();" pero la idea es hacerlo en ccs, gracias..
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 en 15 de Marzo de 2021, 20:38:17
Te creas un array de 14 elementos y los inicializas por ejemplo a 0xff:

Código: C
  1. char rfid[14];
  2. for(int i=0;i<14;i++) rfid[i] = 0xff;

 Ahora, como el primer valor sabes que es un “2”, pues esperas por él:

Código: C
  1. while(rfid[0] != 2) rfid[0] = getc();

Una vez recibido el 2 ya lo tienes cargado en el byte 0 del array
 
  Ahora recibes el resto hasta que te llegue el valor 3 que sabes que es el último:

Código: C
  1. int i=1;
  2. while ((rfid[i-1] != 3) && ( i<14)) rfid[i++] = getc();

 Esto te va a grabar por orden los caracteres que recibas en el array hasta que encuentre el 3 o hasta que se llene el mismo. Lo que primero suceda. Se entiende que estas seguro que siempre van a ser 14 bytes. Si no, le asignas mayor tamaño al array.

 
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod en 15 de Marzo de 2021, 22:00:46
Citar
Publicado por: remi04
« en: Hoy a las 20:38:17 »Insertar Cita
Te creas un array de 14 elementos y los inicializas por ejemplo a 0xff:

Código: C
char rfid[14];
for(int i=0;i<14;i++) rfid = 0xff;
 

 Ahora, como el primer valor sabes que es un “2”, pues esperas por él:

Código: C
while(rfid[0] != 2) rfid[0] = getc();
 

Una vez recibido el 2 ya lo tienes cargado en el byte 0 del array...
que excelente todo esto que se aprende, gracias

he tratado de hacer  el ejercicio partiendo de lo que pude entenderte, aunque no sale nada me dirías por favor como voy? Gracias..
Código: C
  1. #include <16f1827.h>
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #use delay (internal=4000000)
  5. #fuses NOPROTECT,NOWDT,nobrownout,nomclr
  6. #define TX PIN_b2
  7. #define RX PIN_b1
  8. #use rs232(baud=9600,parity=N,xmit=TX,rcv=RX,bits=8,ERRORS)
  9. #bit RXDTSEL = 0x11D.7 // 0X11D HACE REFERENCIA AL REGISTRO APFCON0 bit 7
  10. #bit TXCKSEL = 0x11E.0 // 0X11D HACE REFERENCIA AL REGISTRO APFCON1 bit 0
  11.  
  12. #USE fast_io (A)      // Optimizamos E/S del PORTB ( muy importante para ahorrar memoria )
  13. #USE fast_io (B)
  14. #BYTE porta= 0X0C
  15. #BYTE portb= 0X0D
  16. //#define LED PIN_B0
  17.  
  18.  
  19.  
  20. // ******* variable globales ********
  21.  
  22.  
  23. // INTERRUPCIONES : RDA Recepción USART
  24. ///////////////////////////////////////////////////////////////////////////////////////////////////
  25.  
  26.    void main()
  27.    {
  28.    RXDTSEL=0;// PIN CON VARIAS FUNCIONES EN 0 FUNCIONA COMO RX
  29.    TXCKSEL=0; // PIN CON VARIAS FUNCIONES EN 0 FUNCIONA COMO TX
  30.    //setup_adc_ports(NO_ANALOGS);
  31.    set_tris_b(0b00000010);
  32.    output_B(0x00);
  33.  
  34.     char rfid[14];
  35.     printf("estoy transmitiendo");
  36.    
  37.    while(TRUE);
  38.    {
  39.  
  40.    for   (int i=0;i<14;i++) // aqui coloco todas las posiciones del array en 255 (del 0 al 13)
  41.          {
  42.          rfid[i] = 0xff;  //no se por que hay que iniciarlas
  43.          }
  44.    
  45.    while(rfid[0] != 2) // mientras que la posicion 0 del array sea diferente a 2 vuelva a preguntar
  46.          {
  47.          rfid[0] = getc();
  48.          }
  49.    
  50.    // si pasa aqui es por que la poscicion 0 ya es un 2
  51.    
  52.    int j=1;  // aqui cambie la variable por j por que sale un error que ya se esta usando en el for
  53.    while ((rfid[j-1] != 3) && ( j<14)) // como j es 1 -1 ya j es 0 y diferente a 3 y menor que 14
  54.    {
  55.    rfid[j++] = getc(); // si se cumple, incremento posicion del array en 1 y grabo el siguiente dato
  56.    }
  57.    
  58.    printf("cadena%s",rfid);// aqui no me sale nada en el monitor
  59.  
  60.  
  61.    
  62.    }
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 en 16 de Marzo de 2021, 19:32:48
Puedes ir poniendo print’s en varios sitios para que puedas ir viendo a donde llega y a donde no.  Así vemos donde se nos queda.

 Dos cosas:

   Siempre me gusta inicializar todas las variables que uso en un programa, incluidos los array.  Me parece una buena práctica y te puede evitar problemas.

    Lo otro es que el uso del ++ en una variable es un preincremento si la precede o un postincremento si la sigue. En el caso de :
rfid[j++] = getc();

 primero lee, asigna y luego incrementa, no al revés como has descrito.
 Para que incremente primero y luego asigne sería ++j y no j++

  Por otro lado,

   ¿Como sabes que el módulo te envía solo esos 14 bytes?.  ¿Lo has podido ver en un terminal?.  Si es así, haz una cosa, pon el terminal en modo hexadecimal, y captura una trama entera del módulo rfid. Ponme aquí mismo la trama en hex.  Olvídate de ascii que no aparecen los caracteres de control entre otros, pero en hex aparece absolutamente todo.

 Saludos.

Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod en 16 de Marzo de 2021, 20:59:14
Citar
remi04
Gracias valoro tu tiempo..
la captura lo muestra varias veces porque aun no implemento detener la lectura cuando llena el buffer,,,(pero eso ya lo sabes!)
en el siguiente fragmento de codigo , que significa  o porque  -1
Código: C
  1. int ssvalue = ssrfid.read(); // read  // almaceno el dato entrante en ssvalue
  2.     if (ssvalue == -1) { // no data was read  
  3.       return;

  - Tienes que ingresar para ver archivos adjuntos -  


Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 en 17 de Marzo de 2021, 04:56:04
Está preguntando si ssvalue contiene el valor 0xff.   (Por eso hay que inicializarlas).  Y por lo tanto, no contendría un valor válido.

  El tipo int por si solo puede tener signo en complemento a 2. El -1 es lo mismo que 0xff

 Por otro lado , al mirar la captura de realterm en ascii puro, lo cambia todo.

 Parece que el módulo te está leyendo la rfid de una tarjeta y te lo está convirtiendo a ascii puro imprimible para que puedas imprimir ese rfid en un terminal, monitor, etc directamente por rs232.


  Esto a la hora de recibirlo e interpretarlo con un pic lo tienes que tener en cuenta por que todo cambia. Absolutamente todo. 

Para empezar, del módulo estás recibiendo 28 bytes por trama y no 14 como creías. 

  El número entero “2” en ASCII sería (inicio de texto) te lo está enviando directamente en caracteres  imprimibles ascii, y no solo eso, sino que te envía 02. Lo cual son dos caracteres, un 0 y un 2.   Lo mismo pasa con el “3” del final. No es un 3, es un 0 y un 3, es decir otros dos caracteres.

 Es normal que no funcione el programa por que estabamos esperando por el número 2 entero, sin embargo el módulo está enviando “02” eso son dos caracteres ASCII, el ‘0’ que equivale al entero 48 (0x30) en hexadecimal, y el ‘2’ que equivale al entero 50 (0x32).   

   En el programa entonces no podemos esperar por el 2, tenemos que esperar por el 0x30 y por el 0x32 de forma consecutivas (2 bytes).  Una vez recibidos estos dos caracteres recibes el cuerpo del rfid que son 24 bytes y por último recibes el fin de texto que sería, de nuevo 0, (0x30) seguido en este caso del 3, (0x33). Otros dos bytes. 28 en total.

  Hay una función que sirve para convertir Un carácter ascii en su valor entero atoi();. No se si la implementa CCS, de cualquier modo es muy fácil, simplemente al carácter ascii que recibas le restas 48 y te queda su entero equivalente. 

 Ejemplo: el ascii 0, su entero equivalente es 48.
 int minumero_ascii_en_entero = 48 - 48   //  te daria 0.

  Para el 1:     49 - 48 = 1.

  En base a todo esto es fácil modificar el programa.  Tienes que cambiar el tamaño del array y el bucle de espera que ahora son dos caracteres a detectar antes de capturar trama.

 Saludos.

 Un saludo.
 

Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod en 17 de Marzo de 2021, 22:23:27
Citar
Publicado por: remi04
« en: Hoy a las 04:56:04 »

Está preguntando si ssvalue contiene el valor 0xff.   (Por eso hay que inicializarlas).  Y por lo tanto, no contendría un valor válido.

  El tipo int por si solo puede tener signo en complemento a 2. El -1 es lo mismo que 0xff

 Por otro lado , al mirar la captura de realterm en ascii puro, lo cambia todo.
gracias  de nuevo por tu tiempo..
creo que me falta colocar informacion por que con tu respueta de 28 bits me confundi mas,, ya que mirandolo desde tu perspectiva veo que tienes la razon son 28 bits,  en los ejemplos que he podido investigar dice que la tarjeta maneja los datos en "HEX" pero al momento de transmitirlos los codifica a "ASCII" y ahí es donde veo se reducen los bytes a 14.
te dejo la imagen que podria aclarar dudas, en el pantallazo que te envie antes lo capture en "HEX" agregare la captura en "ASCCI"
(http://[attachment id=2 msg=417867][/attachment])

(http://[attachment id=3 msg=417867][/attachment])





Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod 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"
  - Tienes que ingresar para ver archivos adjuntos -  
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. }
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 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.

 

Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod 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.    }
 - Tienes que ingresar para ver archivos adjuntos -  
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod 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.    }
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 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.

Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod 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..
Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: remi04 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. }


Título: Re:como almacenar 32 bits en EEPROM y saber la próxima posición de escritura?
Publicado por: johenrod 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.     }