B4R Tutorial SD cards

The rSD library allows reading and writing to SD cards. The Ethernet shield as well as other shields include a SD slot.

The steps required to work with files:
1. Initialize a SD object. You need to pass the CS pin used. See this link for more information: http://www.arduino.cc/en/Reference/SDCardNotes

2. Open a file with a call to SD.OpenRead or SD.OpenReadWrite.

3. Read or write to the file stream with SD.Stream property.

4. Close the file with SD.

Note that opening a different file will close the previous one.

There is a bug in Arduino tool chain that can lead to this error message during compilation:
GetFileAttributesEx E:\arduino\libraries\SD\src\File.cpp E:\arduino\libraries\SD\src/SD.h: The filename, directory name, or volume label syntax is incorrect.

The workaround for this error is to press on Ctrl + P (clean project) before compilation.

Listing files


This is done with a For Each loop and a call to ListFiles:
B4X:
For Each f As File In sd.ListFiles("/")
   Log(f.Name, TAB, Round(f.Size / 1024), "kb", TAB, f.IsDirectory)
Next

Example

In this example the Arduino will print currency conversion rates (for 1 USD).
The data comes from this web service: https://openexchangerates.org/

A B4J non-ui program will parse the JSON string and prepare the data file. The data file is then manually copied to the sd card.

This is the important code:
B4X:
For Each currency As String In rates.Keys
   Dim value As Float = rates.Get(currency)
   raf.WriteBytes(currency.GetBytes("ASCII"), 0, 3, raf.CurrentPosition)
   raf.WriteFloat(value, raf.CurrentPosition)
Next
Each record is made of 7 bytes. 3 bytes for the currency code and 4 bytes for the currency rate (float in B4J, double in B4R).
Working with fixed size records makes everything simpler.

The B4R code randomly reads a record and "parses" it with RandomAccessFile (raf object).
B4X:
Sub Timer1_Tick
   Dim recordIndex As Int = Rnd(0, numberOfRecords)
   sd.Position = recordIndex * buffer.Length
   'fill the buffer from the file
   sd.Stream.ReadBytes(buffer, 0, buffer.Length)
   Dim r As Record
   raf.CurrentPosition = 0
   'read the data from the buffer
   r.Currency = raf.ReadBytes2(3, raf.CurrentPosition)
   r.Value = raf.ReadDouble32(raf.CurrentPosition)
   PrintRecord(r)
End Sub
Note that raf is reading from the 7 bytes buffer. It doesn't read directly from the file.

The output:
B4X:
Currency: ALL, Conversion rate: 122.5504
Currency: NAD, Conversion rate: 14.4795
Currency: TOP, Conversion rate: 2.2264
Currency: SHP, Conversion rate: 0.6978
Currency: UYU, Conversion rate: 31.3598
Currency: XPD, Conversion rate: 0.0018
Currency: SVC, Conversion rate: 8.7408
Currency: TTD, Conversion rate: 6.6025
Currency: CRC, Conversion rate: 534.1298
Currency: MUR, Conversion rate: 35.2083
Currency: LBP, Conversion rate: 1509.8867
Currency: ALL, Conversion rate: 122.5504
Currency: EUR, Conversion rate: 0.8822
Currency: EUR, Conversion rate: 0.8822
Currency: BRL, Conversion rate: 3.6019
Currency: BSD, Conversion rate: 1
Currency: ANG, Conversion rate: 1.7888
Currency: BBD, Conversion rate: 2
Currency: UAH, Conversion rate: 25.4788
Currency: MYR, Conversion rate: 3.8872
Currency: MDL, Conversion rate: 19.7002
Currency: BZD, Conversion rate: 1.9943
Currency: CLF, Conversion rate: 0.0246
Currency: VND, Conversion rate: 22304.2167
Currency: PAB, Conversion rate: 1
Currency: LBP, Conversion rate: 1509.8867
Currency: XDR, Conversion rate: 0.7101
Currency: WST, Conversion rate: 2.5689
Currency: DJF, Conversion rate: 177.6560
Currency: LYD, Conversion rate: 1.3618
Currency: DKK, Conversion rate: 6.5687
Currency: MDL, Conversion rate: 19.7002
Currency: GHS, Conversion rate: 3.8247
Currency: IMP, Conversion rate: 0.6978
Currency: RSD, Conversion rate: 108.5291
Currency: IMP, Conversion rate: 0.6978
Currency: RUB, Conversion rate: 66.3405
Currency: KES, Conversion rate: 101.1949
Currency: TWD, Conversion rate: 32.2740
Currency: MRO, Conversion rate: 345.2912
Currency: BZD, Conversion rate: 1.9943
Currency: KGS, Conversion rate: 68.4286
Currency: VND, Conversion rate: 22304.2167
 

Attachments

  • B4J_PrepareCurrencyFile.zip
    2.8 KB · Views: 713
  • SD_Example.zip
    1.1 KB · Views: 914

derez

Expert
Licensed User
Longtime User
Erel
Can you give an example how to write to the sd card ?
Thanks
 

Ronce

Member
Licensed User
How setup?
SD.Initialize(MY_SCLK, MY_MISO, MY_MOSI, MY_CS);
I think, there is no need to set up other pin at SD.Initialize(...); See erel tutorial step 1. on b4r code the SD.initialize(...) is only for CS pin, 4 is the CS pin when using the ethernet shield, 10 is for UNO, 53 is for Mega

And for other pin just ensure you make corrected pin wiring with your board and SD Card module based on link that already given

The communication between the microcontroller and the SD card uses SPI, which takes place on digital pins 11, 12, and 13 (on most Arduino boards) or 50, 51, and 52 (Arduino Mega). Additionally, another pin must be used to select the SD card. This can be the hardware SS pin - pin 10 (on most Arduino boards) or pin 53 (on the Mega) - or another pin specified in the call to SD.begin(). Note that even if you don’t use the hardware SS pin, it must be left as an output or the SD library won’t work.
 
Top