Interfacing a Serial SD Card Logger with RaspberryPi.


Introduction


RaspberryPi, the popular Open Source Hardware Board operating out of different Linux based flavors like Debian, Fedora, Archlinux ARM and Android, does indeed allows us to interface a MicroSD Card Adapter for Data Logging and Recording purposes. The MicroSD Card Adapter is provided with a serial SPI Interface which would be used to communicate Data with RaspberryPi. It uses the Traditional four SPI lines, Chip Select(CS), Serial Clock(SCLK), Master-In, Slave-out(MISO) and Master-Out, Slave-in(MOSI) Lines. The Master in our Project is RaspberryPi, which controls the Chip Select Line, and thus dictates the flow control, and Slave is our MicroSD Card Adapter module, which writes and reads data to the Micro SDCard memory, as per the command bytes issued by the master.

The Micro SDCard Adapter module that we have considered in our Project is a Micro SDCard Adapter from Catalex. I purchased it from Amazon, from the link below:

http://www.amazon.in/gp/product/B00HFQEKI0?psc=1&redirect=true&ref_=oh_aui_detailpage_o01_s00#productDetails

Micro SDCard Adapter, from Catalex



















The above figure shows, a Micro SDCard Adapter, from Catalex, featuring a nice level shifter IC, 74VHC125MCT, which takes care of 5V to 3.3V voltage level conversion, and thus no voltage divider circuit would be required by the user, to take care of that part. The below shows, the Schematic of the above MicroSD Adapter.

Schematic of the MicroSD Card Adapter.








































The Serial lines, MISO(DO), MOSI(DI), CS and SCLK lines, are exposed as output, which needs to be used to interface and communicate with our MicroSD Card Adapter. So, this was about, the Module that we want to connect with. Lets see now, how we are connecting the lines to our RaspberryPi, in the next section. 


Connecting with RaspberryPi.

The RaspberryPi model considered here is Model B, rev2, which uses the following lines, which we are using as normal GPIOs and simulating the SPI Signals of Chip Select(CS), MISO, MOSI and SCLK using them, and no SPI Subsystem of Linux, spidev, SPI Device driver framework is used in our Project. The connection to the MicroSD Card Adapter is as shown below:

Adding the connections between our RaspberryPi and Micro SDCard Module.


























The following GPIO pins were used from the P1 Expansion Header of RaspberryPi, Model B, Rev 2:

GPIO P1. 26    AS        OUTPUT_PIN             AS              Chip Select signal.
GPIO P1. 23    AS        OUTPUT_PIN             AS              Serial CLK signal.
GPIO P1. 21    AS        INPUT_PIN              AS              MISO signal.
GPIO P1. 19    AS        OUTPUT_PIN             AS              MOSI signal

Now, to make the above GPIO Pins as INPUT/OUTPUT, to SET/CLR them, we will need GPIO Pin Access. Here, we have three popular options, for simulating the SPI control signals using GPIO Access library. One is using the WiringPi Library by Mr Gordon, the other is using Mike's BCM2835 Library and last option would be using 'mmap' in the user space to map the Address space of the GPIO, since every Hardware peripheral in ARM based core, is Memory Mapped, and BCM2835 SOC makes it so much true.

Here are the Popular Links to help one, decide the options to access the GPIOs of RaspberryPi(in User Space):
          Writing the Low-level code directly into the Project, without using any GPIO Library.
          GPIO, SPI, I2C, UART and other popular RaspberryPi libraries from Gordon.

          GPIO, SPI, I2C, UART and other popular RaspberryPi libraries by Mike.


The Installation and Setup instructions are provided very precisely and clearly in each of the above three blogs. Now,we will leave it to the discretion of the user, with regard to the choice, tht one will take, and will not have discussion on which one ought to be taken. In our Project, we have just randomly taken, Mike's BCM2835 GPIO Library.

The steps followed for the Installation of BCM2835 Library on RaspberryPi are as follows:

# download the latest version of the library, say bcm2835-1.xx.tar.gz, then:
tar zxvf bcm2835-1.xx.tar.gz
cd bcm2835-1.xx
./configure
make
sudo make check
sudo make install

This will install the bcm2835 library to "/usr/local/lib", by default, or user can indicate his preference using -PREFIX Option.

Elm-Chan FATFilesystem Module.


Now, that we have devised the means of getting the Data to the GPIO Pins, we will need a way of accessing the SD Card Filesystem, so that we are able to write this Data present on the GPIO Pins, to the Micro SDCard. Towards, this end we have considered this FATFilesystem Module by Elm-Chan, which is a generic FAT file system module for small embedded systems. The FatFs module is written in compliance with ANSI C (C89) and completely separated from the disk I/O layer. Therefore it is independent of the platform. It is mostly incorporated into small microcontrollers with limited resource, such as 8051, PIC, AVR, ARM, Z80, 78K and etc. 

For more Info, people can refer to the Webpage of the FatFs Module, here:
http://elm-chan.org/fsw/ff/00index_e.html

Also, people, can download the Complete zip of the FatFs Filesystem module, incase they want to consider it for other platforms, specific to AVR, ATMEGA et al.

https://drive.google.com/file/d/0B6Cu_2GN5atpdnlaSGM3NTJ4MjQ/view?usp=sharing

Since this Module was generic, made us thought why could'nt we port it for RaspberryPi platform.We have modified the elm-chan, Generic FATFS FileSystem Module, MMC Bitbanging code to handle SPI Communication in RaspberryPi. Thus, the generic code as shown below has been changed to handle SPI Communication in RaspberryPi.

Handle and Change the generic code for custom platforms.
































So, here is the code that we have added in the file, "mmcbb.c", which we have added specifically for RaspberryPi platform.


Changes required to adapt the generic code for RaspberryPi.


























Thus, we can view, the complete Architecture as follows:

The FATFS APIs are provided by 'ff.c', which implements the FATFS Interface.
The Device Interface, which provided disk interface to access the Physical space is implemented in 'mmcbb.c' file. The Disk interface uses the above Low-level RaspberryPi GPIO Access routines inside the Disk interface calls.


Architecture of the Implementation.
























Here, we have shared the complete source of the zip, along with the Makefile, which we are currently running on RaspberryPi.

https://drive.google.com/file/d/0B6Cu_2GN5atpRnVfR251VjFRckk/view?usp=sharing


In, the next concluding sections we will see, about the Test file and Makefile created for the Project.



Test and Makefile.


A small test has been written in "main.c", wherein, we are creating a HELLO.txt file for writing some characters like "Hello World", and numbers, since it is sent as ASCII, thus conversion of each of the units, tens, hundreds place have to converted into ASCII and then written to the SD Card using Disk Interface, if we want to write and Log numbers in SDCard as Sensor Values.

Test program in main.c to Write and Log data to the SDCard.











































Now, coming to the Makefile, we must take care to install bcm2835 library or wiringPi library, and include that in the LIBS Variable, as shown below, either as '-lbcm2835' or '-lwiringpi'. The SRC_DIR_0 is the Path, where you copied the SDCard.zip and extracted it, in our case, it is set to "/home/pi/RPI_EEPROM/sdcard/src"


Makefile for our Project.






























After making these changes, and installing the appropriate library successfully, open the "TERMINAL" and we execute the Makefile.

#make library

since, the TARGET Name in the Makefile is library at line number 22. This will generate the Binary executable, "RpiSDCard". To, execute it, just run on the Terminal by typing,

#./RpiSDCard


Results, observations and inferences.

Here is my circuit, which is connected to the MicroSD Adapter Module, as shown below:


SDCard Logger interfaced with P1 Expansion Header of RaspberryPi.





































On, executing the program, we get the following output on the Terminal, as shown below:


Output of our Test Program, "main.c".






























So, this completes our Project. Comments and questionnaire can be added in the comments section below, which is open to all. This is an Open Source Initiative.

Here is a small video of the same:

https://www.youtube.com/watch?v=ihqXzQgaIaw&feature=youtu.be





Thank You,
Rajiv.

27 comments:

  1. A lot of the information in this post has been very useful about Micro SD card.

    cheap 32gb micro sd card

    ReplyDelete
  2. Hi Rajiv

    Thanks and keep it up ... Will try

    ReplyDelete
  3. My console says "Create a new file (hello.txt)." but nothing is happening..

    ReplyDelete
    Replies
    1. In 'main.c', we are creating and opening a file "HELLO.txt" in the Root of the SD Card..and Writing some Characters to it...Now, please check if your SD Card is formatted to FAT Filesystem, before you put it inside the SD Card Module, and its not Write Protected...Also, execute this program, incrementally...sometimes, it fails for the first time, due to sync issues, and then again after that, if we try again, it works..Please check the following points..

      Thanks,
      Rajiv.

      Delete
  4. Everything is working fine till execution and failed with rc=3 as return value.
    Can you explain why?

    ReplyDelete
    Replies
    1. What output can you see on the Console, after you run the ./RpiSDCard program..First, the Hello.txt, Text file should be created successfully..then we should be able to write some Data bytes on it, like "Hello World" and so forth... rc, is the variable which returns the number of Bytes Written or Read...Can you show the output of executing the Test Program ?

      Delete
    2. i want to call that lxterminal command ./RpiSDCard from python and execute it... can anybody help?

      Delete
  5. This comment has been removed by the author.

    ReplyDelete
  6. i want to call that lxterminal command ./RpiSDCard from python and execute it... can anybody help?

    ReplyDelete
  7. To all those having issues, if you have not added a pull_up resistor to the MISO line it will cause you read/write problems and you will get various return codes including 3, which is no card inserted. Using wiringPi library here, and as soon as I added internal pullUpDnControl command in the mmcbb.c file, after configuring pin 21 as input, all works fine.

    ReplyDelete
  8. Quite a bit late to the party but is it possible to daisy chain a few of these together? I dont necessarily need them to stack as one partition but I want to be able to add in multiple smaller cards for a higher overall storage space.

    ReplyDelete
    Replies
    1. Control the Chip Select, CS Signal using a DeMUX IC like 74LS138(1:8 DeMUX) & using GPIO Pins from Rpi to Control the DeMUX when it should be driven LOW & HIGH & vice versa between these chained SD Cards. May need Timing constraints, have to look very closely at the Timing requirements based on the Timing diagram specifications. Suggest using Salae Logic Analyzer or Scope to check the Data In/Out with Clk timings & CS signals.

      Delete
  9. My console says "Create a new file (hello.txt)." but nothing is happening..

    ReplyDelete
  10. Thanks Rajiv, Its really Good Stuff and I tried it Successfully. Only, Problem I see is Transfer Speed. I tried to Transfer file Size of 6MB any Tooks time in Minute. Can we Increase the Transfer Speed ? Pls. Share your Email ID If Possible to discuss more.

    ReplyDelete
    Replies
    1. Limited by GPIO switching speed of BCM2835/2837 Core. Please check the Datasheet. Check writing a simple bit-bang driver for this, User space transactions would be slower than the same in the Kernel space.

      Delete
  11. Thank you. It works for me but as expected quite slow.
    Is there are particular reason why you make the SPI transfers with bit banging but not using the SPI functions provided by the library (for example bcm2835_spi_transfer)? I think using the native SPI functions would speed up the things dramatically.

    ReplyDelete
  12. It will be bit slow, but using SPI APIs in user space call would be undeterministic. The Linux Kernel being pre-emptive and when large transfer ongoing, may pre-empt and lead to SPI READ/WRITE failure. It will be limited by SPI bus Speed, Write and Read chunk sizes, which can even lead to crashes. To prevent this, after thinking about so many failure scenarios. Only way out would be to write a Kernel Driver for the SD Card module, and kernel call would be better than some user space API call, waiting in some scheduling cycle. Since, that would be cubersome, the most simplest solution was using Bit banging to have some control on the SPI READ/WRITE timing without getting pre-empted in between.

    ReplyDelete
  13. This comment has been removed by the author.

    ReplyDelete
  14. This comment has been removed by the author.

    ReplyDelete
  15. I am having trouble finding memory card for my mobile phone.
    I have heard that kingston is better than sandisk memory card.I bought an sd card but it got corrupt.
    Please suggest which one shoud I purchase?

    ReplyDelete
  16. This comment has been removed by the author.

    ReplyDelete
  17. Nice article though it is old. Recently, I purchased a Micro SD (SDHC) card from buykingston.co.uk for my camera. Was it the right decision? It is doing well also.

    ReplyDelete
  18. I’m going to read this. I’ll be sure to come back. thanks for sharing. and also This article gives the light in which we can observe the reality. this is very nice one and gives in depth information. thanks for this nice article. Blumaan

    ReplyDelete
  19. good efforts. thanks for sharing. i really appreciate your efforts.

    ReplyDelete