Progress has been very slow through December, due to both project related issues, and real-life getting in the way (which is actually not a bad thing).
Project issues include a cmos 555 timer with a strange fault, a damaged RaspberryPi USB socket, and discovering my choice of relay was a bad one.
Although the relay had a 1A contact rating and looked suitable for a Raspberry Pi drawing less than 500mA, this rating is for a purely resistive load. (see earlier post for relay circuit details.)
After a few hours of use I found that the relay was "sticking" because the Raspberry Pi inrush current was welding the contacts together. The contacts could be released by either gently tapping the relay, or pressing lightly on the body of the relay.
So I replaced the relay with a power MosFet.
This seemed to work fine, but when I measured the drain to source voltage drop, it was about 180mV, leaving me with a RaspberryPi voltage of around 4.83Volts.
However, as I already had a small 100mA linear voltage regulator in my bag of bits, I decided to incorporate it into my design, so that I could get the full 5 volts to the Raspberry Pi.
I also took Michael's advice and used a 78B5 5V switching regulator to create the Raspberry Pi 5 volt supply from my 12V battery.
Unless I run into any last minute hardware problems, this looks like the circuit I'm going to run with.
Circuit Values & Choice of Components
Here are a few measurements from the current build of this circuit:-
- Powered in standby: 15mA
- Triggered but no RPi: 20mA
- With RPi A + SD card + PiCam, but no WiFi dongle: 0.12A
- RPi supply: 5.05V
The actual standby current (i.e. before the 555 is triggered) is probably largely dependant upon the 555 timer, and I've seen readings between 9 and 15mA. I had a cmos version running for a while with a standby current of about 9mA. But this chip seemed to be faulty and I had to replace with an NE555 (bipolar transistor) version.
If you are thinking of building this circuit, most of the components are available (and cheap) from Spiratronics, with the exception of the switching regulator which came from RS Components.
The semiconductors should be the type shown in the diagram, but the 1N4148 diode could be any small signal silicon device e.g. 1N914, 1N916.
Most of the resistors and capacitor values are not that critical. The 555 timing components (1M5 and 47uF) just need to give a long enough pulse for the RapsberryPi to boot and start running the controller program. The 0.1uF capacitors could probably be any value from 0.001 to 1uF. While the 10k pull-up resistors could be +/-50% of this value.
I've yet to complete bird box illumination tests with ultra-bright LEDs. I have drawn 2 banks of 3 LEDs on the circuit to allow for some further control, as I may find that more light is required for good image quality.
Add Some Code to Test
In order to test this controller I've written some Gambas code which will form the foundation of my final application.
A good place to start a project like this is to write a message logging routine. This will allow me to record just what is happening and aid fault finding.
I've put this code in it's own module so it can easily be re-used in another project.
' modLog: A module to log events, errors and other useful stuff
Const MAX_LOG_SIZE As Long = 1000000
Public Function Event(iType As Integer, strEvent As String) As Boolean
'Timestamp an event/error/info and add to a log
Dim strLogDir As String
Dim strFilePath As String
Dim hFile As File
Dim strStuff As String
strLogDir = "/home/pi/" & Application.Title
Select Case iType
Case 1 'app event
strFilePath = strLogDir & "/AppEvent_Log.csv"
Case 2 'Box-event
strFilePath = strLogDir & "/BoxEvent_Log.csv"
Case Else 'assume Error event
strFilePath = strLogDir & "/Error_Log.csv"
'Save timestamp & event to ?_Log.csv
If Exist(strLogDir) Then
'Delete the Log file if its getting too big!
If Stat(strFilePath).Size > MAX_LOG_SIZE Then
Try hFile = Open strFilePath For Append
If Error Then
strStuff = Format(Now, "yyyy/mm/dd,hh:nn:ss") & "," & strEvent & Chr(10)
Write #hFile, strStuff, Len(strStuff)
message.Error("Oh dear! There seems to be a problem with the logging method: " & Error.Text, "close")
The procedure in this modLog module allows me to either seperate messages into a number of logs, or simply put them all in the same log. For example calling:-
...will add the time stamped message "App started" to the AppEvent log.
Control via GPIO
We need to use wiringPi in Gambas to control some of the I/O ports, so see my earlier post on the basics.
As soon as the RaspberryPi has booted and loaded this controller program, we need to kick the controller circuit to keep power connected to the RPi.
Public Sub KickDog()
'Pulse the output which triggers the 555 monostable to keep power on.
modLog.Event(APP_EVENT, "just gave the dog a kick")
I've added a timer set to fire at 30s intervals which calls the Sub KickDog. The timer code itself looks like this:-
Public Sub tmrDog_Timer()
'kick dog every 30s.
'Overrun time is in minutes
If lngRunCounter >= lngOverRunTime * 2 Then
modLog.Event(APP_EVENT, "No box events for last " & lngOverRunTime & " minutes, so letting go")
The purpose of lngRunCounter is to ensure that we keep calling KickDog for a period of time (the Overrun time) after activity at the nest box entrance has stopped. Once the overrun time has expired (probably 30min) the timer is stopped and the controller is left to power off the RaspberryPi.
The lngRunCounter is reset to 0 each time the nest box circuit detects a visitor.
A second timer is used to poll the nest box entrance detector. This has an interval of 500ms, which should be short enough that a bird does not slip in unnoticed, while not too short that it takes up too much cpu time. 500ms may also avoid some of the multiple counts often detected when a bird is pecking around the entrance.
I also want to avoid multiple counts due to a bird wedged in the entrance, so I only count an event based upon the detector transition from 0 to 1.
Public Sub tmrBoxEventReader_Timer()
'read the box event (entrance) sensor checking for activity.
'reset the run counter if entrance is blocked so that power is maintained.
'only count a new transition (0 to 1) as an event, not successive 1 states.
lngCurrentBoxRead = digitalRead(BOX_EVENT_INPUT)
If lngCurrentBoxRead = 1 Then
lngRunCounter = 0 'reset Run counter
If lngLastBoxRead = 0 Then
lngLastBoxRead = lngCurrentBoxRead
lblBoxRead.Text = CStr(lngBoxEventCounter)
That's it! That's the basis for my test software, although I also have a crude & ugly user interface which shows data such as the value of lngRunCount, the number of box events and whether tmrDog is enabled.
The next steps include:-
- building a new controller board to fit into my chosen enclosure
- test a few 5mm and 10mm ultra-bright LEDs
- develop the software