Mar 20

Raspberry Pi Home Automation book

Raspberry Pi Home Automation with Arduino is a book written by Andrew K. Dennis, and edited by Packt. With this book, the reader learns how to achieve automation tasks using a Raspberry Pi coupled with an Arduino.

After the classical Raspberry / Linux setup and requirements, the book covers several commons task in home automation :

  • Thermometer, to retrieve temperatures from several sensors
  • Thermostat, to control an heating system by switching relays based on Thermometer project
  • Data Storage, to log temperatures
  • Curtain Automation, based on an ambiant sensor and motor control

Finally, the book give few tips to help prototyping with Raspberry Pi.

All the book relies on the Cooking-Hacks RPi-to-Arduino bridge shield. All hardware stuff use the Arduino instead of directly use GPIO. As you will notice with upcoming WebIOPi 0.6, we can use GPIO to make many things, quite easily. We can connect sensors and also control motors without using many devices.

The RPi-to-Arduino bridge and so the book also require the arduPi firmware for the Arduino. In my opinion, the book is more about learning the bridge and arduPi firmware than learning all Raspberry Pi possibilities.

When the reader knows that, I have to admit the book is well written, with good explanations and code snippets. Moreover, using an Arduino with a Raspberry Pi is one of the best combo and a must have for any hobbyist geek and prototype builder. I say that to my friends and co-workers since the Raspberry Pi has been released. It gives the Pi missing hardware PWM output and Analog input with a single extension.

With passing time, I now rather think that the Raspberry Pi should be directly used for many common things, only using a cheap ADC like Microchip MCP3000 series or TI ADS1000 ones. It simplifies the circuit, consumes less, and allow to learn more on electronic components and industrial uses. Arduino should come only to help the Pi in several time critical task. For instance, measuring a PWM signal or using a wheel encoder.

The book is well enough written to reuse explanations in other contexts, and replacing the Arduino with something else should be easy as we can found many explanation on Internet. The Raspberry Pi forum and the Mag Pi are good starts, there is also many hobbyist blogs. But reading components data sheets is more interesting, exciting and provides more precise information. Combining stuff from the book and Internet will providing a powerful set of stuff to unleash the Raspberry Pi power in your electronic projects.

Advanced hobbyist who are already familiar with data sheet reading and implementation should pass away this book.

Intermediate skilled people should get this book to frame their knowledge and lead them further.

Beginners and people who already have both Arduino and Raspberry, but still don’t know how to connect them together must purchase it with the Cooking-Hack bridge. It will ensure a success in your Home Automation projects and learn you many things.

Raspberry Pi Home Automation with Arduino, edited by Packt.
Available at amazon.com, amazon.co.uk, packtpub.com in both paper and eBook.

Nov 25

R/C receiver diagnostic on iPhone

Do you remember my post about a R/C USB adapter ? Today, I tried a Redpark TTL cable for iPhone.

Starting with the R/C USB adapter, I did not changed anything on the Arduino side. I only ported the Processing code on iOS, and connected the Redpark cable to the Arduino. That’s it ! I can now check the output of my R/C receivers on the ground only with my iPhone, an Arduino, and the cable.

You can see the result in the following video :

On the hardware side, the only thing to take care is the voltage used on the serial connection between the Redpark cable and the Arduino. The cable (and the iPhone) uses a 3.3V logic, whereas the Arduino uses a 5V one. Connecting cable TX directly to Arduino RX is OK as Arduino can handle a 3.3V input, but connecting cable RX directly to Arduino TX will damage your cable and maybe your iPhone. You have to make a level-shifter. Best solutions uses transistor or zener diode, but two resistors in voltage-diviser do the job.

For the iPhone app, using the Redpark cable is quite easy, thanks to its SDK. It totally masks the EAAccessory framework. It’s very handy for prototyping using the iPhone dock connector without a MFi access, but you will not learn the EAAccessory framework.

To release it on the AppStore, I need your support in order to subscribe the Apple Developer Program.

Nov 15

R/C receiver USB adapter – Part 1

This is an article I wrote a year ago, but I didn’t take time to finish and publish it…

We often see projects to control an R/C car/plane/craft from a device like a smartphone or gamepad using Arduino. It’s fun and let you play with Arduino, but it’s not as accurate as a real R/C radio.

Another fun and useful thing to do is the opposite : use an RC transmitter to play games ! It perfectly suits RC simulators. Aero pilots already know that, as most of RTF kits include a USB cord for the transmitter and a simulator. Car and boat pilots aren’t so lucky, and we need to buy a dedicated USB pistol or a radio receiver adapter.

Using Arduino, we can create two kinds of adapter to plug into the radio receiver :

  • USB serial, with Processing onto the computer, to diagnose radio receiver’s output channels.
  • USB HID, to use the radio as an HID joystick, in order to play RC simulators.

This first part covers the radio diagnostic tool, but before, I must remind how RC systems work.

The key signal to handle is PWM. An RC radio receiver is linked to servos and controllers with 3 wires : 2 for the power, and one for the signal. The signal consists of pulses proportionals to the input on the transmitter. A pulse is sent every 20ms, and it’s length varies from 1ms to 2ms. So we just need to measure pulses on Arduino, then send the value though the serial interface.

If we take a look on a Futaba servo spec, we can see :

  • Control System: Pulse Width Control 1520usec Neutral
  • Operating Angle: 45 Deg. one side pulse traveling 400usec

So each pulse has a duration between 1120µs (-45°/-100%) and 1920µs (+45°/+100%). Neutral has a duration of 1520µs.

The wiring is very simple, and only 4 wires are required : 2 for the power and 1 for each channel. Connect the + and – of the receiver’s BAT plug to +5V and ground of Arduino, then Channel-1 and Channel-2 signals to Arduino pins 2 and 3.

The simplest way to measure pulses, is the bult-in pulseIn() Arduino function, but it’s not the most accurate one. The best thing to do is to use interrupts. There is only 2 interrupts on the Uno, but it’s enough for the direction and gaz channels. If required, third (and fourth) channel could be measured with pulseIn() function. But, worst than inaccurate, they are blocking functions. Without enter details, the sampling frequency will decrease, divided by 4 in worst case. You can also use a Mega which offer 6 interrupts. One time we have an accurate acquisition, we can directly send pulse duration through the serial interface, but we need an accurate serial transmission.

I also must remind that the serial link between the AT328 and the serial-usb bridge doesn’t include hardware flow control. It means we cannot just send values each time we go in the loop. A buffer overflow and a byte loss will occur. We have to implement a software flow control : when value sent, wait a little time (10µS), then wait for an acknowledgment before sending another value. Decreasing speed will also increase accuracy, 9600bps is enough. A single byte handle a [-100,100] range value. With 2 channels, we have to send 2 bytes. At 9600bps, we can send 9600/8/2 = 600 samples each seconds, whereas the receiver only outputs 50 samples per second. Even best radios will only outputs 100 samples per second.

Well done ! Using Processing.org with the Serial library, we can receive, acknowledge, compute and display data using a bar graph :

This video was recorded and published in september 2011, with a poor Hobbyking radio. After checked its output, I understood why it was so hard to have a reliable setup. I quickly changed for a Futaba one ;)

Arduino sketch :

// convenient macro to fast check pin state
#define intDir (PIND & 0b00000100)
#define intGaz (PIND & 0b00001000)

unsigned long dPulse = 0;
unsigned long gPulse = 0;
long tdir = 0;
long tgaz = 0;

void setup() {
  // Init serial and wait for a remote client
  Serial.begin(115200);
  while (Serial.available() == 0) {
  }
  while (Serial.read() != '*') {
  }

  // attach interrupts, called to both raising and falling edge
  // see http://arduino.cc/en/Reference/AttachInterrupt for int/pin mapping
  attachInterrupt(0, dirChange, CHANGE);
  attachInterrupt(1, gazChange, CHANGE);
}

// int.0 (D2) : channel 1 (direction)
void dirChange() {
  // timestamp
  long t = micros();

  // was a raising edge, store timestamp
  if (intDir) {
    tdir = t;
  }
  // was a falling edge, compute and filter littles changes
  else {
    long delta = t - tdir;
    if ((delta - dPulse) > 4)
      dPulse = delta;
  }
}

// int.1 (D3) : channel 2 (gaz)
void gazChange() {
  // timestamp
  long t = micros();

  // was a raising edge, store timestamp
  if (intGaz) {
    tgaz = t;
  }
  // was a falling edge, compute and filter littles changes
  else  {
    long delta = t - tgaz;
    if ((delta - gPulse) > 4)
      gPulse = delta;
  }
}

void loop() {
  // write direction pulse duration then gaz pulse duration
  Serial.print(dPulse);
  Serial.print(" ");
  Serial.println(gPulse);
  delay(10);
  // wait for an acknowledgment
  while (Serial.read() != '*') {
  }
}

Processing sketch :

import processing.serial.*;

Serial myPort;
String s;

float dirMin = 1020.0;
float dirMax = 2020.0;
float gazMin = 1020.0;
float gazMax = 2020.0;

float dir = 1520.0;
float gaz = 1520.0;

PFont myFont;

void setup() 
{
  // init display and font
  size(500, 200);
  myFont = createFont("Verdana", 32);
  textFont(myFont);

  // init serial
  String portName = "/dev/tty.usbserial-A700dCO3";
  myPort = new Serial(this, portName, 115200);

  while (myPort.available () == 0) 
    myPort.write("*");
}

void draw()
{
  // scale pulses to [-100%, +100%]
  float dirRate = (dir-dirMin)/(dirMax-dirMin);
  float gazRate = (gaz-gazMin)/(gazMax-gazMin);

  // scale pulses to [-45°, +45°]
  float dirAngle = (dir - 1520.0) * 90.0 / 800.0;
  float gazAngle = (gaz - 1520.0) * 90.0 / 800.0;

  background(255);

  // draw bars frame
  fill(255);
  rect(10, 40, 480, 40);
  rect(10, 120, 480, 40);

  // print values
  fill(0);
  text("Direction : " + nf(dirAngle, 1, 2) + "° " + (int)dir + "µS", 10, 30);
  text("Speed : " + nf(gazAngle, 1, 2) + "° " + (int)gaz + "µS", 10, 110);

  // fill bars according 
  rect(10, 40, dirRate*480.0, 40);
  rect(10, 120, gazRate*480.0, 40);

  // check if data present
  if (myPort.available() > 0) {
    s = myPort.readStringUntil('\n');
  }

  // loop back if no data received
  if (s == null)
    return;

  // else acknowledge data
  myPort.write("*");

  // check data format validity
  int i = s.indexOf(' ');
  if (i < 0)
    return;

  String s1 = s.substring(0, i);
  String s2 = s.substring(i+1, s.length() - 1);

  // parse data
  dir = Float.parseFloat(s1);
  gaz = Float.parseFloat(s2);
}

In those sketches, we use plain text representation for signal values through the serial interface. It helps debugging the system. In the second part, I will explain how to change the serial bridge firmware and the Arduino sketch to make it as an HID Joystick and how to optimize data transfert by sending a data structure to the USB bridge.