Category Archives: Raspberry Pi

I2C Communications between Raspberry Pi and Arduino – Update

Over the past few days, I have been able to bit bang the I2C bus with the PIGPIO library. I found a very helpful example at http://raspberrypi.stackexchange.com/questions/3627/is-there-an-i2c-library/4052 which was posted by crj11. This example was using the pigpiod_if.h library. This worked well but required the application to be run with elevated privileges (sudo) which was not acceptable as I needed to run the application from a Python script which in turn was running every 5 minutes from a cron job. The final solution was to use the pigpiod_if2.h and run the pigpio daemon on startup.

The final solution has been running for a few days with three sensors connected over a total of 9 feet (~3 meters) of cable. The data has been logged at Adafruit.IO which I have made public. I may remove or rename the Dashboard in the near future so here is a screenshot of the page.
adafruit_io_v0.1.0

I have also updated the GitHub site for the project so there are now two releases available. Version RC_0.0.1 is the version using the hardware for I2C control and version RC_0.1.0 is the bit bang version.

I still have more work to do to make this project valuable to others. I plan to create some better documentation on the project and provide a full write-up to allow someone to follow along and build there own from start to finish. Right now, 80% to 90% is captured in various places but there are obvious gaps such as the connection to the Raspberry Pi. One can figure this missing information out by looking through the right source files and piece it together however I do not like it when I find a project write-up that is only 80% to 90% documented. It is still better than nothing or only 10% to 25% though.

I hope someone will find some of the information here useful.

Sensor with one cable connected

I2C Communications between Raspberry Pi and Arduino – Update, BOM, and Source Control

Update

I have been working on this project over the past couple of weeks when I have free time but have not been posting updates. This is a general update which is why the title is different from the other posts regarding this project.

My boards from OSH Park arrived last week. I was able to populate them and test them out. Fortunately I did not make any errors on the PCB or schematic so they all worked as designed. There are a few things that I would change on a future version if I choose to make another version of the board.

  1. I would put the ICSP header on the bottom of the board so it does not stick out from the front. This would make it much easier to assemble and would make it possible to not have any exposed circuitry which may allow the device to be damaged from static electricity.
  2. I would move the resistors toward the bottom of the board if possible. It would allow the DHT11 sensor to stick out further from the case.
  3. I would also try to push the ATtiny85 a little further towards the bottom for the same reason as the resistors.

Currently I am looking to bit bang the I2C bus on the Raspberry Pi. I seem to have gotten around the clock stretching issue if there is only one device connected to the I2C bus but as soon as I add another device, the clock stretching becomes an issue again. I really wish that the Pi Foundation would work with Broadcom and fix the issue with the I2C bus.

Here are some pictures.

This slideshow requires JavaScript.

Bill of Materials (BOM)

Materials List (For One Sensor)

  • QTY 1 – PCB (Source: OSH Park)
  • QTY 2 – 3.5mm 4 Pole Audio Jack, J1 & J2 (Source: MCM Electronics NOTE: I ordered 27-9485 but received ones which look like 27-9487)
  • QTY 1 – 2×3 Position Male Header 2.54mm Pitch, JP1 (Source: MCM Electronics NOTE: This is a 2×13 header. You will need to cut it for 2×3 header.)
  • QTY 1 – T-1 3mm LED, LED1 (Source: MCM Electronics NOTE: May choose another color)
  • QTY 1 – CDS Photoresistor Photoelectric 5549 GL5549, PH1 (Source: Ebay)
  • QTY 2 – Resistor 1/4W 10K Ohm, R1 & R2 (Source: MCM Electronics)
  • QTY 1 – Resistor 1/4W 220 Ohm, R3 (Source: MCM Electronics)
  • QTY 1 – DHT11 Digital Temperature & Humidity Sensor Moudle, SE1 (Source: Ebay)
  • QTY 1 – ATMEL ATtiny85, U1 (Source: Newark)

Materials List for Raspberry Pi Hat

  • Qty 1 – Perfboard (Source: Adafruit)
  • Qty 1 – GPIO Header for Raspberry Pi NOTE: The one you will need depends on which model of Raspberry Pi you are using. (Source: Adafruit 2×13 Header for original Raspberry Pi or 2×20 Header for newer Raspberry Pi)
  • QTY 1 – 3.5mm 4 Pole Audio Jack (Source: MCM Electronics NOTE: I ordered 27-9485 but received ones which look like 27-9487)
  • Optional items

Source Control

I have added the source files for the Hardware and Software onto GitHub. I did this so the community may have access to the files and any updates to them. I mainly did it because I was having a hard time remembering which set of files I last worked with especially if a few days went by when I could not work on the project. I think this is a win-win for me and anyone interested in this project.

The files are located at https://github.com/TeelSys/TeelSys_THL. When you first go to the page, it may look like there are mo project files included in the project. If that is the case it is because I am still trying to get everything working properly before I commit code to the master branch. You will see a button with the text “Branch: master” and a downward arrow. Click that button and select another branch such as “dev”. You will then see the project files in their current state.

If you wish to contribute, add a comment here or if you can request through GitHub, do that. I will reply once I see the request but keep in mind that it may be a few days.

I2C Communications between Raspberry Pi and Arduino – Part Four

It has been two weeks since my last post but it has been out of frustration on porting the code over to the ATtiny85. The first thing that I ran into was that the Wire library is not supported on the ATtiny85. I needed to modify my code to work with the TinyWireS library. This did not seem too bad and worked once in a while. It was a bit frustrating as I followed examples and it appeared that I was doing everything correctly but that is typically how it goes when coding.

I finally took a look at the specs for the ATtiny85 and realized that memory may be my issue so I started to pare down the memory requirements. The Arduino IDE was not complaining but I recalled an posting that was published on Adafruit a couple of years ago called Arduino Memories. After rereading the article and looking at a couple of other references, I determined that I needed to tackle the memory is see if it was an issue.

At some point in my debugging, I had noticed that the examples for TinyWireS were utilizing a buffer and pointer method to do fast reads and writes. I had a significant switch statement on the request data handler so I removed that and went with the buffer option. By doing so I reserved a whopping 256 bytes for the buffer. This was a very stupid move which I realized when I took a look at the specs for the the ATtiny85. The ATtiny85 has only 512 bytes of RAM so I was consuming half of it for the buffer which did not leave much room for anything else.

I dropped the buffer size down to 32 bytes which helped a great deal. After reducing the size of the buffer, I could get communications between the ATtiny85 and the Raspberry Pi to work a few times before the communications stopped working. I further refined the code to reduce memory usage and swapped out the Adafruit DHT library for one written by Rob Tillaart for the DHT11 only.

Book1

With these modifications, I was able to get the code down to using 113 bytes of RAM and 4,918 bytes (60%) of Flash.

With these changes, the code works quite well but sometimes it appears that the ATtiny85 does not read the correct request from the Raspberry Pi. After some searching it was found that there is a known issue with the Raspberry Pi and clock stretching. It appears that there is a bug which has not been fixed yet if the slave stretches the clock at the right moment and the stretching is too short. The ATtiny85 implements I2C in software so this is going to happen at some point.One of the best articles on this issue is the Raspberry Pi I2C clock-stretching bug.

There are some suggested fixes which I need to read more to understand well enough to use. The most promising fix appears to use Python to perform I2C communication in software. The recommendation is to use the PiGPIO library.

Below is the code that I have thus far on the ATtiny85.

Here is the code on the Raspberry Pi to verify that things are working.

Running the Raspberry Pi program produces the following result.

 

Next step is to see if I can resolve the clock stretching issue and then connect to adafruit.io to post data. If it is not possible to address the clock stretching issue, it would be possible to identify when it occurs and reset the power to the I2C slave devices. I am trying to avoid that solution but I may need to resort to that solution.

I2C Communications between Raspberry Pi and Arduino – Part Three

Today’s goal is to send a string from the Arduino to the Raspberry Pi. The setup is the same as from day two.

After several attempts and stupid mistakes, I was finally able to get a “Hello World” message from the Arduino to the Raspberry Pi.

Here is the code for the Arduino

Here is the code for the Raspberry Pi

Compile the code
gcc testi2c03.c -o testi2c03
Config_I2C_103

Run the code
./testi2c03 254
Config_I2C_104
Config_I2C_105

We can see that once the string ends, the data on the I2C buss is 255. Let’s tweak the code on the Raspberry Pi to stop once we receive 255.

Compile the code
gcc testi2c03b.c -o testi2c03b

Then run the application
./testi2c03b 254
Config_I2C_107

We can see that the output is now cleaner.

Let’s do even better and print the string as a string instead of a list of characters.

Compile the code
gcc testi2c03c.c -o testi2c03c

Then run the application
./testi2c03c 1 2 3 254 250 251
Config_I2C_108

Yes, I included additional arguments this time. The code was setup to handle this which is really nice. This allows us to teak the code if we like to print out what the values actually are and get some additional information. So let’s create a new application which will do exactly that but will not take in any arguments. I am also going to add a few other things such as detecting if we are using a Raspberry Pi Rev 1 or Rev 2 as well as scanning the I2C Bus.

I was doing some searching on valid I2C addresses and found a great reference article from Total  Phase at 7-bit, 8-bit, and 10-bit I2C Slave Addressing. The article provides a diagram showing the valid range of 7-bit I2C addresses.

slave-address-fig3

From this diagram, we can see that the address used in the examples is a reserved address. I will change the address in the Arduino code so that it is in the valid address range.

Here is a modified version of the code which finds all connected I2C devices. Determines which ones are the sensors that we are interested in, and reads values from each one. This will be a great program for making certain that the design works and all of the sensors are working.

Arduino Code

Raspberry Pi Code

 

Compiling the Raspberry Pi code is a bit different as we need to link the math library. In order to do this, we need to add -lm to the command line.

gcc testi2c03d.c -o testi2c03d -lm

Config_I2C_110

Here is the results of running the application.
Config_I2C_112

 

The passing of a string was successful however there are several standards which may be better suited to the goal that I have in mind. One worth further consideration is the System Management Bus (SMBus). For the moment, I am leaving the code as is since the information that I need to send may be sent as simple integer responses. A future enhancement will be to get a better messaging system in place.

The next step is to replace the Arduino with a ATTiny85 and get it all working.

I2C Communications between Raspberry Pi and Arduino – Part Two

The goal of the day is to get the Raspberry Pi and Arduino talking to each other over I2C.

I followed a few examples provided on the internet and was able to get the two to talk to each other. Just to be clear, the Raspberry Pi will be the I2C master and the Arduino will be the slave. One of the nice advantages to this configuration is that it is not necessary to do any voltage level shifting between the two devices. If you are not aware, the Raspberry Pi GPIO is at 3.3V and the Arduino is at 5V. If the Arduino were to supply 5V to any of the Raspberry Pi’s GPIO pins, the Raspberry Pi will be toast.

I followed the tutorial at http://blog.retep.org/2014/02/15/connecting-an-arduino-to-a-raspberry-pi-using-i2c/. Below are some of the high level steps.

  1. Download the latest Raspbian image from https://www.raspberrypi.org/downloads/raspbian/
  2. Unzip the file and write the image to the SD Card using Win32DiskImager from https://sourceforge.net/projects/win32diskimager/
  3. Once the Raspberry Pi boots, open a terminal window and run raspi-config to enable I2C Support
    sudo raspiconfig
    Config_I2C_000
  4. Select “Advanced Options” from the menu
    Config_I2C_001
  5. Select “I2C” from the Advanced Options menu
    Config_I2C_002
    Select “Yes”
    Config_I2C_003
    Select “OK”
    Config_I2C_004
    Select “Yes”
    Config_I2C_005
    Select “OK”
    Config_I2C_006
    ”Select “Finish”
    Config_I2C_007
  6. Install i2c-tools
    sudo apt-get update
    Config_I2C_011
    sudo apt-get install i2c-tools
    Config_I2C_012
  7. Run i2cdetect to make certain that i2c-tools installed properly
    i2cdetect –y 0
    or
    i2cdetect –y 1
    Config_I2C_013
    If all worked well, you will see the following output
    Config_I2C_014
    If there are devices connected to the I2C pins, you will see the devices listed as in this example.
    Config_I2C_015
  8. Wire up the Arduino and Raspberry Pi
    Raspberry PI        Arduino
    GPIO 0 (SDA)    <–>    Pin 4 (SDA)
    GPIO 1 (SCL)    <–>    Pin 5 (SCL)
    Ground    <–>    Ground
    Step002_bb
    Step002_schem
  9. Upload Code to the Arduino
  10. Write the application on the Raspberry Pi
    nano testi2c02.c
    Config_I2C_020
  11. Type of copy paste the following code
  12. Save the file by pressing <Ctrl> + o

    Config_I2C_022
    Config_I2C_023
  13. Exit the editor by pressing <Ctrl> + x
    Config_I2C_024
  14. Compile the application
    gcc testi2c02.c -o testi2c02
    Config_I2C_025
    If you do see errors, go back and edit the file to correct them.
    Config_I2C_025
    Once the changes are made, recompile and if you do not see any error messages, you are good to go.
    Config_I2C_026
  15. Run the application
    ./testi2c02 1 {Gets the temperature in Celsius}
    Config_I2C_030
    ./testi2c02 2 {Gets the relative humidity in percent}
    Config_I2C_031

    ./testi2c02 3 {Gets the light level}
    Config_I2C_032

    ./testi2c02 4 {Turns the LED On}
    Config_I2C_033

    ./testi2c02 5 {Turns the LED Off}
    Config_I2C_034

    ./testi2c02 6 {Flashes the LED when reading sensors. This is the default behavior of the LED}
    Config_I2C_035

    ./testi2c02 7 {Echos the number 7. This may be repeated with any other number up to 255}
    Config_I2C_036

    Config_I2C_037

That’s all for the day. Next I plan to try to send strings and develop a format for messages.

I2C Communications between Raspberry Pi and Arduino – Part One

My daughter has a science project for school on bread mold growth. She will need to monitor the temperature, humidity, and light level of 3 separate environments. Being the geeky dad that I am, I decided to make her some data loggers to monitor each environment. I would also like to take this further by connecting to an online IoT site such as adafruit.io to store and graph the data. There are a few options available such as using an Arduino with a Wi-Fi shield to connect to the site and monitor the environment but that is not an elegant solution. What I have opted to do is to use a Raspberry Pi instead and use I2C to communicate to the sensors using ATTiny85 microcontrollers. One of the reasons for this choice was that she will need to monitor the growth with 10 to 30 slices of bread for each environment. With that many slices in one batch,  there could be a considerable variation throughout the area containing the bread so more than one data logger/sensor cluster should be used. I2C is the perfect solution as you may have up to 127 devices connected with just 3 wires.

Use an Arduino Uno R3 to get information from the sensors and verify that the code works correctly.

Step001_bb

Step001_schem

Arduino Code

Output

 

 

Next Step -> Add Raspberry Pi and I2C Communication

Raspberry PI B+

Hardware

Needed

  • Raspberry Pi
  • MicroSD Card 4GB or larger
  • USB Keyboard
  • USB Power Supply and cable with micro USB Connector
  • Display (Composite or HDMI)
  • Display cable (Type of cable depends on monitor)
  • MicroSD Card to SD Card Adapter (Needed only if your PC has a SD Card Reader but not a MicroSD Card Reader)

Nice to Have

  • Raspberry Pi B+ Case (Note cases for other models may not work)
  • WiFi module or Ethernet Cable

Steps

  1. Download the Raspbian Image from http://www.raspberrypi.org/downloads/ (As of this post, the file is 2014-06-20-wheezy-raspbian.zip)
  2. Unzip the Raspbian Image File
    Image2
  3. Follow the instructions at http://www.raspberrypi.org/documentation/installation/installing-images/README.md for your operating system. I will be using Windows and will mirror the steps from the installation instructions page

Windows Installation

  1. Insert your MicroSD card into the card reader on your PC (NOTE: You may need a MicroSD to SD Card Adapter)
  2. Download the Win32DiskImager utility from http://sourceforge.net/projects/win32diskimager/ (As of this post, the file is Win32DiskImager-0.9.5-install.exe)
  3. Install the Win32DiskImager Utility by double clicking the downloaded file
  4. Click on the “Next >” button on the setup wizard
    Welcome to the Win32DiskImager Setup Wizard
  5. Select the “I accept the agreement” radio button and click the “Next >” button
    License Agreement
  6. Click the “Next >” button on the destination location dialog
    Select Destination Location
  7. Click the “Next >” button on the Select Start Menu Folder dialog
    Select Start Menu Folder
  8. If you do not want a desktop shortcut, uncheck the “Create a desktop icon” checkbox
  9. Click the “Next >” button on the Select Additional Tasks dialog
    Select Additional Tasks
  10. Click the “Install” button on the Ready to Install dialog
    Ready to Install
  11. Wait for the installation to complete
    Installing
  12. Click the “Finish” button on the Completing the Win32DiskImager Setup Wizard dialog
    Completing the Win32DiskImager Setup Wizard
  13. It is possible that you may see the following error message
    Unable to execute file
  14. If you see the error message above
    1. Click the “OK” button
    2. Right-click on the desktop shortcut and select “Run as administrator” from the pop-up menu
      Run as administrator
    3. When the User Access Control dialog is displayed, click the “Yes” button
      User Access Control dialog
  15. The application is now open
    Win32 Disk Imager
  16. Click the folder icon and select the Raspbian image file downloaded earlier
    Selecting the image file
  17. Select the drive letter for your MicroSD Card
    WARNING: Be very careful to select the correct drive letter as the utility will erase all data on the drive! You have been warned!
    Select the MicroSD Card
  18. Click the “Write” button
    Write the image
  19. Click the “Yes” button on the confirmation dialog
    Confirm Write
    If you see the following error (), check that there are no open Explorer Windows or other applications attempting to access the SD Card
    Write Error
    If you see the following error, check the write lock switch on the MicroSD Card Adapter
    Lock Error  SD Card Lock Switch
    Wait for the process to complete
    Wait
  20. When the process is complete, click the “OK” button
    Write Sucessful
  21. The main window will display the status as “Done.” Click the “Exit” button to exit the utility
    Done.
  22. Eject the MicroSD Card

Once the Raspbian Image has been written to the MicroSD Card, you are ready to boot and configure the Operating System (OS).

Booting and Configuring the Raspberry Pi using Raspbian OS

  1. Insert the MicroSD Card in the Raspberry Pi
  2. Connect the monitor, keyboard, mouse (optional), and power
  3. The Raspberry Pi Software Configuration Tool (raspi-config) will launch

Initial Configuration of the Raspberry Pi

First Step – Getting the Raspberry Pi to Boot

Required Items

  • Raspberry Pi
  • 2 GB or larger SD Card
  • Keyboard
  • Monitor (Composite or HDMI)
  • Display cable (Composite or HDMI)
  • USB Power Supply
  • USB Cable for power (Micro USB)
  • PC connected to the internet with a card reader

Optional Items

  • Case for Raspberry Pi
  • USB Mouse
  • Book – Raspberry Pi User Guide
    by Eben Upton & Gareth Halfacree
    ISBN: 978-1-118-46446-5 (Amazon Link)

NOTE: I am running these steps from a Windows 7 PC. If you are running from another OS be certain you read the information on the http://www.raspberrypi.org/downloads page for information for your OS. I am also using a 16 GB SDHC Card.

Steps

  1. Go to the download section at http://www.raspberrypi.org/downloads
  2. If you are running a Windows PC, download Win32DiskImager
    I downloaded the version 0.5 binary (win32diskimager-binary.zip)
  3. Download the Raspbian “wheezy” image
    I downloaded via the direct download.
    The version at the time of this blog entry is 2012-12-16-wheezy-raspbian.zip
  4. Open the zip file (2012-12-16-wheezy-raspbian.zip) and extract the image file (2012-12-16-wheezy-raspbian.img)
    The following steps are modified from the “Easy Way” section from http://elinux.org/RPi_Easy_SD_Card_Setup
  5. Insert the SD card into your SD card reader and check what drive letter it was assigned. You can easily see the drive letter (for example G:) by looking in the left column of Windows Explorer. If the card is not new, you should format it; otherwise Win32DiskImager may hang.
  6. Extract the Win32DiskImager utility files from the zip file (win32diskimager-binary.zip) and run the Win32DiskImager utility (Win32DiskImager.exe). You should run the utility as Administrator! (Right click on Win32DiskImager.exe and select “Run as administrator from the context menu.)
    001
  7. Select the 2012-12-16-wheezy-raspbian.img image file you extracted earlier
    002
  8. Select the drive letter of the SD card in the device box. Be careful to select the correct drive; if you get the wrong one you can destroy your computer’s hard disk!
    003
  9. Click Write and wait for the write to complete.
    004005
  10. Exit the imager and eject the SD card.
  11. Insert the card in the Raspberry Pi, power it on, and it should boot up. There is an option in the configure script that comes up to expand the partitions to use all of the SD card if you have used one larger than 4 GB

Second Step – Initial Configuration of the Raspbian “wheezy” distribution

When you boot up the Raspberry Pi, the Raspi-config utility will launch.

There are a few things that you should configure right away or you may have problems later.

  • Expand the root partition if your SD Card is greater than 4 GB (Optional)
    1. Select “expand_rootfs” from the Raspi-config menu
    2. The Raspi-config widow will disappear for a bit then a new window will display telling you that the root partition has been resized and the file system will be enlarged upon the next reboot. Click enter to close the dialog.
  • Configure the keyboard (You must do if you are not using a UK keyboard!)
    I did not perform this step the first time I booted up the Raspberry Pi and I had issues as I could not use the pipe symbol. The “|” was mapped as a tilde “~” symbol.

    1. Select “configure_keyboard” from the Raspi-config menu
    2. You may keep the default “Generic 105-key (Intl) PC” model or change it to match your keyboard
    3. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    4. If you are not using a UK keyboard, select “Other”
    5. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    6. Select your country of origin from the list (i.e. English (US))
    7. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    8. Select the keyboard layout (i.e. English (US))
    9. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    10. Select the option for the AltGr modifier (i.e. The default for the keyboard layout)
    11. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    12. Select the option for the Compose key (i.e. No compose key)
    13. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    14. Select an option for the Control+Alt+Backspace key combination
    15. Press enter
    16. There will be some delay as the options are saved
    17. The Raspi-config menu will reappear
  • Change the locale (You should do if you are not in the UK)
    1. Select “change_locale” from the Raspi-config menu
    2. Scroll down to the “en_GB.UTF-8 UTF-8 option and deselect it by pressing the spacebar (You do not need to remove it. You may keep it if you like.)
    3. Scroll through the list to find the locale(s) you wish to install and select it/them by pressing the spacebar (i.e. en_US.UTF-8 UTF-8)
    4. Tab to the bottom options and select “<OK”>” and press enter
    5. Select the default locale for the system (i.e. en_US.UTF-8 UTF-8)
    6. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    7. There will be some delay as the options are saved
    8. The Raspi-config menu will reappear
  • Change the time zone (Unless you want to stick to UTC)
    1. Select “change_timezone” from the Raspi-config menu
    2. Select your geographic area (i.e. US)
    3. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    4. Select your time zone (i.e. Eastern)
    5. Press enter or Tab to the bottom options and select “<OK”>” and press enter
    6. There will be some delay as the options are saved
    7. The Raspi-config menu will reappear
  • If you have a hardwired internet connection, you may try to update Raspi-config
    1. Select “update” from the Raspi-config menu
    2. Press enter or Tab to the bottom options and select “<OK”>” and press enter
  • Once you are done making changes, press the tab key to jump to the options at the bottom of the screen and select “<Finish>”
  • Depending on the options selected, you may be prompted to reboot. If given the option, reboot your Raspberry Pi as most options do not take effect until the Raspberry Pi reboots.