Rock Pi 4B: I2C Communication

Getting I2C to work between a Rock Pi 4B and an Arduino can be a challenge for those who are new to the world of Single-Board Computers. Many tutorials can be found for getting I2C ready on a Raspberry Pi. Those tutorials, however, do not translate directly to the Rock Pi 4B because of differences in hardware.

For reference, I am running Armbian 5.67. I will be using a Python script to demonstrate I2C communication between a Rock Pi and an Arduino-based Pro Mini. In my demonstration, the Rock Pi will be the master device, sending data to the Arduino. The Arduino will be the slave device, accepting data from the Rock Pi.

Wiring for I2C

Rock Pi 4B

I have attached a GPIO map for the Rock Pi 4B. This diagram was sourced from Radxa’s official hardware page for this board. For our I2C connection, we will be using pins 27 (SDA) and 28 (SCL). The labels for these pins let us know that we will be connecting to the I2C-2 interface. The extension, 2, is important to note as we will have to specify which I2C interface to join later on.

There is more than one I2C bus available via the GPIO pins on the Rock Pi 4B.

Arduino

For the Arduino-based Pro Mini that I am using, pins A4 (SDA) and A5 (SCL) are used for I2C. The same pins can be used for other boards such as the Uno and Nano. To connect the devices, we will connect the following pins from Rock Pi -> Arduino.

  • SDA -> SDA
  • SCL -> SCL
  • GND -> GND

Dependencies

Before writing any code, we should install a few dependencies onto the Rock Pi. We will be installing the packages python3-pip and i2c-tools. Pip is a Python package manager that makes installing necessary packages very easy.

# Update and upgrade apt.
sudo apt update && sudo apt upgrade
# Install python3-pip
sudo apt install python3-pip

With Pip installed, we can install the Python package, SMBus, that will allow us to join the I2C bus easily.

sudo pip3 install smbus

Arduino Sketch

With our dependencies now installed, we can move onto writing some code. Lets start off the Arduino sketch with a necessary import.

#include <Wire.h>  // Import Wire for I2C.

Then, we can initialize some variables to hold an address and any incoming data.

#define ADDRESS 0x04  // This device's I2C address.
int incomingInt  // To store incoming integers.

Next, lets write the setup function. We start a serial connection with a baud rate of 9600, for displaying received data to the serial monitor. We also join the I2C bus on our defined address by calling Wire.begin, passing in ADDRESS as our only parameter. Then, we define a function to call whenever data is received. That function, in my example is named printData.

void setup() {
  Serial.begin(9600);  // For displaying data.
  Wire.begin(ADDRESS);  // Join I2C bus on ADDRESS.
  Wire.onReceive(printData); // Function to call when data is received.
}

Now lets write the printData function. This function, as the name suggests, will print the data that is received over the I2C bus. We use Wire.read to read in data that is sent over the I2C bus.

void printData()
{
  incomingInt = Wire.read();  // Store data in incomingInt.
  Serial.println(incomingInt);  // Print incomingInt to console. 
}

Finally, we can write our loop function. This one is easy…

void loop() {
  // Nothing to do here.
  // Whenever data is received, printData will be called.
}

Altogether now!

#include <Wire.h>  // Import Wire for I2C.

#define ADDRESS 0x04  // This device's I2C address.
int incomingInt;  // To store incoming integers.

void setup() {
  Serial.begin(9600);  // For displaying data.
  Wire.begin(ADDRESS);  // Join I2C bus on ADDRESS.
  Wire.onReceive(printData); // Function to call when data is received.
}

void printData()
{
  incomingInt = Wire.read();  // Store data in incomingInt.
  Serial.println(incomingInt);  // Print incomingInt to console. 
}

void loop() {
  // Nothing to do here.
  // Whenever data is received, printData will be called.
}

Python Script

With our Arduino sketch finished, we can write a short Python script that sends integer data to the Arduino. Just as before, we will start by importing a few libraries.

from smbus import SMBus  # Import SMBus for I2C.
from time import sleep  # Import sleep for a delay.

To be able to use functions from the SMBus library, we have to create an object from that library. We will pass in the number 2 as a parameter because that is the I2C interface that we are utilizing.

bus = SMBus(2)  # Join I2C-2 interface.

Now we will initialize a variable to hold an address to the slave device. This address should match that which we defined in our Arduino sketch.

ADDRESS = 0x04  # Address to slave device. Send data here.

Finally, we create a for-loop that will send the Arduino numbers in an incremental fashion. To send data over I2C, in Python, we will use our bus object. Because we created this object using the SMBus class, we have access to the methods of that class.

for x in range(255):  # Will increment from 0 to 254.
    bus.write_byte(ADDRESS, x)  # Send x to ADDRESS.
    sleep(0.25)  # Delay to slow down the script. 

Altogether now, again!

from smbus import SMBus  # Import SMBus for I2C.
from time import sleep  # Import sleep for a delay.

bus = SMBus(2)  # Join I2C bus number 2.
ADDRESS = 0x04  # Address to slave device. Send data here.

for x in range(255):  # Will increment from 0 to 254.
    bus.write_byte(ADDRESS, x)  # Send x to ADDRESS.
    sleep(0.25)  # Delay to slow down the script. 

Running The Program

For our circuit and program to run correctly, upload the sketch to your Arduino and open a serial monitor on port 9600. Then, from a terminal on the Rock Pi, execute the following command.

cd
nano i2cScript.py

You should find yourself in the Nano text editor. Copy the Python script into the editor. After you have copied the script, save and exit Nano by pressing Ctrl-X, followed by the letter y, and finalized with Enter.

Once the script is ready to go, you can run the program by executing the following command.

sudo python3 i2cScript.py

If you followed along, correctly, you will see a count showing up on the serial monitor.

Thanks for following along!

Rock Pi 4B: Some Advice.

Rock Pi 4B

The Rock Pi 4B is touted as an alternative to the popular Raspberry Pi. What I was not aware of when deciding to implement one of these boards into a project, was the many quirks that come included with the Rock Pi.

Partitions

First, not just any ARM-compatible Linux image will work on the Rock Pi. I found this out the hard way, by waiting five minutes for the OS to boot, before doing some research. The image must be made compatible with the Rock Pi by containing several partitions that are required for the OS to boot. For reference, a Raspberry Pi disk image requires only two partitions to boot, a boot partition, and a root partition. The Rock Pi, on the other hand, requires five partitions to boot.

  • 1st Stage Loader partition
  • Boot loader partition
  • ARM Trusted Firmware partition
  • Kernel partition
  • Root Filesystem partition

This is not a deal breaker for using this board. Not even close. While the choice of compatible Linux images is limited, it is diverse enough to cover many use-cases. The company behind the creation of this board, Radxa, hosts four officially supported disk images as well as three 3rd party disk images. After giving each distribution a try, I settled on a 3rd party distribution, Armbian.

Heat

As a budget-friendly Single-Board Computer, not much should be expected in terms of temperature management. Depending on how you use your Rock Pi, you may need to account for a way to reduce and disperse heat generated from the board’s CPU. Lucky for me, a massive heat-sink was included with my Rock Pi. The heat-sink makes direct contact with the Rockchip RK3399 CPU, which gets very hot to the touch. Granted, I was compiling a large piece of software when I made this judgement.

Final Thoughts

For someone who has used the Raspberry Pi, and is looking for a different SBC to add to their project, the Rock Pi 4B makes an excellent choice. With a similar form-factor to the Raspberry Pi, you can find many cases and parts that will just work, without much modification. Before committing yourself to the Rock Pi, I would advise checking out the list of compatible Linux distributions to ensure that any required software can be made to work.

Sources

Rock Pi Required Partitions: https://wiki.radxa.com/Rockpi4/partitions

Build a 3D Printed Autonomous Robot

Getting Started

This robot build is meant to be relatively cheap and easy. It should provide a good first project for people looking to learn to code, specifically in the Python programming language. Here is what you will need to get started:

Hardware

Tools

  • Hot Glue Gun
  • Soldering Iron

Prepare Frame

  • Decide how you will position your components.
  • This is important to do before you start installing components.
FrameFrame.

HC-SR04 Sensor

  • Install the HC-SR04 sensor by press fitting it into the holes in the frame.
  • Position the sensor so that the pins are facing up.
  • Using hot glue, secure the sensor in place.

HCSR04HC-SR04 Installed.

Motors

  • To install the motors, slightly lift up on one of the tabs on the frame.
  • Push the motor into the slot under the tab until it reaches the end.
  • The tabs have “teeth” on the end which should clip onto the motor housing, keeping it secure without the need for glue.
MotorsMotors installed
Dual H-Bridge Motor Driver

  • Connect each lead from the motors into the “out” pins on the H-Bridge board
    • Do not worry about which lead connects to each “out” pin. We can change the pins later if necessary.
  • Glue the H-Bridge board onto the frame.

DSC_0019
H-Bridge Installed.

Buck Converter & Bread Board

  • Solder the proper leads onto your Buck Converter.
    • The leads connected to the in+ and in- spots should have a connector to connect to the lipo battery.
    • The leads coming off of the out+ and out- can be normal jumper wires.
    • The out- will need to have 2 leads coming off of it.
      • One will be connected to ground on the H-Bridge.
      • The other lead will be connected to a ground pin on the Raspberry Pi. This lead acts as a common ground.
  • The breadboard will be used to create a voltage dividing circuit. This will be covered more in depth in the next step.
TopNoWheelsBuck Converter Installed (Top Left), Breadboard Installed (Top Right).

Wiring the Dual H-Bridge

IN1 -> GPIO 2

IN2 -> GPIO 3

IN3 -> GPIO 4

IN4 -> GPIO 17

Wiring the Ultrasonic Sensor

VCC -> 5V GPIO

TRIG -> GPIO 27

ECHO -> Voltage Dividing Circuit -> GPIO 22

Voltage Dividing Circuit Guide.

Why use a voltage dividing circuit?

The echo pin on the HC-SR04 sensor outputs 5 volts. The GPIO pins on the Pi are only rated for 3.3 volts. Giving a GPIO pin 5 volts may cause damage to the Pi. A voltage dividing circuit will give 3.3 volts to GPIO 22.

Software Setup

Here is what you need to do to get the necessary software up and running.

  1. Install Raspbian onto a micro SD.
  2. Enable SSH and setup WIFI configuration.
  3. SSH into the Raspberry Pi.
  4. Download the code from GitHub.
  5. Download any missing dependencies.
  6. Bring your robot to life.

1. Installing Raspbian

To burn an image to the SD card you can use Etcher.

  • Head over to https://etcher.io.
  • Download the version for your operating system.
  • Run the installer.

Screen Shot 2018-10-21 at 7.09.39 PM

Using Etcher is very intuitive and straight forward.

  1. Select image – Browse to the Raspbian image that you downloaded.
  2. Select disk – Select the SD card for your Raspberry Pi.
  3. Click “Flash!” Then wait for the image to be written.
  4. Done! Raspbian is now installed on the SD card.

Screen Shot 2018-10-21 at 7.10.22 PM

2. Enable SSH and configure WIFI

For security reasons SSH is disabled by default. To enable SSH you will need to keep the Raspberry Pi’s micro SD card inserted into your computer.

Mac Users

  • Open a terminal and run “touch /Volumes/boot/ssh” to create a file named “ssh” on the SD card.

Windows Users

  • Using Notepad, open a new file, enter one empty space and nothing more
  • Click File / Save As …
  • Be sure to set Save As type to All Files (so the file is not saved with a .txt extension)
  • Save the file as ssh onto the SD card.

Configuring the WIFI prior to boot is very useful for a headless Raspberry Pi. Doing so removes the need for an extra keyboard, mouse, monitor, and HDMI cable.

To setup the WIFI configuration file, you will need to:

  1. Create the configuration file on the SD card.
  2. Enter the following text into the configuration file;

country=US

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev

update_config=1

network={

ssid=”NETWORK-NAME”

psk=”NETWORK-PASSWORD”

}

Mac Users

  • Open a terminal and run “touch /Volumes/boot/wpa_supplicant.conf” to create the WIFI configuration file on the SD card.
  • Edit the wpa_supplicant.conf file and paste the text from above into the file. Make sure to enter your WIFI login details in the correct field (NETWORK-NAME).

Windows Users

  • Using Notepad, paste in the text from above. Make sure to enter your WIFI login details in the correct field (NETWORK-NAME).
  • Click File / Save As …
  • Be sure to set Save as type to All Files (so the file is not saved with a .txt extension)
  • Save the file as “wpa_supplicant.conf“.

3. SSH into the Raspberry Pi

  • Eject SD card from your computer and insert it into the Raspberry Pi.
  • Power on the Raspberry Pi and wait for it to boot up (> 90 seconds)
  • Find ip address of the Raspberry Pi

Mac Users

  • Open a terminal and run “ssh pi@ip_address_of_pi” replacing ip_address_of_pi with the actual ip address of your Raspberry Pi.
  • A prompt may appear asking if you would like to continue connecting despite the lack of authenticity. Enter “yes“.
  • Then you will be prompted for the password. The default password is “raspberry“.

Windows Users

  • Head over to https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html and download the version for your operating system.
  • In PuTTY, create a new configuration for your Raspberry Pi.
    • Default username: pi
    • Default password: raspberry
    • Host name: ip address for your Raspberry Pi
    • Port: 22
  • SSH into your Raspberry Pi.

After SSH-ing into your raspberry pi you will want to update the system by running:

  1. sudo apt-get update
  2. sudo apt-get upgrade

You should then improve the security of your Raspberry Pi by following this guide.

Screen Shot 2018-10-21 at 8.37.17 PM.png

4. Download the code from Github

While connected to your Raspberry Pi over SSH:

  • Download git and pip3 by running “sudo apt-get install git python3-pip”.
  • Download the code from my Github by running “git clone https://github.com/Psuedohim/ARCRobot/”

Screen Shot 2018-10-21 at 8.48.14 PM.png

5. Download any missing dependencies

My code relies on the RPi.GPIO library to work correctly.

  • Download RPi.GPIO using pip3 by running “pip3 install RPi.GPIO”

Screen Shot 2018-10-21 at 8.51.27 PM.png

6. Bring your robot to life

  • Change into the ARCRobot-1 directory inside of the arcrobot directory by running “cd arcrobot/ARCRobot-1/”
  • Start the robot’s autonomous mode by running “python3 go_auto.py

Screen Shot 2018-10-21 at 8.55.42 PM.png

That it! Whenever you reboot your Raspberry Pi, all you need to do is re-do step 6 to get your robot up and running. Thank you for following my guide! Please leave feedback regarding anything that was unclear so that I can help clarify.