Raspberry PI I2C

Once again playing with erlang ale, and last time I played with the gpio module and to change it up I decided I would give a go at the I2C module. I’m very interested in using it coupled with something like this board from adafruit to drive servos.


I happen to have a teensyduino v2.0 board (have v3.1 in the mail) laying around and decided to turn it into an i2c slave device and use erlang_ale to talk to it. This was a fairly simple to do actually. I started with the example sketch here for i2c on the arduino, and modified it to suit my needs; I only used the slave_receiver example and my code turned out like

#include <Wire.h>

const int iPin = 11;
const int dPin = 13;

void setup() {
    Wire.begin(4);
    Wire.onReceive(receiveEvent);
    pinMode(iPin, OUTPUT);
    pinMode(dPin, OUTPUT);
    debugLed(2, 500);
    Serial.begin(9600);
}

void debugLed(int times, int d) {
    digitalWrite(dPin, LOW);
    delay(100); 
    while (times-- > 0) {
        digitalWrite(dPin, HIGH);
        delay(d); 
        digitalWrite(dPin, LOW);
        delay(d); 
    }
    digitalWrite(dPin, LOW);
}

void loop() {
    delay(100);
}

void receiveEvent(int howMany) {
    while (0 < Wire.available()) {
        Serial.print("found: ");
        Serial.println(Wire.available());
        int c = Wire.read();
        if (c == 0x01) {
            digitalWrite(iPin, HIGH);
            digitalWrite(dPin, LOW);
        }
        else if (c == 0xff) {
            digitalWrite(iPin, LOW);
            digitalWrite(dPin, HIGH);
        }
        Serial.println(c);
    }
}

It Simply flips between two leds depending on the byte sent and only handles 0x01, and 0xff. Not particular reason I chose those values, just did.


On the Raspberry side I fired up an erlang shell via make shell in the root of the erlang ale directory and ended up typing:

%% running make shell in the erlang_Ale 
%% root brings up a shell start the i2c supervisor
i2c_sup:start_link([{i2c1, "/dev/i2c-1"}]).

%% using a named fun to create an infinite loop 
%% effectively bouncing between the two leds.
D = fun Blink(on) ->
    i2c:write(i2c1, 16#04, { 1 }),
    timer:sleep(500),
    Blink(off);
Blink(off) ->
    i2c:write(i2c1, 16#04, { 255 }),
    timer:sleep(500),
    Blink(on)
end.

%% set it in motion
D(on).

This creates a named fun that calls itself over and over swapping the leds that are on. Not much to it, but still pretty cool to do something that simple to just talk to the teensyduino.


Interestingly I didn’t quite understand on the erlang side if I was sending one byte or multiple bytes and on the arduino side I was assuming a single byte: I wasn’t able to switch the leds when sending 0xff though – which led me down some rabbit holes.

First thing to note, which you can see in the github gist is that on the erlang side all you have to do is send

i2c:write(..., ..., { 1 }). %% or

%% if it makes you feel better you could express 
%% this as 16#ff instead of 255 or 16#01 instead of 1
i2c:write(..., ..., { 255 }). 

and it will just send a single byte – furthermore if you happen to want to send multiple bytes you send them by adding more elements to the tuple. So { 16#ff, 16#01, 16#ff } would actually send three bytes (which i verified in the serial output) and if for example you send { 16#ffff } it would get truncated to a single byte. However, that led me to play with erlangs bit syntax, thinking I needed to explicitly send a byte and that maybe I was sending more than one byte etc… and turns out that that was not the case at all which is how I found all this out.

The issue actually ended up being this line but instead of int c, it was char c. So { 1 } would work but { 255 } would not work. That is still odd to me. I’m almost thinking that I did something brilliant like

if (c = 0x01) ...
// instead of 
if (c == 0xff) ...

I’m not sure that the fact that it was char vs integer would have mattered, though char would be signed though, so barring that I didn’t actually make an error in comparing, then perhaps it was me not catching the char being signed (I know it is signed, but wasn’t thinking about it…)

For those curious as far as hooking them up this helped on the pi side, and this for the teensydunio side. Match up the scl and sda pins, and I chose to power the teensyduino from the pi, so I also used the +5v and ground pins on the pi which get hooked up to the VCC and ground pin on the teensyduino.

here is another extremely exciting video of two leds blinking! Enjoy. It’s still pretty damn cool type a few lines into the erlang shell and suddenly this spings to life and here is the gist with the code

 

Advertisements
Posted in Embedded, Erlang | Leave a comment

Raspberry PI with Erlang

Just recently got around to using the Raspberry PI I bought almost a year ago and have a bit of interest in using Erlang with it. A friend got me into Erlang a few years ago and my primary interest in it was how two VMs could easily talk to one another and in general from the point of view of the code you are writing it just works.

You don’t really care if the message you just sent is on the node your module is on or on a remote node — it’s mostly transperent. I really dig that. I haven’t written a large amount of code in Erlang, but the more I write – the more I like it; still quite new to it though.

The idea is to use something like the raspberry pi running erlang as a subsystem in robot or some other electronic projects. Erlang would be the communication hub between other robots, and a server. Currently toying with the idea of creating something like robocode, but with rc tanks (I say rc more so you picture what I’m talking about, they would really be autonomous not RC).

Today I setup the PI up again; for the second time. I’m running Raspbian (won’t go into the configuration) and have a cheap usb wifi dongle plugged in that works really well. I did set it up a few weeks ago running the arch distro, which I is the distro (well not the arm version) I use for my laptop — but hosed it messing with configuration (like any good programmer/hacker). Just figured I would go with raspbian this time around as it seems to be more popular.

On top of that I installed erlang-mini (checkout the raspbian tab and scroll down a bit) which is smaller version targeted for this purpose, after which I subsequently compiled Erlang ALE. This provides a set of modules backed by c libs that interface with the GPIO header on the raspberry pi. All of this was fairly simple to do, and then I wired up a simple led to the 4th pin on the GPIO header for the obligatory hello world of electronics projects and set out to make that damn thing blink.

Fortunately the git hub page for erlang ale has some good examples along with enough info to get me started so looking at the page I so that I could do

make shell

in the root of the ale directory to bring up an erlang shell ready to go and that’s just what I did. I followed their directions modifying them for the pin I used and ended up with something like

%% spin up a process, and link to it that 
%% manages pin 4, and set pin 4 as an output pin
gpio_sup:start_link([{4, output}]).

%% pull pin 4 high
gpio:write(4, 1).

%% pull pin 4 low (I was typing this in the shell,
%% and obviously pausing to see the result in between)
gpio:write(4, 0).

and I’ll be damned if the led didn’t come on when I pulled the pin high and go off when I pulled the pin low. I then proceeded to repeat this several times because it was cool. No other reason, I was just amazed at how simple all this was and to be able to just do this in a shell interactively. Used to typically writing C code compiling and burning then trying it, then repeat (and yes I’m sure there setups out there that let you do this interactively etc…).

So I was like ok, now I’d like to make it go blinky blinky, to make it a true hello world program. At his point I also remembered the new named funs in Erlang R17, so I proceeded to type this into the shell

F = fun Blink(0) ->
   gpio:write(4, 0),
   timer:sleep(1000),
   Blink(1);
Blink(1) ->
   write(4, 1),
   timer:sleep(1000),
   Blink(0)
end.

%%now set it in motion
F(0).

And sure enough it blinked, and that’s where I left off. I do have a handy dandy servo laying on my work bench (AKA, dinner table) so my next goal will be trying the PWM module.

Posted in Embedded, Erlang, Uncategorized | Tagged , , | Leave a comment