Gestión e indexación de registros de una tabla en SD.

Bueno. La cosa requiere bastante paciencia, pero al menos ya se pueden dar de alta registros. Las bajas serán el próximo paso a depurar.

¡¡¡ EUREKA !!! Creo que tengo la primera version operativa. Necesitaría ayuda para testear. Si alguien tiene ganas, puede testear el sketch de ejemplo, o intentar adaptarlo a otro tipo de estructura personalizada. Cualquier duda, comentario o fallo detectado será bienvenido. De momento creo que va un poco lenta la cosa. Tendré que mirar por dónde puedo ahorrarme escrituras en SD, porque actualmente hace muchas.

Estoy armando mi Mega con la placa Ethernet para probar tu código Noter. También estoy con el problema de salvawis asi que mato dos pájaros de un tiro, ya que no puedo simularlo y me cansé de perder tiempo con el Proteus.

Arreglado algún pequeño error y convertido ya en librería. ;D

Bueno, yo ya resolvi el error de compilación. Era la versión IDE 1.5.4, pase a la 1.6.0

donde está la llibreria para probar? quiero ayudar.

Adjunta al primer post. Así tiene cualquier duda o sugerencia, o detectas cualquier problema comenta aquí. Gracias.

Leí durante el post que hubo modificaciones. ¿Estas estan actualizadas?

Sí. Cada vez que modifico, actualizo en el primer post y publico en el hilo que ha habido modificación, para que se vea la fecha de última actualización.

Ya hace una semana que no la toco, pero creo que con la última actualización ya se puede instalar como librería (que trae un ejemplo sencillo incluido).

Bueno, te comento que si se instala y compila correctamente con la version 1.6.

Y si se puede quiero usarla para un lector de tarjetas rfid y probar si anda con almenos 100 usuarios.

Y de paso te pregunto algunas cosas. ¿como guarda los datos, como texto o binario? ¿Se podria implementar la no indexacion para usarla como almacen logs, o en ese caso es mejor usar el modo habitual con la SD?

Gracias por tan buen aporte

Hola. Gracias por la colaboración. Respecto de tus preguntas, te respondo. La librería guarda los datos en formato binario. Hay que definir una estructura que representará los datos de un registro, pudiendo ésta contener cualquier tipo de dato numérico o array de datos de tamaño definido. Hay que tener en cuenta que no debes incluir en tu estructura punteros, pues sólo guardará el propio puntero y no los datos a los que apunta; es decir, que para cadenas por ejemplo deberás declararlas en formato char cadenaLONGITUD_FIJA y no en formato char *cadena (sólo guardaría los dos bytes que apuntan a la cadena). Respetando esto, creo que tiene capacidad para guardar estructuras de datos complejas (subestructuras, arrays, etc...). Está pensada (otra cosa es que cumpla lo esperado :P ) para gran cantidad de registros y/o tamaño grande de registro; por lo que para cien usuarios (salvo que se guarden muchos datos por usuario) tal vez no notes beneficio con respecto al acceso secuencial, y sí notes retraso en la escritura de un nuevo registro (no es lo mismo escribir directamente al final del archivo que andar buscando, recolocando y escribiendo datos de un lugar a otro para mantener el orden. Todo es cuestión de probar en cada caso y usar lo que mejor convenga. Respecto a lo de quitar la indexación, es precisamente la parte que me ha dado casi todo el trabajo. Para guardar estructuras sin indexar, te puede valer la Extended Database Library, aunque requiere una pequeña adaptación para utilizarla con SD (inicialmente estaba pensada para EEPROMs y demás). No obstante miraré si puedo sacar una versión "downgraded" (sin índices).

Entiendo lo que dices, en mi caso particular me interesa que sea rapido asi sean 3 registros. Quiero guardar los codigos Alfanumericos de llaveros RFID y el nombre del usuario y eventualmente algun dato mas, pero como son 10 caracteres para hacerlo en una eeprom tardaria bastante entre cada registro. La demora de escritura no importa porque se hace una sola vez salvo pierda o agregue un usuario nuevo, y despues seria replicar ese archivo en los demas equipos.

Y lo de hacer un log sin indexar se puede imprementar como parametro opcional, que solo escriba al final. Y al ser binario es mas seguro, que plano muy facil de modificar.

Lo que preguntaste en un momento sobre la velocidad, cuando son divisores resistivos para adaptar la señal no andan a maxima velocidad, si si usas un CD4050 o 74hc4050

Tengo una semana para tener un modelo de prototipo, sigo probando y comento.

anda muy bien incluso con divisor resistivo en vez de level converter. Mi pregunta es si la busqueda siempre es por el int DNI o puede ser otro campo? Quisiera poder buscar un array de 10 caracteres como clave.

Pues me has impresionado, maxid; porque debo decir que prácticamente dejé olvidado el proyecto, dada la poca utilidad que parecía tener para otros usuarios. Por supuesto que para mí quedó almacenado en mi biblioteca de librerías, pues creo que me puede servir a más o menos corto plazo; pero sinceramente creía este hilo en el olvido. Ahora paso a responderte. La búsqueda y comparación de registros se realiza sólo por el campo clave (más bien por el criterio clave, que podría abarcar varios campos incluso) que definas, así que si quieres utilizar un array alfanumérico de 10 caracteres como tal no hay problema. Lo único, que debes facilitar a la librería una función (como la ComparaRegistro del ejemplo) que tome dos registros como parámetros, y devuelva el resultado de la comparación según tu criterio clave(FDB_MAJOR, FDB_MINOR O FDB_EQUAL). Si no tienes cuidado en el diseño de esa función vas a tener problemas. Si tienes definido tu modelo de registro y necesitas ayuda, ponlo por aquí y te ayudo a implementarlo en la librería.

PD. He actualizado el post #1 con la versión que tenía en mi ordenador de la librería, que creo que es básicamente la misma, sin los Serial.print de depuración.

Para nada Serafín. También forma parte de MI LIBRERIA. Esperando el momento de tener que usarlo y consultarte si surge la duda. En su momento lo hiciste pensando en aquel forero que tenia un mes para un sistema biometrico (te acuerdas) y que pasó... que asi como vino y como no aportaba mas a su propio trabajo tampoco los demás lo hicimos pero tu proyecto fue un verdadero logro.

Gracias Noter, realmente funciona de maravillas y ahora la entiendo mas a la libreria. Voy a seguir probando y comento. Incluso el ejemplo de carga de datos es genial lograrlo en tan pocas lineas, jajaja. Surbyte, estoy en el mismo baile que ese forero pero con varias cosas a la vez por eso hace meses que ni entro por aquí. Hice mi aporte poniendo en los proyectos un lector tagRFID completo que lleva 3 meses sin apagarse ni colgarse. Realmente como siempre decimos Filtros y mas filtros hacen que un prototipo funcione siempre.

Con respecto a la libreria, puedo cominar el uso con la libreria estandar sd para guardar un log en txt?

Por supuesto que puedes declarar y utilizar normalmente un objeto File. De hecho en el ejemplo ha quedado un objeto dbFile, que no se usa en el programa, de pruebas anteriores que hice. No lo he probado en profundidad, pero no creo que interfiera en el funcionamiento normal de la librería, salvo que se te ocurra abrir el mismo archivo que el que vas a trabajar con FDB, claro :). De todas formas, si necesitas trabajar con archivos a la vez que con FDB, comenta los resultados por aquí. También podrías declarar más de un objeto FDB, pero no es cuestión de matar moscas a cañonazos. Para un log es más efectivo y sencillo un simple archivo de texto.

Noter. Le estoy dando caña a la libreria y me pregunto que performance tiene en la busqueda. Bueno hice una prueba en una base con 4 registros

buscar el registro numero:

3: 152 microsegundos 1: 440 microsegundos 4: 300 microsegundos 2: 296 microsegundos

nuevamente el 3: 152 microsegundos

Registros no encontrados: 440,296,210 depende de que numero intenta comparar

Lo mas importante estos valores se mantienen entre reseteos y reprogramaciones

Espero ayudar con esto

coloco la porcion para calcular el tiempo

    unsigned long t0;
    unsigned long t1;
.
.
.
.
.
   t0= micros();
    if (bbdd.EncuentraIndex(nuevo, numRegistro) == FDB_OK) 
    {
      t1= micros();    
      Serial.print(F("Encontrado en pos "));
      Serial.println(numRegistro);
      } 
      else 
      {
        t1= micros();    
        Serial.print(F("No hay coincidencia. Posición registro actual: "));
        Serial.println(numRegistro);
      }
      Serial.print("Tiempo de busqueda: ");
      Serial.println(t1-t0); //imprimo cuanto tarda en encontrar

Gracias, maxid; aunque con pocos registros no creo que el rendimiento sea superior a una lectura secuencial. Aún no la he puesto a prueba en serio, pero donde debería ser "rentable" es con gran número de registros, ya que con n comparaciones debería poder encontrar un registro indexado entre 2n registros, es decir, que con 16 comparaciones debería poder encontrar un registro entre más de 60000 registros. Ahí sí que debería ser más eficiente que ir leyendo todo. Aún no he necesitado algo así, pero como dije, creo que puede ser una buena opción para tratar un volumen de datos importante sin necesidad de recurrir a conexión con una bbdd externa.

Si entiendo Noter, pasa que no me puse a cargar tantos datos. Y me picaba la curiosidad de cuanto tarda en encontrarlo, mas que todo por la eficiencia de la memoria en modo spi. En breve si funciona todo tendre funcionando una con cerca de 100 usuarios.

Lo que me interesa si me podes ayudar es a hacer el archivo desde una pc basado en la estructura, facilitaria las pruebas y carga de datos, redueciendo codigo, que ya voy medio ajustado.