September Arduino BlinkM Project

25 replies [Last post]
scott-ellis
Offline
Joined: 07/23/2009

A new thread for the Arduino/BlinkM project at the next meeting.

I haven't heard any dissent, so I think the agreed goal is to develop a Linux interface for the programmable BlinkM leds using the Arduinos as a USB/serial to I2C converter. Ideally, we'll end up with working code clean enough to post somewhere for others to use. It's a small project, but since we only have a couple of hours and are all relatively new to Arduinos, it should keep us busy.

I thought it would be nice to do at least two implementations, one in Perl and another in Python. If someone wants to tack on some other languages that would be cool.

To help get things moving, I've posted some serial communication examples here

Bogart
Offline
Joined: 06/10/2009
I just received the Arduino

I just received the Arduino today. I downloaded the IDE for Mac OS X and hooked it up with USB power, tried some LED examples and it's working, so far. (Though I must say the unit appears to be used, and not lightly either). Scott, I tried your "SimpleSerial.pde" sketch. It didn't seem to work at first when sending from the IDE serial monitor, but when I ran "echo hello > /dev/tty.usbserial-A700fjZE" it appeared in the serial monitor, appended to the text I had entered before. Perhaps the serial monitor is not adding a newline character...

wbirthisel
Offline
Joined: 01/04/2010
Perl SerialPort

As the link indicates, the Windows version is a little different (not much, though).
I'll see if I can post the Windows one, or perhaps a cross-platform version that works everywhere.

-bill

scott-ellis
Offline
Joined: 07/23/2009
Serial monitor and newline

I think you're right about Serial Monitor stripping the newline. You can also use ':' to terminate the command. The sketch code on the web page isn't exactly what's in the pde. That's because, I can't figure out how to cut-n-paste from the Arduino editor into another app in Linux. I fixed the web page.

That's too bad about your units condition. I ordered a second from Amazon and the barrel connector for power is slightly skewed, but otherwise looks new.

Bill, fix my Perl code if you have a better way. Looking for a LF in the response, but don't want to wait forever. It's shameful that the Perl code is longer then the Python ;-)

richardbarnett
Offline
Joined: 06/21/2010
Doesn't work for me..

First of all, my Arduino from Sparkfun was in perfect condition...and I just received the BlinkMs. The Arduino sketch seems to work using a terminal emulator but refuses to work with the Perl code, both on Linux and my modified version for Windows. Sending seems to go ok as far as I can tell but nothing ever comes back.

Is there something funny going on with control lines? Time to get out the scope :-(.

richardbarnett
Offline
Joined: 06/21/2010
Problem solved - sort of

The problem is that DTR from the FTDI chip goes low when the port is opened on the PC. This causes a 2mS reset pulse into the CPU. If you put a "sleep(2)" call into the Perl code just before sending the test string, that leaves enough time for it to work properly but that's kind of ugly. I have been expereimenting with calls like dtr_active() to see if I could stop the pulse but there doesn't seem to be an easy way.

scott-ellis
Offline
Joined: 07/23/2009
Re: Doesn't work for me

Does the serial code I posted work? As they say, "It worked good on my machine."

This morning I also posted some code using the Gumstix (could be a Beagleboard) as I2C master and the Arduino as a slave and slung some data back and forth. Might be useful for some later project if we have to string a bunch of Arduinos together on one bus. Just fooling around right now.

The ADC's on the Arduino are butt simple to use too.

richardbarnett
Offline
Joined: 06/21/2010
Doesn't work

Scott - I was using your code from your web site and, no, it (the Perl code) didn't work for the reason I mentioned (the reset problem). Do you know how make sure that DTR stays high from the FTDI when the port is opened? I have totally failed to manage to do this.

With the sleep(2) fix, I now have it working on Linux and Windows.

I just got the BlinkM test code running - it really is quite bright!

Nice to see that you have totally cracked the issues of using OMAP I2C. I expect to find that useful in the near future - my xMs are due to turn up on Monday (via pigeon post apparently).

richardbarnett
Offline
Joined: 06/21/2010
BlinkM code

I came up with some simple code (essentially a terminal emulator) that works with the BlinkMTester code for Arduino downloaded from here: http://thingm.com/fileadmin/thingm/downloads/BlinkM_Examples.zip. All it does is allow the commands implemented by the BlinkMTester to be typed on the PC but at least it proves the basic concept. The only change I made to BlinkMTester was to set the port speed to 115200.

Since I don't yet have a convenient place to post code (maybe the group should have one?), I'll add the Windows version here (the two Linux version changes are as in Scott's original code). Due to the way the code works, I got away with a sleep(1) instead of a sleep(2). And as you'll see, Perl is not a language I use very much!

#!/usr/bin/perl -w

use strict;

# Change line below for Linux
use Win32::SerialPort qw( :STAT 0.20 );

# Change line below for Linux or for different COM port
my $port = Win32::SerialPort->new("COM12") || die "Failed to open port\n";

$port->baudrate(115200);
$port->parity("none");
$port->handshake("none");
$port->databits(8);
$port->stopbits(1);
$port->read_char_time(0);
$port->read_const_time(20);
sleep(1);

while(1)
{
my $response = "";
my $timeout_tries = 50;

while ($timeout_tries > 0)
{
my ($count, $data) = $port->read(255);

if ($count > 0)
{
$response .= $data;
last if ($data =~ /cmd>/);
}

$timeout_tries--;
}

if ($timeout_tries)
{
print "$response";
}
else
{
die("Arduino is not responding\n");
}

while (1)
{
my $inp = ;
chomp($inp);
if (length($inp) == 0)
{
next;
}
if (lc(substr($inp, 0, 1)) eq "x")
{
exit(0);
}
$port->write($inp);
last;
}
}

scott-ellis
Offline
Joined: 07/23/2009
Re: BlinkM code

Thanks Richard. I'll try this out tomorrow morning.

richardbarnett
Offline
Joined: 06/21/2010
Where we could take this

How about this for a slightly longer term goal - since the whole idea is that the Arduino is the hardware interface that allows PC programs to do things, we could develop code for the Arduino that allows the Arduino's operation to be specified by the PC application. This would mean that no other Arduino programming is required to use it as a sort of proxy hardware interface.

For example, an interface to the Arduino could be developed that allowed the application to define which pins on the Arduino are being used for which function (say I2C, ADC, GPIO or whatever). The interface would then also include a way of writing data to an I2C device, reading back data, reading back ADC values, setting and getting GPIO states etc. For perhaps some specific support for popular devices (such as the BlinkM) could be added also. Not to mention Arduino shields...

In this way the Arduino becomes a standard and very easy way of controlling devices from a PC. Might be of interest to those who don't want to get involved directly with Arduino programming. So some Arduino code along with library code for popular langauges to assist with PC application development might have some value out there in the big wide world.

scott-ellis
Offline
Joined: 07/23/2009
Github organization account for the TechMaine LUG

http://github.com/techmainelug

Send me your github account name and I'll add you as a member.

We can use this for the shared code repository.

richardbarnett
Offline
Joined: 06/21/2010
Github

Funny - I was just looking at Github and wondering if that was the way to go :-). My name there is "tirokartchief".

richardbarnett
Offline
Joined: 06/21/2010
Re: http://github/techmainelug

BTW that link didn't work for me - I did find your scottellis/LUG but nothing else.

Bogart
Offline
Joined: 06/10/2009
I just installed the Arduino

I just installed the Arduino IDE on my Ubuntu laptop. (Yesterday it was on my Mac desktop, but I'm not lugging that to the meeting). The Arduino web site's Ubuntu instructions were spot on. (Running 10.4). I got the Perl and Python samples both working and also uploaded the sketch (again, but this time from the laptop). Interesting: I got "Arduino is not responding" on the very first run of simple_serial.py after the sketch upload, *then* it started working... not sure why.

Scott, you were right about the colon being the line-terminator in the serial monitor output box. I was not familiar with that convention.

Fortunately everything has worked so far because I find the thing rather befuddling. I'm looking forward to learning!

wbirthisel
Offline
Joined: 01/04/2010
Github link

It looks like the link now exists - but doesn't have any members yet.

My github account is wbirthisel (same as the TechMaine account).

So we now have at least two "initialization issues" to investigate:
1. First time fails, then it starts working.
2. Resets due to control line toggles when the port is opened.

Issues like this are not really uncommon when connecting different serial devices - especially when the "device driver" is new. Sometimes a delay is enough (e.g. the sleep 1). Other times the sequence of initialization commands is relevant (especially in Windows). Since the sketch functions, in some fashion, as a part of the device driver, then we can consider this just part of the debugging fun!

We need to keep good notes - we may be able to contribute some application hints to the Arduino folks.

-bill

scott-ellis
Offline
Joined: 07/23/2009
Re: colon as terminator

It's not a convention in SerialMonitor, it's just code I put in the sketch so I could test with SerialMonitor. I had the same problem as you.

scott-ellis
Offline
Joined: 07/23/2009
Re: Github link

Fixed the github link and added wbirthisel and tirokartchief. The way to access it is to log into your personal github account and then use the Switch Context dropdown on the right side of the News Feed bar on top.

Added an arduino_serial_tests project: http://github.com/TechMaineLug/arduino_serial_tests

scott-ellis
Offline
Joined: 07/23/2009
BlinkM shell

I added http://github.com/TechMaineLug/blinkm_misc to Github and checked in Richard's code with some slight mods as blinkm_shell.pl

Works good Richard, thanks. I still don't need the sleep() call for it to work on my workstation. I'll have to try some other machines. And if you don't like my changes, make some mods and push them back up to github. Good exercise if you are new to git.

richardbarnett
Offline
Joined: 06/21/2010
Github

I have just about worked out how to use Github for my own stuff but I am not sure about collaboration. Is this the way to go - http://help.github.com/forking/ ?

Scott - you are 10,000,000 times better than me at Perl clearly! I took a course in Perl at UCSD about 6 months ago (Perl for Bioinformatics) but I've now successfully forgotten everything I learned :-(.

scott-ellis
Offline
Joined: 07/23/2009
Re: Github

No, just clone the repository and push your changes back. No need to fork the project.

I think Bill is the Perl expert here. I'm just trying to remember myself how to do things the Perl way.

richardbarnett
Offline
Joined: 06/21/2010
Arduino reset

If you check out the Automatic Reset section here (http://www.arduino.cc/en/Main/ArduinoBoardDuemilanove) you'll see that the behavior I was seeing is not unexpected. What I don't understand is why Scott isn't seeing this (unless his Arduino already has the mod described in the link). Anyway, for future projects, it's worth keeping in mind.

scott-ellis
Offline
Joined: 07/23/2009
Re: Arduino reset

So you guys don't think I'm bonkers...

Arduino #1

scott@quad:~/Arduino/arduino_serial_tests$ time ./simple_serial.py
hello
real 0m0.046s
user 0m0.010s
sys 0m0.000s
scott@quad:~/Arduino/arduino_serial_tests$ time ./simple_serial.py
hello
real 0m0.046s
user 0m0.010s
sys 0m0.000s
scott@quad:~/Arduino/arduino_serial_tests$ time ./simple_serial.pl
hello
real 0m0.128s
user 0m0.020s
sys 0m0.000s
scott@quad:~/Arduino/arduino_serial_tests$ time ./simple_serial.pl
hello
real 0m0.107s
user 0m0.020s
sys 0m0.000s

Arduino #2
scott@quad:~/Arduino/arduino_serial_tests$ time ./simple_serial.py
hello
real 0m0.036s
user 0m0.010s
sys 0m0.000s
scott@quad:~/Arduino/arduino_serial_tests$ time ./simple_serial.py
hello
real 0m0.037s
user 0m0.010s
sys 0m0.000s
scott@quad:~/Arduino/arduino_serial_tests$ time ./simple_serial.pl
hello
real 0m0.097s
user 0m0.020s
sys 0m0.000s
scott@quad:~/Arduino/arduino_serial_tests$ time ./simple_serial.pl
hello
real 0m0.096s
user 0m0.030s
sys 0m0.010s

I do get the initial timeout Bill mentioned after first uploading a sketch or first powering the Arduino. From then on, I never get a timeout and never have to delay. One board from Sparkfun, the other from Amazon. I'll be bringing them both on Wednesday so we can look them over for differences.

richardbarnett
Offline
Joined: 06/21/2010
Re: Resets!

If I can get my little PC oscilloscope to work on my notebook, I'll bring it to the meeting and see if we can get to the bottom of what's going on (and why mine doesn't work like yours!).

scott-ellis
Offline
Joined: 07/23/2009
Test Equipment

I'll also have an oscope, multi-meter, signal analyzer (serial, i2c, spi) available at the meeting.

wbirthisel
Offline
Joined: 01/04/2010
Perl and Python

On the way home last night, I recalled that I could create a very close approximation to the python version using a tied filehandle. The support is already included in the perl modules (although not in the emulator - but it would not be difficult to add).

The tied filehandle interface talks to the port using readline and print (and getc, syswrite, etc.).
The unexpected part is that the tie constructor opens a configuration file that is saved after initializing the port (and can be reused many times and includes all the parameters we would ever care about). The tie is built on top of the save and start methods in the modules. I'll see if I can whip together a demo that functions like simple_serial.py. I'll put the initialization into a separate script.

-bill