Tag: c

Chasing a Rollover Crash

I was reminded recently that when writing code in C, you have to take care to understand how variable are going to be used when declaring them. I was had just finished working on the code used to control the fire effects at The Crucible‘s Maker Faire 2013 booth when the system just seemed to come to a halt. That’s not quite what it was supposed to do.

The system was designed to have 3 24′ towers as the central part of the booth. On top of the towers would be accumulator based fire effects – a 24″ round sphere w/ a 2″ exhaust port, a 9″ x 24″ oblong tank w/ a massive 3″ pneumatic solenoid / exhaust and three smaller accumulators based on old fire extinguishers. The solenoids on the fire effects would all be controlled with an Arduino. The idea was that there would be no direct user interaction this year but the system would run automatically. Plug in the Arduino and away we go.

The code would run one of a number of possible sequences, pause between 30 and 90 seconds, randomly run the next sequence, pause . . . And it did that, most of the time. A couple of times after starting up the Arduino, several sequences would run and then nothing else would happen. Made me wonder if I had crashed the Arduino.

I added some Serial.print statements to the code to dump out details on what was happening internally and ran the code again. This time it ran without issue for almost 2 hours before coming to a halt. Looking at the output on the serial console showed that that pause value was -31438. Of course everything came to a halt, the system was attempting to pause negative 31,438 milliseconds! This didn’t make much sense until I reread the Arduino docs and saw that ints are 16 bit values. Of course it rolled over into a negative number.

Digging into the code I realized that I had used int’s in several places where an unsigned long was needed. Once fixed, all was right with the world and the system went on to work just fine for both days of the Maker Faire.

Perhaps I need to start writing these systems on a Raspberry Pi where I can use Python 😉

Tags : , ,

Arduino Switches

Part of the Exuro project includes the setup for a momentary contact switch that can be used to trigger the poofer. This way the system can either be run as a donation machine with the bill reader being used to trip the poofer or it can be manually controlled via a momentary contact switch.

My first attempt at connecting a switch was done by just connecting one switch terminal to ground and the other to the Arduino pin 2. The code was pretty straight forward:

int relay_state = LOW;
 
void toggle_relay()
{
  relay_state = !relay_state;
}
 
void setup() {
    Serial.begin(57600);
    attachInterrupt(0, toggle_relay, CHANGE); 
}

This had an number of unfortunate problems. The biggest one was that every once in a while the interrupt would be triggered all by itself . Without doing anything, the poofer relay would trigger. That wasn’t good. (The code for the poofer relay isn’t shown here.) It turns out that the problem was the electrical circuit. Since the switch was just connected between ground and pin 2, the wire running to the switch would act as an antenna and cause the hardware to think that the interrupt should be triggered. To resolve this problem, a 1k resistor was placed between pin 2 and ground. This ensured that the electrical signal traveling over the switch wire was stable.

The second annoying problem was that every once in a while an interrupt would be missed and the relay_state would be wrong. The toggle_relay code merely sets the relay_state to the inverse of what it was. That is if it’s a 1 then it becomes a 0 and if it’s a 0 then it becomes a 1. So if an interrupt is missed then the relay_state would be wrong and the poofer relay would be be the inverse of what it was supposed to be.

To resolve that, the toggle_relay code was changed to:

void toggle_relay()
{
  int val = digitalRead(2);
 
  if (val == LOW) {
    relay_state = LOW;
  } else {
    relay_state = HIGH;
  }
}

This way the relay_state is always set to the state of the switch as read off pin 2. With these two changes, adding a 1k resistor and directly reading the pin, the system is much more stable and works as needed. Yea!

Many thanks to CTP for the pointer to using a resister to stabilize the switch.

Tags : ,

Arduino and LEDs

I’m a software developer by training and one aspect of the software that I’ve always developed is that it just lives inside a computer or network. It doesn’t interact with the real world. That’s been well and good for the last 20 years but of late I’ve been wanting to break out and have software that I develop effect some change in the physical world.

There have been fits and starts where I’ve tried writing code for some embedded system or chip but the mountain of basic knowledge thats needed to get started has always been overwhelming. I would read some book (like Embedded System Design on a Shoestring ) and while the books make it seem easy to get going, the projects would always die a quick and quiet death. There’s nothing wrong with Embedded System Design on a Shoestring or any of the other books I tried, many people have used them quite successfully. Unfortunately it just never clicked for me.

But that’s all changed.

I recently discovered the Arduino platform. The system provides a small microprocessor, a bunch of I/O pins, a USB connection and a very easy to use IDE. The basic features of the platform allow for most any type of interaction with the physical world that I can currently envision. I’m sure there will be some scenario that it won’t support but for right now, I’m very happy with the capabilities.

One of the problems that I encountered in the past was connecting an embedded system to a host platform. It may have involved a vendor specific hardware or something else that wasn’t supported on my systems. The Arduino uses a USB port. After installing the needed drivers on my OS X system, I was able to connect the Arduino without any problems. Seems way easier than other solutions.

The place that I see the Arduino really shining is with the IDE. It’s different that any other IDE that I’ve used but the interface is really straight forward and very easy to use. I was able to quickly try out one of the sample C programs that turns an LED on and off again. The thing that really got me was that it compiled, loaded and ran on the first try. This was just brilliant. Easy to use and works the first time. Outstanding.

When a friend asked for help with a project he was doing and told me that he’d like to have 3 LEDs turning on and off in a random fashion, I knew that an Arduino would be the perfect tool to use. I was able to rework the sample code for turning an LED on and off to work on this project.

The idea behind the project is to have an LED inside of a wax pumpkin where the LED would turn on and off like the light on a firefly. There would be three pumpkins on a small platform, hence the three LEDs.

Here’s the code for the project:

/*
* firefly multibutt illumination
*
* Copyright (c) 2008 Peter Kropf. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
 
 
// all times are in milliseconds
#define SPIN_DELAY 10
 
#define ILLUMINATION_MAX       255
#define ILLUMINATION_MIN       0
#define ILLUMINATION_INCRIMENT 5
 
#define MAX_ILLUMINATION_TIME 2000
#define MIN_ILLUMINATION_TIME 500
 
#define MAX_DARK_TIME 10000
#define MIN_DARK_TIME 2000
 
 
#define LED_COUNT    6
#define LED_OFF      1
#define LED_ON       2
#define LED_SPINUP   3
#define LED_SPINDOWN 4
 
int led_pin[LED_COUNT]   = {3, 5, 6, 9, 10, 11};
int led_state[LED_COUNT] = {LED_OFF, LED_OFF, LED_OFF, LED_OFF, LED_OFF, LED_OFF};
int led_spin[LED_COUNT]  = {0, 0, 0, 0, 0, 0};
int led_level[LED_COUNT] = {0, 0, 0, 0, 0, 0};
 
 
void setup()
{
    randomSeed(analogRead(0));
}
 
 
void loop()
{
    for (int led = 0; led < LED_COUNT; led++) {
        switch (led_state[led]) {
        case LED_OFF:
            if (led_spin[led] > SPIN_DELAY) {
                led_spin[led] -= SPIN_DELAY;
            } else {
                led_state[led] = LED_SPINUP;
            }
            break;
 
        case LED_ON:
            if (led_spin[led] > SPIN_DELAY) {
                led_spin[led] -= SPIN_DELAY;
            } else {
                led_state[led] = LED_SPINDOWN;
            }
            break;
 
        case LED_SPINUP:
            if (led_level[led] < ILLUMINATION_MAX) {
                led_level[led] += ILLUMINATION_INCRIMENT;
            } else {
                led_level[led] = ILLUMINATION_MAX;
                led_state[led] = LED_ON;
                led_spin[led]  = random(MIN_ILLUMINATION_TIME, MAX_ILLUMINATION_TIME);
            }
            break;
 
        case LED_SPINDOWN:
            if (led_level[led] > ILLUMINATION_MIN) {
                led_level[led] -= ILLUMINATION_INCRIMENT;
            } else {
                led_level[led] = ILLUMINATION_MIN;
                led_state[led] = LED_OFF;
                led_spin[led]  = random(MIN_DARK_TIME, MAX_DARK_TIME);
            }
            break;
        }
 
        analogWrite(led_pin[led], led_level[led]);
    }
 
    delay(SPIN_DELAY);
}

The code is pretty straight forward. Each of the LEDs has a particular state that it’s in: off, on, spinning up or spinning down. That’s tracked in the led_state array. The led_level array holds the current level of illumination for each of the LEDs and the led_spin array holds the random amount of time that the LED will remain on or off. The rest of the code manages the arrays, sets the current level of the LEDs and waits for a small delay before doing it all over again.

Note that the code is currently setup to illuminate up to 6 LEDs since that’s the number of digital I/O lines on the Arduino that supports pulse width modulation, PWM. PWM is how the Arduino is able to vary the light level produced by the LEDs.

Here’s a short video I took while working on the LED timing. It shows only one LED instead of the three that were used in the finished project.

With this project successfully completed, I’m looking forward to my next project: having a flashing light turned on when a specific voicemail box on a Asterisk based phone system has messages waiting. This’ll involve connecting an Arduino to ethernet and controlling a 120v circuit. I can’t wait.

Tags : ,