Go Down

Topic: Compiling an SD/MMC and fat16 library (Read 5 times) previous topic - next topic


Ok I'll try and expalin but someone else probably can do it better. If you are writing numbers larger than bytes (8bits =  2^8-1 = 255) then you need to split the number up into separate bytes. I'll give a code example. I wanted to store the values of the arduino ADC in the memory card. Values from the ADC are 10bit (10bits = 2^10-1 = 1023). So the 10bit number needs to be split into two values to be able to be stored in 8bits.

Code: [Select]

// Store my 10bit value in an int (NOT a byte, which is only 8bits) so 16 bit number. High(1111 1111) Low (1111 1111)
int temp;

byte low;    // Variable to store the low byte in
byte high;   // Variable to store the high byte in

temp=analogRead(0); //Read in the value

// AND the number with 255 which wipes the 8bits at front of number
// The front 8 bits gets wiped->High(1111 1111) Low(1111 1111) = High(0000 0000) Low(1111 1111)
// So you can store half the number in the low byte variable

// Rotate the number 8 bits right to get the high bits.

So you can then store each byte in an array and then write it to disc. To read back from the disc you read in each byte and then join them together again.
Code: [Select]

byte low;
byte high;
byte info[2];
int value;

sd_raw_read(0,info,2); // Read the 2 values from disc
low=info[0];  // store low byte
high=info[1]; //Store high byte
result=high<<8; // rotate left 8 bits the high value and store in result
Serial.print(result+low,DEC); //Add low and high together to get the original number you split up into 2 bytes

The easiest way to see how this all works is to try this code and use Serial.print after each operation and print the numbers in binary. Then you can see how the bit manipulations are working. For larger values long int etc, you have to split the number up into 8bytes and then store each byte individually. So if you wanted to store a 32 bit number you would need to split it into 4 bytes and then write each byte to disc.

Well, hopefully I explained it ok  :)


How can i get an unsigned long int converted to it´s bytes?
I want to store the offset in the start range of the card, the first four bytes.
So this could be read the next time it starts recording and does not overwrite the record from before.

I thought code like this could help, but i googled extensively for a solution, but didn´t found something really helpful.
Here´s how i thought:

Code: [Select]

unsigned long int sdoffset=1024;  // r/w offset
// offset 0 to 1023 is for rw offset and whatever storage.
// for the first usage have to write zeroes to that.

void checkStartOffset(){
 byte offsetstored[4];
 sd_raw_read(0, offsetstored ,4);
 sdoffset=(unsigned long int)offsetstored;
 Serial.print("sdoffset read: ");
void WriteLastStartOffset(){
 char offsetstored[4];
 sd_raw_write(0, offsetstored ,4);

the start check compiles, but don´t know at the moment if that works. The read function will not compile.
Could someone point me into the right direction?

Thank you very much for any help with this!


i will think before i post..  ;D

got the simple answer about 3.3V 2min later with measurement equipment: 3.3V pin works with a 9V alkaline.



that code really helped! thanks a lot! Works perfect!

At the moment i am still over it, run i a little question ... What about the 3.3V! I believe i read some time ago it´s only powered when connected to usb, got it from ftdi chip? Is that right? So i would need for sure an additional voltage regulator for external power supply.
Does someone know exactly?

Now i have arduino connected to usb with a kingston 1G card in the slot. Powered from diecimilia 3.3V supply and added a 0.47uF Elco to 3.3V power supply of the card. For the moment no problems with it.

First i will power the board with 9V alkaline for testing, later a 3.7VLiPo with stepUp. (does someone have a circuit for that? Will also add an Max1811 for LiPo charging when on usb. Have the max appnote for that.
But if someone has a working version for arduino would be fine.)

Nice sun at the moment here, hopefully get it working for a walk in the outside soon!


Feb 16, 2008, 01:37 am Last Edit: Feb 16, 2008, 01:39 am by agent_orange Reason: 1
That define thing is handy, saves all my hacking in the library, much neater this way!

This code should write 2 bytes to the SD card starting from memory location 0. Then read them back into the tempBytes array. If you were writing your NMEA string, then read it in from serial port into an array of correct length of the string(i.e. 16 bytes or 32 or whatever an NMEA string is) then write that array to a memory location.  It's pretty easy, try this example code.
Code: [Select]

// Define an array for storing data.
byte tempBytes[2];
// Store some example numbers

// Write the 2 bytes stored in tempBytes to memory location 0

// Zero the tempBytes array to make sure read works ok.

// Read 2 bytes starting from memory location 0 into tempBytes print to serial output.

Go Up