Skip to content

Presenting at the Toronto Flex User Group

Just a quick note that I will be presenting at the Toronto Flex User Group on Thursday October 23rd, 2008 at the Oakham House on the Ryerson Campus, starting at 6:30pm.

Oakham House
Room: Oakham Lounge
55 Gould Street
Toronto, Ontario
M5B 1E9

I’ll be presenting: ActionScript or Flex Project? Development lessons learned building client projects.

Data Logging to the Arduino EEPROM

Data Logger Schematic

I made the first successful run with the data logger yesterday. I’ve wired up a hall sensor to the wheel of my bike and recorded 60s intervals of my ride into work and back. Ideally I’m looking for increased resolution over a typical bicycle computer; where a low cost CatEye gives you average speed over the course of a total ride, I’d like to see how that average speed changes in increments. I recognize I wouldn’t be able to compete with a device such as a Garmin, but I could definitely improve on the $30 devices you get at bike stores.

The first issue was how to deal with the intermittent pickups of the Hall Sensor. If the sensor fired too rapidly and the loop method wasn’t in the right position you wouldn’t pick up the digital I/O change. The solution, offered by Blalor, was to use the Arduino Interrupt commands. The Interrupt fires whenever a digital I/O signal is received. In this case I receive a 1 every loop. I’d be looking for a 0, so I’d set the Interrupt to look for a FALLING attribute.

The EEPROM was the next issue. 512 bytes is a serious limitation. Some math was required to see if I what wanted to do was even possible. If I were to poll every minute over a ride I’d be able to record 8.5 hours of one byte readings. That’s pretty good, seeing a 200km ride would take approximately 6 hours.

One byte is capable of storing 256 possible values. Is that enough, or would I need more values? If my revolutions were 255 with a wheel circumference of 2110mm I’d be traveling an average speed of 32km/h. Clearly not enough. I’d need to peak at 70km/h, with an average at maybe 30-40km/h.

Is it possible to compress a value of over 256 into a byte? Neil sent along an interesting piece of code on Octet Packed Integers. This code is a little beyond my comprehension so I gave it a pass. Instead it was decided to use a second byte. This allows a max value of 65535 rotations to be recorded — and at a circumference of 2110mm a max speed of 8257km/h. Well over the speed of sound! That should give me ample room to accelerate.

Problem is the second byte reduces my overall recording time to 4.25 hours. I also decided to remove 2 bytes from the array so I could track my counter when the device was turned off. When you start it back up it starts recording at the next address from where you left off. One possible solution to the space issue is to externalize the EEPROM and use the wire.h library to communicate. This would also reduce the issue of each address of the EEPROM only be written (and guaranteed) 100,000 times.

Neil also helped with the splitting of the rotation counter across two bytes. We took the full rotation count and masked it out with a hex value of 0x00FF and stored that as an int low. Then the full rotation count was bit-shifted right ( << 8 ) and stored as int high. When the report is generated after the ride the values are recombined and reported back to the screen.

I also added in three indicator LEDs for the Hall pickup, reset button, and report button. The reset button when held down for three seconds deletes all the data on the EEPROM,  anything less than that will generate a report of the current EEPROM memory.

I’ve included the code below, any suggestions on improvements would be much appreciated.

#include 
 
#define PIN_SENSOR_HALL 2 //Hall Sensor
#define PIN_LED_HALL 13 //Hall indicator LED
#define PIN_LED_RESET 6 //Reset indicator LED
#define PIN_LED_RESET_COMPLETE 5 //Reset complete indicator
#define PIN_BUTTON_RESET 7 //Reset/Report Button
#define TIME_INTERVAL 60000 //EEPROM write interval (60s)
#define MEM_SIZE 510 //EEPROM memory size (remaining 2 bytes reserved for count)
 
long countReset = -1;
long countCurrent = -1;
int countEEPROM = 0; //EEPROM Address Count
volatile int countRotation = 0; //Rotation Counter
 
void setup()
{
  pinMode(PIN_SENSOR_HALL, INPUT);
  pinMode(PIN_LED_HALL, OUTPUT);
  pinMode(PIN_LED_RESET, OUTPUT);
  pinMode(PIN_LED_RESET_COMPLETE, OUTPUT);
  pinMode(PIN_BUTTON_RESET, INPUT);
 
  Serial.begin(115200);
 
  countEEPROM = EEPROM.read(512); //Set counter to last known free space
 
  reportEEPROM();  //Report all EEPROM entries
}
 
void loop()
{
  digitalWrite(PIN_LED_HALL, LOW);
  digitalWrite(PIN_LED_RESET_COMPLETE, HIGH);
 
  //Write to EEPROM at specified interval
  if ((millis() % TIME_INTERVAL) == 0)
    writeEEPROM();
 
  //If Hall Sensor triggered then init the test
  attachInterrupt(1, incrementRotation, FALLING);
 
  resetEEPROM();
}
 
void reportEEPROM()
{
  Serial.println("EEPROM Report: ");
 
  Serial.print("[");
  for (int i = 0; i &lt; (MEM_SIZE - 1); i = (i + 2))
  {
    int h = EEPROM.read(i) < < 8;
    int l = EEPROM.read(i + 1);
 
    Serial.print(h + l);
 
    if (i != (MEM_SIZE - 1))
      Serial.print(",");
  }
  Serial.println("]");
}
 
void incrementRotation()
{
  countRotation++;
  digitalWrite(PIN_LED_HALL, HIGH);
 
  Serial.print("Rotations: ");
  Serial.println(countRotation);
}
 
void writeEEPROM()
{
  byte low = countRotation & 0x00FF;
  byte high = countRotation >> 8;
 
  Serial.print("EEPROM Address: ");
  Serial.print(countEEPROM);
  Serial.print(", High: ");
  Serial.print(high, BIN);
  Serial.print(", Low: ");
  Serial.print(low, BIN);
  Serial.print(", Stored: ");
  Serial.print(low + (high < < 8), DEC);
  Serial.println(";");
 
  EEPROM.write(countEEPROM, high);
  EEPROM.write(countEEPROM + 1, low);
 
  if ((countEEPROM + 2) < MEM_SIZE)
    countEEPROM = countEEPROM + 2; //Increment the EEPROM Address
  else
    countEEPROM = 0; //Loop back to start address
 
  EEPROM.write(512, countEEPROM);
 
  countRotation = 0; //Reset the rotation count
}
 
void resetEEPROM()
{
  if (digitalRead(PIN_BUTTON_RESET) == LOW)
  {
    digitalWrite(PIN_LED_RESET, LOW);
 
    if (countReset == -1) //Start Reset counter only if -1
      countReset = millis();
  }
  else
  {
    digitalWrite(PIN_LED_RESET, HIGH);
 
    if (countReset != -1)
    {
      countCurrent = millis();
      if ((countCurrent - countReset) > 3000)
      {
        Serial.println("Reset");
 
        for (int i = 0; i < MEM_SIZE; i++)
        {
          EEPROM.write(i, 0);
        }
 
        digitalWrite(PIN_LED_RESET_COMPLETE, LOW);
        delay(1000);
        digitalWrite(PIN_LED_RESET_COMPLETE, HIGH);
      }
      reportEEPROM();
      countCurrent = countReset = -1;
    }
  }
}

The post ride report looks something like this (values are in rotations per minute):

EEPROM Report:
[-31156,310,332,300,392,306,216,598,228,516,390,282,254,354,
496,198,436,60,254,263,400,382,280,394,362,340,300,306,256,
380,354,297,284,20,72,378,486,450,104,398,522,372,370,133,366,
360,164,336,460,542,488,366,396,384,512,484,300,300,332,346,
344,360,398,226,360,390,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

There appears to be some irrelevant data in the mix (see the array item 0 for example) which I haven’t quite figured out. The numbers don’t quite calculate to the precision I expect from a cycle computer. I have a feeling the Hall count is firing multiple times per revolution — like it has a FALLING state more than once.

Here is a quick JavaScript rendition of the data in a bar chart format. The RPMs are converted using this equation:

(((rpm * wheel circumference) / 1000) / 1000) * 60 = km/h

The next phase is to gather data on multiple days for the same course and comparing the results for analysis. I’m looking at developing an Adobe AIR Project which would allow me to keep an offline/online database. Getting real time data is another big incentive and I’d be looking at the XBee solution for that. Being able to record heart rate data and GPS/Digital Compass are also interesting but the limitations of the EEPROM don’t easily allow for recording of data that complex. So I think hooking up an SDCard is the next most probable option. I’ve already tried a USB adapter but the Arduino does not have USB host capabilities, so that didn’t work. There are options to get the USB host to work, but it involves purchasing another PCB. Finally, I don’t think any of this makes much sense without introducing a mapping API to add context to the data. So there’s still lots more to come!

Data Logger

Been working on a data logging application lately with the intentions of recording my biking sessions and displaying them on a mapping API. The general idea is to use the Hall sensor common in many RPM applications to record revolutions to the EEPROM onboard the Arduino.

I’m having a few issues getting the readings I need, namely the revolutions are not counting with any consistency. I think the issue is with the way Arduino loops through the script. Below is the first iteration of the code I’ve written.

NOTE: Script updated August 31, with Blalor’s suggestions. The RPM reading now works with a high rate of speed.

int pinHall = 2; //Hall Sensor
int pinLed = 13; //Indicator LED
int time = 10000; //EEPROM Write Interval
volatile int rpm = 0; //RPM Counter
 
void setup()
{
    pinMode(pinHall, INPUT);
    pinMode(pinLed, OUTPUT);
 
    Serial.begin(9600);
}
 
void loop()
{
    //Write to EEPROM at specified interval
    if ((millis() % time) == 0)
        writeEEPROM();
 
    //If Hall Sensor triggered then init the test
    attachInterrupt(1, incrementRPM, FALLING);
}
 
void incrementRPM()
{
        rpm++;
        digitalWrite(pinLed, HIGH);
 
        Serial.print("RPM: ");
        Serial.println(rpm);
}
 
void writeEEPROM()
{
    noInterrupts();
    Serial.print("EEPROM: ");
    Serial.println(rpm);
    rpm = 0;
    interrupts();
}

It appears to me like the checkReading() method isn’t firing with any consistency and therefore I’m not incrementing rpm properly. The writeEEPROM() method is firing on target, however I worry that the writing process may be delaying the rpm count.

Below is a Fritzing illustration of the circuit I’ve wired up:

Setup of the Data Logger

Suggestions? I’m open to any hints someone might have on how to structure this a little differently.

Expose saved passwords with Firebug

I’m filing this one under useful tricks. If you’ve got a password field the browser has saved and you can’t recall the text (and you’re too lazy to check the browser password save dialogue), fire up Firebug and press inspect. Target the password field and click. It will pull the HTML up into the screen. Click on type=”password” and change password to “text”. This should display the password in plaintext.

Passing the kid test

Passing the kid test

I’ve had the Solenoid project working for about a week and a half now, but the rain and lack of sunlight was getting in the way of making a video of everything in action. It worked out well because it gave me the chance to demonstrate the project to a number of visitors today, all at once. And, as the photo above demonstrates, the project passes the kid test.

Aligning the valves

Solenoid controller

Solenoids in circular pattern

The project is still in need of refinement, but I’m thinking that’s where things would get expensive. I’ve sourced out some new solenoids that could be used in a multimedia environment, I’m just unsure of the cost. The solenoids I have used are $7 washing machine parts. Specialty valves are bound to be more expensive. Some of the valves leak, and I’m pretty sure it’s not occurring in the sections I’ve sealed, the valves may be defective, or they may have a scratch in the plastic I created when I was reconfiguring the orientation of the connectors.

The brace you can see in the photo on the left was constructed to correctly position the hoses in sequence. the centre photo demonstrates the digital radio, Arduino, and transistor controller. The green wires leading out of frame are wired to the Solenoids. On the right, the solenoids are hooked up to the hoses. (All the photos have notes visible in Flickr)

In the above video, I’ve got the device filled with water, and directed through flexible hoses. Valves 2, 4, 6, 7, and 1 turn on. They then cycle off, leaving valve 1 open. The camera then pans up to the controller where it zooms in on the LEDs which I’m using as indicators of which valves are turned on. We then go through a test of all the valves on and off to demonstrate the flow when everything is open. A couple of the valves don’t work, and I’ve traced that back to a point on the controller circuit that I think has not been soldered correctly.

I think it would be important to note the projects out there that are doing the same thing. The Jeep waterfall was unveiled at a Detroit autoshow in 2000. This waterfall was published on the Make blog just the other day. MIT’s building made of water is scheduled to open at the 2008 Expo, they’ve hired Lumiartecnia to produce the valves. Also check out this water keyboard for its innovative use of sensing electric resistance when you touch the water to control the solenoids — in this case controlling air flow in a liquid. All these examples show that the envelope can be pushed that much further, and that there’s a large degree of possible variatons.

Still lots more ideas to play with, but many of these will be with the code. I’ve got some really interesting image processing ideas coming up.

Controlling 3DS Max from Arduino

My brother, Neil has been playing with an Arduino too. Here’s his latest script for controlling 3DS Max via Arduino:


Arduino connected to 3DS Max from Neil Marshall on Vimeo.

XBee Solenoid Controller

This Solenoid controller has been filled with a ton of small successes. Today I’m chalking up one more success to the list. I’ve got the XBee portion of the controller working. I had been working on this for a long time now, and the more I work on it the more I see the potential in this platform.


XBee Solenoid Controller from Eightlines on Vimeo.

The issues I had getting the XBee to work appear to be common based on the message board threads I have seen:

  • Upgrade your firmware. The listing on the website is not necessarily in order. I had assumed that since I had 1.0.8.4 I was one version off the most current. After reading the tech docs there were not that many features I appeared to be missing. The 1.0.A.n firmware appears to be a far more advanced stream, use it whenever possible. X-CTU appears to order this list in a more straightforward manner.
  • If you don’t have a USB-TTL adapter you can run an Arduino headless (remove the ATMega168 chip) to communicate directly to the XBee. Remove the chip with an IC extractor so you don’t bend the pins. Even better, you can leave the IC in place and communicate directly with the XBee via the Software Serial library. I ended up doing all three methods.
  • M. Yarza has an excellent sheild for the Diecimila. I’ve since switched over to the Arduino Nano, but I’m still using this one as a remote connection.
  • Build out Tom Igoe’s XBee Terminal to communicate with the XBee. It correctly sends the “+++” Command mode initialization without a carriage return (“\r”). It also displays results on a new line making for reading the settings much easier. I had started by using the OS X Shell but this was much easier. In fact, buy the book Making Things Talk. It explains all this stuff in plain english.
  • The RSSI Graphing was useful. You can see how this could be used to trangulate position of three+ Xbee’s.
  • Check out the XBee API Library for Processing written by Dan Shiffman and Rob Faludi. This makes the connections to the XBee API mode simple.
  • The XBee Analog Duplex script was somewhat confusing, but explains the methods used to communicate from peer to peer. Note, in all of the tutorials, I’d love to see more documentation stating which is the base XBee and which are the remotes. It gets confusing when you can’t figure out which is which.
  • Mark the radios themselves with indicators. I’ve added permanent marker dots to designate which XBee I’m looking at. Write down the corresponding configuration settings somewhere you can see them. It will save you polling the chip every time you need it.

A Simple redesign

If you can’t explain it simply, you don’t understand it.

 — Albert Einstein

Solenoid Prototype ReduxThe big issue I was having with the Solenoids was too much pressure. So while on a trip to Sudbury my Stepfather and I redesigned it. Well, I just told him what I was thinking of doing, and he came up with a much simpler way of doing it.

It’s a good thing too, because I’ve easily broke the budget on this project! So this design uses a cap from a sewage pipe, and some garden hose adaptors. No soldering required. The pressure in the system is regulated by the height of the pipe and how much water is pumped in. When the solenoids are open and the water is draining a plunger falls, triggering an aquarium pump to refill the container. It stops when the plunger rises past a certain point.

Yes, this thing is now an electronically controlled toilet.

Off to buy some more parts, wire up the XBee controller, and waterproof the remote breadboard.

Listo Destructo

So the guys at the electronics stores are loving me lately. I’m pretty good at destroying things. While electronics is a reasonably affordable hobby, I’ve managed to turn it into something a little more extreme. So without further adieu, here’s my “listo destructo”:

  • ATMega168 IC — I was using a headless Arduino as a Serial connection. Removing the ATMega IC each time I had to reprogram the XBee chip. Missing one vital component, an IC extractor. The extractor is cheap, at least cheaper than a replacement IC. If you bend the pins once removing the IC by hand, don’t do it again… and again… and again. In the end I bought a new ATMega168, IC extractor, and USB-TTL module so I wouldn’t have to extract it again. (But at this moment the Arduino is sitting on my desk headless)
  • HM55B Digital Compass — Red wire, Black wire. Its not that difficult is it? I thought it would save time to just use my existing precut Green wire to wire up the Digital Compass. Wasn’t getting the response I wanted. Turns out I had the positive and negative reversed. Whiff of the burning silicone smell. Definitely not getting the results I want anymore.
  • Battery Holder & Two AA’s — Smelled that awful burning smell again last night. Ripped out the power going to the XBee’s, Arduino, USB-TTL. Now I see wisps of smoke coming through the air but nothing’s plugged in. Start throwing papers off my desk to find the culprit. Where there’s smoke there’s two AA’s shorting out. Unplug the AA’s with my IC extractor and promise myself to wire up a two pin plug and clean the desk. (It’s still messy)
  • Countless plumbing prototypes — I’ve resoldered the Solenoid structure about ten times now. Still don’t have a final result I’m pleased with. Still have another design up my sleeve but I haven’t spawned the courage to start building it.
  • DVD Player — This one’s a good one, I’ve identified hundreds of components scavenged from a DVD Player that didn’t work anymore. IR Emitter and receiver, momentary switches, capacitors, RGB Jacks, connectors, motors, and a frickin’ laser beam. To think this DVD player cost $30. Easily aved me that cost of buying all these little parts at Radio Shack.
  • Inkjet printer — Again, tons of little components. Varistors, servos, gears, USB jack, power supply, zener diodes, etc. I’m thinking someone should make a website documenting all the components we can dig out of discarded things. Made a mental note to get rid of the plastic casing before my basement fills up with junk.
  • Nintendo Powerglove — I think I just heard hearts shatter. This one was destroyed about two years ago, but it counts in this list because I’m using the parts for one of my project. Recovered Ultrasound emittors and receivers, flex sensors, etc.

One of the guys at work said I probably shouldn’t put a price list on this. I have to agree, it would hurt too much. Oh and this is by no means a complete list, I intend to update as I keep making stupid mistakes.

Arthur Ganson - Sculpter

TED is always an excellent source of inspiration. Arthur Ganson has one of the more magical demonstrations I have ever seen. What a fabulous body of work!