Okt 17, 2017 by Robin Category: Unkategorisiert 0 comments

iolinker with Arduinos and Raspberry Pi

The iolinker board connected to four Arduinos, a Raspberry Pi, an LCD and a servo

An example application

This example application will show you how to quickly and easily wire up four Arduinos, one Raspberry Pi, one LCD and one servo through the iolinker board. The Raspberry Pi will supply a web interface in which the Arduino that has control over the LCD can be chosen. It then reconfigures the iolinker board accordingly, and sends out a UART message to the Arduino that was — dynamically — wired up to control the servo, to change its angle and thereby point an arrow at the Arduino that currently is connected to the LCD.

The hardware setup

In this example application, we use the iolinker board on top of the iolinker Arduino shield — on top of an Arduino Leonardo or Uno. The power supply and six digital pins of three Arduino Pro Mini 5V boards and of an LCD are also connected to the ioliker Arduino shield. The UART of the Arduino Leonardo, six digital pins for LCD usage and another for servo control are also connected to the iolinker, along with the digital input of a servo. RX / TX of a Raspberry Pi UART are connected to COM2 / 3 of the iolinker shield, and the TX pin is also wired up to another GPIO of the iolinker shield. Power supply for the Arduinos, for the LCD and for the servo was connected directly to 5V / GND. The GPIOs on the iolinker board are chosen freely and randomly.

Connection diagram

What the software does

The Arduinos all try to write to an LCD. Since there is only one LCD, they need to share it, though, so the Raspberry Pi switches through wiring configurations that it transfers to the iolinker. In effect, one Arduino’s digital outputs are connected to the LCD at any given time.

One Arduino has its UART connected to the iolinker board. The Raspberry Pi can use that to wire up its own UART with that Arduino, and transfer a message. In the example application, this is used to allow the Raspberry Pi to transfer the servo value in a single byte to the Arduino, thereby allowing it to turn it in any direction. The angle is encoded in letters from ‚a‘ to ‚z‘ for reasons of simplicity.

The Raspberry Pi runs the iolinker web interface that allows dynamic reconfiguration of the iolinker pins. In the web interface, configurations can be saved and loaded at a later point, which allows us to quickly change between the LCD wirings for Arduino #0 to #3. Whenever another configuration is loaded, a shell script sends out a UART message with a new servo position. The servo is outfitted with an arrow, that points in the direction of the Arduino that currently controls the LCD.

LCD shows text from Arduino 1

Example source for the Raspberry Pi

On the Raspberry Pi, the iolinker web interface was installed on an Apache web server. Details and source on the web interface part will follow.

Changing the configuration in the web interface

The web interface writes out a shell script currentconfig.sh on every change, that, when run, transfers the entire iolinker configuration onto the board. The daemon.sh shell script does this automatically for you. It was modified slightly for this application to also run a script sendmsg.sh with the file name of the current configuration as parameter:

#!/bin/bash
echo > pipe
lastfile=""

tail -f pipe | while read date cmd param tmp
do
    echo "$ $date $cmd $param $tmp"

    if [ "$cmd" == "load" ]; then
        lastfile=".`basename $param`"
    fi

    if [ "$cmd" == "load" ] || [ "$cmd" == "update" ]; then
        echo -e "\tsendmsg $lastfile"
        ./sendmsg.sh $lastfile

        echo -e "\tupdated config"
        ./currentconfig.sh
    fi
done

The sendmsg.sh script simply writes out the parameter onto the UART:

#!/bin/bash
dev='/dev/ttyAMA0'
stty -F $dev 115200
echo $1 > $dev

Example source for the Arduinos

The Arduino source configures the serial port, outputs the iolinker configuration, writes a message to the LCD and updates the servo position when a UART message is received. For all four Arduinos, you can use the same source, just modify the LCD message.

Note that in the setup in the video, I did not actually connect the Arduino to the configuration input of the iolinker. Instead, a Raspberry Pi configured the ciruit. Still I left the source in here, because it just does nothing if unused; but it could configure the schematic on the Arduino as well — without any help from the Raspberry Pi. The web interface and reconfiguration ability would then be missing.

Also, the UART and servo code is not required on the Arduino Pro Minis in the video, but again, doesn’t hurt either.

Pin numbers need to be updated according to your setup.

#include <SPI.h>
#include <Wire.h>
#include <IOLinker.h>
#include <LiquidCrystal.h>
#include <Servo.h>

IOLinker iolinker;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
Servo myservo;

void setup()
{
  Serial1.begin(115200);
  
  while (!Serial1) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  iolinker.beginStream(Serial1); // Connect to iolinker chip via UART
  iolinker.targetAddress(0x7f); // Address of the chip to connect to
  
  iolinker.setPinType(IOLinker::IOLINKER_INPUT, 43, 49); /* Arduino 1 LCD connections */
  iolinker.setPinType(IOLinker::IOLINKER_OUTPUT, 13, 19); /* LCD outputs */
  
  for (int i = 0; i < 6; i++) {
    iolinker.link(33 + i, 13 + i); /* Link Arduino 0 to LCD */
  }
  
  iolinker.setPinType(IOLinker::IOLINKER_INPUT, 32); /* Arduino0 servo output */
  iolinker.setPinType(IOLinker::IOLINKER_OUTPUT, 47); /* Servo output */
  iolinker.link(32, 47); /* Connect servo */

  myservo.attach(3);
}
 
boolean okay = false;
void loop()
{
  lcd.begin(16, 2);
  lcd.setCursor(0,0);
  lcd.print("Arduino 0");
  lcd.setCursor(0, 1);
  lcd.print("Servo controller");

  /* Read servo position from UART */
  while (Serial1.available()) {
    char inChar = (char)Serial1.read();
    if (inChar == '.') {
      okay = true;
      continue;
    }
    if (inChar == '\n') {
      continue;
    }
    if (okay) {
      okay = false;
      myservo.write((uint8_t)(inChar - 'a') * 255/26);
    }
  }

  delay(300);
}

Sorry, the comment form is closed at this time.