Carl's Blog

Researcher. Mountaineer.

Archive for December, 2011

Arduino Gas Meter Sensor – Part 1

without comments

Motivation

My newly ordered Arduino Uno came in the post today so I got to start building with it!

An upcoming sensing deployment needs a way of sensing gas usage, so I’m building a basic sensor to measure it. Luckily, most gas meters have an LED pulse which goes off every so often and we can measure that. The one in my house informs me the light will pulse every 10 dm^3 of gas, so every time the second number from the right on the meter ticks the light will pulse. Failing this, the 0 on the right most dial is very reflective, and an LED can be used to reflect light from it.

As the extra bits I need to finish the sensor hasn’t come yet, namely the SD card shield and a battery pack, I can’t lock the sensor in my gas cupboard and give it a test, so for the time being I’m turning off my computer screens and lights, then flashing a red head torch at it to simulate a pulse.

Code

After a bit of internet trawling, I found an ace site laying down how to do the wiring for a digital light sensor (http://www.ladyada.net/learn/sensors/cds.html#bonus_reading_photocells_without_analog_pins). From that, I added in a method which took a rolling average of the last 5 measurements and outputted if the measured light was brighter than 110% of the average (not exactly statistical, but I intend for these to be locked in a dark box…).

Here’s what I have so far:

/* Based on: Photocell simple testing sketch. 
Connect one end of photocell to power, the other end to pin 2.
Then connect one end of a 0.1uF capacitor from pin 2 to ground 
For more information see www.ladyada.net/learn/sensors/cds.html */

// Number of measurements for averaging
const int AVERAGE_LENGTH = 5;

int photocellPin = 2;     // the LDR and cap are connected to pin2
int photocellReading;     // the digital reading
int ledPin = 13;    // you can just use the 'built in' LED

// for the circular buffer
int lastReadings[AVERAGE_LENGTH];
int average = 0;
int counter = 0;

void setup(void) {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600);

  // Initialise the array 
  for(int i=0;i<AVERAGE_LENGTH;i++) {
    lastReadings[i] = 0;
  }   
}

void loop(void) {
  // read the resistor using the RCtime technique
  photocellReading = RCtime(photocellPin);

  // Calculate rolling average
  ++counter %= AVERAGE_LENGTH;
  lastReadings[counter] = photocellReading;
  calcStats();
  int bound = average - (average/10);

  // Glorious debug
  Serial.print("Av = ");
  Serial.print(average);
  Serial.print(" = [");
  for(int i=0; i<AVERAGE_LENGTH;i++) {
    Serial.print(lastReadings[i]);
    Serial.print(",");
  }
  Serial.print("] ");
  if (photocellReading < bound) {
    Serial.print(" . RCtime reading = ");
    Serial.println(photocellReading);     // the raw analog reading
  } else {
    Serial.println();
  }

  delay(100);
}

// Calculates the new mean based on the last 20 measurements 
int calcStats() {

  // average
  average = 0;
  for(int i=0;i<AVERAGE_LENGTH;i++) {
    average += lastReadings[i];
  }
  average /= AVERAGE_LENGTH;
}

// Uses a digital pin to measure a resistor (like an FSR or photocell!)
// We do this by having the resistor feed current into a capacitor and
// counting how long it takes to get to Vcc/2 (for most arduinos, thats 2.5V)
int RCtime(int RCpin) {
  int reading = 0;  // start with 0

  // set the pin to an output and pull to LOW (ground)
  pinMode(RCpin, OUTPUT);
  digitalWrite(RCpin, LOW);

  // Now set the pin to an input and...
  pinMode(RCpin, INPUT);
  while (digitalRead(RCpin) == LOW) { // count how long it takes to rise up to HIGH
    reading++;      // increment to keep track of time 

    if (reading == 30000) {
      // if we got this far, the resistance is so high
      // its likely that nothing is connected! 
      break;           // leave the loop
    }
  }
  // OK either we maxed out at 30000 or hopefully got a reading, return the count

  return reading;
}

Next Steps

Well apart from the hardware I need, so issues need to be addressed which may or may not require extra hardware – as I’ve just thought of them.

  • DateTime equivalent object for when I register a pulse
  • Work out how long these will last on battery
  • Can I set an interrupt to go off when a digital value hits a threshold? Or does this require analogue input? If I can it would massively save on battery as no polling! But, it may require fiddly per-house calibration, which the brute force method ignores
  • Laser/3d Printed box and some form of mounting which will let me attach to anything. Probably going to be velcro.

Here’s a video of it working:

Written by carl

December 13th, 2011 at 5:37 pm

Posted in Academia,Tech,Tutorial

Tagged with , , ,

JSXGraph

without comments

I found this cool graphing JS library which has a wordpress plugin! It’s called JSXGraph and is rather nifty!. Here is an example graphs showing Facebook users over time.

Here’s the code:


<jsxgraph width="600" height="200" box="box">
var brd = JXG.JSXGraph.initBoard('box',
            {boundingbox: [-50, 900, 3000, -150],
             keepaspectratio:true,
             axis:true,
             grid:0,
             showNavigation:false});

brd.suspendUpdate();

//Points for graph
var p = [];
  p[0] = brd.create('point', [0,0], {style:6,name:""});
  p[1] = brd.create('point', [1665,100], {style:6,name:"100"});
  p[2] = brd.create('point', [1890,200], {style:6,name:"200"});
  p[3] = brd.create('point', [2050,300], {style:6,name:"300"});
  p[4] = brd.create('point', [2193,400], {style:6,name:"400"});
  p[5] = brd.create('point', [2359,500], {style:6,name:"500"});
  p[6] = brd.create('point', [2527,600], {style:6,name:"600"});
  p[7] = brd.create('point', [2672,700], {style:6,name:"700"});
  p[8] = brd.create('point', [2787,800], {style:6,name:"800"});

//Line
var graph = brd.create('curve',
              brd.neville(p),
              {strokeColor:'red',
               strokeWidth:5,
               strokeOpacity:0.5});

//Labels
xtxt = brd.create('text',[1400,-110, 'Days Online'], {fontSize:12});
ytxt = brd.create('text',[10,850, 'Millions of users'], {fontSize:12});

brd.unsuspendUpdate();
</jsxgraph>

Written by carl

December 8th, 2011 at 6:30 pm

Posted in Tech,Tutorial

Tagged with ,

Programming languages course

without comments

So I ran a talk on learning programming languages last week. It was the second time I had done that particular talk, and in this case the hardware setup went smoothly – as it was done by Stephen Wattam the CSLU VP.

We had a pretty good turn out, mostly of year year undergraduate students who so far had only played with a little C. I took pictures of everyone hard at work doing their task … well, ok. They were mostly on tryruby.org which was even better.

It showed that they had an interest in a new language which is fairly good at prototyping and will allow them to try out their ideas fast. I may have semi pushed them on to it in my talk, so I’m glad they were listening. No one tried learning Haskell though, but then I’ll drop in on everyone next term and see how they are doing. The slides and some info for my talk can be found  at the CSLU site.

On a side note … My Instagram tshirt came! I’m not sure if I’ll ever wear it outside as it’s a bit long, but still!

Written by carl

December 5th, 2011 at 6:12 pm

Posted in CSLU,Ruby

Tagged with , , , ,