Follow the Orange Paint path

It was a nice autumn day so we decided to go on a bit of a hike. We  have a wealth of choices here and we thought to try a bit more of the Sörmlandsleden (in english) which is a 1000km trail to the south of Stockholm. Its lovingly maintained by a group of volunteers who as part of that mark it with orange paint. The trail is generally pretty good for hiking with paths near the trailheads leading to more rugged territory. You can get to the trailheads on public transport and there are something like 100 sections. At various places along the trail there is access to fresh water and shelters. And you can exercise your Swedish ‘right to roam‘ and camp.

sormslandsleden2

For 200 SEK you can join and get access to the maps which are very good and a worthwhile investment for your own safety and to keep the volunteers supplied with paint and lumber.

As you can see, the trail is well marked and where necessary there are bridges across any watercourses that you need to traverse.

sormslandsleden1 sormslandsleden3

We have hiked other parts but today we decided to start at the beginning and hike stages 1 & 2, totaling about 15km and taking about 4 hours. It was great to get out and experience the fresh air and the countryside.

sormslandsleden4 sormslandleden5

To get to the trailhead we took the T-bana to Björkhagen and to return we caught the 573 bus from Nyfors. There are circular routes, although a lot are linear but they tend to go between public transport locations so you can leave the car at home.

Thanks to all those volunteers who maintain this fabulous asset that is so accessible.

Real Time Clock accuracy

I have a real time clock attached to my RPi and I thought that it would be an interesting project to monitor its accuracy. The clock I am using is a Maxim DS1307… this type does not have any fancy compensation, but from what I read it should be around 10ppm.

So I built a program for monitoring the clock and comparing it with a reference. For a reference I am using the RPi system clock slaved to NTP… which should provide synchronisation to within a few milliseconds. The linux clock of course reports to quite a fine resolution (1 microsecond ticks)… but the DS1307 only reads out to the 1 second level which means on the face of it that a fairly long run would be needed to make an estimate of the clock accuracy.

Here is a table of expected deviation in seconds for clocks of various accuracies… as you can see we would have to wait for 10 days to get a result from a 10ppm clock with a significant offset. The problem being after 1 or 2 days the error might be 1 second, and the resolution of the measurement is +/-1 second… not great for measuring drift.

clockerrortheory1

So I thought a bit more about the problem of measuring. We actually have more info than this as we can measure the time on the RPi to a resolution of 1 microsecond and we can measure frequently. So while we run we can compare the time from the real time clock to that more accurate clock. (it is accurate as it is set from ntp and it has finer resolution). Of course the rounding implied in the RTC result compared to the system clock will give  a a false sense of accuracy.  So what I decided to do was to round both and compare to only 1 second resolution. You might ask how does this help? Well what we can do now is see the statistics of the comparison at 1 second resolution and use them to see the drift rate.

First we set the RTC to be the same as the system clock set by ntp. Then we read both and compare the seconds. Initially we will get an answer of 0, with the occasional -1 or 1 due to the rounding. Gradually as the RTC drifts the number of reads that say 1 will increase (assuming it is running slower than the system time.This gives us an estimate of how far apart they are. In effect we are looking at the ‘density’ of rounding transitions up or down over time to estimate the drift.

This looks like the following;

The y axis is the delta and the x axis is the run time… here I picked 256 samples of a part of the run about 1000 readings into the process.

clockerrortheory2

So now time for a  test run. I started the program and let it log to a file. Unfortunately after about 2 days the RPi crashed … but after all that was the point of looking at this method… to avoid the need for very long runs. Here is the picture of the just over 11,000 points taken every 15 seconds.

clockerrortheory3

Now we can see a clear trend of drift between the clocks. There is a fair amount of noise due to the rounding jitter so we’ll need some filtering a to derive a trend. I applied an average of the offset (last 64, 128,  256 and 512 samples), calculated the sliding average  and plotted a trend in excel to see if this technique would work. Here is the result:

clockerrortheory4

It looks like we have about 8ppm drift from this result. of course we could try estimate to more accuracy, but that would require more detailed examination of the filter length and noisiness of the signal to come up with something reliable… I did a quick check of the results and 1ppm seemed to be about the right level of resolution as with the different filters the slope was varying by about 0.5ppm. While running this test  the temperature variation was about +/- 2C and the ntp was locked to a stratum 2 clock.

So in conclusion, in 2 days we managed to get an estimate of clock drift using the trend line of the offsets even though the absolute drift was only 2 seconds and the resolution of the RTC is 1 second. Next we need to test this for a longer period of time, and build in the filters and calculations to remove the manual processing steps in excel. Plus look more into the ntp stats for the local clock drift compensation as we are measuring versus the system clock slaved to ntp.

Here is the code for the program.


#!/usr/bin/env python
#
# ClockTest Program
# original and driver by John C. Shovic, SwitchDoc Labs
# 07/10/2014
# Modified by hobbyistdave, Oct 2015
#
# imports

import sys
#sys.path.append ('./lib')              # path for local libraries
import time
import datetime
import requests   # HTTP for humans
                  # by Kenneth Reitz  docs.python-requests.org
import SDL_DS1307 # the RTC driver

# setup the info needed to send the results to thingspeak

thingspeakurl = "https://api.thingspeak.com/update"   # url for sending updates to thingspeak
apikey = "1234567890123456"     # thingspeak api address for this channel 
ioTInterval = 15                # interval for maximum writes to thingspeak in seconds (min interval is 15 seconds)
url = thingspeakurl

def writeToIoT(payload):        # function to write to IoT
    try :
        r = requests.get(url, params=payload)  # send to thingspeak
        print time.time(), "  ", r.text, "  ", ntpSecs ,"   ", rtcSecs ,"   ", deltaSecs ,"      ", runTime , " ", r.status_code  
        #r.text will be the data point number
        #r.status code should be 200 if the page posted correctly
    except requests.exceptions as e :
            print e # some simple error trapping to avoid the program timing out
    except requests.exceptions.ConnectionError as e1 :
            print e1 # some simple error trapping if the connection is lost
    return

# Main Program

print ""
print "ClockTest, hobbyistdave"
print ""
print "Program Started at: "+ time.strftime("%Y-%m-%d %H:%M:%S")

filename = time.strftime("%Y-%m-%d%H:%M:%SRTCTest") + ".txt"
startTime = datetime.datetime.utcnow()
#print startTime
print "Writing system time to RTC to make them equal at start of test"
ds1307 = SDL_DS1307.SDL_DS1307(1, 0x68)
ds1307.write_now()


try :    # wrapper to allow clean exit
    # now setup the command shell for printing the results
    print " "
    print "---------------------------------------------------------------------------"
    print " "
    
# Main Loop - sleeps 1 seconds, then reads and prints values of all clocks
# checks time since last update and writes to IoT

    startTime = datetime.datetime.now()
    print "startTime : ", startTime
    print " "

    print "---------------------------------------------------------------------------"
    print "  Time          Point    NTP     RTC   Delta    Runtime         Response   "
    print "  (s)                   (s)     (s)   (s)                                  "
    print "---------------------------------------------------------------------------"

    ioTTimeStamp = time.time()
    lastDelta=0   # initialise delta
    while True:

        ntpTime = datetime.datetime.now()
        rtcTime = ds1307.read_datetime()
        #deltaTime = ntpTime - rtcTime
        ntpSecs = datetime.datetime.now().strftime('%S')
        rtcSecs = rtcTime.strftime('%S')
        #print ntpTime, "  ", rtcTime, "  ", deltaTime
        deltaSecs =  int(ntpSecs)  - int(rtcSecs)
        if lastDelta < 30 and deltaSecs <-30 : # fix instances where the seconds wrap across a minute boundary deltaSecs = deltaSecs+60 # we dont expect time to drift apart by more than 30 seconds elif lastDelta > -30 and deltaSecs >30 :
            deltaSecs = deltaSecs-60
        lastDelta = deltaSecs  # remeber the last delta

        runTime = ntpTime - startTime

        payload = {'key' : apikey, 'field1' : ntpTime , 'field2' : rtcTime , 'field3' : deltaSecs , 'field4' : runTime  } # make the payload
        if time.time() >= (ioTTimeStamp + ioTInterval):  #check if enough time has passed before updating thingspeak
            writeToIoT(payload)
            ioTTimeStamp = time.time()
        else:
            time.sleep(0.001)

        time.sleep(1)

except KeyboardInterrupt:
    print " "
    print "Exiting program due to Keyboard Interrupt"
    print " "
    time.sleep (1)
finally:
    print "----------- The End----------------"



Mirroring command line output to a file

Quite often when you are running a program, you would like to capture its output into a file for later analysis. I want to do this for a real time clock accuracy monitoring project that I am in process of running. Of course you can write to the file directly from your program, but there is a neat trick to both write to the standard command output, capture to a file and monitor the output at the same time.

First you run your program with the output redirected into a file;


sudo python -u myprog.py > proglog.txt

The > is the redirect and the python -u switch means do not buffer. Without this you will not see your log file change for a while as the OS will buffer a significant amount of the output.  When you write directly to the command line the buffer is flushed every line, but not when you redirect. In the Debian wheezy used on the RPi the buffer is 4kbytes so if you redirect to a file you wont see output for a while if you don’t use the -u switch. This is a common problem and makes for a confusing time as you see the log file size stays at 0 while the buffer fills.

Then in another terminal window use;


tail -f proglog.txt

You will now see the last 10 lines of the file that is being created with the output. As the file is updated the ‘tail’ will ‘follow’ it continuously so you get the benefit of writing to the console and of logging to a file. You can increase the number of lines tailed with the -n switch followed by the number of lines you require.

Another way you can do this is to ‘tee’ the output so that the file is generated and the command line shows in one terminal.

sudo python -u myprog.py  | tee proglog.txt

or

sudo python -u myprog.py 2>&1 | tee proglog.txt 

The second version with 2>&1 sends both the standard output and the standard error to the file.

These files are great for post processing the data, for example by importing them into excel. If you want to append lines to the last file rather than create the file new each time, use >> rather than >.


sudo python -u myprog.py >> proglog.txt

Spicy Swedish Pizza Salad

While on the Stockholm archipelago island of Utö we stopped at a small restaurant and ordered some pizza for lunch and with it we were offered pizza salad. After checking that we heard correctly as we had never heard of it we agreed and what showed up was a kind of vinegar coleslaw. Here’s my attempt at it.

First take about a quarter of a cabbage (500g) and chop it into sections that will go into the blender.

pizzasalad1

Be very careful here with the knife as cabbage can be quite tough to cut and its easy to slip.

pizzasalad2

Then chop them to the size that suits you.  Add vinegar to your taste (we used about 1/2 a cup of the strong vinegar Winborgs Attiksprit, diluted a bit as it is 12%). Then add fresh ground pepper to spice it up. Add a teaspoon of oil and a little salt (not too much as you want this to be crunchy, not break down into Sauerkraut).

pizzasalad4

To add a little colour chop up half of a red pepper and add it.

pizzasalad5

Leave in the fridge overnight to marinate. And now you have some spicy Swedish pizza salad to go next to your pizza. Its a great way to add some vegetables to a delicious meal of pizza and french fries (chips).

Pressure, Humidity and Temperature

My weather project is coming along nicely. Now I have added the DHT22 humidity and temperature sensor. Once again I used the drivers from Adafruit. Here is a link to the information: Adafruit DHT tutorial

A few pointers… somehow I managed to install the modules as root, not under my login name (the penalty of not paying attention with lots of terminal windows open). Use ‘chown -R’ to change back the ownership. The DHT22 uses the Dallas Semiconductor one wire interface. On the Raspberry Pi this is accomplished using a GPIO pin and thus the program needs to be run as ‘sudo’ to command the pins. The one wire interface is not as robust as others, so its possible that you will get error messages (if the program crashes with an error of the wrong data type then what happened is that  a ’round’ was not returned). Hence I use the read_retry command from the Adafruit library. The DHT22 library returns a long , so I have used round() to truncate the answer for display on the console.

You should note that the one wire bus needs a pull up resistor on the bus. I am using a 4.7kohm pull up to Vcc. Only one pull up resistor is required. Note how the BMP180 and the DHT22 are powered from different rails.

DHT22+BMP180_2

A few other notes:

I have added code to enable a cleaner exit from the program (the wrapper ‘try’ loop)

To check the i2c devices use “sudo i2cdetect -y 1”.  This will show you the addresses of the various modules. Each needs to be unique. The BMP180 should show up at address 77. If you see UU it means that the kernel has a module running and talking to that address.

i2CdetectSCR

you can see here that I have another device on my I2C… it happens to be a DS1307 RTC.

Here are the new results. Looks like the DHT22 reported an erroneous value in there so eventually I will need to take a look at the driver and see if the robustness can be increased.

temp2humiditypressure

Here is the circuit. Note that the BMP180 is powered from 3.3V and can communicate with the RPi directly. I am using a bi-directional level converter (Fritzing part included in the files) to communicate with the DHT22 which I have powered from 5V.

pressuretemphumidity2

Fritzing files can be found at http://fritzing.org/projects/pressure-temperature-and-humidity

#!/usr/bin/python
# Original Author : Tony DiCola of Adafruit
# With additions by hobbyistdave  www.hobbyspot.org
#
# 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.

# Can enable debug output by uncommenting:
#import logging
#logging.basicConfig(level=logging.DEBUG)

import Adafruit_BMP.BMP085 as BMP085   # the pressure and temnperature sensor
import Adafruit_DHT as DHT22           # the DHT22 hunidty and temperature sensor
import smbus
import time
import requests  # HTTPfor humans
                 # by Kenneth Reitz  docs.python-requests.org

# Default constructor will pick a default I2C bus.
#
# For the Raspberry Pi this means you should hook up to the only exposed I2C bus
# from the main GPIO header and the library will figure out the bus number based
# on the Pi's revision.
#
# For the Beaglebone Black the library will assume bus 1 by default, which is
# exposed with SCL = P9_19 and SDA = P9_20.
sensor = BMP085.BMP085()  # pressure and temperature
sensor2 = DHT22           # humidity and temperature
onewirepin = 4            # the pin for the one wire sensor
sensor1type = "BMP180"    # the type of sensor    
sensor2type = 22          # the type of sensor    

# Optionally you can override the bus number:
#sensor = BMP085.BMP085(busnum=2)

# You can also optionally change the BMP085 mode to one of BMP085_ULTRALOWPOWER, 
# BMP085_STANDARD, BMP085_HIGHRES, or BMP085_ULTRAHIGHRES.  See the BMP085
# datasheet for more details on the meanings of each mode (accuracy and power
# consumption are primarily the differences).  The default mode is STANDARD.

sensor = BMP085.BMP085(mode=BMP085.BMP085_ULTRAHIGHRES)

# setup the info needed to send the results to thingspeak

thingspeakurl = "https://api.thingspeak.com/update"   # url for sending updates to thingspeak
apikey = "1234567890123456"     # thingspeak api address for this channel 
TempField = "field1"            # temperature field
PressField = "field2"           # pressure field

# some debug info... here we print the BMP180 cal table
print "Calibration Coefficients read from sensor device "
print "-------------------------------------------------"
print "ac1 ", sensor.cal_AC1
print "ac2 ", sensor.cal_AC2
print "ac3 ", sensor.cal_AC3
print "ac4 ", sensor.cal_AC4 
print "ac5 ", sensor.cal_AC5
print "ac6 ", sensor.cal_AC6
print "b1  ", sensor.cal_B1
print "b2  ", sensor.cal_B2
print "mb  ", sensor.cal_MB
print "mc  ", sensor.cal_MC
print "md  ", sensor.cal_MD
print "--------------------------------------------------"
print " "

print "Initial data read to check sensors            "
print "-------------------------------------------------"
print "Time          ", time.ctime()
print "Epoch Seconds ", time.time()
print " "
temperature = sensor.read_temperature()  # Note: fixed an error in the Adafruit module where it incorrectly divides by 10 
pressure = sensor.read_pressure()

print "Data read from Sensor 1              "
print "---------------------------------------------------------"
print "Sensor type", sensor1type
print 'Temperature= {0:0.1f} *C  Pressure= {1:0.1f} mbar'.format(temperature,pressure/100)
print " "

print "Data read from Sensor 2              "
print "---------------------------------------------------------"
print "Sensor type", sensor2type
humidity2, temperature2 = DHT22.read_retry( sensor2type, onewirepin )
print 'Temperature= {0:0.1f} *C  Humidity= {1:0.1f} %'.format(temperature2,humidity2)
print " "

print "---------------------------------------------------------------------------"
print "  Time          Point    Temp     Temp2   Pressure     Humidity     Status "
print "(Epoch)           #       C         C        mbar          %         Code  "
print "---------------------------------------------------------------------------"
print " "
time.sleep(2)  # wait for the DHT sensor as it does not like to be accessed faster than every 2 seconds
# Now we enter the min code

try:           # wrapper to allow clean exit
    while True:

        temperature = sensor.read_temperature()
        pressure = sensor.read_pressure()
        humidity2, temperature2 = DHT22.read_retry( sensor2type, onewirepin )
        humidity2 = round(humidity2,3)
        temperature2 = round(temperature2,3)
        time.sleep(0.5)

        url = thingspeakurl
        payload = {'key' : apikey, 'field1' : temperature , 'field2' : pressure/ 100. , 'field3' : temperature2 , 'field4' : humidity2 } # make the payload
    
        try :
            r = requests.get(url, params=payload)  # send to thingspeak
            print time.time(), "  ", r.text, "   ", temperature ,"   ", temperature2 ,"   ", pressure / 100.,"      ", humidity2, "      ", r.status_code
            #r.text will be the data point number
            #r.status code should be 200 if the page posted correctly
        except requests.exceptions as e :
            print e # some simple error trapping to avoid the program timing out
        except requests.exceptions.ConnectionError as e1 :
            print e1 # some simple error trapping if the connection is lost
    
        time.sleep(15) # thingspeak is set to ignore requests that come faster than every 15 seconds

except KeyboardInterrupt:
    time.sleep (0.1)
    print " "
    print "Exiting program due to Keyboard Interrupt"
    print " "
except:
    time.sleep (0.1)
    print " "
    print "An error occurred"
    print " "

# end
 

The terminal output looks like this

presstemphumidSCR

Making Breadcrumbs and Croutons

A quick post on bread crumbs which were needed for the Scotch eggs and many other recipes. These are pretty easy to make at home.

Buy a cheap loaf of sliced bread. Best not to wait until the bread is too stale as I think they taste better if you dry them yourself in the oven. Its also safer to cut the fresh bread.

  • Cut the bread into largish chunks (1″) by hand
  • Lay the bread chunks out on trays in the oven
  • Dry them in the oven

The oven should be 300F, the time is a bit variable depending on how moist and fresh the bread was when it went in. It might take 15 minutes to 45 minutes. Wait until they are thoroughly dried out.

What comes out of the oven are croutons that can easily be turned into crumbs of varying fineness.

This picture is the result of making one loaf’s worth of croutons… they were cooked/dried on 3 trays and have been consolidated for the crumbing part.

crutons

We only have a hand blender, the fantastic Bosch MSM67160. Its powerful at 750W and we use it for every type of  blending and chopping.

crutons2

Its pretty easy to grind different grades as you can see. Store them in sealed plastic bags in a dark cupboard.   We season them then they are used to give the most flexibility. Making this much takes about 10 minutes total from the dried croutons.

breadcrumbs

They should last 6 months in this state as they are dried and the bags sealed, although we consume them much faster than that. The key being keeping them away from moisture and making sure they stay cool and dry in the cupboard.

Graphing sensor data from a Raspberry Pi

I’m interested in the Internet of Things and thought that the Raspberry Pi would be a good way to explore it. So as a getting starter project I attached a temperature and Humidity sensor to my RPi and set about exploring. The sensor I used is the Bosch BMP180 digital barometer and temperature sensor. This is the successor of the BMP085 and uses I2C to communicate with the host.  BMP180 Datasheet

I purchased it on a small board suitable for breadboarding.

BMP180

To communicate with the BMP180 I used ADAFruit’s BMP085 libraries. They have a fantastic tutorial on how to use it and how to connect the device. AdaFruit BMP085 info

I also found some great data on this device  posted by on his blog at http://blog.bitify.co.uk/

Here is the overall setup. In the picture you can see the RPi is feeding its I2C bus to a breadboard. I am using an external power unit (9V brick feeding regulators with 5V and 3.3V outputs).  In general I am using Arduino sesnor modules setup for 5V whereas the RPi uses 3.3V, so there is a bidirectional level shifter converting between the two voltage rails that you can see to the right by the power supply. On the left is the BMP180 temperature and barometer device… in the center is a real time clock (not being used here) and just off the picture a DHT22 one wire humidity and temperature sensor that will be used in future projects.

BMP180+RPi

Once the sensor was running the next task was to plot the results. At first I used GNUplot on the RPi but that was not a long term solution. After a bit of research I came upon thingspeak, an internet of things platform run by The Mathworks. This seemed ideal as it allows you to set up channels that you can write to as webpages, and it plots them in real time and makes them accessible on the internet. This seemed much easier than setting up a local web server. There are a couple of limitations that seem minor, basically each channel supports up to 8 fields and you can only send data every 15 seconds.

Now the task was to get the information sent to the thingspeak site. I played a bit with the native python libraries (UrlLib) for doing this but they make pretty unreadable code that is hard to debug. Then I stumbled on this fantastic library that made things readable.

http://docs.python-requests.org/en/latest/  by Kenneth Reitz who with his colleagues have done a great job of making this task simpler. With ‘requests’ sending the data to thingspeak became much easier to debug.

Here is the code that I put together. It uses the Adafruit BMP library coupled to “requests” to send to thingspeak.


#!/usr/bin/python
# Original Author : Tony DiCola of Adafruit
# With additions by hobbyistdave  www.hobbyspot.org
#
# 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.

# Can enable debug output by uncommenting:
#import logging
#logging.basicConfig(level=logging.DEBUG)

import Adafruit_BMP.BMP085 as BMP085
import smbus
import time
import requests  # HTTP for humans by Kenneth Reitz  docs.python-requests.org

# Default constructor will pick a default I2C bus.
#
sensor = BMP085.BMP085()

# You can also optionally change the BMP085 mode to one of BMP085_ULTRALOWPOWER,
# BMP085_STANDARD, BMP085_HIGHRES, or BMP085_ULTRAHIGHRES.  See the BMP085
# datasheet for more details on the meanings of each mode (accuracy and power
# consumption are primarily the differences).  The default mode is STANDARD.

#
sensor = BMP085.BMP085(mode=BMP085.BMP085_ULTRAHIGHRES)

# setup the info needed to send the results to thingspeak

thingspeakurl = "https://api.thingspeak.com/update"   # url for sending updates to thingspeak
apikey = "1234567890123456"     # add your own thingspeak api address for your channel
TempField = "field1"            # temperature field
PressField = "field2"           # pressure field

temperature = sensor.read_temperature()  # Note: fixed an error in the Adafruit module where it incorrectly divides by 10
pressure = sensor.read_pressure()

print " "
print "---------------------------------------------------------"
print "Time          ", time.ctime()
print "Epoch Seconds ", time.time()
print "Temperature   ", temperature
print "Pressure      ", pressure/ 100.
print " "
print "---------------------------------------------------------"
print " "
print "Time            Point  Temp    Pressure        Status    "
print "---------------------------------------------------------"
print " "

while True:

temperature = sensor.read_temperature()
pressure = sensor.read_pressure()

time.sleep(1)

url = thingspeakurl   # the thingsspeak url
payload = {'key' : apikey, 'field1' : temperature , 'field2' : pressure/ 100. }  # set up  the payload

try :
r = requests.get(url, params=payload)   # send the data to thingspeak
print time.time(), "  ", r.text, "   ", temperature ,"   ", pressure / 100.,"      ", r.status_code # print locally
except requests.exceptions as e :
print e # some simple error trapping to avoid the program timing out
except requests.exceptions.ConnectionError as e1 :
print e1 # some simple error trapping if the connection is lost

time.sleep(15) # thingspeak is set to ignore requests that come faster than every 15 seconds

# end of code

Locally on the RPi you get a print out of the temperature and pressure, timestamp, data point number and return code from the server… In the code you can see the apikey (put your own one in there).  The thingspeak website has great instructions for setting their end up.

The key code block shows the elegance of the  “requests” api for handling the http:


url = thingspeakurl   # the thingsspeak url
payload = {'key' : apikey, 'field1' : temperature , 'field2' : pressure/ 100. }  # set up  the payload
r = requests.get(url, params=payload)   # send the data to thingspeak

And published to the cloud you get:

temppandpressure

Which is what I was aiming to achieve.

Scotch Eggs

You wont see too many recipe posts from me, but I did get inspired to cook Scotch Eggs today. Not exactly a health food, but delicious to eat once a year or so.

First I boiled 10 eggs for 12 minutes to make sure they were nicely cooked as I intend to freeze the eggs.

To keep things simple I bought sausages and used the meat out of them as the wrapping. The first set of sausages that I bought had skins that I could not peel off… so then I upgraded to ‘real’ sausages from the butcher which worked perfectly as the casing was easy to remove. Each sausage has enough meat to encase one medium egg. Of course you can make your own sausage meat from ground meat and a binder.

sausagemeat

Next I setup for the following steps.

  • Roll the eggs in flour
  • Pat the sausage into a patty and cover the egg
  • Roll this in flour then in beaten egg
  • Roll the whole thing in breadcrumbs

I used 3 types of sausage; beef, lamb and pork.

scotcheggprep    makingtheegg

And finally the cooking. I don’t have a deep fryer as this is a once a year event so I did this very carefully in a deep saucepan. I used a candy thermometer to monitor and keep the temperature between 150C and 160C and a splash guard. About 7 minutes seemed to do it, with a few minutes in the oven to make sure the meat was cooked.

cookingeggs

Remember to keep a careful watch on the frying process at all times and don’t overfill the pan with oil or eggs or get it too hot. Better if you have a real enclosed  deep fryer and don’t do this if you have a gas stove. I keep a fire blanket nearby to smother it if there is a problem.

CAD for electronic projects

As part of exploring the Raspberry Pi and the Arduino, I am interested in the aspect of those computers that interacts with the real world. This means adding sensors and actuators and the circuitry that  runs them and interfaces them to the microcomputers. Plus I wanted to document such projects in a good way that I can reproduce and share. So I have taken a  quick look at the CAD tools available to the amateur for designing electronic circuits.

I will admit that did not do an exhaustive search. I wanted a tool that not only allowed me to do designs but that also had a good community of people with a similar ambition to share ideas with and to get started. Libraries and part creation are some of the most important aspects as if you are doing anything interesting you will soon need to use a wide range of parts and also create your own parts.

At first I started with RS components DesignSpark as it seemed the most comprehensive with a large library of parts and modules and lots . This is a powerful CAD tool available for free to the hobbyist that contains full schematic capture, PCB layout, parts libraries and even simulation tools such as an inbuilt Spice.

I did start using DesignSpark and created a few schematic templates and explored some that other had done.  But the very first small project I started on required me to create new components (a specific opto-coupler that I wanted to use) and I found that this was not very intuitive in the tool and the learning curve a bit steep.

So I thought that I would look further and have now launched into using an open source tool called Fritzing.

This is a simpler tool although it too includes schematic capture, pcb layout, breadboard layout and part libraries. Once again this required me to add a component for the very first project, but the system was relatively simple. In Fritzing you can clone existing parts and use a vector graphics (SVG) editor to adjust them. I tried an on-line graphics tool but it was not precise enough in its dimension handling so now I am using Inkscape which is quite a powerful tool yet I found it reasonably simple to get started using.

While I am a fan of hobbies that require some investment of time to get going, if the process is too frustrating then people give up. So the combo of Fritzing and Inkscape seem good to get going.

Here is a screen shot of my first project.

FirstFritzing

Bike Recall, skewers and cam levers

Its worth noting that there is a large bike recall occurring at the moment. It is related to the quick release skewer and the possibility of the cam lever getting stuck in the disc brakes.

The details are here:

http://quickreleaserecall.com/

I found that Haro, the manufacturer of one of my bikes is involved so I checked the various skewers. I found that the Haro bike I own has a slightly different design skewer than the one involved in the recall. Here you can see that when it is open, the skewer cannot move back against the disc as it cannot open more than 180 degrees. This type is the split cam type with a plastic washer. Its essential that the washer is in the right place on this one when you tighten it or it can loosen.

skewer1    skewer2   

I think its a good idea to check these things when manufacturers do a recall, so I inspected the rest of the bikes. Three had that type of quick release, but the 4th, a Rocky Mountain had the type of skewer and cam lever that is implicated in the recall.

Here are a couple of images. You can see the lever that is part of the Cam is to the side, and rotates beyond 180 degrees… indeed it could protrude towards the disc.

skewer3  skewer4   

It so happened that I had assembled this bike, and I’d always worried that the levers might catch on something , so I had pointed them back and parallel to the ground. During that process I had installed the lever on the opposite side to the disc. Not sure if it makes a difference but it does mean that it could not have hit the brake. I checked the distance and it had the requisite clearance anyway.  For now I’ll leave it on the opposite side and I’ll get a replacement eventually.

So its worth checking all the bikes in your collection as even if not named in the recall they may have an offending skewer/lever. The issue is not just with new bikes so expect to see more recalls as other manufacturers catch up. Safety first is a good policy here so remember to follow the instructions for replacing the skewer or take it to a bike shop if you are not confident in doing this right.