Sunday, 14 June 2015

Being a 21st Century Teacher

I LOVE being a 21st century teacher! 

By most measures, teaching in general, and teaching computing in particular, is easier and more fun than ever before. A bold statement perhaps?  For me, the way technology facilitates community is key.

For starters, social media allows me to join a great club of fellow professionals. Entry criteria: a twitter account and a willingness to learn and share.

With the advent of resource-sharing sites like TES and primaryresources.co.uk, not to mention our own site, there really is no excuse for poorly planned, boring lessons.

If I get stuck and need to learn something new myself, well, just like Neo in the Matrix you can get on Youtube and learn just about anything (it can take a bit longer than it did for Keanu). For example I learned lots of Kodu tricks from @GeekyNicki and returned the favour with some Kodu and Flowol tutorials of my own.

In a typical day I can wake up to inspirational tweets from the likes of @urban_teacher@markbarnes19 and @ICTEvangelist. I can teach lessons from plans I've found and adapted from CAS, TES or computing super heroes like Simon Haughton, and in the evening I can study Computer Science at MIT.

I can't imagine, now, not being able to connect quickly and easily with the best educators in my chosen field.

Teaching from just your own experience, behind a closed door, from a book? 

That's so 20th century, darling!


Thursday, 16 April 2015

Pi-based Domestic Electricity Monitor - Part 7 - Project stalled indefinitely.

For now this project has been halted while I work on other things to develop my skills further, especially with databases and web publishing.

Eventually I hope to buy a cheap model A Pi and get this project up and running again.


Thermobot Update

Video of Bot in operation.



The thermobot also stores and plots 24 hours of data. It's finished its job now, but was logging live every minute to a webpage. You can see its results from my conservatory for 16th April 2015 here:

http://jcwyatt.ddns.net/thermobot.html

Initially, pyplot was producing a wierd colouring-in effect under the graph, but adding   

plt.clf()
 
to reset pyplot after each plot fixed the problem. I discovered this accidentally.

the updated code to include the data logging and plotting is here:


import RPi.GPIO as GPIO
import time
import matplotlib
matplotlib.use('agg')
import os
import matplotlib.pyplot as plt


#pseudo code:
#   fill a list with 60 zeros
# set the t1_temp variable to 18 deg c
# every minute:
# get the t2_temperature from the chip
# ext:write the temperature to a list or database
# calc the temperatures difference from previous value
# move the bot an amount relative to the temp difference

#initialise bot settings (stepper motor))
GPIO.setmode(GPIO.BCM)
 
enable_pin = 18
coil_A_1_pin = 7
coil_A_2_pin = 8
coil_B_1_pin = 23
coil_B_2_pin = 24
 
GPIO.setup(enable_pin, GPIO.OUT)
GPIO.setup(coil_A_1_pin, GPIO.OUT)
GPIO.setup(coil_A_2_pin, GPIO.OUT)
GPIO.setup(coil_B_1_pin, GPIO.OUT)
GPIO.setup(coil_B_2_pin, GPIO.OUT)
 
GPIO.output(enable_pin, 1)
 
delay = 2

def forward(delay, steps):
 for i in range(0, steps):
  setStep(1, 0, 1, 0)
  time.sleep(delay)
  setStep(0, 1, 1, 0)
  time.sleep(delay)
  setStep(0, 1, 0, 1)
  time.sleep(delay)
  setStep(1, 0, 0, 1)
  time.sleep(delay)
 
def backwards(delay, steps):
 for i in range(0, steps):
  setStep(1, 0, 0, 1)
  time.sleep(delay)
  setStep(0, 1, 0, 1)
  time.sleep(delay)
  setStep(0, 1, 1, 0)
  time.sleep(delay)
  setStep(1, 0, 1, 0)
  time.sleep(delay)
 
def setStep(w1, w2, w3, w4):
 GPIO.output(coil_A_1_pin, w1)
 GPIO.output(coil_A_2_pin, w2)
 GPIO.output(coil_B_1_pin, w3)
 GPIO.output(coil_B_2_pin, w4)

#from http://www.modmypi.com/blog/ds18b20-one-wire-digital-temperature-sensor-and-the-raspberry-pi:
#load drivers for temperature probe
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

temp_sensor = '/sys/bus/w1/devices/28-0414607111ff/w1_slave'

#Get the raw data from the sensor:
def temp_raw():

 f = open(temp_sensor, 'r')
 lines = f.readlines()
 f.close()
 return lines

def read_temp():

 lines = temp_raw()
 while lines[0].strip()[-3:] != 'YES':
  time.sleep(0.2)
  lines = temp_raw()
        
 temp_output = lines[1].find('t=')

 if temp_output != -1:
  temp_string = lines[1].strip()[temp_output+2:]
  temp_c = float(temp_string) / 1000.0
  return temp_c

#initialise current temperature
currentTemp = 14.00

#make an empty list for 24 hours worth of data
tempLog = [0] * (60*24)

#run the bot
while True:
  oldTemp = currentTemp
  currentTemp = read_temp()
  tempDiff = currentTemp - oldTemp
  if tempDiff >= 0:
   steps = tempDiff * 256
   forward(int(delay) / 1000.0, int(steps)) 
  else:
   steps = tempDiff * -256
   backwards(int(delay) / 1000.0, int(steps))
  setStep(0,0,0,0)

#now do the graph stuff:
#add the new reading to the end of the list 

  tempLog.append(currentTemp)

#delete the first item in the list

  del tempLog[0]

#plot the graph as an image    
  
  plt.plot(tempLog)
  plt.ylabel ('Bedroom Temperature (deg C)')
  plt.xlabel ('Time (minutes) (Full width = 24hrs)')
  plt.savefig('/var/www/images/tempLog.png')
  plt.clf()

  hrlog=(tempLog[-60:]) 
  plt.plot(hrlog)
  plt.ylabel ('Temp (deg C)')
  plt.xlabel ('Time (minutes) last hour')
  plt.savefig('/var/www/images/tempLog60.png')
  plt.clf()

  time.sleep(60)
 

Pi Science Project: Tank Power - Part 1 - Outline of project

New Project: Tank Power

Aim:

To establish whether, in the summer, I should heat my hot water tank using electricity via the immersion heater or use gas via the central heating boiler. 

Hypothesis: Electricity is a more efficient way to heat the water in the tank because when using gas, there is heat loss via the pipes transporting the heat from the boiler to the tank and also heat lost from the boiler flue pipe.

 

Proposed Method:

Use Raspberry Pi and temperature sensor to log the temperature of the tank by fitting the sensor to the outside of the tank. Record the value every 2 minutes. By looking for when the temperature is rising, the length of time for which energy is being supplied to the tank each day can be measured. 

For gas heating, if the quantity of gas used during the same 24hr period is known, the energy consumption can be calculated. 

For electrical heating, if the power consumption of the the heater is known then the energy consumption can be calculated.

Other factors should be revealed, for example the rate of heating for gas compared to electricity and how well the thermostats work at regulating the temperature.

Step 1: Rig up the pi logging the temperature of the tank with the sensor taped to the outside to gather preliminary data. 

draft pseudo code:

#import sqlite to write the temperature and time data to a file
#import matplotlib to write the data  to graphs
#import OS  to access the temperature sensor

#if it doesn't exist create the database
#open the database

#read the current temperature and time

#write time and temp to the end of db

#get the data from the db (how much?)

#1) last 24 hours
#2) last 6 hours
#3) last 3 hours

#plot each graph to a .png for showing on a database

#data analysis extension:
#import last 24 hours data (midnight to midnight)
#read temperature values
#if temperature is rising start the timer
#if temperature is falling stop the timer
#might need to average these values out to allow for small fluctuations
#add the timer value to total 'on' time
#return a value for total time of rising temperature in 24 hrs
#calculate the theoretical value of energy used vs actual?
#for electrical this is easier done by the program if the power rating of the heater is known
#for gas would need to input the meter reading for the 24hour period and do some calcs.







 


Monday, 30 March 2015

Thermo-Bot Project




In this post, I describe how I took a stepper motor, some Lego(R) and a temperature probe to make a temperature sensitive robot. Basically it's a Pi-on-wheels that moves to the correct position on a temperature scale to indicate the current room temperature. Don't ask why I thought this was a good idea, but I'm quite proud that it works!



Video of it working here (time lapse of 50 minutes) https://youtu.be/bbkwAPPF_vY


I bought a stepper motor with a view to making some kind of robot.

This tutorial from Simon Monk on the Adafruit site is all you need for Pi-controlled stepper motors:

https://learn.adafruit.com/adafruits-raspberry-pi-lesson-10-stepper-motors

I bought my stepper motor from ebay with the controller chip included on a board with some LEDs, which were really helpful in debugging, since the wires in the Adafruit diagram don't 'line up' obviously with the Pi GPIO pins. My motor would only go forwards until I followed the diagram MUCH more carefully. (The fault was with me not Simon's diagram.)

I also did some work with the single wire temperature sensor, again using the Adafruit tutorial from Simon Monk:

https://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing

Although some of the Python code came from here:

http://www.modmypi.com/blog/ds18b20-one-wire-digital-temperature-sensor-and-the-raspberry-pi:


However, this time it wasn't my fault when it didn't work. With model B+ Pis you have to add this to the /boot/config.txt file:

dtoverlay=w1-gpio,gpiopin=4

Once this was in place the sensor worked fine.

The robot is cobbled together really quickly (badly) using lego. Initial belt-drive version had problems with the elastic-band drive belt jumping off the drive wheel, so direct drive was used instead.

Then it was time to combine the two tutorials and with a few extra lines of code I have a robot that moves up and down a temperature scale according to the current room temperature.


Here's the code I used. You'll notice most of it is pretty much left as per the Adafruit example and the modmypi link above, so credit to Simon Monk and the ModMyPi guru.



import RPi.GPIO as GPIO
import time
import os

#initialise bot settings (stepper motor))
GPIO.setmode(GPIO.BCM)
 
enable_pin = 18
coil_A_1_pin = 7
coil_A_2_pin = 8
coil_B_1_pin = 23
coil_B_2_pin = 24
 
GPIO.setup(enable_pin, GPIO.OUT)
GPIO.setup(coil_A_1_pin, GPIO.OUT)
GPIO.setup(coil_A_2_pin, GPIO.OUT)
GPIO.setup(coil_B_1_pin, GPIO.OUT)
GPIO.setup(coil_B_2_pin, GPIO.OUT)
 
GPIO.output(enable_pin, 1)
 
delay = 2

def forward(delay, steps):
 for i in range(0, steps):
  setStep(1, 0, 1, 0)
  time.sleep(delay)
  setStep(0, 1, 1, 0)
  time.sleep(delay)
  setStep(0, 1, 0, 1)
  time.sleep(delay)
  setStep(1, 0, 0, 1)
  time.sleep(delay)
 
def backwards(delay, steps):
 for i in range(0, steps):
  setStep(1, 0, 0, 1)
  time.sleep(delay)
  setStep(0, 1, 0, 1)
  time.sleep(delay)
  setStep(0, 1, 1, 0)
  time.sleep(delay)
  setStep(1, 0, 1, 0)
  time.sleep(delay)
 
def setStep(w1, w2, w3, w4):
 GPIO.output(coil_A_1_pin, w1)
 GPIO.output(coil_A_2_pin, w2)
 GPIO.output(coil_B_1_pin, w3)
 GPIO.output(coil_B_2_pin, w4)

#from http://www.modmypi.com/blog/ds18b20-one-wire-digital-temperature-sensor-and-the-raspberry-pi:
#load drivers for temperature probe
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')

temp_sensor = '/sys/bus/w1/devices/28-0414607111ff/w1_slave'

#Get the raw data from the sensor:

def temp_raw():

 f = open(temp_sensor, 'r')
 lines = f.readlines()
 f.close()
 return lines

def read_temp():

 lines = temp_raw()
 while lines[0].strip()[-3:] != 'YES':
  time.sleep(0.2)
  lines = temp_raw()
        
 temp_output = lines[1].find('t=')

 if temp_output != -1:
  temp_string = lines[1].strip()[temp_output+2:]
  temp_c = float(temp_string) / 1000.0
  return temp_c

#initialise current temperature start value (and place bot on 14 deg C mark before running)
currentTemp = 14.00


#run the bot
while True:
  oldTemp = currentTemp
  currentTemp = read_temp()
  tempDiff = currentTemp - oldTemp
  print (oldTemp, currentTemp, tempDiff,)
  if tempDiff >= 0:
   steps = tempDiff * 256
   forward(int(delay) / 1000.0, int(steps)) 
  else:
   steps = tempDiff * -256
   backwards(int(delay) / 1000.0, int(steps))
  setStep(0,0,0,0)
  time.sleep(60)
  
 
It works!

Tuesday, 10 March 2015

Pi-based Domestic Electricity Monitor - Part 6 - First Log - Success and Failure

Summary:

I logged 24hrs of data from my domestic electricity meter, but discovered that writing each event to the db with SQlite seemed to be taking 4 seconds, making the program as it stands no good for logging an event which can happen more than twice a second on occasions of high consumption. Values below 1kW were recorded accurately I believe.

To run the program via SSH I used nohup for the first time so that it would run even once I closed the session...and then had to learn how to find and kill said program:

To hunt running program: 

$ ps -e | grep python


To kill running program:

$ sudo kill 3861


Detail:

I used the program below to log the meter for around 24 hrs

(House averages 1kW, or 800 flashes per hour. 24hrs is therefore around 20,000 flashes)

This was to test the logging process and to see the size of the data file that would be created.

However, on analysing the data I soon noticed the data was suspect:
a) not enough readings for 24hrs (~9000, rather than ~20,000)
b) readings which never go above around 1kW:


(graph created in Libre office after exporting data from sqlite. This site was helpful here: http://www.sqlite.org/cli.html)


 Here's a sample of the data: (Time|Consumption|Meter Reading)

Tue Mar 10 07:23:49 2015|0.980246908963771|16791
Tue Mar 10 07:23:54 2015|0.939329897684513|16791
Tue Mar 10 07:23:58 2015|0.978048032653337|16791
Tue Mar 10 07:24:03 2015|0.977999583707987|16791
Tue Mar 10 07:24:08 2015|0.959483188529128|16791
Tue Mar 10 07:24:12 2015|0.955398819345674|16791
Tue Mar 10 07:24:17 2015|0.97396251715844|16791


Every interval is around 4 seconds and 1kW at a time when it should be well above this.

When I remove the lines that write the data to the db, the consumption data becomes correct, so I think that writing the data to the db is taking around 4 seconds.

The size of the data file is not going to be a problem: ~9000 readings is ~500kB.

Here's the code I used:

It features a facility for calculating the meter reading based on initial values and 800 flashes of the LED being 1kWh.


#!/usr/bin/env python
     
#First go at logging data from the meter

import RPi.GPIO as GPIO, time, os
import sqlite3


#initiaise database tools
conn = sqlite3.connect('elecmeter.db')
c =  conn.cursor()

#create database
#what to send to db: ascitime, power consuption, meter reading
c.execute("CREATE TABLE e_meterlog01 (time float, power float, meter_reading integer)")

#initialise pins     
DEBUG = 1
GPIO.setmode(GPIO.BCM)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)



#procedure to wait for LED flash front edge
def wait_for_flash():
    try:
        GPIO.wait_for_edge(23,GPIO.RISING)
    except KeyboardInterrupt:
        GPIO.cleanup()       # clean up GPIO on CTRL+C exit 
        conn.close() 
 
#initialise meter reading tools 
meter_rdg = 16777
impulse_count=0

#timing and kW calcs based on 800 imp / kWh:
 
start_time=time.time()

for i in range (0,22000):
    wait_for_flash()
    elapsed_time = time.time()-start_time
    start_time=time.time() 
 
#increment the meter reading every 800 pulses:
 
    if impulse_count < 800:
        impulse_count += 1
    else:
        meter_rdg +=1
        impulse_count=0 
 
    kW=((1/elapsed_time)*4.5) 
 
    print (elapsed_time,kW,meter_rdg,impulse_count)
    c.execute("INSERT into e_meterlog01 VALUES(?,?,?)",(time.asctime(),kW,meter_rdg))
    conn.commit()
    time.sleep(0.3) #to allow for LED to turn off
    
GPIO.cleanup()           # clean up GPIO on normal exit        
conn.close()

print("Ending Program")


Saturday, 7 March 2015

Remote accessing a Raspberry Pi

Just a few tweeks to the pi to make it easier to work on it remotely:

1) Autostart the VNC server - https://learn.adafruit.com/adafruit-raspberry-pi-lesson-7-remote-control-with-vnc/running-vncserver-at-startup (EDIT - I had to turn this off. After the first time of working, thereafter the remote screen was just grey with an 'x' mouse pointer. Starting manually works fine)

2) Get LAMP installed to allow remote access: http://elinux.org/RPi_A_Simple_Wheezy_LAMP_install

3) Install and get no-ip working -http://www.noip.com/support/knowledgebase/installing-the-linux-dynamic-update-client/

It all works: http://jcwyatt.ddns.net

However I installed no-ip using some other instructions, which I won't link to, which put the noip client in the home directory, which I think is why I can't start noip the same way as I start TightVNC. It needs root privileges to run noip now, and I don't think it should if you install it properly.

(EDIT - My mobile network provider is blocking access to this site, but I can access it from everywhere else I've tried. Will try changing the re-direct settings on my router and the no-ip settings.)


Next task is writing the data continually to a sqlite db for 24 hours, to gauge the file size.