Category Archives: Electronics

Using Re:load Pro on Ubuntu Linux

A couple quick notes to make Re:load pro work on Ubuntu Linux without requiring root privileges and without having to manually figure out the device file name

Using Re:load Pro from an unprivileged user (non-root).

€ sudo apt-get install expect-dev
€ unbuffer udevadm monitor --environment | grep 'ID_SERIAL='

Plug in the device.


Create or update udev configuration to recognize your Re:load Pro and assign it regular permission bits and ownership.

€ sudo vi /etc/udev/rules.d/60-ttyUSB.rules

Contents of the udev rules file should be as below, where you change:

  • the OWNER id to your own username
  • the ENV{ID_SERIAL} string with the one found using the above grep command, notice the unique serial number!!

ACTION!="add", GOTO="persistent_serial_end"
SUBSYSTEM!="tty", GOTO="persistent_serial_end"
KERNEL!="ttyUSB[0-9]*", GOTO="persistent_serial_end"

# IMPORT="usb_id --export %p"

ENV{ID_SERIAL}=="Arachnid_Labs_Ltd_Re:load_Pro_DAXWP0Z7" , SYMLINK="reLoadPro" , SYMLINK+="ttyUSB006" , OWNER="yourUsername"


Reload udev configuration to activate it.
Unplug the Re:load Pro

€ sudo udevadm control --reload

First time set up for flashing firmware

€ sudo apt-get install python-pip
€ sudo python -m pip install cyflash

The defaults on the flash tools are such that you need to be root to execute it. This is a good thing security-wise, you don’t wat to accidentally flash your Re:load Pro or accidentally flash another device connected to your computer with a similar chipset. If you really don’t like the root-requirement, you can change it as follows:

€ sudo chmod a+rx /usr/local/lib/python2.7/dist-packages/cyflash
€ sudo chmod a+r /usr/local/lib/python2.7/dist-packages/cyflash/*

Firmware update
Download the latest release from github: , check the correct file you are about to download:

€ wget

Flashing the firmware

€ sudo python -m cyflash --serial /dev/reLoadPro "Reload Pro v1.9.cyacd"
Initialising bootloader.
Silicon ID 0x04a61193, revision 17.
Array 0: first row 22, last row 255.
Device application_id 0, version 259.
Uploading data (211/211)
Device checksum verifies OK.
Rebooting device.

Using Re:load Pro from USB serial

Install screen. A nice GUI alternative is putty

€ sudo apt-get install screen putty

Open the serial connection as follows, where reLoadPro is the device file that is defined in udev at the top of this article:

€ screen /dev/reLoadPro 115200

Commands typed in the console are not echoed to the screen. Type version to check if all works as expected. Re:load Pro should answer similar to:

version 1.9

Exit screen using Ctrl-A K.

Timed 1 millisecond interrupt routine for Arduino.

With Arduino (or AVR in general for that matter) you sometimes have the need to execute some code at regular intervals. A timed interrupt routine is the proper solution, but the Arduino IDE doesn’t come with standard code for this and it can be quite complicated for those who are unfamiliar with directly programming the hardware.

I created a simple proof of concept code that runs on AVR-type Arduino’s and uses a timed interrupt to time exact 1 ms, based on the 16MHz system clock. Thus 1000 counts equals 1 second with the same accuracy as the system clock. As proof the standard LED on pin 13 will start to blink in a 0.5Hz rhythm, one second on, one second off.

Timer0 and Timer1 are commonly used for the Arduino and third party libraries, so that leaves us with Timer2. Arduino’s system clock runs at 16MHz. Timer2 is clocked through a prescaler, this basically means that the system clock is first divided before it is fed to the Timer/Counter. I selected a 128 prescaler by configuring TCCR2B. This means the Timer/Counter is clocked at 16MHz / 128 = 125kHz.

Next I decided to make Timer/Counter2 compare to a set value 125 by setting OCR2A to 125 and configuring ‘Clear Timer on Compare’-bit in TCCR2A. This results in an exact 1kHz interrupt. TIMSK2 is configured to enable the Timer/Counter2 CompareA interrupt. Then all that is left is to attach the interrupt to some code, which is done with the ISR( TIMER2_COMPA_vect ) command. The Interrupt Service Routine counts to 1000 and so we arrive at 1 second ticks which can be used in the main loop to make the LED blink.

udev file for Texas Instruments LaunchPads

To be able to use the various devices on Linux as an unprivileged (non-root) user, it is required to configure udev in such a way that appropriate authorizations are assigned to it upon plugging in the device.

For both the MSP430 and the Stellaris LaunchPad I’ve developed a simple but safe udev rules file, based on its configured serial number. This means that even when more than one LaunchPad is attached to the system, it will get a unique identifier that survives reboots. Every LaunchPad supplied by TI has a unique serial number configured upon delivery.

Retrieving the serial number

To be able to create a unique device name that survives a reboot, it is essential to retrieve the serial number of the device. This can easily be done by following these instructions:

  1. Detach the LaunchPad from the system;
  2. On the command line type (this requires the expect-dev package being installed): unbuffer udevadm monitor --environment | grep 'ID_SERIAL='
  3. Plug in the LaunchPad. Notice that MSP430 takes about 10 seconds to fully register with the system.
  4. Output similar like this is displayed for MSP430:ID_SERIAL=Texas_Instruments_Texas_Instruments_MSP-FET430UIF_36FF49ABB1D22050
  5. Output similar like this is displayed for Stellaris:ID_SERIAL=Texas_Instruments_In-Circuit_Debug_Interface_0E10A714

Creating the udev rules file

With this knowledge we can build the the udev rules file:

ACTION!="add", GOTO="persistent_serial_end"
SUBSYSTEM!="tty", GOTO="persistent_serial_end"
KERNEL!="ttyACM[0−9]*", GOTO="persistent_serial_end"

ENV{ID_SERIAL}=="Texas_Instruments_In−Circuit_Debug_Interface_0E10A714" , SYMLINK="stellaris−001" , OWNER="jhendrix" , MODE:="0600"
ENV{ID_SERIAL}=="Texas_Instruments_Texas_Instruments_MSP−FET430UIF_36FF49ABB1D22050" , SYMLINK="msp430−001" , OWNER="jhendrix" , MODE:="0600"

  1. Edit lines 6 and/or 7 to contain the serial number found in the previous paragraph. Notice that only the part between double quotes needs to be edited. Of course you need as many lines as you own LaunchPads. I currently own two, so I have two lines.
  2. Where it says “jhendrix“, change that to your own username under which you will be working with the device.
  3. Save the file as /etc/udev/rules.d/60-ttyACM.rules

Using the the rules file

  1. Reload udev:
    sudo udevadm control --reload
  2. Unplug the LaunchPad;
  3. Plug the LaunchPad and wait a couple of seconds;
  4. Check the device file:ls -l /dev | grep ttyACM
    lrwxrwxrwx 1 root root 7 Feb 2 21:57 msp430-001 -> ttyACM1
    lrwxrwxrwx 1 root root 7 Feb 2 21:23 stellaris-001 -> ttyACM0
    crw------- 1 jhendrix dialout 166, 0 Feb 2 21:23 ttyACM0
    crw------- 1 jhendrix plugdev 166, 1 Feb 2 21:57 ttyACM1
  5. From this moment onward you can use the Launchpad under any of the devices listed:
    1. msp430-001 and stellaris-001 will survive a reboot;
    2. ttyACM0 and ttyACM1 are dynamic, they change according of attaching the devices.
  6. If the demo program is loaded that Stellaris comes with, you can access it from now on by typing:screen /dev/stellaris-001 115200

TI MSP430 LaunchPad Temperature Demo Application


When you receive a new Texas Instruments MSP430 LaunchPad, it comes with a small demo application installed so you can easily check its functionality. The interesting thing is that it also interfaces with the PC through a virtual serial interface, but reading the data from a Linux PC appears to be non-trivial. This is partially caused by the fact that the user’s guide states that the demo application can be read with any serial console application, which in practice just doesn’t always work.

Attaching the LaunchPad

When an MSP430 LaunchPad is attached to the system, dmesg logs a few lines similar like these:

[19:52:40] usb 2-2.3: new full-speed USB device number 85 using ehci_hcd
[19:52:40] usb 2-2.3: New USB device found, idVendor=0451, idProduct=f432
[19:52:40] usb 2-2.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[19:52:40] usb 2-2.3: Product: Texas Instruments MSP-FET430UIF
[19:52:40] usb 2-2.3: Manufacturer: Texas Instruments
[19:52:40] usb 2-2.3: SerialNumber: 36FF49ABB1D22050
[19:52:40] cdc_acm 2-2.3:1.0: This device cannot do calls on its own. It is not a modem.
[19:52:40] cdc_acm 2-2.3:1.0: No union descriptor, testing for castrated device
[19:52:40] cdc_acm 2-2.3:1.0: ttyACM0: USB ACM device
[19:52:50] hid-generic 0003:0451:F432.003E: usb_submit_urb(ctrl) failed: -1
[19:52:50] hid-generic 0003:0451:F432.003E: timeout initializing reports
[19:52:50] hid-generic 0003:0451:F432.003E: hiddev0,hidraw3: USB HID v1.01 Device [Texas Instruments Texas Instruments MSP-FET430UIF] on usb-0000:00:1d.7-2.3/input1

According to line 9 of this logging, in this case the LaunchPad is attached to the system as ‘/dev/ttyACM0′.

Reading the data from MSP430 LaunchPad

For me only minicom (2400 8N1) was showing some data, but in contrast to what I understood from the user’s guide the received data is binary, not in ASCII.  I wrote a quick and dirty Perl script that easily allows for reading the data.

After attaching the LaunchPad and pressing button P1.3 on it, it starts to send data several times per second. Running the script below from the command line, outputs the current temperature.

Receiving serial data ...
22.2C 22.2C 22.8C 22.8C 22.8C 22.2C 22.8C 22.8C
22.2C 22.8C 22.8C 22.8C 22.2C 22.8C 22.8C 22.8C
22.8C 22.8C 22.8C 22.8C 22.8C 22.2C 22.2C 22.8C

The script is no rocket science, its main goal is to prove the LaunchPad is working properly and to act as a starting point for others.


use warnings;
use strict;

use Device::SerialPort;
use Time::HiRes qw( usleep );

my $PortName = '/dev/ttyACM0';
my $PortObj;
$| = 1;

print STDERR "Waiting for serial port ...\n";
while ( not( $PortObj = new Device::SerialPort ($PortName, 'false' ) ) ) {
print STDERR "Waiting: Cannot open serial port: $!\n";
sleep( 1 );

$PortObj->databits( 8 );
$PortObj->baudrate( 2400 );
$PortObj->parity( "none" );
$PortObj->stopbits( 1 );
$PortObj->handshake( "none" );

print STDERR "Receiving serial data ...\n";
my $newline = 8;
while ( 1 ) {
if ( not $newline ) {
# print 8 values per line
print "\n";
$newline = 8;
# try to read a byte of data
my ( $count, $data ) = $PortObj->read( 1 );
if ( ( defined( $count ) ) and ( $count != 0 ) ) {
# if data available, then convert from Fahrenheit to Celcius
printf( "%3.1fC " , ( ( ord( $data ) - 32 ) * 5 / 9 ) );
usleep( 100000 ); # wait 100ms

TI MSP430 LaunchPad from the Linux Command Line

Installing required packages

$ sudo apt-get install binutils-msp430 gcc-msp430 gdb-msp430 msp430-libc msp430mcu mspdebug


mspdebug home page

$ mspdebug rf2500
MSPDebug version 0.19 - debugging tool for MSP430 MCUs
Copyright (C) 2009-2012 Daniel Beer This is free software; see the source for copying conditions. There is NO

Trying to open interface 1 on 050
rf2500: warning: can't detach kernel driver: No data available
Initializing FET...
FET protocol version is 30394216
Configured for Spy-Bi-Wire
Set Vcc: 3000 mV
fet: FET returned error code 4 (Could not find device (or device not supported))
fet: command C_IDENT1 failed
fet: identify failed
Trying again...
Initializing FET...
FET protocol version is 30394216
Configured for Spy-Bi-Wire
Sending reset...
Set Vcc: 3000 mV
Device ID: 0x2553
Device: MSP430G2553
Code memory starts at 0xc000
Number of breakpoints: 2

Available commands:
= delbreak gdb load opt reset simio
alias dis help locka prog run step
break erase hexout md read set sym
cgraph exit isearch mw regs setbreak

Available options:
color gdb_loop iradix
fet_block_size gdbc_xfer_size quiet

Type "help " for more information.
Press Ctrl+D to quit.

(mspdebug) step
( PC: 0fcc6) ( R4: 09b66) ( R8: 0ffdf) (R12: 00000)
( SP: 0027e) ( R5: 0c7ff) ( R9: 0ff65) (R13: 0fd90)
( SR: 00000) ( R6: 0defc) (R10: 0e7ff) (R14: 00000)
( R3: 00000) ( R7: 0e157) (R11: 00298) (R15: 0ffff)
0fcc6: b2 40 6e fd 36 02 MOV #0xfd6e, &0x0236
0fccc: b2 40 6e fd 38 02 MOV #0xfd6e, &0x0238
0fcd2: b0 12 66 fd CALL #0xfd66

Driving the Adafruit mshield v1.0 from Bitlash

Bitlash is a brilliant and powerful sketch for Arduino to do your ad hoc interactive bit banging on attached hardware. Once loaded on an Arduino, you can simply connect to it with a serial terminal emulator and start typing commands.

So yesterday I decided to find out exactly how powerful Bitlash is by bit banging an Adafruit motorshield (v1.0) for a single bipolar stepper motor. The power is in the fact that Bitlash allows you to define functions that are subsequently stored in EEPROM and so you can figure out bit by bit how to control the shield. Now I’m not going through the whole step by step procedure of reverse engineering out how the shield is wired, as the resulting Bitlash code turned out pretty straightforward and there are circuit diagrams for that.

First various Arduino output pins are to be initialized as output:

function initstepper {pinmode(3,1);pinmode(4,1);pinmode(7,1);pinmode(8,1);pinmode(11,1);pinmode(12,1);d3=1;d7=0;d11=1};

  • pin 3 → enable M2
  • pin 4 → serial clock (rising edge)
  • pin 7 → shift register not(Output Enable)
  • pin 8 → serial data
  • pin 11 → enable M1
  • pin 12 → shift register latch

To save digital pins, the motor pins are attached through a shift register. This implies that motor outputs can only be changed by shifting bits into the register and latching it to its outputs. The following functions are called under water:

function bo {d4=0;d8=arg(1);d4=1;};
function latch {d12=0;d12=1;};
function dataout {bo(arg(1));bo(arg(2));bo(arg(3));bo(arg(4));bo(arg(5));bo(arg(6));bo(arg(7));bo(arg(8));latch};

  • bo → shift a single bit into the shift register
  • latch → copy the shift register contents to its output register
  • dataout → shift 8 bits data into the shift register, then latch it to its outputs

Now the tricky bit is how the bits in the data are related to the motor pins. Here is a table:

M1 x x
M2 x x
bit 0 1 2 3 4 5 6 7
M3 x x
M4 x x

The last step is to define the separate steps for the stepper motor. For a full step, eight substeps can be identified:

b5 b4 b3 b6
M1 M2 M1a M1b M2a M2b
s1 + 0 1 1 1
s2 + + 0 1 0 1
s3 + 0 0 0 1
s4 - + 1 0 0 1
s5 - 1 0 0 0
s6 - - 1 0 1 0
s7 - 1 1 1 0
s8 + - 0 1 1 0

And code that into Bitlash functions:

function s1 {dataout(0,0,0,1,1,0,1,0);};
function s2 {dataout(0,0,0,0,1,0,1,0);};
function s3 {dataout(0,0,0,0,0,0,1,0);};
function s4 {dataout(0,0,0,0,0,1,1,0);};
function s5 {dataout(0,0,0,0,0,1,0,0);};
function s6 {dataout(0,0,0,1,0,1,0,0);};
function s7 {dataout(0,0,0,1,1,1,0,0);};
function s8 {dataout(0,0,0,1,1,0,0,0);};

To run the stepper motor:

function runstepper {while (1) { s1;s2;s3;s4;s5;s6;s7;s8};};


As a bonus it is pretty simple to change the stepper´s torque. The easiest way is to PWM the shift register’s output. The function below takes a single argument (0-255).

function torque {a7=255-arg(1);};

This will however affect all four half bridges on the shield. A prettier, though lightly more complex method is to PWM the enable M1 and M2 pins (resp. 11 and 3). This allows for microstepping, but the Bitlash method is really too slow for that.

Simple rotary encoder controlled PWM dimmer

This post is basically a proof of concept for how to use a rotary (quadrature) encoder with an Arduino. Rotary encoders look a bit like classic potentiometers, but instead of changing resistance between its pins, it has two outputs with digital signals 90 degrees shifted with respect to each other. Because of this 90° phase difference between its outputs, it is relatively simple to determine in which direction it was turned as at any given time only one of its outputs will change. An example of the output sequence is given in the table below.

       Left   Right
Step   B A    B A
 a     1 1    1 1
 b     1 0    0 1 
 c     0 0    0 0
 d     0 1    1 0
 a     1 1    1 1

There are two ways of implementing a rotary encoder in an Arduino sketch. The first one simply polls the state of the input pins and checks the current state with the previous state. The other option is to use one encoder output as interrupt trigger and the other output to indicate direction.

Using pin state polling

In this example Arduino’s inputs are continuously polled and stored in currentState. When currentState is different from the previousState polled, then the rotary encoder has changed its position and the PWM value has to be updated. The if-then construct (lines 37-41 and 45-49) is used to decide whether the change implies an increase or a decrease. Then a second if-then (lines 42 and 50) prevents PWM from changing from 100% to 0% (and the other way around) by passing end of scale.

The code:

This sketch implements a simple dimmer using a rotary encoder. The
encoder is connected to pins 22 and 23.
The standard led on pin 13 will be dimmed using pwm.
More on:

// Arduino Mega1280

const uint8_t pwmPin = 13;
const uint8_t encoderPinA = 22; // encoder input channel A
const uint8_t encoderPinB = 23; // encoder input channel B
uint8_t previousState = 0;
uint8_t analogValue = 128; // initialize at 50% PWM
const uint8_t stepSize = 2; // step size to increase PWM setting

void setup(){
analogWrite( pwmPin , analogValue );
pinMode( pwmPin , OUTPUT );
pinMode( encoderPinA , INPUT_PULLUP );
pinMode( encoderPinB , INPUT_PULLUP );

void loop() {
uint8_t currentState = ( digitalRead( encoderPinA ) << 0 ) | ( digitalRead( encoderPinB ) << 1 );

red yellow Digital
1 1 3
1 0 2
0 0 0
0 1 1

if (
( ( previousState == 3 ) & ( currentState == 2 ) ) |
( ( previousState == 2 ) & ( currentState == 0 ) ) |
( ( previousState == 0 ) & ( currentState == 1 ) ) |
( ( previousState == 1 ) & ( currentState == 3 ) ) ) {
if ( analogValue <= ( 255 - stepSize ) ) {
analogValue += stepSize;
} else if (
( ( previousState == 1 ) & ( currentState == 0 ) ) |
( ( previousState == 0 ) & ( currentState == 2 ) ) |
( ( previousState == 2 ) & ( currentState == 3 ) ) |
( ( previousState == 3 ) & ( currentState == 1 ) ) ) {
if ( analogValue >= stepSize ) {
analogValue -= stepSize;

if ( previousState != currentState ) {
analogWrite( pwmPin , analogValue );
previousState = currentState;

It is fairly easy to adapt this code for any other Arduino board types. It doesn’t rely on any specific hardware, just requires two digital input pins and one pin that can drive PWM.  Just change encoderPinA and encoderPinB. Most Arduino boards have an on board LED on pin 13 which is used for PWM here.

Using interrupts

The second option to implement a rotary encoder is using interrupts. An interrupt can be used to temporarily stop execution of the main program to service an event (interrupt), after which the main program is being resumed. The trick used here is to use one of the encoder outputs as a clock event (both rising and falling edges) attached to the interrupt input and the other input as direction indicator.

All the main loop does in this example is setting PWM value from analogValue, where the interrupt routine increases/decreases this value. This only works because of the fact that both edges (rising and falling) can be used to trigger the routine. Whenever the interrupt routine is entered, both encoder inputs are read. When both inputs are different (LOW, HIGH) the analogValue is increased, if both inputs are identical the analogValue is decreased.

The interrupt driven version for an Arduino Mega:

This sketch implements a simple dimmer using a rotary encoder. The
encoder is connected to pins 21 and 22.
The standard led on pin 13 will be dimmed using pwm.
More on:

// Arduino Mega1280

Encoder state
red yellow Numeric
1 1 3
1 0 2
0 0 0
0 1 1

const uint8_t pwmPin = 13;
const uint8_t encoderPinA = 21; // encoder input channel A
const uint8_t encoderPinB = 22; // encoder input channel B
const uint8_t interruptChannel = 2; // pin 21, encoder input channel A
const uint8_t stepSize = 1; // step size to increase PWM setting

volatile uint8_t analogValue = 128; // initialize at 50% PWM

static void interruptHandler(){
delay( 10 ); // debounce
if ( digitalRead( encoderPinA ) != digitalRead( encoderPinB ) ) {
if ( analogValue <= ( 255 - stepSize ) ) {
analogValue += stepSize;
} else {
if ( analogValue >= stepSize ) {
analogValue -= stepSize;

void setup(){
analogWrite( pwmPin , analogValue );
pinMode( pwmPin , OUTPUT );
pinMode( encoderPinA , INPUT_PULLUP );
pinMode( encoderPinB , INPUT_PULLUP );

attachInterrupt( interruptChannel , interruptHandler , CHANGE );

void loop() {
analogWrite( pwmPin , analogValue );
delay( 100 );

Notice that the interrupt pins vary with Arduino board type, check its product page which exact pins you have to use and don’t forget to update the settings for interruptChannel and encoderPinA.