Massachusetts Institute of Technology

Media Lab

Matt Hirsch

Pinkuino

Introduction

The PLW had a project called OpenIO which used a board called a pinkie, to connect general purpose I/O pins to the network. The pinkie has an XPort on it, providing network access to an Atmel ATmega32 microcontroller.

Sadly, the OpenIO project has fallen into disrepair. The custom server side software is no longer running and we're stuck with a dozen or so pinkie boards with no one to talk to. I decided that it was sad to see these nice little boards going to disuse, so I have ported Arduino to the pinkie. I call this portmanteau Pinkuino.

Pinkie

Photo credit original OpenIO wiki

I always thought that the goal of OpenIO was flexible programmability at the leaves of the network. The Pinkuino allows this. You can push your Arduino sketchs to a Pinkuino over the network.

Setup

Setup Environment

Download my modified Arduino code (checked out svn 942), with modified atmega32 bootloader, or this patch against Arduino SVN 942. The patch does not add the bootloader for atmega32. So if you go that route you'll have to download the bootloader seperately. The atmega32 bootloader I have listed there is a slightly modified version of the bootloader found on the retrointerfacing.com blog here.

Once you have downloaded the SVN snapshot from above, or applied the patch, build the Arduino source according to the instructions here.

Once the build is complete, you should be able to run the modified arduino IDE. You should see a new option in the ToolsSerial Port menu. This option will allow you to specify a network serial port, for programming pinkies of the network.

modified arduino IDE

Bootloader

If your pinkie board has does not already have the Arduino bootloader, you need to program the bootloader onto the pinkie board. If you already have the bootloader on your board, you can skip this step.

In order to write the bootloader, I used the USBtinyISP programmer, but you can use any SPI programmer. I used the 6 pin header. Connect the following pins on the programmer to pins on the pinkie board:

Programmer Pin   Pinkie Pin         ISP Pinout
1IO6MISO
2V-*+Vcc
3IO7SCK
4IO5MOSI
5Not ConnectedRESET
6V+*Ground

*V+ and V- seem reversed on the pinkuino board (i.e. +3.3V → V-, 0V → V+).

Be sure to setup your programmer to run in board-powered mode. On the USBtinyISP this means disconnecting the jumber on the front. Also be sure your programmer supports 3.3V board powered programming.

Here is a photo of my improvized programming header. The wires in the photo connected to the RX and TX pins are not required. I've connected to the RX/TX pins for monitoring, but take care not to tie either of these to a low impedance pin, since the XPort RX is connected to the ATmega32 TX and vice versa.

pinkuino isp header

Configuring the XPort

The next step is to configure the XPort to work with the pinkuino.

The easiest way to configure the XPort is over the network. This requires that the XPort is configured either to accept a DHCP address or with a known static IP address. If the XPort cannot be found on the network it also supports configuration over a serial interface at 9600 baud. Refer to the manual for full instructions.

You can find the IP address of your pinkuino by any method you like. I setup a dhcp server on my computer and connected the pinkie directly to my ethernet port. If you don't have an ethernet port that autodetects the sense of devices attached to it you will need a crossover cable for this configuration.

Here is the dhcpd.conf file I used under Fedora 12 Linux.

ddns-update-style none;
default-lease-time 7200;
max-lease-time 8800;

subnet 192.168.2.0 netmask 255.255.255.0 {
option subnet-mask 255.255.255.0;
option routers 192.168.2.1;
option domain-name-servers 18.85.2.138, 18.85.2.171;
range 192.168.2.2 192.168.2.250;
}

I configure my second ethernet port:

# Networking Interface
DEVICE=eth1
BOOTPROTO=none
HWADDR=XX:XX:XX:XX:XX:XX
ONBOOT=yes
USERCTL=yes
IPV6INIT=no
PEERDNS=yes
TYPE=Ethernet
IPADDR=192.168.2.1
NETMASK=255.255.255.0

Then:

sudo ifup eth1
sudo service dhcpd start

Now, when you connect the pinkie you will see messages like this in /var/log/messages

Mar 15 15:22:25 localhost dhcpd: DHCPDISCOVER from 00:20:4a:8d:86:17 via eth1
Mar 15 15:22:26 localhost dhcpd: DHCPOFFER on 192.168.2.6 to 00:20:4a:8d:86:17 via eth1
Mar 15 15:22:26 localhost dhcpd: fancy bits in fqdn option
Mar 15 15:22:26 localhost dhcpd: Wrote 6 leases to leases file.
Mar 15 15:22:26 localhost dhcpd: DHCPREQUEST for 192.168.2.6 (192.168.2.1) from 00:20:4a:8d:86:17 via eth1
Mar 15 15:22:26 localhost dhcpd: DHCPACK on 192.168.2.6 to 00:20:4a:8d:86:17 via eth1

In the above example the DHCP address of the pinkie is 192.168.2.6.

Once you know the IP address of the XPort on the pinkie board, type the address into a browser bar. Just press ok when prompted for a password. You should get a page like this:

xport configuration page

Click on "Serial Settings."

xport serial settings page

Apply the following settings by pressing the OK button:

Protocol:RS232
Baud Rate:230400
Data Bits:8
Flow Control:None
Parity:None
Stop Bits:1

Click on "Connection"

xport connection settings

Apply the following settings by pressing the OK button:

Connection Protocol
Protocol:TCP
Connection Mode
Accept Incoming:Yes
Active Connect:Manual Connection
Endpoint Configuration
Local Port10001
Remote Port10002

Click "Apply Settings"

When the XPort reboots it will have the proper settings for communicating with the Pinkuino bootloader.

xport apply settings

Programming the Pinkuino

Make sure you change the active board to pinkuino.

select board

Once you have a working environment you should test it by sending a program to the pinkuino. Download the sample blink program.

Open blink in the modified Arduino IDE. The onboard LED is on a different pin in the Pinkuino, so you'll have to change the ledPin variable to this:

int ledPin = 23;

Select net from the ToolsSerial Port menu. In the resulting dialog box, enter the IP address and port number of your pinkuino in the ipaddress/host:port form. For example, to program a Pinkuino at 192.168.2.4 on port 10001 (the port we configured in the setup section above), enter the following and click OK:

pinkuino net dialog

Now press the reset button on the pinkuino board. This activates the bootloader. You will see the onboard amber LED flash. After the flashing stops you have about three seconds to send the Pinkuino a program over the network. Send your code to the Pinkuino by pressing the program button in the modified Arduino IDE, just as if it were connected serially. The IDE will continue to try to program the Pinkuino for some time, so the system is fairly tollerant of the timing of button pushes.

That should be it. You now have a program on the Pinkuino.

The analog (PWM) output pins on the ATmega32, in Arduino, are 4, 5, 7, and 11. These are the pins you can analogWrite to.

The pins labeled HV1 through HV4 are not driven by the ATmega32 directly, but instead by a Microchip TC4424 high current MOSFETs. This means they are suitable for driving high current devices such as line-level relays.

Working on the Network

I hope this section will be improving with libraries and further code examples. For now I'll just tell you how to command the XPort over the serial interface.

We have configured the XPort, above, to work in Manual Connection mode at 230400 baud. The use of Manual Connection mode is documented in the manual, but basically to open a TCP connection to ipaddr:port, you must send it this string of the format C[ipaddr]/[port]. For example, to connect to 192.168.2.1 on port 10002, the command would be:

C192.168.2.1/10002

Here is some example Arduino code to test your Pinkuino's networking capability.

First setup an instance of netcat to listen for tcp connections on a destination port:

nc -l 10002

Then, run this code on the Pinkuino:

void setup() {
    Serial.begin(230400);
    Serial.print("C192.168.2.1/10002\n"); }

void loop(){
    Serial.print("hello world\n");
    delay(1000);
}

If everything is setup correctly, you should see hello world show up on the command line. Be careful that you don't have a firewall blocking port 10002, or whichever port you choose.

$ nc -l 10002
hello world
hello world
hello world
hello world
hello world
hello world
^C

Press Ctrl-C to stop netcat from listening.

One caveat with the XPort is that I have not discovered a good way to force it to disconnect. The connection will time out after a short while, once closed by netcat. However, if you rerun your program quickly, the XPort may be transmitting your connection command to a dangling connection, rather than obeying it.