Saturday, October 17, 2009

Duino644 software updates

I was close to giving up on SDuFAT library in favour of FAT16, but my one last attempt worked. I was trying to implement a feature suggested by fellow Arduino blogger BroHogan, to set up the clock using a file on the SD card. Since real time clock is set up quite rarely, this idea makes perfect sense.
Here is how it works:
  • the user creates/copies the file "time.txt", which contains the time, formatted as HH:MM:SS, onto the SD card;
  • after reset, if "time.txt" is found, the clock is set with the given (in the file) time;
  • "time.txt" file is deleted, so the next reset won't find the file anymore;
It is always easier said than done.
Firstly, SDuFAT requires the file to have some characteristics, the most important being to contain a pseudo-EOF (0x03) character.
Secondly, the deletion of the file is not physical, the file does not disappear from the SD card, but it is rather modified so that its first character is the pseudo-EOF (0x03). The "deleted" file can be opened and its content read. The code decides that the file is "deleted" by checking the first character. How smart is that?

setRtcFromSDCard() shown below is the function that gets called in setup().

void setRtcFromSDcard()
{
numSectors = (int) SD.getSectors("time.txt");
if (numSectors == 0)
{
// try again;
delay(500);
numSectors = SD.getSectors("time.txt");
}

if (numSectors == 0)
{
#ifdef _DEBUG_
Serial.println("File time.txt not found.");
#endif

return;
}

// open file time.txt and read its content;
sectorContent = SD.readBytes("time.txt", 0);

// search for the time in the sector buffer;
boolean isTimeFound = false;
for (int i = 0; i<512; i++)
{
if (sectorContent[i] == 0x03)  // EOF
break;

for (int j=0; j<8; j++)
{
timeBuffer[j] = sectorContent[i+j];
}
if (timeBuffer[2] == ':' && timeBuffer[5] == ':')
{
// found the time;
isTimeFound = true;
break;
}
}

if (!isTimeFound)
{
#ifdef _DEBUG_
Serial.println("Could not find time (HH:MM:SS) in file time.txt");
#endif
return;
}

#ifdef _DEBUG_
Serial.print("Time from file is: ");
Serial.println(timeBuffer);
#endif

int hh = 10*(timeBuffer[0]-48) + (timeBuffer[1]-48);
int mm = 10*(timeBuffer[3]-48) + (timeBuffer[4]-48);
int ss = 10*(timeBuffer[6]-48) + (timeBuffer[7]-48);

#ifdef _DEBUG_
Serial.print("RTC time to be set to: ");
Serial.print(hh);
Serial.print(":");
Serial.print(mm);
Serial.print(":");
Serial.println(ss);
#endif

if (hh < 24 && mm < 60 && ss < 60)
{
setTime(hh, mm, ss);
SD.del("time.txt");
}
}


The other software change I made was also the contribution of BroHogan, who wrote (see reply #147) a few functions that perform "fast writes" to the LED display from Sure Electronics. Basically, the calls to digitalWrite() in ht1632_writebits() function have been replaced with calls to fWriteA(). This allows control over the speed of scrolling, ranging from fast to slow, rather than from slow to slower.


No comments:

Post a Comment