Author Archives: garreth

Local Weather forecasting

Just a quick note to enquicken someone else’s google seaches in the future,

For local weather forecasting based on ambient air pressure, the algorithm you need is the Zambretti algorithm .

The original Hackaday article on this is here:

And some useful matlab code to get you started is here:

Finally, some tags to help google air pressure wheel forecast ambient air pressure bmp280 bmp180 air pressure forecast etc.

Arduino ethernet hardware watchdog

So I have a few raspberry pis that (3 in fact!), and sometimes have them set up for remote access such as a raspberry pi webcam using the raspberry pi camera, web servers, remote power socket control, weather monitoring, energy usage – the usual geeky stuff.

Various raspberry pi projects of mine!

Anyway, sometimes the thing runs smoothly and reliably for years on end without problems (usually the less you tinker with it!), surviving power cuts and what have you. My first Model B Rev 1 Pi (thanks Dad!) is an example of these. It ran for years monitoring temperature/humidity and air pressure, before finally being shutdown due to a house move (someday i’ll have to resurrect it!).

Sometimes however, things don’t go to plan and Linux will crash or lock up, or the network interface will go down on power cuts. For instance I once wrote a script to restore the wifi connection of a pi in my GF’s locked and empty house using a lovely blackberry smartphone while sitting in a buddy’s car eating kfc chicken outside. But that’s another story! (Thanks Andy!). It usually happens right when you’re away the Pi and trying to login remotely!

I tried using the raspberry pi watchdog timer (see here: Raspberry pi Watchdog timer), but this didn’t seem to fix the problem

So I built an Arduino hardware watchdog that keeps an eye on the ping result of a host on the network, and reboots the device if it fails tor respond. IT has a 16×02 lcd to display current action/state although someday i’d like to have leds for each state instead. with a button to manually reboot.

The project utilized a remote control socket (from Maplin, RIP), an arduino uno with an ethernet shield and a 16×02 lcd shield (with pin 10 bent out to prevent issues between the ethernet shield and the lcd shield backlight) plus a 433mhz tx module and the rcswitch library.

Maplin/Wilko remote sockets, available here 

code below

Ping Example

This example sends an ICMP pings every 500 milliseconds, sends the human-readable
result over the serial port.

Ethernet shield attached to pins 10, 11, 12, 13
433mhz tx module on pin 2
LCD on pins 8, 9, 4, 5, 6, 7

Pin 10 of the LCD bent out of socket to prevent issues caused by the backlight

created 30 Sep 2010
by Blake Foster

Modified by Garreth Tinsley

const int txDataPin = 2;

#include <SPI.h>
#include <Ethernet.h>
#include <ICMPPing.h>
#include <RCSwitch.h> // for 433 tx module/remote switch control
#include <LiquidCrystal.h> // For LCD
long retrytimeout = 15L * 1000L; //recheck every 15 seconds
long cycletimeout = 120000;
long starttime;
long currtime;

bool looptwice = false;

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // max address for ethernet shield
//byte ip[] = {192,168,2,177}; // ip address for ethernet shield
IPAddress pingAddr(192, 168, 1, 2); // ip address to ping

SOCKET pingSocket = 0;

char buffer [256];
ICMPPing ping(pingSocket, (uint16_t)random(0, 255));
RCSwitch mySwitch = RCSwitch();
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // initialize the LCD library with the numbers of the interface pins

void setup()
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(“Rebooter 0.2”);
//0.1 it works!
//0.2 it works an is neater (lcd printing countdown, ip addr print not . after last octet, padding seconds)
lcd.setCursor(0, 1);
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {

lcd.setCursor(0, 0);
lcd.print(“IP DHCP CONFIG”);
lcd.setCursor(0, 1);
lcd.print(“Failed! Halting.”);
// no point in carrying on, so do nothing forevermore:
while (true) {
Serial.println(“no dhcp, halted”);

lcd.setCursor(0, 0);
lcd.print(“IP DHCP CONFIG”);
lcd.setCursor(0, 1);

//start the rc tx module

void loop()
ICMPEchoReply echoReply = ping(pingAddr, 4);
if (echoReply.status == SUCCESS)
lcd.setCursor(0, 0);
lcd.print(“Ping succeeded.”);
“Reply[%d] from: %d.%d.%d.%d: bytes=%d time=%ldms TTL=%d”,,
millis() –,

starttime = millis();
currtime = starttime;
long prevtime = starttime;

while (currtime <= starttime + cycletimeout) {
if (currtime >= prevtime + 1000) {
//update the lcd every second
lcd.setCursor(0, 1);
lcd.print(“retest in: “);
lcdPrintSecondsQuad(((starttime + cycletimeout) – currtime) / 1000L);

prevtime = currtime;
currtime = millis();

sprintf(buffer, “Echo request failed; %d”, echoReply.status);
lcd.setCursor(0, 0);
lcd.print(“Ping failed”);

//ensure ping has failed twice consecutively
if (looptwice == true) {

lcd.setCursor(0, 1);
lcd.print(“Switching off…”);
/* See Example: TypeB two rotary */
mySwitch.switchOff(4, 4);


lcd.setCursor(0, 1);
lcd.print(“Switching on…”);
mySwitch.switchOn(4, 4);

lcd.print(“Waiting 1 minute”);
lcd.setCursor(0, 1);
lcd.print(“please wait…”);
looptwice = false;

starttime = millis();
currtime = starttime;
long prevtime = starttime;

while (currtime <= starttime + cycletimeout) {
if (currtime >= prevtime + 1000) {
//update the lcd ever second
lcd.setCursor(0, 1);
lcd.print(“reteest in: “);
lcd.print(((starttime + cycletimeout) – currtime) / 1000L);
prevtime = currtime;
currtime = millis();

else {
lcd.setCursor(0, 1);
lcd.print(“retest in 15s”);

looptwice = true;

starttime = millis();
currtime = starttime;
long prevtime = starttime;

while (currtime <= starttime + retrytimeout) {
if (currtime >= prevtime + 1000) {
//update the lcd ever second
lcd.setCursor(0, 1);
lcd.print(“retest in: “);
lcdPrintSecondsQuad(((starttime + cycletimeout) – currtime) / 1000L);
prevtime = currtime;
currtime = millis();


void printIPAddress()
Serial.print(“My IP address: “);
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
lcd.print(Ethernet.localIP()[thisByte], DEC);
Serial.print(Ethernet.localIP()[thisByte], DEC);
if (thisByte < 3) { //dont dot if last octet


void lcdPrintSecondsQuad(int digit)
/* A ten percent reduction in input voltage
will cause the lower bound to drop by ten.
This sketch is calibrated for ~4.9-5.1v
using the linksprite LCD shield. */
if (digit < 10)
{ // 9s
lcd.print(” “);
lcd.print(digit, DEC);
else if (digit < 100)
{ // 99s // 10s
lcd.print(” “);
lcd.print(digit, DEC);
else if (digit < 1000)
{ //999s //100s
lcd.print(digit, DEC);
else if (digit > 999)
{ //1000s
lcd.print(digit, DEC);

Links to guides for some of the projects i’ve tried:

  • Raspberry ambilight clone for Raspbmc/OSMC (Kodi on Linux) – Hyperion Project:

    WS2812b leds providing ambilight like backwash

  • Raspberry pi hardware watchdog timer (reboot on crash using kernel module, only requires raspberry pi, no external hardware) – Raspberry pi Watchdog timer

Ps sorry this post is long and a bit rambly, it was written across a few years!

PPS if anyone knows how to get wordpress to display C++/Arduino sketches nicely with syntax highlighting etc, please let me know in the comments!

Arduino Variable Types Explained

Here’s something for reference.
I can never find just quite the succinct reference to Arduino Variable types. Nowhere could i find a list of minimum and maximum values, the bits, and the memory used by each variable type.

Neither was there any clear definition of meaning of ‘unsigned’, which just means no plus or minus signs in this type – that is all numbers positive. This increases the highest number that can be stored in the same memory. (thank me in the comments).

Usage Variable type Bits Min value Max value Ram usage Comments
common boolean 8 TRUE FALSE 1 byte
common byte 8 0 255 1 byte
char 8 -128 127 1 byte  A single ‘character’ e.g. ‘a’ is a single char.  Represented by chr(65) or the binary: 01000001
word 16 0 65535 2 byte
common int 16 -32768 32767 2 byte
unsigned long 32 0 4,294,967,295 4 byte
common long 32 -2,147,483,648 2,147,483,647 4 byte
common float 32 -3.4028235E+38 3.4028235E+38 4 byte
The below types are only included for compatibility or further study.
redundant unsigned char 8 0 255  1 byte use byte instead
redundant unsigned int 16 0 65535  2 bytes use word instead
redundant double 32 -3.4028235E+38  3.4028235E+38  4 bytes use float instead
The below types are special types (see
special string variable  1 byte + x An array of chars
(used for storing strings to modify)
special enum variable  N/A Like boolean but custom fixed set of values allowed instead of TRUE/FALSE.
special struct variable  N/A Public sub variables
(as if you’d made a public class)
special pointer  N/A I’ll be honest, I wasn’t sure the use of this one. Here for completeness though!
Remark: “Unsigned” means no negative sign. This increases the range of positive numbers available.
Remark: Unsigned variables that exceed their capacity roll over back to zero. This could be useful to iterate through arrays of limited length

PPS If anyone can figure out how to properly format this table so it looks nice, with ‘center’ aligned text, please let me know wordpress was being frustrating!

(The formatting css is in the source, see the table tag)

Find Windows workstation logon script

This is a super quick tip from an online forum…
[ Where is the location for the windows logon script?]

If you’re looking for the location of the active logon script in a Windows domain network on a workstation, or just to figure out which logon script is being used for a workstation

TLDR; ‘Get to the point, where is the bleeding thing?!’:

To find the location of a user’s logon script, while logged in as the user, run the command:
net user “%USERNAME%” | find “Logon script”
or for a domain user,
net user “%USERNAME%” /domain | find “Logon script”

Standard location

The logon scripts themselves can be found on the network in the standard domain network share location:


Additionally, the commands:

net user “%USERNAME%” /domain


gpresult /r

Give interesting results for the current user and what Group policy rules are active for the currently logged in user/(machine?) respectively.

Obviously this is only relevant to windows computers in active directory with primary domain controller and group policy ordaining that each machine should run a logon script.


Search Terms:

Things i searched for in order to try and find this out:

  • find out what logon script a computer is using
  • find path of logon script from workstation
  • find path of logon script from workstation registry

(I couldn’t find the registry location as it turns out!)

If this post helped you, or you have additional tips, please leave them in the comments!

Excel tip – adding two numbers where one is text

Just a quick tip as i couldn’t quickly find the answer in google.

If you have two cells of data and you want to add them when one might have text instead of a number, use the SUM function.

For instance

Class Section 1
Section 2
Robots 10,000 1,000 =sum(B2:C2)
Humans 9,000,000,000 n/a =sum(B3:C3)
Plants n/a n/a =sum(B4:C4)

I also searched for: sum two values if isnumeric, excel add two numbers if text only include the non text and excel add two numbers if text.

Three Mobile Hotspot MITM Attack?


Is three performing a Man In The Middle SSL attack/proxy on my mobile hotspot?

Loading paypal:


Well hello NSA & GCHQ lol.

Funnily enough after searching Google for this issue and then retrying I don’t get some asshat trying to proxy my SSL connection. Or if they are they have a ‘genuine’ root certificate from a valid CA.

Project Teaser


Heres a little something that has come about from a related project I have built (and need to test)

Maybe I’ll write up both projects together!

Relevant hashtags #RaspberryPi #HTML5  #WS2812b


An explanation more beautiful than my words could ever be:
Giving Is The Best Communication – Thai Mobile Ad…:

The World full of horrible injustices, life is cruel and unfair. Survival of the fittest is now survival of the richest.

And the worst thing?
It feels like you’re just too powerless, poor or insignificant against the size if it.

Starvation, Cancer, HIV, Natural disasters whatever.

Well the truth is there is something you can do to change the world.

And its cheap, and simple and should make someone smile.

Its called A Random Act Of Kindness or RAOK.

Just do one small thing to improve the life of a stranger.
See that a Girl sobbing? Go give her a tissue.
Give your elderly neighbour a Christmas card or invite him round for a cup of tea.
Hold the door open for someone.
Carry a lighter just in case someone asks for a light.
Give out free hugs (I did this once. It was hugely fun. I made sure I got all the people with the saddest expressions 😉 ).

Have a think. Be good to people, even if you don’t know them.

Leave a note that says ‘pass it on’

Now you may never know the difference that a small random act of kindness makes to that stranger. But this is not about fame or fortune, its about changing the world one small random act of kindness at a time.

My hot tip? Why just one RAOK?

Share the love.

And Dear stranger,
If you find this, pass it on, and have a brilliant week!
(I know my name is on here, but who I am doesn’t matter. Thank me by doing a RAOK and asking them to pass it on 😉 )