Code and Life

Programming, electronics and other cool tech stuff

Supported by

Supported by Picotech

PiSerial Arduino Communication Library

RGB LED demo

As a continuation to my Raspberry Pi and Arduino communication post, I thought I’d do the same but opposite way. This time, I thought it would be nice to make a proper Arduino library to make the process more streamlined.

To make communication more robust, I decided to implement a more formal communication over serial to enable applications that have some idea if a command sent to Arduino was successfully carried out or not, and also introduce basic error recovery if invalid commands or wrong number of parameters are received.

If you haven’t worked with Arduino libraries before, I suggest you to familiarize yourself with this basic tutorial or the other one at Arduino Playground. If you’re not familiar with AnalogWrite(), a quick peek to Arduino PWM Tutorial may also be in order.

Serial communication protocol

I wanted to make a simple formal protocol to send commands and hex, byte or word-sized parameters related to that command over serial line to the Arduino. For the protocol, I had these requirements:

  1. Text-based, so communication can be emulated with Arduino IDE’s “Serial Monitor” tool
  2. Size-efficient to speed up communications with slow baud rates
  3. Support for at least a few dozen commands and free number of parameters
  4. Success and error messages from Arduino
  5. Capability to return to known state after invalid commands, invalid number of arguments, communication errors or breakdowns

After some consideration, I chose to select non-overlapping sets of symbols from the ASCII character set for commands, parameters, control characters and success/error messages:

  • Small letters (a-z) for commands (26 should be enough for everyone, right?)
  • Numbers 0-9 and capital letters A-F to send parameters as hex-encoded values
  • Newline to mark end of command and parameters (either ‘\r’ + ‘\n’ or just ‘\n’)
  • Capital letters O, K, and R for success (OK) and error (RR) indications

With non-overlapping characters used for different things, detecting errors in sent commands becomes easier, as any “non-expected” character marks an error situation and as status messages OK and RR do not appear in commands, implementing two-way communication (commands to both directions) is easy later on.

Read post

Raspberry Pi as Arduino HDMI Shield

Arduino to Pi serial link

Merry Christmas to everyone! Today’s hack is something that I’ve been planning to try out for a while: Using the Raspberry Pi as a (relatively inexpensive) “HDMI shield” for the Arduino microcontroller. While the Pi can easily do most things that the Arduino can and usually much more, one might have an otherwise complete project (for example, something related to home theater automation) that would benefit from HDMI output.

Arduino display shields are not the least expensive, so why not use a RaspPi instead? There have been hacks for using RaspPi as network shield, too, and this project is very much like it (actually, you could change the Pi-side code just a bit and have some network-related commands available for your Arduino in no time).

The basic hardware premise for this hack is very straightforward – wire the Pi and Arduino together using the serial interface available on both. Because Pi is 3.3V and Arduino 5V, a level converter is needed – I used one from Adafruit this time, as it’s dead simple to use and doesn’t pose the dangers of overloading Pi like my simple resistor option does (you might, however, check that link out as it contains the pinouts for RaspPi serial pins in the GPIO header).

On software side, the Pi acts as a “server”, taking simple display commands via serial link. You could even start the Pi server script and connect to the serial port with Putty, and the session could look a bit like the following:

# initialize viewport - not actually implemented yet  
init 500 500  
# draw a 10x10 rectangle at (5,15)  
draw 5 15 10 10  
# exit the server  
exit  

The python server uses pyserial for serial communications, currently at 9600 bps, but the Pi and Arduino should be able to do 115 200 as well. For graphics, pygame framework is used. Current version of code initializes a 500×500 pixel graphics viewport, but one could use the parameters given by “init” command from Arduino side to define that, too. The code should be rather straightforward to understand: there are only two supported commands, “draw” with four parameters, and “quit” to exit the otherwise infinite loop waiting for draw commands (I named the file ar2pi.py):


#!/usr/bin/env python

import serial
import string
import pygame

ser = serial.Serial("/dev/ttyAMA0",9600)
ser.open()

pygame.init()
window = pygame.display.set_mode((500, 500))
colour = pygame.Color("blue")
pygame.mouse.set_visible(False)

quit = False

while not quit:
	line = ser.readline()
	words = line.split()

	if words[0] == "rect":
		pygame.draw.rect(window, colour, (int(words[1]), 
                                 int(words[2]), int(words[3]), int(words[4])))
	elif words[0] == "exit":
		quit = True
		
	pygame.display.flip()

ser.close()

Read post

Website hiccups since Sunday

The WebFaction web server hosting Code and Life (and other my sites) has been experiencing filesystem issues and has been down for fscking several times. Apologies for site readers, hopefully the provider gets these glitches ironed out soon.

Read post

PicoScope 3206B Review

As I mentioned earlier, I got a PicoScope 3206B back in August. After a few months of use I have gathered enough experience with it to feel qualified to write a review on the device.

Those who haven’t yet done so, I suggest you to check out my earlier review of PicoScope 2204 – it covers a bit of my rationale for a USB scope, and the basic features of Picoscope software, which is the same for the whole PicoScope product line.

The 3206B is the top-of-the-line two-channel scope in the 3000 series. The prices have dropped a bit after the introduction of mixed signal version 3206B MSO, so for $1320, you’ll get this device with fairly impressive key feature set:

  • Two channels, and external trigger line
  • 200 MHz analog bandwith
  • 500 MS/s sampling rate
  • A huge 128 MS sample buffer
  • Arbitary waveform function generator (20 MS/s)
  • Two 250 MHz probes, storage bag and software CD

For full details, I suggest you to look up the 3200 series spec sheet from Picotech’s website. Let’s get started!

Unpacking the box

Picotech ships from UK and within EU, no additional taxes or import fees need to be paid. Both my deliveries from them have arrived promptly within two days, well packaged and in impeccable condition.

The scope comes in a cardboard box that also has space for the probes, a storage bag and software CD. Nothing too fancy, but works well for longer term storage, too.

Read post

Aladdin: USB password generator-inspired project at Indiegogo

I’ve been quite busy with work and had a few fully booked weekends, so no updates in a while. Well, it’s going to change now, as I have two more updates in the pipeline already! The first one is an interesting project that’ll surely interest those that have read my USB tutorials: Alvin Chang has started a USB password generator project at indiegogo!

Mr. Chang’s project is inspired my USB password generator hack, and builds upon the (GPL licensed) codebase it also used. Many people have expressed the desire to get the USB password generator as a ready-made device, so if you’re one of those, check out the project and decide yourself if you want to participate funding in the Aladdin key project:

Aladdin: The Key to Your Computer at indiegogo.com

Note: I’m associated with the project only via the DIY password generator hack that the project is partly based on (basic hardware design and source code).

Read post

Stellaris Launchpad PWM Tutorial

After receiving my Stellaris Launchpad, I decided to browse the little amount of tutorials there was available on the subject. I was really impressed by the Getting Started hands-on workshop offered in TI’s wiki. After watching the first few tutorials, I had a somewhat firmer grasp on how this little puppy was supposed to be programmed, and the capabilities of the Code Composer Studio IDE.

I got as far as Chapter 4: Interrupts until I hit the first snag: After the Lab4 assignment, the friendly instructor told that as a home assignment, one could try out the PWM (pulse-width modulation) capabilities of the Launchpad before proceeding further. Little did I know how many hours I would spend on that topic! After a solid 8 hours of banging my head against the documentation, Launchpad and CCS (which is prone to hanging at least on my PC), I finally got it working, and decided this would be a great place for a tutorial.

Rule 1 of PWM on Launchpad: There are no PWM units

The initial four hours of my PWM efforts were spent on the StellarisWare Driverlib documentation concerning PWM. In case you haven’t yet watched the tutorials, the Driverlib is essentially a bundle of code that takes away the burden of writing into dozens of control registers, and instead presents the programmer with a couple of hundred API calls to enable a higher-level approach.

It wasn’t until the third hour of googling around that I discovered, that while the timer functionality of the Launchpad includes a PWM mode, there are no actual PWM units on board! So if you’re looking at the PWM functions in Chapter 21 of Stellaris Peripheral Driver Library User’s Guide – stop it and get back to the Chapter 27: Timer functions.

Step 1: Setting up the timer0 PWM mode

So the only PWM functionality the Launchpad supports is the “PWM mode” of the six hardware timers. Thankfully, that’s already quite nice (if I ever find out how to use interrupts with PWM, even better). So unless you already know how the timer system works, now’s a good time to watch the Chapter 4 video which explains it quite nicely. Based on that tutorial, we learn that the following piece of code should initialize the timer for us:


SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);

ulPeriod = (SysCtlClockGet() / 10) / 2;
TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod - 1);

TimerEnable(TIMER0_BASE, TIMER_A);

Read post