Hola, he estado trabajando en un código que obtiene los datos desde un archivo en la tarje SD y luego los envía a un servidor, el problema es que estaba haciendo mal la concatenación de los datos recibidos desde la SD, lo que yo hacía era algo más o menos así:
estos datos son obtenidos desde una acelerógrafo, los datos con un asterisco (*) son los datos ya enviados.
- No sé como poder eliminar los espacios en blanco (como el trim de String) desde el array final, yo lo he definido con un tamaño de 100, porque los datos del acelerógrafo varían, por lo que me gustaría poder dejar sólo los datos con información para luego enviarlos.
¿alguien puede explicarme como puedo hacer esto?
he modificado el título debido a que esas dudas las he corregido, sin embargo el problema principal con mi código, continúa (la memoria)
SD.ino: In function 'void loop()':
SD.ino:53: error: return-statement with a value, in function returning 'void'
lo comento y funciona.
Esta bien lo que dice. No puedes terminar un void loop con un return algo.
lo copiaste de otro código mas grande?
Otro error falta <SPI.h>
Agregado y compila con IDE version 1.5.4
Simulando con Proteus, ya casi funciona.
Tengo algunos errores pero es cosa de 1 momento y compartimos experiencias.
si se me ha pasado ese error, en el loop va de esa forma
Serial.println(inputString);
es un código mucho más largo y esa parte va dentro de una función, me he olvidado de quitar el return, cuando ya solucione todos los problemas dejaré el código completo para ver si a alguien más le sirve.
yo uso sublime text con el plugin para arduino que utiliza el compilador de del IDE (1.0.6) y hasta ahora no he necesitado de incluir la librería SPI
Mira el tiempo que llevo luchando con la simulación por dios....
para CS usas pin 10 no pin 4.
Pero ya estamos, se me queda inicializando SD y no avanza.
cuando demora eso en tiempo real?
Adjunto el esquema que tengo. Claro que el tuyo esta armado en el shield.
No logro que funcione el código.
se me queda inicializando y puede ser la simulación, no se.
cualquier otro parámetro me da error.
Cuando ejecuto el código, la lectura es muy rápida, una linea demora solo un par de milisegundos
el archivo completo ese que adjunté, demorará unos 4 o 5 segundos.
si, lo sé, pero si saco o modifico los parámetros, en ocasiones mi shield deja de funcionar.
De todas maneras, yo consigo leer y escribir correctamente los datos de la SD.
Lo tengo así porque en los sketch de ejemplo de la librería SD dice:
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
Lo que entiendo de eso, es que SD.begin() inicializa el pin CS
y el pinMode y digitalWrite el pin SS
Hola.
Efectivamente, como indica gepd en el último post, para que el SPI pueda funcionar, el pin SS digamos, general (10 en UNO y 53 en el Mega) debe establecerse como salida, independientemente de que luego utilicemos otro pin SS para un dispositivo determinado (en este caso el 4). En este caso, tratándose del MEGA, lo de poner el pin 10 en OUTPUT no parece tener ningún sentido. En tal caso debería ser el pin 53, pero tal vez la propia inicialización de SD esté realizando ya esa tarea.
En resumen, que deberías modificar las dos líneas que hacen referencia al pin 10 para que hagan referencia al pin 53.
Ya se que tu problema es otro, pero no tenia el shield porque estuve todo el dia de ayer en mi casa y queria simularlo pero no pude superar la inicialización y me cansé.
Hoy lo pruebo con el shield.
Tengo 3 variantes.
He encontrado una solucion a mi problema, la explicaré para cuando alguien más tenga:
Lo primero, los espacios en blanco lo solucioné agregando \0 al final del array, esto le indica al compilador donde debe terminar de leer, lo hice después de haber agregado todos los datos dentro de la variable inputString, esta última variable tiene un máximo de caracteres a agregar, definido en el comienzo del código, por lo tanto hay que asegurarse que el array tenga el espacio suficiente para para almacenar la información que necesitamos y \0.
en mi caso he modificado el máximo de caracteres a 25
char inputString [25];
Es una buena costumbre también comprobar si no se están agregando más caracteres de los que acepta el array para no tener un desbordamiento de datos.
if(stringIndex < 25)
Con esto me aseguro que solo agregue 24 caracteres y le de el espacio al \0
se puede agregar un mensaje para avisar que hubo un desbordamiento, pero en mi caso no es necesario
Este código lo estoy haciendo para poder enviar linea por linea datos a un servidor remoto. Una vez que los datos se envían, y se obtiene el mensaje que se han recibido correctamente, se "comentan" para no enviarlos nuevamente.
cuando termine de realizar todo dejaré el código por aquí.
Luego de haber aclarado mis dudas con lo anterior, haciendo las pruebas correspondientes, me he dado cuenta que mi problema principal aún no está resuelto. Este es que, cada vez que extraigo una linea desde la SD queda en la memoria, obviamente, pero mi duda es como liberar esa memoria, cuando extraigo una nueva linea.
he agregado la librería para visualizar la memoria disponible y me di cuenta que la memoria no se está liberando.
Lo que hace el código es abrir automáticamente un archivo (hay uno de muestra en el primer mensaje) en la carpeta ACC y comenzar a leer su contenido linea por linea, omitiendo aquellas que comienzan por un *
no puedo ver donde está mi error que hace que la memoria no se sobre escriba o libere.
EDIT: al parecer el problema está en la función getFileName();
tocando de oido completamente y basado en lo que dices de que puede ser getFileName la rutina responsable del problema observo que abres archivo pero nunca lo cierras.
Si lees la recomendación de la librería sugiere que siempre cierres el archivo abierto.
La acumulacion de archivos abiertos implica RAM. Y la RAM es limitada.
Entonces dos sugerencias: 1) intenta leer la RAM en las rutinas en las que sospechas. Otra opcion
2) Cierra el archivo en sea rutina.
while (file.openNext(sd.vwd(),O_READ))
178 {
179 file.getFilename(filename);
180 if ( isFnMusic(filename) ) {
181
182 if (count == fn_index) {
183 Serial.print(F("Index "));
184 SerialPrintPaddedNumber(count, 5 );
185 Serial.print(F(": "));
186 Serial.println(filename);
187 Serial.print(F("Playing filename: "));
188 Serial.println(filename);
189 int8_t result = MP3player.playMP3(filename);
190 //check result, see readme for error codes.
191 if(result != 0) {
192 Serial.print(F("Error code: "));
193 Serial.print(result);
194 Serial.println(F(" when trying to play track"));
195 }
196 char title[30]; // buffer to contain the extract the Title from the current filehandles
197 char artist[30]; // buffer to contain the extract the artist name from the current filehandles
198 char album[30]; // buffer to contain the extract the album name from the current filehandles
199 MP3player.trackTitle((char*)&title);
200 MP3player.trackArtist((char*)&artist);
201 MP3player.trackAlbum((char*)&album);
202
203 //print out the arrays of track information
204 Serial.write((byte*)&title, 30);
205 Serial.println();
206 Serial.print(F("by: "));
207 Serial.write((byte*)&artist, 30);
208 Serial.println();
209 Serial.print(F("Album: "));
210 Serial.write((byte*)&album, 30);
211 Serial.println();
212 break;
213 }
214 count++;
215 }
216 file.close();
217 }
Hola.
Creo que tal vez podría ser debido a que reabres myFile sin haberlo cerrado antes. Aunque parezca contraproducente, utiliza un File adicional para el directorio (por ejemplo myDirectory), y cierra ambos File al salir de la función.
Prueba a ver y cuenta.
Saludos