Graphing has happened

Some hunting later and I’ve found a graphing module which suits my needs and hacked up the first version (only filters for ‘TEMP’, doesn’t accont for the sensor ID etc etc).

Oh and yes I’m reading the database as root due to some weirdness with the permissions which needs fixing.

https://rockhopper.vom.org.uk/~mark/wirelessthing/CreateSensorGraph.py

On the todo list for the whole project

  • Make the logger & grapher sensor ID aware
  • Handle “BAR” and “HUM” data types
  • Optionally handle the “BUTTON” type
  • Graph multiple temperature sensors onto a single graph
  • Rolling 24h graph; Day, Week and Month graphs
  • Move the Pi to a central location and get wlan0 working

IoT monitor script

As promised here’s the code I’ve currently got watching for incoming messages from the slice of pi.  It’s a hacked up version of the script from Fernando Lourenco’s instructable

The code pulling from Weather Underground is gone and I’ve shuffled things around a bit for my purposes.  No judging what I’ve done to the python if you please, I’m fresh in from years of abusing perl to meet my needs but have shifted to python for pi related stuff since solstice.

https://rockhopper.vom.org.uk/~mark/wirelessthing/monitor_sql.py

#!/usr/bin/env python
# --------------------------------------------------
from time import time, sleep, gmtime, strftime
import logging
import logging.handlers
import serial
import os
import os.path
import datetime
import sys
import MySQLdb as mdb
# --------------------------------------------------
# create table things ( 
#    thistime timestamp, 
#    ID varchar(2), 
#    type varchar(10), 
#    value float );
# --------------------------------------------------
DEVICE = '/dev/ttyAMA0'
BAUD = 9600
ser = serial.Serial(DEVICE, BAUD)
TIMEOUT = 10
# --------------------------------------------------
my_logger = logging.getLogger('MyLogger')
my_logger.setLevel(logging.INFO)
handler = logging.handlers.SysLogHandler(address = '/dev/log')
my_logger.addHandler(handler)

#my_logger.debug('this is debug')
#my_logger.critical('this is critical')
# --------------------------------------------------
def dumpResults( thingMsg ):
    print "Message : " + thingMsg
    readValue    = -100
    readID        = "99"
    readType    = "NONE"
    writeMe     = 0

    # Raw mesg logging
    thisTime = strftime("%Y-%m-%d %H:%M", gmtime())
    my_logger.info( "%s,%s\n" % ( thisTime, thingMsg ) )

    readID = thingMsg[1:3]
    if thingMsg[3:7] == "TEMP":
        writeMe = 1
        readType = "TEMP"
        readValue = thingMsg[7:]
    if thingMsg[3:7] == "BATT":
        writeMe = 1
        readType = "BATT"
        readValue = thingMsg[7:11]
        if readValue == "LOW":
            readValue = 0

    if writeMe:
        thisMsg = "%s,%s,%s,%s\n" % ( thisTime, readID, readType, readValue )
        with open( "logfile.txt", "a", 0 ) as thisFile:
            # Dump the information to file and setup the message
            thisTime = strftime("%Y-%m-%d %H:%M:%S", gmtime())
            thisFile.write( thisMsg )
            print( thisMsg )
        try:
            con = mdb.connect('192.168.0.250', 'monitor', 'password', 'houseLogging');
            with con:
                # SQL stuff
                cur = con.cursor()
                cur.execute( "insert into things values ( '%s', '%s', '%s', %s )" % ( thisTime, readID, readType, readValue ) ) 
                con.commit()

        except mdb.Error, e:
            print "Error %d: %s" % (e.args[0],e.args[1])
            my_logger.critical( 'Could not write to db - '+thisMsg )
            #sys.exit(1)    
    return( 1 )

def get_temp():
    global ser
    fim = time()+ TIMEOUT
    my_logger.debug('Attempting to get temp')
    while (time()<fim):
        n = ser.inWaiting()
        if n != 0:
            data = ser.read(n)
            nb_msg = len(data) / 12
            print "Number of message blocks " + str(nb_msg)
            for i in range (0, nb_msg):
                msg = data[i*12:(i+1)*12]
                print ">>" + msg
                dumpResults( msg )
        else:
            sleep(5)
    return {1}

# --------------------------------------------------
# main function
# This is where the program starts 
def main():
    while True:
        temperature = get_temp()


        #else:
        #    print ("temperature=ERROR-Timeout!")
            

if __name__=="__main__":
    main()
# --------------------------------------------------

Wireless Things or “Fighting with IoT”

So I’ve been hunting around for a decent system to build out some initial “smart home” type projects, focusing to start with on temperature, humidity and pressure.

As part of the excessive digging through google and testing out my ability to keep changing search parameters until something good pops up I came across the range of radio sensors from Ciseco (http://www.wirelessthings.net/) which merrily plug into the RPi and an Instructable which at least pointed in the right direction while missing some of the key steps which aren’t entirely clear from the product docs.

2016-01-07 17.28.09 2016-01-07 21.06.42 2016-01-07 21.06.52

Setup

First things first, install the hat onto your RPi of choice, I’ve installed on a RPi B+, but the forum indicates that it should work just as well on a RPi 2.  The hat isn’t stackable so the RPi 2 might be better in the long term by keeping access to some of the GPIO pins.

Pop the lid off the sensor, you’ll need access to the configure button later on.

You must either install the LaunchPad application on the RPi and be able to run an X based display either locally on the RPi or exported back to your working system of choice (I’m using on a Win7 machine running Xming).  This is needed to setup the sensor which arrives in a deep sleep and no hint as to what the device ID is.

Disable the serial console from the raspi-config application, or go through the manual steps to remove /dev/ttyAMA0 from /etc/inittab and /boot/cmdline, reboot as necessary.  Failure to do this blocks the ability to actually access the radio device.

Follow the LaunchPad documentation (PDF Doc from github), first setting up the encryption key for the radio device (I’m using the Slice of Radio for the RPi).  Then run the LaunchPad and follow the instructions for getting the Message Bridge running and setting up the sensor for the first time.

For inital testing purposes I’d recommend setting the reporting interval at 10 seconds so you’re not spending the entire evening waiting for the next poll.

Providing that everything has gone well, you’ve worked out the permission problem on /dev/ttyAMA0 (or are running with root privs) you should be seeing something like the following in minicom

aAATEMP019.0
aAAAWAKE----
aAABATT3.15-
aAASLEEPING-
aAATEMP019.1

The Message Bridge appears to be there to provide a pretty interface into the serial port, however if all you intend to do is listen for information landing on the serial port I would ditch it and just run a script in your language of choice and parse the data as it comes in.

To come

I need to add in some more monitors, work out the range on the sensor and position the monitorPi appropriately in the house, then some graphing to make it actually useful.

I’ll post the script I’m using later.

Links and other useful stuff

Language of things : https://www.wirelessthings.net/language-of-things
LaunchPad : https://www.wirelessthings.net/launchpad
Alternate Instructable

IR Trigger test #1

So, first admission, this doesn’t work yet.  In theory everything is perfect, checking the circuit shows the IR LED is firing, the test green LED goes “blip” and the red indicates when the code is off having a kip.  However the camera is sat there like a dumb lump ignoring the IR codes through either port (there’s one front and back on the K10D).

Back to pondering on what’s happening, or not happening, whether the IR can fire fast enough or if the IR LED is up to the job or indeed should I find the black chicken to wave over the circuit to finish it off.

Diagram of Pentax IR sequence

The circuit

The Code

/*
  Pentax firing code (file : blink_test2)

  Code used with modified setup with parallel LEDs to simulate standard LED
  and IR LED for triggering K10D camera

  References:
    PIR based firing code
    http://luckylarry.co.uk/arduino-projects/arduino-motion-triggered-camera/

    Pentax IR sequence
    http://www.picbasic.co.uk/forum/showthread.php?t=14182
 */

int pinLED   = 11;
int pinIRLED = 10;

// Normally the clock cycle is 38kHz
// halfCycle == (26.32×10-6s) / 2
int halfCycle = 13;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(pinIRLED, OUTPUT);     
  pinMode(pinLED, OUTPUT);     
}

// sets the pulse of the IR signal.
void pulseON(int pulseTime) {
  unsigned long endPulse = micros() + pulseTime;        // create the microseconds to pulse for
  while( micros() < endPulse) {
    digitalWrite(pinIRLED, HIGH);                       // turn IR on
    delayMicroseconds( halfCycle );                              // half the clock cycle for 38Khz (26.32×10-6s) - e.g. the 'on' part of our wave
    digitalWrite(pinIRLED, LOW);                        // turn IR off
    delayMicroseconds( halfCycle );                              // delay for the other half of the cycle to generate wave/ oscillation
  }
}

void pulseOFF(unsigned long startDelay) {
  // startDelay = startDelay * 1000;
  unsigned long endDelay = micros() + startDelay;       // create the microseconds to delay for
  while(micros() < endDelay);
}

void takePicture() {
  // Pentax K10D firing sequence
  // 13ms pulsing
  // 3ms silence
  // 1ms pulse + 1ms silence, looped seven times

  for (int i=0; i < 2; i++) {
    // Loop to fire the signal twice, just in case
    pulseON( 13000 );    // pulse = 13ms
    pulseOFF( 3000 );   // silence = 1ms
    // 1
    pulseON( 1000 );    // pulse = 1ms
    pulseOFF( 1000 );   // silence = 1ms
    // 2
    pulseON( 1000 );    // pulse = 1ms
    pulseOFF( 1000 );   // silence = 1ms
    // 3
    pulseON( 1000 );    // pulse = 1ms
    pulseOFF( 1000 );   // silence = 1ms
    // 4
    pulseON( 1000 );    // pulse = 1ms
    pulseOFF( 1000 );   // silence = 1ms
    // 5
    pulseON( 1000 );    // pulse = 1ms
    pulseOFF( 1000 );   // silence = 1ms
    // 6
    pulseON( 1000 );    // pulse = 1ms
    pulseOFF( 1000 );   // silence = 1ms
    // 7
    pulseON( 1000 );    // pulse = 1ms  
    pulseOFF( 1000 );   // silence = 1ms

    // slacking
    pulseOFF( 1000 );   // silence = 1ms
    pulseOFF( 1000 );   // silence = 1ms

    // defined slacking
    pulseOFF(400000);
  }
}

void blink( int thisPIN, int delayMe ) {

  digitalWrite( thisPIN, HIGH ); // Sleep LED on
  for (int i=0; i <= delayMe; i++) {
    delay( 950 );                  // 2 seconds twiddling our thumbs
    digitalWrite( thisPIN, LOW  ); // LED off
    delay( 50 );
    digitalWrite( thisPIN, HIGH ); // Sleep LED on
  }
  digitalWrite( thisPIN, LOW  ); // LED off
}

void LEDTest() {
  // Just here to prove the LEDs are up for measurement purposes.
  digitalWrite( pinIRLED, HIGH );
  digitalWrite( pinLED, HIGH );
  delay( 5000 );
  digitalWrite( pinIRLED, LOW );
  digitalWrite( pinLED, LOW );
  delay( 2000 );
}

void loop() {
  // LEDTest();

  // Click (hopefully)  
  takePicture();
  // Make the red LED go blinkitty.
  blink( pinLED, 5 );
  delay( 1000 );
  digitalWrite( pinLED, HIGH );
  delay( 500 );
  digitalWrite( pinLED, LOW );
  delay( 1000 );
}

Dances with electronics

In which your humble narrator manages to get his shiny new Arduino to make the Pentax K10D go “click”.

After some digging around I managed to find out how the remote cable on the K10D is setup, 2.5mm stereo jack.

Tip – Shutter
Ring – Focus
Sleave – Common

All nice and simple, close ring & sleave, watch the camera focus. Close tip and sleave, click. All nicely tested with a bit of wire and a nice fresh jack from Maplin. The important part of the circuit is I don’t want anything from the control side spilling over into the camera side, frying the camera would be a bad thing.

Enter the optocoupler, a nifty little device which allows control on one side to open or close a circuit on the other with no crossover of circuits.

The circuit

U1 – 4N25 optocoupler
R1 – 470 ohm
R2 – 560 ohm

Code

The code is effectively the blink test just slightly tweaked for the LED circuit, nothing exciting or sexy yet.

/*
K10D
Optocoupler based firing mechanism
*/

// Control PIN
int pinLED = 11;
int pinCAM = 10;

// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(pinLED, OUTPUT);
pinMode(pinCAM, OUTPUT);
}

void loop() {
delay( 1000 ); // Delay one second
digitalWrite(pinLED, HIGH);
digitalWrite(pinCAM, HIGH);
delay( 1000 ); // Delay one second
digitalWrite(pinLED, LOW);
digitalWrite(pinCAM, LOW);
}

Photos

Next… seeing if I can get the IR LED to fire the camera.