Go Down

Topic: Problem reading SD card high bytes (Read 633 times) previous topic - next topic

ThiagoT

Hello guys,

I'm working in a project which i have to read a entry of the Serial input and search the entry in SD card. The entry is 12 byte length, and it terminate with '*' (in SD card, don't have '*').

The code works well in the first entries, but when i try read the entries in card above the position 2730, the function "seek" return false.

I tried read the card  sequentially, and the arduino can read all bytes of the archive. This mean the problem isn't the archive lenght.


here is my code
Code: [Select]

#include <SD.h>


// Variáveis para entrada (buffer e contador)
byte bufferIn[15];
byte count_buffer = 0;
// indicador de comando
boolean command = false;
// Controlador de Arquivo
File fp;
int count_busca;
char c;

boolean found = false;

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

  if(!SD.begin(4)){ // inicializando o cartão
    Serial.println("Error");
    return;
  }
  Serial.println("Memoria Pronta");


}

void loop(){
  if(command){ // Espera por comando
    command = false; // Para não voltar
    fp = SD.open("teste.txt", FILE_READ); // Abre arquivo
    for(count_busca = 0; fp.seek(12*count_busca) && !found;count_busca++){
      found = compare();
    }
    Serial.println(count_busca);
    fp.close();
      if(found){
        Serial.print("Entrada encontrada na posicao ");
        Serial.println(count_busca);
      }
      else{
         Serial.println("Entrada nao encontrada!!");
      }
      found = false;
  }
}

boolean compare(){ // Compara dado de entrada com o cartão
  int i = 0;
  for(i = 0; i< 12; i++){
    if(bufferIn[i] != fp.read()){ // Se algum byte for diferente, a entrada é diferente
      return false;
    } 
  }
  return true; // Caso os 12 bytes sejam iguais, Retorna true. Caso algum byte seja diferente,o código entra no "if"
}

void serialEvent(){ // Dado de entrado pronto
  bufferIn[count_buffer] = Serial.read(); // Leitura da porta Serial

  if(bufferIn[count_buffer] == '*'){ // Final de String(*) e tamanho do dado(12)
    if(count_buffer != 12){
       Serial.println("Entrada Rejeitada");
       count_buffer = 0;
        return;
    }
    Serial.println("Entrada aceita");
    count_buffer = 0; // zera buffer
    command = true; // Command is ready
    return;
  }


  count_buffer++;
  if(count_buffer > 12){
    Serial.println("Entrada rejeitada");
    count_buffer = 0;   
  }
}



Sorry by lacks in my english and thanks for replies

PaulS

Quote
The code works well in the first entries, but when i try read the entries in card above the position 2730, the function "seek" return false.

Are you skipping a number of bytes after each bit read?

Why not just make compare() read those bytes and ignore them?

Actually, it doesn't appear that you are skipping any bytes, so the seek operation is going to find the current position, anyway, and is, therefore, completely unnecessary.

ThiagoT

the function compare stop when it found a different byte. For example, i have the entry "100000000000" in Serial input, if i read a '0' in first byte of SD card, a don't need the rest of bytes, because i know the entry is different, so i can jump for the next entry in sd card.

countrypaul

2730 * 12 = 32760  which is the highest value you can get below 32767. 32767 being the highest value in a 16bit unsigned integer.

If you want to go further than record 2730 you will need to use a datatype larger than 16bit surely?

PaulS

Quote
2730 * 12 = 32760  which is the highest value you can get below 32767.

Good catch. From File.cpp, in the SD library:
Code: [Select]
boolean File::seek(uint32_t pos) {
So, the function takes a long, to allow for files larger than 32,767 bytes.

OP: Change
Code: [Select]
int count_busca;
to
Code: [Select]
uint32_t count_busca;

Go Up