Tuesday, 20 December 2016

Arduino 3D Printed Binary Clock

Ok, so I wanted to build something to use as a clock in the office. But I didn’t want to build a conventional one. With some research into existing designs and different ideas (and being an electronics self-confessed geek) a Binary clock fitted the bill.
What is a binary clock? Put simply the time is displayed by lit and unlit LED’s arranged into a Binary configuration. Here's a quick guide to reading the time. It's a 12 hour format as per most wrist watches / office clocks etc as this helps to keep the total number LED's down and is quicker to read.

The example above would read 4:36. Common sense will tell you if this is AM or PM!!
Using an Arduino nano as the basis for the clock was an easy choice as I had one to hand, the size is small and it has its own mini B USB port for easy clock setting / programming and for power. One issue with the Arduino though is that the internal clock is not very accurate over longer periods of time and you have to contend with stack overflow plus when power is lost the time is lost. The best thing to do here is to add a RTC (real time clock) module to the project to keep accurate time and they come with their own battery back up in case of power loss. I opted for the DS3231 as its accuracy is around 1 minute per year. You could also use a DS1307 which is slightly less accurate but still good enough. Both these modules communicate over the I2C bus and you’ll need to download the RTC Arduino library from here.

Arduino, Screen, DS3231 & RHT03
The LED’s in each column share common power connections which are connected to digital pins 9, 10 and 11 as these are PWM pins so the LED brightness can be controlled. The negative side of the LED’s are connected individually via a 470Ω resistors to the Arduino. (pin outs can be seen in the circuit diagram). The 470Ω resistor kept the current draw through each LED at about 5mA so at the worst case 8 LED’s could be lit at the same time, the total max current draw would be about 40mA form the LED’s. We are both powering the LED’s and sinking them through the Arduino so the Arduino is handling 80mA total and 15mA maximum pin draw so well within the Arduino’s capability.

LED Modules ready to install
I also had a RHT03 (DHT22) temperature / humidity sensor knocking around and thought it would be nice to add this functionality too. Using the DHT22 Arduino library it was easy to interface this with the rest of the clock. Library available here.

The display screen to present the temperature and humidity readings was a 0.96” (128x64) OLED display module seemed a good choice as the size is small with good resolution and it also runs on the I2C bus so it doesn’t need any more pins on the Arduino. I’m using the Adafruit graphics library for this screen which can be downloaded here.

Setting the clock is done via a dedicated setting Sketch. The program takes the PC time and date at the point the sketch compiles and loads it directly to the clock. The sketch is largely the same as the normal program except it sets the time during the setup routine. With the power still on to the Arduino you need then need to load the normal clock sketch back into the device. If the power is turned off between loading the setting program and the normal running program then the time will be reset when the power comes back on to the same time the setting program was compiled which will now be incorrect. Time setting should only be required twice per year when daylight saving starts and finishes. A future update maybe to add daylight saving an automatic feature?

Circuit Schematic for the Clock
Next phase was to design the housing. I had about 6 different ideas from a tower to a zigzag but ended up with a cylinder as it was easier to package the electronics and the screen. It looks pretty good too (I might be a bit biased). I used DesignSpark Mechanical from RS Components to complete the 3D model for the housing and base. DesignSpark is a free 3D design software which can be downloaded from this link. It’s very easy to use and has most features readily available. You could also use SketchUp which is also free and widely used with lots of online tutorials. Ultimately you need a .stl 3D file to send to the printer. I used www.3dhubs.com to do the printing for me as I don’t want to invest in a 3D printer. 3D Hubs is an online printer sharing website which will print in various materials at reasonable prices and is available in lots of countries.

3D printed case. A little bit of cleaning up is required.
Clock Sketch
Clock Setting Sketch
Main Unit 3D File
Base 3D File

Everything fits, but it is tight
This is purely a blog of what I did to make a Binary Clock. No warranties or gaurantees are given. I hope this inspires others to build unusual clocks but you would do so at your risk. 

Tuesday, 24 May 2016

Digital Pit Board

I wanted to make an upgrade to our ageing Pit Board which was simply a square piece of carbon fibre with the word ‘In’ written on it in yellow tape. Given that we race in darker conditions (24hr races and dark indoor circuits) we needed something that was lit up in some way. We also can run 3 or 4 different teams in one race so we had to ensure the right kart was being signalled. After some careful (and some not so careful) consideration a double digit LED pit board was born. The board is made up of 14 segments with 4 white straw hat LED’s in each segment. Each segment is then switched on or off using an IRL510 Mosfet (a bit over kill but I had some lying around) mounted on each segment. The IRL510’s are then controlled by an Arduino (Nano) as the basic controller for the board. There is an IRF9530 (P Channel) Mosfet on the positive side to give the PWM and flashing capability.

The numbers are selected via a 16 digit keypad on the back of the board which I converted to use only 1 Arduino pin (see below for the conversion details).

The front and back are 3mm acrylic sheet with a wooded frame in between. This was then drilled for each individual LED. The overall size is the same as an A4 piece of paper.

Unlit Board

Circuit diagram for each segment
Arduino Pin Out Diagram + the Power Control via IRF9530
All 14 segments wired on stripboard and connected to the Arduino via the 220Ohm resistors

Power Consideration:
In a 24hr race we would normally do 11 pit stops with an average of 2 minutes of lit pit board per stop gives 22 minutes per team. We can run 4 teams so that means the battery life has to exceed 88 minutes (I used 2 hours as the target for safety). Each segment runs 4 Parallel LED’s each consuming 20mA so each segment uses 80mA.  If the number 88 was used then all 14 segments would be lit and this would consume 1120mA or 1.12A. So we would need a power source capable of around 1A and at least 2200mAh. At this point the voltage wasn’t a major consideration as the LED resistors could be adjusted to compensate providing they were higher than 3.5v when almost empty. I first looked at Li-ion receiver packs as used in radio controlled cars etc. These have more than enough power and reasonably priced. However, they also require specialist chargers which can add considerable cost, especially if you wanted to charge them from your car or trackside. In the end I decided to use a 5v USB power bank as I already had 3 basic 2600mAh ones lying around in draws. The other advantage to using a power bank is they are very easy to re charge almost anywhere and can easily be swapped. The basic ones will cost less than £5 and deliver 1A output (not quite enough if 88 is required but you can’t see the LED de-rating with the naked eye). Given that these are really 3.7v li-ion batteries which are converted to 5v there is some loss in the conversion so the 2600mAh rating is probably more like 2000mAh at 5v, but this should give 2 hours of run time before re charging.

Rear showing the key pad and the 5v power bank

Making the 16 digit keypad work with 1 Arduino pin:
Converting an 8 pin, 16 digit keypad to use 1 Arduino pin is relatively simple and there are many versions available via google. Essentially we will make each row and each column have a different resistance creating a unique voltage for each key and as a result any of the analog pins on the Arduino can read this voltage and work out which key was pressed.
Resistor used to convert key pad to use a single pin

Power on via the rear mounted power switch will bring the device on and a zero will be displayed on the board (this is to show the user its on and ready but also its to draw power on the power bank, Typically power banks require at least 50mA draw to stay switched on). The first key press will then move the zero to the left digit and display the number on the right digit. The second key press will the move the right digit to the left position and add the new number to the right digit. The 3rd press will reset the board and return a zero to the left digit and the new number to the right digit.
i.e. 1st press = 5 then the board will display ‘05’.
2nd press = 7 then the board will display ‘57’.
3rd press  = 8 then the board will show ‘08’
There are also some other functions available, pressing the * key will toggle the flash function on or off. Press the ‘A’ key and the board will display ‘FL’, this could be used for fastest lap or a reminder to fuel the kart (which is what we use it for). Pressing the ‘B’ key will display a ‘P’ on the left digit, follow this with a number press and the display can then show race position. And finally the ‘C’ and ‘D’ keys will increase or reduce the display brightness.

The sketch is quite basic (it could probably be more basic). It starts by checking if a flashing function is set or not and then takes the appropriate action. After that it just loops waiting for a key press to occur. Once a key press occurs it then reads the voltage from the analog pin and then through a series of ‘IF’ statements works out which key was pressed. Once the key has been worked out it then takes the appropriate action.

Arduino Sketch available soon

Wednesday, 17 February 2016

IR Laptimer using Arduino

So here’s my problem, I love karting and take part in lots of different races from corporate grand prix to the British 24hr and anywhere in between. I wanted to record and display my lap times but didn’t want the expense of buying an off the shelf unit at over £500 (cheaper ones are available but I needed one which would record 24 hours’ worth of racing and more than 1000 laps). I also like to tinker with electronics so I decided I would see if I could make something instead (and hopefully it would be cheaper too).
Firstly I needed to work out which type of system to make, Infra-Red or magnetic pick up. Most karting tracks have a magnetic loop fitted in the track so in theory that meant using a hall effect sensor to pick it up. The problem is some track don’t have a loop and some have 2 or 3 loops (for intermediate timing) so this wouldn’t fulfil my requirements. I decided on the Infra-Red option as it was already used in professional systems and I could take it to any track, the down side is that I now have to build an Infra-Red transmitter as well.
Having then researched the IR option further I came across a very useful blog where Jim Ele had already built a similar timer which utilised an existing IR transmitter but used an Arduino as the processor. This would form the base of my build.

The Transmitter
The first part was to build the IR transmitter which would sit on the pit wall repeatedly sending out a set code. I simply built a home brew circuit board with the bare minimum to run the Arduino’s Atmeg328p processor as per the diagram below and attached 4 AA batteries for the power. I used 2 IR LED’s purchase from Maplin’s to send the signal out.
The power circuits have been simplified for the diagram
The next problem to overcome was how to avoid false triggers from other IR sources, I.e. other IR transmiters that could be at the circuit and also things like the Sun / strip lights etc. The answer was to use a 38Khz carrier frequency with a matched receiver and send out a specific code that the receiver would recognise (The same way your tv knows that you’ve pressed a certain button on the remote). Because the receiver isn’t in the beam for very long I needed a short code which could be received very quickly. After again looking at what Jim Ele had found out I decided to give 3 ‘On’ pulses each 416µs with a 1200µs ‘Off’ gap between each. After the 3 pulse there is a 6ms gap an then the code repeats itself. I’ve tried to show this visually below.

I housed all this inside a suitably side housing purchased from Maplin and attached an old mini tripod as a stand. Waterproofing is done by covering the whole box is a clear plastic bag with the 2 LED tubes sticking out. The total cost was less than £20 and has a range of about 20 meters. The AA batteries easily last for more than the 24hours I needed (more than 50 hours actually).
Finished Transmitter, The two small plastic tubes sit over the LEDs and are mainly for Aesthetics.

The Receiver
As the beam was using a 38Khz carrier frequency I needed an IR receiver that was set to that frequency so I opted for the TSOP38238 as it was easily available for a low price and had good performance and will run at 3.3v. The TSOP38238 receives the signal from the transmitter and inverts the signal as shown below.
 I housed this about half way inside a separate small box with a small window so that it could be attached to the front panel of the kart for best view of the transmitter. This also meant it wasn’t in direct sunlight. It was sealed closed to make it waterproof. A 3 core lead then connected it directly to the main unit on the steering wheel.

The Main Unit
Again I started with a basic circuit to support the Atmega328p processor. I then added a 16x2 LCD display module with LED backlighting (be careful here as the backlighting is the main current draw and can easily exceed 100mA with some models. I choose a module that had a single LED for backlighting to reduce the current consumption for optimum battery life). To record the lap times I added a microSD module. The microSD card also contains a text file which can be altered to tell the unit how long to ignore the receiver for (I’ll come back to this later)
The power circuits have been simplified in this diagram
Note: The system runs at 3.3v not 5 as per the diagram. Because of the change to 3.3v I also changed the IR receiver to a TSOP38238.

This was then housed into suitably sized box from Maplin with foam padding around the circuit board to protect it from vibration.

I then used a second identical box to house the batteries which was then mounted onto the back of the first box around the steering wheel. This meant it could be swapped from one kart to another very quickly and even attached to hire karts.
Originally I wanted to use 9v pp3 batteries for the power but an initial test showed these couldn’t stand the vibration and they destroyed themselves within an hour. I swapped these out for an RC car Ni-mh receiver pack battery – 6v 2500mAh and again wrapped it in foam. This works great and lasts over 30 hours per charge.

How the system works
As the receiver picks up the beam from the transmitter, the sketch checks the length of each pulse and counts them if they are the correct length. Once its counted to 3 it knows a ‘good’ code was received. If a pulse doesn’t fit the right time frame or no further pulses are received then the count is reset. After receiving a good code the sketch then works out the lap time (the time between the last ‘good’ code and this one) to the nearest 1000th of a second, increments the lap counter, works out the delta time to the fastest lap and adds it to the total time expired since the start of the race in hours and minutes. This is then displayed on the screen and also stored onto the micrSD card as a .csv file type and can be opened in excel. The system then ignores any signals from the IR receiver for a period of time, this period of time was set by the text file on the SD card as mentioned earlier. This time should be set to the best possible lap time minus 3 to 4 seconds. This way the IR cannot receive any false signals from other transmitters. About 4 seconds before you pass through the beam again the system starts looking for a beam again.

Receiver Sketch

A Note on using microSD cards: When reading and writing SD card can use quite a high current (200mA or more) so make sure your voltage regulator can handle it! Also they run at 3.3v not 5v so I run the whole system at 3.3v which means you need an LCD module capable of running at that voltage. I also used the SDFat library for this project not the standard Arduino one as the SDFat library (available from GitHub) puts the microSD card to sleep between read/write events which saves a lot of current and prolongs the battery life. The standard SD library keeps the card awake by default and it makes quite a difference.
Finally to make the unit rainproof I printed the front panel onto OHP transparency in reverse. The text was left blank and spray painted in silver afterwards. Turning the transparency over then reveals a nice shiny front cover with silver text and a clear window for the screen. This was double sided taped to the front and worked great.
The total cost for the unit was around £40

Further improvements coming.
I also tested a OLED 16x2 screen and this worked better than the standard LCD as no backlighting is required and its clearer in bright and dark conditions. I used blue text on a black background.

I’ve also started work on a unit with a 2.9inch graphical touch screen but its yet to make it onto a Kart. More on this one to come.

Laptimer Arduino Sketch

Sketch for the laptimer used here

Simply copy below into the Arduino sketch program.

/* Lap Timer for Team Barnato karting races by Matt Wall
Use at own risk, Sketch is in the public domain but no profit shall
be gained from using it.

 Pin allocation.
 d0 - No Connection
 d1 - display RS
 d2 - IR signal from IR receiver
 d3 - PWM signal for display backlight
 d4 - display data pin - d4
 d5 - display data pin - d5
 d6 - display data pin - d6
 d7 - display data pin - d7
 d8 - display Enable
 d9 - no Connection
 d10 - Sd Card CS
 d11 - Sd Card MOSI
 D12 - Sd Card MISO
 D13 - Sd Card CLK / SCK
#include <LiquidCrystal.h>// include the LCD library
#include <SdFat.h> // include the new sd card library
SdFat sd;
float lapdelay = 20000;// set the default lap delay to 20 seconds unless updated from SD card file.
SdFile myFile; // file to read SD card lap delay data
float decade;// to be used in reading sd card
float temp;// to be used in reading sd card
float number;// to be used in reading sd card
int backlight = 3;//PWM for display backlight to be connected to pin 3
int lapcount = 0;// start with a lap count of 0
long start = 500;//set values (system will random asign if left blank) will be changed later
long finish = 0;//set values (system will random asign if left blank) will be changed later
long laptime = 0;//set values (system will random asign if left blank) will be changed later
long elapsed1 = 0;//set values (system will random asign if left blank) will be changed later
long elapsed2 = 0;//set values (system will random asign if left blank) will be changed later
long oldlaptime = 0;//set values (system will random asign if left blank) will be changed later
long delta = 0;//set values (system will random asign if left blank) will be changed later
#define IRpin_PIN      PIND // assign pin 2 raw mapping to IRpin 2
#define IRpin          2

#define MAXhighPULSE 2000 // Time counts to reset tokens to zero if no beam detected incase of false trigger, 2000 * RESOLUTION = 40ms
#define MAXlowPULSE 28 // the maximum pulse count we need. 560us / RESOLUTION = 28
#define MINlowPULSE 18 // the minimum pulse count we need. 360us / RESOLUTION = 18

#define RESOLUTION 20 // Multiplier - will be used to take reading of IRpin every 20ish microseconds
int lowpulse = 0; // start with 0 for the pulse length.
int highpulse = 0; // start with 0 for the pulse length.
int token = 0; // start with 0 count for tokens. We'll need 3 tokens to trigger the timer.

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(1, 8, 4, 5, 6, 7);
const int chipSelect = 10; //choose the chip select pin for the SD card
SdFile myfile;

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  pinMode(backlight, OUTPUT);// Output for the PWM on the backlight
 // pinMode(10, OUTPUT);// must be set fot the SD Card to work
  lcd.print("  Team Barnato"); // Print a message to the LCD.
  delay(2000);// Wait 2 seconds before clearing the LCD.

  if (!sd.begin(chipSelect, SPI_HALF_SPEED)){// start up the sd card
    lcd.print("SD Card failed!");// Incase no SD card or problem with SD Card
  else{ //SD Card is ok
    lcd.print("   SD Card OK");// tell the world the sd card is ok
    delay(2000);//give people time to read the message
  if (sd.exists("times.csv")){//check if the file to record the lap times in already exists?
    lcd.print("    File OK");//tell the world it exists
    delay(2000);//give people time to read the message
  else{ //it doesn't exist
    lcd.print(" Creating File");//tell the world your creating the file
    myfile.open("times.csv", O_RDWR | O_CREAT | O_APPEND);// create the file
    myfile.close();// save the file
    delay(2000);//give people time to read the message
    if (sd.exists("times.csv")){// re check that the file exists after creating
    lcd.print("    File OK");//tell the world it exists
    delay(2000);//give people time to read the message
    else{// file still not available
      lcd.print("File Error");// tell the world the is a problem
      delay(5000);// give people time to read the message

  if (myFile.open("lapdelay.txt",O_READ)) // Open SD Card and retreive lap delay information.
      lapdelay = 0; // if the file is ok on the sd card then set lapdelay at zero ready for reading the correct delay
      decade = pow(10, (myFile.available() - 1));
      number = 0;
       temp = (myFile.read() - '0');
       number = temp*decade+number;
       decade = decade/10;
      lapdelay = number*1000;
  lcd.print("   Target Lap");
  lcd.setCursor(4, 1);
  lcd.print(" secs");
  lcd.print(" Ready To Race");
  lcd.setCursor(0, 1);
  lcd.print(" -- Out  Lap --");

void displayResult(){
  /*This procedure will calculate the laptime, delta time, display the result to the LCD screen, record the lap time to SD card (not yet working)
   and finally set a system delay to allow you to pass the start / finish straight without re triggering from other beams*/
  laptime=finish-start;// Calculate lap time
  if (lapcount>0){// will display times after completing the first flying lap.
    //This section works out the actual lap time
    float m1,s1,ms1;// create variables for hours,minutes,seconds and milliseconds
    unsigned long over1;// create variable for the calculation over spill
    m1=int(elapsed1/60000); //Calculate the minutes
    over1=elapsed1%60000; // Work out the remainder
    s1=int(over1/1000);// Calculate the seconds
    ms1=over1%1000;//work out the milliseconds
    lcd.setCursor(0, 0);// Set cursor to top left position.
    lcd.print("LAP");//Print text to LCD
    lcd.setCursor(9, 0);
    if (oldlaptime<laptime)// If the last lap was less than the new lap then the delta needs to be a plus value
      lcd.print("+");//shows these values on screen if new lap was slower then previous lap
    else// If the last lap was more than the new lap then the delta needs to be a minus value
      lcd.print("-");// shows these if your new lap was quicker then the last
    float s2,ms2;// create variables for seconds and milliseconds
    unsigned long over2;// create variable for the calculation over spill
    s2=int(delta/1000); // work out the delta time
    ms2=delta%1000; //work out the milliseconds
    lcd.print(s2,0);//print delta seconds
    if (ms2<100){lcd.print("0");}// if milliseconds is below 100 we need to add a zero
    if (ms2<10){lcd.print("0");} // if milliseconds is below 10 we need to add another zero
    lcd.setCursor(0, 1);// move cursor to second line first character
    lcd.setCursor(8, 1);// move cursor to second line 8th character
   if (ms1<100){lcd.print("0");}// if milliseconds is below 100 we need to add a zero
    if (ms1<10){lcd.print("0");} // if milliseconds is below 10 we need to add another zero
    if (myfile.open("times.csv", O_RDWR | O_CREAT | O_APPEND)){// Open SD Card File
      myfile.print("Lap,");//Start line with Lap
      myfile.print(lapcount);//add the lap count to the file
      myfile.print(",");//add a comma for use in excel later
      myfile.println(laptime);//save laptime and start new line
      myfile.close();// close and save the file
  else { // this section is only used during the first flying lap.
    lcd.print("   First  Lap");
    lcd.print(" Timer  Running");
  // This line reserved for entering the save to SD card routine
  start=finish; // set the new lap start time to the same value as the last lap finish time
  oldlaptime=laptime;// store new lap time as old lap time for next lap
  lapcount++;// increase lap count by 1
  token = 0; // reset token counter ready for next lap
  delay(lapdelay);// delay to prevent re triggering if other beams are present.

void loop() {
  highpulse = lowpulse = 0; // start out with no pulse length
  while (IRpin_PIN & (1 << IRpin)) { // while irpin is high - no beam is beam is being received.

    delayMicroseconds(RESOLUTION);// wait some time, the multiplier.

    if (highpulse >= MAXhighPULSE) { /* check to see if no signal has been received for over 40ms (we should
     recieve 3 tokens in 4ms, so if we only receive one or two tokens in 40ms it must be a false signal),
     then reset the token count if true as no/false signal is being received.
      token = 0;
      highpulse = 0;// reset high pulse counter
  while (! (IRpin_PIN & _BV(IRpin))) {// while irpin is low, signal being received
  if ((lowpulse >= MINlowPULSE)  && (lowpulse <= MAXlowPULSE)) {// was the pulse length what we expected?
    token ++; // if so then count 1 token, we need 3 tokens to trigger
  if (token == 3) { // If we receive 3 correct pulses then trigger the lap timer.
    finish=millis();// Record the time
    displayResult();// run through the display procedure

IR Transmitter Sketch

Sketch for the IR transmitter used here

Simply paste below into the arduino sketch window.

/* This is the beam pattern for the Team Barnato timing beacon. Use at own risk and no warranties are given.
in Micro Seconds
On - 468 uS
Off - 1200 uS
On - 468 uS
Off - 1200 uS
On - 468 uS
Off - 6000 uS */

int IRledPin =  3;    // LED connected to digital pin 3
int powerLed = 13;    //Power LED is connected to pin 13

void setup()   {              
  // initialize the IR digital pin as an output:
  pinMode(IRledPin, OUTPUT);
  pinMode(powerLed, OUTPUT);
  digitalWrite(powerLed, HIGH);
  digitalWrite(powerLed, LOW);

void loop()                  

// This procedure sends a 38KHz pulse to the IRledPin
// for a certain # of microseconds.
void pulseIR(long microsecs) {
  // we'll count down from the number of microseconds we are told to wait

  cli();  // this turns off any background interrupts

  while (microsecs > 0) {
    // 38 kHz is about 26 microseconds - to give 50% duty cycle 13 microseconds high and 13 microseconds low
   digitalWrite(IRledPin, HIGH);  // this takes about 3 microseconds to happen
   delayMicroseconds(10);         // hang out for 10 microseconds
   digitalWrite(IRledPin, LOW);   // this also takes about 3 microseconds
   delayMicroseconds(10);         // hang out for 10 microseconds

   // so 26 microseconds altogether
   microsecs -= 26;

  sei();  // this turns them back on