Reading a gas meter with an Arduino, Part 2

Standard

In Part 1 of Reading a Gas Meter with an Arduino, I outlined in brief what I wanted to achieve and how I thought I might go about it.

In this second article, I detail my experiences using the photo-reflector purchased from Maplin. Since I haven’t yet created any circuits more complicated than some basic traffic lights, this would be my first real experience using this type of sensor in a circuit. I had a feeling when starting that I’d be needing to use the pull-down resistor type set-up on one of the sensor pins, and it turns out I was right – special thanks to everyone on the Arduino Forums for assisting.

It turns out, with a little help from the Arduino forums, it was pretty easy (it always is when you know how!). Having first connected the sensor to a digital input, and reading the value from the digital pin in the loop() method, it quickly became clear that trying to count one pass of the reflective disc on the gas meter in this manner wouldn’t work. Adding delay statements wouldn’t work either – I might miss the disc moving past the sensor as the speed it rotates is variable (depending on the amount of gas being consumed). If you’re not sure why this won’t work, think of the Arduino and photo-reflector as a high-speed camera: taking many frames per second the second a reflection is detected. You might receive – for argument’s sake – 1,000 ‘frames’ while the gas meter disc is passing under the sensor, but how do you know – in code – which one to ‘act’ upon and which to ignore? Clearly, you can’t send a thousand ‘pulses’ to your data logger, because your data will all be wrong. This dilemma only came up because in my limited knowledge of the Arduino and the C++ implementation it uses meant that I was trying to stuff all this “detection logic” into the loop() statement.

Enter the Hardware Interrupt… the simplest answer to the problem

In my traditional .NET coding, I’d simply use an ‘event’ to achieve what I wanted, and then write some minimal state-checking code. On the Arduino, however, I have learned that the hardware interrupt is basically very similar (but a bit cooler, actually!). What’s even better is that I don’t even need to bother with any complex code to determine whether or not the sensor is still sensing the same revolution of the disc: when you initialise the interrupt, you state whether you want it to be triggered when a certain condition is met, i.e. any state change, from low to high, from high to low etc. This really nifty feature is exactly what I needed.

Refer to line 7 of the sketch sample below to see how easy it is to register the interrupt. In this example, I simply use the interrupt to turn on an LED whenever the photo-reflector is LOW, i.e. it is detecting a reflection. In later articles, I’ll be changing this to do some logging. The reason for this, is simply that this hardware interrupt is fired only ONCE – and not again until the state changes.

Finding out what’s going on under the hood

I use the Serial library to output ‘debug’ information to help me figure out what’s happening inside the Arduino. It’s not necessary for reading values from the photo-reflector, and at a later stage in this project I’ll probably remove the debug information as I’ll need to be sending the information that is read from the gas meter back to the PC somehow.

The Sketch


int ledPin = 13;                     // select the pin for the LED
volatile int state = LOW;            // remember the current state

void setup() {
  pinMode(ledPin, OUTPUT);            // declare the ledPin as an OUTPUT
  Serial.begin(9600);
  attachInterrupt(0, check, CHANGE);  // attach an interrupt (interrupt 0 = digital pin 2)
}

void loop() {
  digitalWrite(ledPin, state);
}

void check() {    // Checks for feedback from the phototransistor
  state = !state;
  Serial.print("State changed to: ");
  Serial.print(state);
  Serial.print(".\n");
}

Photograph

Schematic

I have attempted to re-create the above in schematic form, using Fritzing. As mentioned in earlier posts, Fritzing is a beta tool and it doesn’t currently have symbols for all the electrical components one might use. Having searched the web for a suitable circuit symbol for my photoreflector, I can’t find one. I suspect that because, although the photo-reflector is an ‘all-in-one’ design, it is actually just comprised of an LED and a photosensitive transistor:

Arduino schematic showing placement of maplin photo-reflector

Next Steps…

Now that I have figured out how to interpret a value from a photo-reflector within the Arduino, what I need to do is build a prototype sensor ‘bar’ that I can mount to the gas meter. The next post on this subject will probably be just that – how I made (or am making!) the sensor bar. One point I’ll be bearing in mind is that I’d like to site the Arduino remotely from the sensor arm, and I’d like to be able to collect data from other sensors attached to the same board. Thinking ‘out loud’ as I go really, but I promise to write a proper ‘How-To’ article when I’m on the other side of the learning curve!

Advertisements

Reading a gas meter with an Arduino, Part 1

Standard

Ok, since I received my Arduino, I have been playing around with some simple projects in an effort to understand more about the way the Arduino board works, and to gather some of the basic electronic skills necessary to work with it. So now, I want to turn my attention to something a little more in tune with my reasons for actually buying the Arduino in the first place: home automation.

After a trip to the gas meter cupboard, unfortunately my gas meter is not the type that outputs a digital ‘pulse’ at regular intervals: it’s an odometer type. However, usefully, I did discover that it has a little reflective disc between the digit ‘6’ and ‘7’, which could presumably be read with some kind of reflection sensor. I did some digging around to see who else on the web has built their own gas-meter readers, and found BWired.nl. This is an awesome site – certainly way beyond what most of us mere mortals could aspire to for our home automation setups! Anyway, on this page, the owner describes using a ‘CNY70 Reflective Optical Sensor with Transistor Output’. After some digging around, I found that Maplin has something which (I think) might be similar here – it’s called “Photoreflector SY-CR102” and it costs £0.79! This neat little device includes a photo-emitting diode and a phototransistor, which should do the trick.

I’ll go down to the store and pickup the Photoreflector later today, and have a go at playing with it over the coming days. Essentially what I need to do is figure out how the sensor responds whenever the reflective disk of the gas meter passes the sensor aperture. In theory then, at least, it’s then going to be a case of simply counting the ‘pulses’ from the sensor. Once I can do that, given that the dial will rotate once a known quantity of gas has been consumed, I should be able to create a very accurate sensor device that is synchronous with the gas meter itself.

Here’s how I imagine the project to unfold:

I’m quite excited about this – it’s such a steep learning curve though! 🙂

/Rich

Arduino Traffic Lights – Take Two

Standard

Ok, so after starting my first project (yesterday: Arduino timer-based traffic lights), I decided to expand upon the concept today. In keeping with the traffic light theme (it seemed like a good idea!), I added a few extra LEDs and a digital switch so that someone can ‘cross the road’ by pressing the button to change the lights to red.

Scenario: traffic and crossing lights

Instead of having the lights cycle from red – amber – green infinitely as in the previous project, this time I wanted the lights to go through a fake initialise sequence (i.e. turn on the Arduino board, have the red LED blink 5 times, then have all three traffic lights switch on, as an example) then to step to amber, then green. To make things a little more interesting, I also added two new LEDs: a ‘Green Man’ and a ‘Red Man’ light – to help our little pedestrians figure out when it’s safe to cross the road. 🙂

The traffic lights should remain on green until a ‘pedestrian’ presses the crossing button, at which point we should go to amber, then red. We should wait a little bit for the pedestrian to cross, blink the green man light a few times to indicate that the pedestrian needs to get out of the road, followed by blinking the Amber light a few times to alert the traffic to get ready, then go back to a green traffic light and a red man light.

The lights and crossing should obey the following rules:

  • When a red traffic light is displayed, the green man light should be on
  • When a green traffic light is displayed, the red man light should be on

Common sense really! 🙂

So our sequence of events needs to resemble the following:

  • Initialise the lights (blink red LED 5 times, then turn on all three traffic lights)
  • Show amber traffic light
  • Show green traffic light and wait on green
    • When the crossing button is pressed:
      • Show the amber traffic light
      • Show the red traffic light
      • Show the green man
      • Wait a preset amount of time to let the pedestrians cross
      • Blink the green man light a few times
      • Blink the amber traffic light a few times
      • Extinguish the green man light and turn on the red man light
    • Resume green traffic light
    • Repeat!

After about a half hour tinkering, I’d stripped the breadboard and added a digital switch and two new LEDs (for the crossing indicators). The Arduino sketch was modified to include controls for the crossing LEDs, and the continuous alternating traffic light sequence was replaced with a solid green LED (which remains green until the switch is pressed).

A quick observation: the digital switch and pull-down resistors

My switch is connected to a digital input. Initially, this resulted in an intermittent switch: picking up HIGH or LOW sometimes worked, and sometimes didn’t. I figured out after a little bit of Googling that I actually needed to connect the switch in a mini ‘pull-down resistor circuit’ which now works brilliantly. I will admit, I have yet to fully understand the principles behind why this works, but that’s something I will continue to look into (besides wanting to just have fun with the Arduino, one of my goals is to learn more about the basic electrical principles regarding physical computing).

The board setup:

Pedestrian Crossing with Traffic Lights

And the wiring diagram:

Now then! The lovely Fritzing program I used to create the above diagram (which I absolutely love), is so new, that it doesn’t (yet) have a switch symbol for the type of switch I have used. Hence, with my very limited knowledge of electrical schematics, I’ve used the standard switch symbol and tried to represent how I’ve actually wired the switch up. Here’s a close-up photograph of what I’ve actually done, in the hopes that someone can correct me:

Switch Detail

I found this technique here.

Video:

The Sketch

This is a bit messy at the moment, but I’ll clean it up tomorrow (I’ve used generic on/off methods to set light states instead of just using a ‘setRed’ or ‘setGreen’ method, which encapsulates the code to extinguish lights that aren’t used by that mode, for instance) and also remove some of the ‘debugging’ serial code I wrote:

// Configure the light pins
int redLed = 2;
int yelLed = 3;
int grnLed = 4;
int redManLed = 8;
int grnManLed = 7;

// Program variables
int lightState = 0;
int crossingRequestSwitchPin = 13; // The pin our crossing button is connected to
int switchStatePin = 6;

// Traffic Light Variables
int timerDelayTime = 3000; // The ms between each light change when running in timer mode
int crossingTime = 5000;

// Setup
void setup() {
pinMode(redLed, OUTPUT);
pinMode(yelLed, OUTPUT);
pinMode(grnLed, OUTPUT);
pinMode(switchStatePin, OUTPUT);
pinMode(grnManLed, OUTPUT);
pinMode(redManLed, OUTPUT);
pinMode(crossingRequestSwitchPin, INPUT);
Serial.begin(9600); // Initialise the serial port for debugging
changeLightState(-1); // Set the light state to “initialise”.
}

void loop() {
if (lightState == -1) {
doBeginSequence();
changeLightState(0); // Now our “initialise” phase is done, increment the light state
}
if (lightState == 0) {
lightOn(redLed);
lightOn(yelLed);
lightOn(grnLed);
delay(1500);
startLightsOnTimer();
}
}

void doBeginSequence() { // Handles the lighting sequence for lights that have just been started.
Serial.println(“Begin sequence was requested.”);
blinkLed(redLed, 5, 500);
}

void startLightsOnTimer() {

Serial.println(“Starting timed-sequence.”);
allLightsOff(); // Turn all lights off

while ( lightState == 0 ) {

lightOn(grnLed);
lightOn(redManLed);

/*lightOn(redLed);
delay(timerDelayTime);
lightOn(yelLed);
delay(timerDelayTime);
lightOff(redLed);
lightOff(yelLed);
lightOn(grnLed);
*/

// When the light is green, allow anyone to signal for a crossing request
int request = checkForCrossingRequest();
if (request > 0) {
Serial.println(“Beginning crossing sequence…\n”);
beginCrossing();
}

}

}

// Switch lights to red for a crossing sequence
void beginCrossing() {

changeLightState(1); // Indicate that we’re beginning a crossing sequence

// Goto Amber…
allLightsOff();
lightOn(yelLed);
delay(timerDelayTime);

// Goto Red, and wait for crossingTime milliseconds before continuing…
lightOff(redManLed);
lightOff(yelLed);
lightOn(redLed);
lightOn(grnManLed);
delay(crossingTime);
blinkLed(grnManLed, 5, 500);

// Blink the Yellow Led…
lightOff(redLed);
blinkLed(yelLed, 5, 500); // Blink the Yellow LED 5 times to signal to drivers to proceed if the way is clear
lightOn(grnLed);
lightOff(grnManLed);
changeLightState(0); // Change back to timer mode lighting

}

// Check for crossing button push
int checkForCrossingRequest() {
int val = digitalRead(crossingRequestSwitchPin);
if (val == HIGH) {
Serial.println(“*** Crossing Request Received ***\n”);
return 1; // Crossing requested
} else {
return 0;
}
}

// Helper functions
void lightOn(int pin) { // Turn an LED on
digitalWrite(pin, HIGH);
Serial.print(“Set pin “);
Serial.print(pin);
Serial.print(” to HIGH.\n”);
}

void allLightsOff() { // Turns all LEDs off
digitalWrite(redLed, LOW);
digitalWrite(yelLed, LOW);
digitalWrite(grnLed, LOW);
Serial.println(“All lights turned OFF.\n”);
}

void lightOff(int pin) { // Turn an LED off
digitalWrite(pin, LOW);
Serial.print(“Set pin “);
Serial.print(pin);
Serial.print(” to LOW.\n”);
}

void blinkLed(int pin, int timesToBlink, int blinkIntervalMs) { // Blinks the LED pin the set number of times
Serial.print(“Beginning blink sequence… Pin “);
Serial.print(pin);
Serial.print(“, “);
Serial.print(timesToBlink);
Serial.print(” times with a “);
Serial.print(blinkIntervalMs);
Serial.println(“ms interval between each blink.\n”);

for (int i=0; i <= timesToBlink; i++) { digitalWrite(pin, HIGH); delay(blinkIntervalMs); digitalWrite(pin, LOW); delay(blinkIntervalMs); } } void changeLightState(int newLightState) { // Changes the current lightState Serial.print("Light state changed from "); Serial.print(lightState); Serial.print(" to "); Serial.print(newLightState); Serial.println(".\n"); lightState = newLightState; } [/sourcecode] So! There you have it... My second Arduino project... or, rather an extension of the first! Thanks for reading! /Rich

Introducing Prezzylist – Always Get What You Wish For

Standard

I thought it was about time I introduced you to a wonderful project I have been working on recently, along with two other indviduals (one of whom had the idea!). Together we have worked to relaunch Prezzylist, a free web site that allows you to create lists of presents (or ‘Prezzy lists’) that you can share with your friends (think: a central place to store wish lists for all occasions, that work with nearly all online retailers and traditional high-street stores).

Prezzylist works by allowing you to list presents or gifts that can be bought online, or on the high street. You simply list the item name, it’s price (at the time you created your list), and if it’s available online, the URL where others can find it. Depending on your privacy settings, friends can search for your lists online and have the option of ‘reserving’ items that you desire, or downloading and printing your Prezzylist to go shopping with.

You can create as many lists as you want, and set privacy options (so you can create private lists, and choose who gets to view certain lists), and you can even ‘buddy’ with your friends.

Prezzylist is currently receiving between 10-20 new registrations per day, and we’re still very much in the early stages of where we would like to take the product, however initial takeup has been more than encouraging. With much more to follow around the social element, and a host of new apps and features planned, be sure to head there today – and sign up for your free Prezzylist account!

😉

Announcing project “Datazzle” – and connecting with CurrentCost

Standard

Today I have been working on the project I mentioned a few weeks back, to collect, store and graph data sent from my current cost unit. If you have been following this blog, you will know that I plan to make the service available to anyone, for free, so that they can do the same.

As I intend to release this service to the community in the coming months, I realised I couldn’t keep referring to the project as ‘the project’, so from here on in it has been lovingly code-named ‘Datazzle’ (say: dah-taz-all).

Ok, so what’s the deal? What is it? How will it work?

Datazzle will comprise initially of an XML web service (for receiving your sensor data)  and a companion web site, or web front-end, that will allow you to view all your sensor data from one place, graph it, and also let you define various options for sharing your data with others.

To get started, all one will have to do is sign-up for a free account, define at least one ‘environment’ (eg. “My House”) with one location inside it (eg. “Living Room”), and setup at least one sensor (eg. “Temperature sensor”). That’s it. It’s all point-and-click.

Then, you’ve got to get your hands dirty because it’s up to you to send compatible XML data to the API on a regular basis. To help you along the way, I will be releasing an open-source version of my test code (cleaned-up a little, of course!) that will initially connect to the current cost, take your API key, User Id and the environment configuration variables, and publish the data for you. This will basically convert the current cost XML data into XML that conforms to the “Datazzle Data Specification”, which is basically just a tweaked-version of the EEML standard.

You can use Datazzle to store data from ANY compliant device, not just the Current Cost…

Datazzle will be device-agnostic, meaning that you can use it to connect any physical or virtual sensor data (eg output from something like Second Life), and it will store it and allow you to navigate your data in a variety of different ways. From one Datazzle account, you will be able to setup multiple environments, and locations within those environments, to store data from as many sensors as you wish. You’ll get a ‘sensor dashboard’ to maintain all your sensors, from multiple locations.

Introducing the Datazzle Data Specification… feedback please 🙂

Although still only in the design phase, I have decided to base my XML format loosely around the EEML specification, already well established for sharing sensor data. The web service includes a web front-end that lets users setup and configure their devices and set a bunch of parameters (such as sensor types and locations) from the GUI, so the EEML that is sent to the server need only specify the corresponding ID values, instead of the actual string values every time. Take a look at the snippet to see what I mean:

<datazzle>
  <userId>123456</userId>
  <apiKey>00000000-0000-0000-0000-000000000000</apiKey>
   <eeml>
    <environment updated="2008-10-12T16:35:42" creator="" id="3456789">
      <location id="123" />
      <data sensorId="101"> <!-- Current temperature, in degrees celsius -->
       <value>28.7</value>
      </data>
      <data sensorId="102"> <!-- Current energy consumption, in watts -->
       <value>2692</value>
      </data>
    </environment>
  </eeml>
</datazzle>

You will note that there is less EEML here than in the specification and that some of the attributes have changed. I have also added “userId” and “apiKey” elements. A lof of the data included in the EEML specification has been ommitted from the EEML element you are required to send to the server, simply because you have already specified it once – when you were setting your sensor up online (i.e. the status of your feed, a description, a title, any links/copyright data etc, latitude and longitude, tags for each <data/> element and the units of measure).

Of course, when the service is available, there will be a nice UI to help you get up and running with the XML standard as quickly as possible (and a lot more documentation!). For now though, that’s all the info I have for you. If anyone has any thoughts or ideas, please feel free to comment – I’m open to adapting the specification to suit the needs of the community.

Here’s a quick preview of the tray app monitor that lets you see what data the current cost is sending to your computer, and the converted output being sent to Datazzle:

I will try to post more information and screenshots on the application and the service soon.

Thanks for reading!

Second CurrentCost display has arrived

Standard

Happy to report that my second CurrentCost display has arrived, just a day after ordering it off eBay from CurrentCost themselves. A bargain at just £15 plus postage, it enables me to have this unit on our kitchen worktop, while the other is connected to my server ready to connect to the web service I am developing.

A quick update on that: having had so much fun so far creating an infrastructure capable of handling the current cost data, I have decided to extend it so that other users from around the world can publish and share their sensor data, not just from the current cost. I know, I know… there’s also the very good Pachube out there for those who are inclined to use it, but I figured what I’d like to do is offer something a bit more consumer friendly, with graphing and social features as well.

If anyone is interested in helping me test this out (or even in lending a hand with the design and build), do get in touch. More on the current project progress soon…