Science and technology

Expand your Raspberry Pi with Arduino ports

As members of the maker group, we’re all the time on the lookout for artistic methods to make use of hardware and software program. This time, Patrick Lima and I made a decision we needed to increase the Raspberry Pi’s ports utilizing an Arduino board, so we may entry extra performance and ports and add a layer of safety to the gadget. There are loads of methods to make use of this setup, reminiscent of constructing a photo voltaic panel that follows the solar, a house climate station, joystick interplay, and extra.

We determined to begin by constructing a dashboard that enables the next serial port interactions:

  • Control three LEDs to show them on and off
  • Control three LEDs to regulate their gentle depth
  • Identify which ports are getting used
  • Show enter actions on a joystick
  • Measure temperature

We additionally need to present all of the interactions between ports, hardware, and sensors in a pleasant consumer interface (UI) like this:

You can use the ideas on this article to construct many various initiatives that use many various elements. Your creativeness is the restrict!

1. Get began

The first step is to increase the Raspberry Pi’s ports to additionally use Arduino ports. This is feasible utilizing Linux ARM’s native serial communication implementation that allows you to use an Arduino’s digital, analogical, and Pulse Width Modulation (PWM) ports to run an software on the Raspberry Pi.

This mission makes use of TotalCross, an open supply software program improvement package for constructing UIs for embedded gadgets, to execute exterior purposes via the terminal and use the native serial communication. There are two courses you should use to realize this: Runtime.exec and PortConnector. They symbolize other ways to execute these actions, so we’ll present find out how to use each on this tutorial, and you’ll resolve which method is finest for you.

To begin this mission, you want:

  • 1 Raspberry Pi three
  • 1 Arduino Uno
  • three LEDs
  • 2 resistors between 1K and a couple of.2K ohms
  • 1 push button
  • 1 potentiometer between 1K and 50Okay ohms
  • 1 protoboard (aka breadboard)
  • Jumpers

2. Set up the Arduino

Create a communication protocol to obtain messages, course of them, execute the request, and ship a response between the Raspberry Pi and the Arduino. This is completed on the Arduino.

2.1 Define the message format

Every message acquired could have the next format:

  • Indication of the operate referred to as
  • Port used
  • A char separator, if wanted
  • A worth to be despatched, if wanted
  • Indication of the message’s finish

The following desk presents the checklist of characters with their respective features, instance values, and descriptions of the instance. The selection of characters used on this instance is unfair and may be modified anytime.

Characters Function Example Description of the instance
* End of the instruction
, Separator
# Set mode #eight,zero* Pin eight enter mode
< Set digital worth <1,zero* Set pin 1 low
> Get digital worth >13* Get worth pin 13
+ Get PWM worth +6,250* Set pin 6 worth 250
Get analogic worth -14* Get worth pin A0

2.2 Source code

The following supply code implements the communication protocol specified above. It should be despatched to the Arduino, so it might interpret and execute messages’ instructions:

void setup()

void loop() {
String textual content="";
char character;
String pin="";
String worth="0";
char separator='.';
char inst='.';

 whereas(Serial.obtainable()) // confirm RX is getting information
   delay(10);
   character= Serial.learn();
   if(character=='*')
     motion(inst,pin,worth);
     break;
   
    else

   if(character==',')

void motion(char instruction, String pin, String worth)

2.three Build the electronics

Define what you must check to examine communication with the Arduino and make sure the inputs and outputs are responding as anticipated:

  • LEDs are related with optimistic logic. Connect to the GND pin via a resistor and activate it with the digital port I/O 2 and PWM three.
  • The button has a pull-down resistor related to the digital port I/O four, which sends a sign of zero if not pressed and 1 if pressed.
  • The potentiometer is related with the central pin to the analog enter A0 with one of many aspect pins on the optimistic and the opposite on the damaging.

2.four Test communications

Send the code in part 2.2 to the Arduino. Open the serial monitor and examine the communication protocol by sending the instructions under:

#2,1*<2,1*>2*
#three,1*+three,10*
#four,zero*>four*
#14,zero*-14*

This must be the consequence within the serial monitor:

One LED on the gadget must be on at most depth and the opposite at a decrease depth.

Pressing the button and altering the place of the potentiometer when sending studying instructions will show completely different values. For instance, flip the potentiometer to the optimistic aspect and press the button. With the button nonetheless pressed, ship the instructions:


Two strains ought to seem:

three. Set up the Raspberry Pi

Use a Raspberry Pi to entry the serial port through the terminal utilizing the cat command to learn the entries and the echo command to ship the message.

three.1 Do a serial check

Connect the Arduino to one of many USB ports on the Raspberry Pi, open the terminal, and execute this command:

cat /dev/ttyUSB0 9600

This will provoke the reference to the Arduino and show what’s returned to the serial.

To check sending instructions, open a brand new terminal window (maintaining the earlier one open), and ship this command:

echo "command" > /dev/ttyUSB0 9600

You can ship the identical instructions utilized in part 2.four.

You ought to see suggestions within the first terminal together with the identical consequence you bought in part 2.four:

four. Create the graphical consumer interface

The UI for this mission will probably be easy, as the target is simply to indicate the ports growth utilizing the serial. Another article will use TotalCross to create a high-quality GUI for this mission and begin the applying backend (working with sensors), as proven within the dashboard picture on the high of this text.

This first half makes use of two UI elements: a Listbox and an Edit. These construct a connection between the Raspberry Pi and the Arduino and check that the whole lot is working as anticipated.

Simulate the terminal the place you place the instructions and look ahead to solutions:

  • Edit is used to ship messages. Place it on the backside with a FILL width that extends the part to the whole width of the display.
  • Listbox is used to indicate outcomes, e.g., within the terminal. Add it on the TOP place, beginning on the LEFT aspect, with a width equal to Edit and a FIT peak to vertically occupy all house not crammed by Edit.
bundle com.totalcross.pattern.serial;

import totalcross.sys.Settings;
import totalcross.ui.Edit;
import totalcross.ui.ListBox;
import totalcross.ui.MainWindow;
import totalcross.ui.gfx.Color;

public class SerialPattern extends MainWindow
   ListBox Output;
   Edit Input;
   public SerialPattern()

   @Override
   public void initUI()
       Input = new Edit();
       add(Input, LEFT, BOTTOM, FILL, PREFERRED);
       Output = new ListBox();
       Output.setBackForeColors(Color.BLACK, Color.WHITE);
       add(Output, LEFT, TOP, FILL, FIT);
   

It ought to seem like this:

5. Set up serial communication

As said above, there are two methods to arrange serial communication: Runtime.exec and PortConnector.

5.1 Option 1: Use Runtime.exec

The java.lang.Runtime class permits the applying to create a connection interface with the setting the place it’s operating. It permits this system to make use of the Raspberry Pi’s native serial communication.

Use the identical instructions you utilized in part three.1, however now use the Edit part on the UI to ship the instructions to the gadget.

Read the serial

The software should consistently learn the serial, and if a price is returned, add it to the Listbox utilizing threads. Threads are a good way to work with processes within the background with out blocking consumer interplay.

The following code creates a brand new course of on this thread that executes the cat command, checks the serial, and begins an infinite loop to examine if one thing new is acquired. If one thing is acquired, the worth is added to the following line of the Listbox part. This course of will proceed to run so long as the applying is operating:

new Thread () {
   @Override
   public void run() {
       attempt
           Process Runexec2 = Runtime.getRuntime().exec("cat /dev/ttyUSB0 9600n");
           LineReader lineReader = new LineReader(Stream.asStream(Runexec2.getInputStream()));
           String enter;
         
           whereas (true)
               if ((enter = lineReader.readLine()) != null)
                   Output.add(enter);
                   Output.selectLast();
                   Output.repaintNow();
               
           
          catch (IOException ioe)
            ioe.printStackTrace();
         
       }
   }.begin();
}

Send instructions

Sending instructions is an easier course of. It occurs everytime you press Enter on the Edit part.

To ahead the instructions to the gadget, as proven in part three.1, you could instantiate a brand new terminal. For that, the Runtime class should execute a sh command on Linux:

attempt
   Runexec = Runtime.getRuntime().exec("sh").getOutputStream()        catch (IOException ioe)
   ioe.printStackTrace();

After the consumer writes the command in Edit and presses Enter, the applying triggers an occasion that executes the echo command with the worth indicated in Edit:

Input.addKeyListener(new KeyListener() );

Run the applying on the Raspberry Pi with the Arduino related and ship the instructions for testing. The consequence must be:

Runtime.exec supply code

Following is the supply code with all elements defined. It contains the thread that can learn the serial on line 31 and the KeyListener that can ship the instructions on line 55:

bundle com.totalcross.pattern.serial;
import totalcross.ui.MainWindow;
import totalcross.ui.occasion.KeyEvent;
import totalcross.ui.occasion.KeyListener;
import totalcross.ui.gfx.Color;
import totalcross.ui.Edit;
import totalcross.ui.ListBox;
import java.io.IOException;
import java.io.OutputStream;
import totalcross.io.LineReader;
import totalcross.io.Stream;
import totalcross.sys.Settings;
import totalcross.sys.SpecialKeys;

public class SerialPattern extends MainWindow {
   OutputStream Runexec;
   ListBox Output;

   public SerialPattern()

   @Override
   public void initUI() {
       Edit Input = new Edit();
       add(Input, LEFT, BOTTOM, FILL, PREFERRED);
       Output = new ListBox();
       Output.setBackForeColors(Color.BLACK, Color.WHITE);
       add(Output, LEFT, TOP, FILL, FIT);
       new Thread() {
           @Override
           public void run() {
               attempt catch (IOException ioe)
           }
       }.begin();

       attempt
           Runexec = Runtime.getRuntime().exec("sh").getOutputStream();
        catch (IOException ioe)

       Input.addKeyListener(new KeyListener()
           @Override
           public void specialkeyPressed(KeyEvent e)
               if (e.key == SpecialKeys.ENTER)
           

           @Override
           public void keyPressed(KeyEvent e)
           @Override
           public void actionkeyPressed(KeyEvent e)
      );
   }
}

5.2 Option 2: Use PortConnector

PortConnector is particularly for working with serial communication. If you need to comply with the unique instance, you may skip this part, because the intention right here is to indicate one other, simpler solution to work with serial.

Change the unique supply code to work with PortConnector:

bundle com.totalcross.pattern.serial;
import totalcross.io.LineReader;
import totalcross.io.gadget.PortConnector;
import totalcross.sys.Settings;
import totalcross.sys.SpecialKeys;
import totalcross.ui.Edit;
import totalcross.ui.ListBox;
import totalcross.ui.MainWindow;
import totalcross.ui.occasion.KeyEvent;
import totalcross.ui.occasion.KeyListener;
import totalcross.ui.gfx.Color;

public class SerialPattern extends MainWindow {
   PortConnector laptop;
   ListBox Output;

   public SerialPattern()

   @Override
   public void initUI() {
       Edit Input = new Edit();
       add(Input, LEFT, BOTTOM, FILL, PREFERRED);
       Output = new ListBox();
       Output.setBackForeColors(Color.BLACK, Color.WHITE);
       add(Output, LEFT, TOP, FILL, FIT);
       new Thread() {
           @Override
           public void run() {
               attempt
                   laptop = new PortConnector(PortConnector.USB, 9600);
                   LineReader lineReader = new LineReader(laptop);
                   String enter;
                   whereas (true)
                       if ((enter = lineReader.readLine()) != null)
                   
                catch (totalcross.io.IOException ioe)
           }
       }.begin();
       Input.addKeyListener(new KeyListener() {
           @Override
           public void specialkeyPressed(KeyEvent e)
               if (e.key == SpecialKeys.ENTER)
                   String s = Input.getText();
                   Input.clear();
                   attempt catch (totalcross.io.IOException ioe)
                       ioe.printStackTrace();
                   
               
           

           @Override
           public void keyPressed(KeyEvent e)

           @Override
           public void actionkeyPressed(KeyEvent e)
      });
  }
}

You can discover all the code within the project’s repository.

6. Next steps

This article reveals find out how to use Raspberry Pi serial ports with Java by utilizing both the Runtime or PortConnector courses. You may also name exterior recordsdata in different languages and create numerous different initiatives—like a water high quality monitoring system for an aquarium with temperature measurement through the analog inputs, or a hen brooder with temperature and humidity regulation and a servo motor to rotate the eggs.

A future article will use the PortConnector implementation (as a result of it’s targeted on serial connection) to complete the communications with all sensors. It will even add a digital enter and full the UI.

Here are some references for extra studying:

After you join your Arduino and Raspberry Pi, please go away feedback under along with your outcomes. We’d like to learn them!

Most Popular

To Top