OutoSoft

Odd Software for Odd Jobs

DarcyBot, Mk. 2

This is the second iteration of the first 'robot' I ever built with my eldest son Darcy.

The first was a fairly bog-standard robot - it had two bumper-switches at the front. Move forward until one or both are triggered. Back-off, turn a bit, then proceed.

That was fun. We learned how to use H-bridges to control motors and how to make simple decisions.

We figured a new challenge would be to understand how to interface discarded bits of electronics - in this case, we had the transmitter and receiver of a broken remote controlled police car.

You can see the final result below - we even kept the flashing red/blue lights.

2016-01-31 21.16.40

The transmitter/controller was re-housed in a new box. Pretty simple - just wire up new buttons for forward/reverse/left/right to the circuit board and add a new battery holder:

2016-01-31 21.15.17

The robot itself is built upon a tracked chassis (Jaycar KR-3130, seems discontinued). In the picture below you can see the separate parts:

2016-01-31 21.09.58

The brain is a Freetronics Eleven (Arduino Uno compatible). There are then two shields plugged into the Arduino. The first shield, sandwiched in the middle between the Arduino & the top shield, is the H-bridge. We used a pair of L6202 full-bridge drivers, one for each side of the robot.

2016-01-31 21.10.22

On top of this is another shield that is used to interface the Arduino with the receiver from the broken toy car. The receiver is attached with some double-sided tape (high-tech). The black & red wires are for the flashing lights and the yellow wires are the control signals received from the transmitter - backwards, forwards, left, right.

2016-01-31 21.11.04

The control signals are fed into the Arduino via the analogue inputs. These are simply read and the motors controlled appropriately.

So, from this exercise we learned:

  • What are H-bridges and how they're used to control the direction of motors
  • How to program simple intelligence into a robot to allow it to make decisions based on stimuli
  • How to interface discarded bits of electronics to allow wireless control of completely different devices
  • To never throw away remote control stuff - it can be re-used for simple, one-way wireless communication (i.e. a weather station sensor)

The next iteration of the DarcyBot will probably be some sort of line or light follower - this will teach us how to use visual inputs.

Average Speed Calculator, part 3

Took my little average speed calculator for a quick field-test around the local streets. Seems to be doing the job I wanted it to. Need to enlist the wife's help to do a proper test at highway speeds.

Field test

I also added a sixth screen of information - the maximum speed recorded and the timestamp:

LCD6

I still need to sort out the localisation of the date from the UTC date received. And also tidy up the code - add some more functions instead of just replicating the code (I feel terrible about it!).

Average Speed Calculator, part 2

I have got my prototype ready for field-testing, i.e. driving around in a car.

The final parts list is:

  • Freetronics Eleven (Arduino Uno compatible)
  • GPS module using a u-blox NEO-6M (board is labelled "GY-GPS6MV2")
  • 16x2 LCD display (labelled "JHD162A")
  • Two SPDT microswitches that I've soldered onto the prototyping area of the Eleven (Jaycar SM-1036)
  • 10kΩ potentiometer to control the LCD contrast
  • 1 x 4.7kΩ, 3 x 10kΩ, 1 x 220Ω resistors

The 4.7kΩ & one 10kΩ resistor are used for the GPS module's Tx pin to the Arduino (the GPS module uses 3.3V).
The 220Ω resistor is connected between the LCD display's pin 15 (LED+), the backlight anode, and the Arduino's 5V supply.
The final two 10kΩ resistors are connected between the switches and the Arduino.

One of the buttons is used to switch between five screens of information:

Screen #1 - current speed and altitude

LCD1

Screen #2 - when speed averaging is activated (i.e. when you pass under the first point-to-point camera), it shows the duration since it started and the current calculated average. The asterisk indicates whether the average is currently being updated (asterisk) or is from the previous activation (no asterisk)

LCD2

Screen #3 - current latitude and longitude

LCD3

Screen #4 - number of visible satellites and the current HDOP

LCD4

Screen #5 - finally, the current date & time - the date/time is received in UTC so I've hardcoded +11 hours to compensate for current Sydney DST

LCD5

Oh, bugger - I haven't bothered compensating the date either. Okay, still some polishing to do.

Anyway, the Freetronics Eleven can be run off 5V via the micro-USB or 7-12V so I have the option of wiring up a cigarette lighter plug to power it or simply use a cigarette light -> USB plug.

If it seems to be accurate - I'll measure against my TomTom - then I'll move to the next step and create a proper hardwire prototype in a jiffy box.

Here's the current Arduino code if anyone is interested - I used Mikal Hart's 'kitchen-sink' example from his TinyGPS++ library as the basis.

Average Speed Calculator

There are now a few point-to-point speed cameras on the highways in Australia. These apparently calculate your average speed over a fixed distance by snapping your number plate at the start point and then again at the end point. Now I know that my car's speedometer under-reports by about 10% - if it says I'm doing 100km/hr then I'm actually doing about 92km/hr. I've confirmed this from both my TomTom SatNav and by the road-signs they have roadworks that flash your speed up at you.

So I was wondering if I could hack something together to get a rough estimate of what my average speed is in real-time. I got a GPS unit off eBay some time ago but never got around to trying it out - it's a uBlox NEO-6M (marked GY-GPS6MV2).

Anyway, I finally gave it a go using the TinyGPS++ library by Mikal Hart.

And it worked pretty much straight away! Too easy. Thanks Mikal!

I wanted to use an e-ink/e-paper display so it would be nice and clear. I'd also gotten a 2.7" screen with developer board from Adafruit some time ago, but again had put it aside whilst I worked on other things.

So this was my starting point:

2016-01-26 07.15.08-1

The e-paper display was a harder to get going - a lot harder. The instructions on how to put it together were clear enough, but I found a lot of difficulty getting the examples to work. I finally got one of the examples to work using an Arduino Mega. Unfortunately, it seems the available libraries are slanted towards graphics rather than just text. As I'd gotten the largest 2.7" version, it turns out there's not enough memory to really run it properly. I'd have been better off using the 2" model perhaps.

So that was a disappointment. I might re-visit this later. In the meantime, I had a few 16x2 LCD displays lying around, so put one to use pretty quickly & simply. Unfortunately the contrast was all wrong (I'd used a 1kΩ to ground and a 10kΩ to 5V), but you can just make out the latitude and longitude from the GPS unit being output on the LCD:

2016-01-27 18.46.20-1

I sorted the LCD contrast issue pretty quickly by replacing the two resistors with a 10kΩ pot (blue). I've also added a momentary action switch to the small prototyping area on the Freetronics Eleven board to use as a start/stop button. Added some quick de-bouncing code and it was working as desired.

2016-01-27 20.09.36

So the next step will be to figure out how I want to calculate the average speed - so I just average the speed that the GPS unit reports, or do I actually calculate the distance travelled and divide by the time between start & stop button pushes … ? Something to figure out later.

As I'm limited to just a 16x2 display at the moment, figuring out how to display the info I want might be the biggest challenge! But let's see.

Gotto Time

This is my most ambitious project from about three years ago.

I wanted to create a 'wall clock' for my workspace in the garage. It would do the following:

  • Initialise the current local time via NTP,
  • Store the result to a battery-backed real-time clock,
  • Check the current temperature (and humidity),
  • Alternately output the time & date and then the temperature & humidity via two four-digit seven-segment LED displays,
  • And finally, upload the data to my website so I can lazily check the temperature in the garage from anywhere in the world!

I had a breadboard version pretty much working. The hard-wired version was about 80% complete when I got bored (about three years ago).

This is the state it's been in for a while - pretty much done except for the LED display wiring.

It's in two parts - the 'shield' that I'm building sitting on-top a Freetronics EtherTen.

Grotto Time

This is how it will look when assembled:

Grotto Time, assembled

And this is the underside view - you can see the LEDs haven't been soldered in yet:

Grotto Time, underside

I had some issues fitting all the code into the 32kB available - I think I had to exclude the NTP code as I originally developed it on an EtherMega or something.

Anyway, it was working! The webpage were the data was uploaded is still 'working' … just waiting for new data:

http://www.outosoft.com.au/arduino/

Let's see if I can get it working!

Temperature & Humdity

This is one of my very early experiments with Arduino that succeeded in the move from idle breadboard tinkering into a "manufactured product".

I built a thermometer for my son. It comprises:

  • an Arduino Micro,
  • a DHT22 temperature & humidity sensor (labelled "AM2302"),
  • a two-digit, seven-segment LED display (labelled "CA15621BS", common anode),
  • a 10kΩ resistor for the DHT22,
  • seven 680Ω resistors for the LED display,
  • a SPST temporary action pushbutton,
  • a 9V battery,
  • and an iPod touch case

The result can be seen below:

Temperature Gauge 1

Temperature Gauge 2

(Probably could've made the black negative wire from the switch to the circuit board a little longer)

Why a momentary action switch? I didn't trust that my young son would remember to switch it off after quickly checking the temperature - so you need to hold the button down to check the temperature. So far I've never had to replace the 9V battery!

The LED display alternates between temperature and humidity. As I live in Sydney and the display is limited to two digits, there is no expectation that negative temperatures are needed. Actually, checking the code I wrote, it seems that I don't bother checking the temperature result at all - I think I assumed that the temperature returned by the DHT22 will always be above freezing point (0 Celsius)! Maybe I need to do some cold weather testing, or at least add some sanity checking! Anyway, it's safe for Sydney usage at least.

The code is here.

Here's a short video of it in action.

Bike Sonar, 2nd test run

Took it for a quick test run this morning. No traffic around so I couldn't properly test it, so I rode past some parked cars instead!

Here's a screen grab from the Fly6 video.

Fly6 screengrab

An idea for a different implementation - replace the LED display with a Bluetooth module and feed the data to an app on my phone. This would be an opportunity to both figure out how to implement BT in my Arduino projects and also how to write an iOS app.

Anyway, refinement continues. I will probably replace the LeoStick with an Arduino Nano clone so I can run it off a 9V battery and thus enclose the ultrasonic sensor, Arduino and battery in a more-waterproof Jiffy box or similar. I could probably do the Bluetooth version at the same time so the whole sonar would be in a single box - much less fiddly.

I'm having fun regardless of how useful this may turn out to be!

Bike Sonar, Arduino code

Here's the Arduino code of the prototype I've got running on my bike after a bit of cleanup.


// Simple "bike sonar" ... aka rear parking sensor for a bicyle Winking
// Version 1.1, Brett Hallen, 2016
// Uses: HR-SC04 ultrasonic sensor,
// MAX7219 LED driver,
// four-digit LED display,
// and a piezo buzzer (Jaycar AB-3459)
// Implemented on my bike using a Freetronics LeoStick - requires 5V
// so powered with a "USB battery bank"

// http://playground.arduino.cc/Main/LedControl
#include "LedControl.h"

// http://playground.arduino.cc/Code/NewPing
#include "NewPing.h"

/* ---------------> Sonar Stuff <--------------- */
#define triggerPin 7
#define echoPin 6
#define maxDistance 400 // the HR-SC04 has a max range of about 450cm
#define triggerDistance 100 // when to trigger buzzer, in cm
#define pingDelay 50 // pause between sonar pings
NewPing sonar(triggerPin,echoPin,maxDistance);

/* ---------------> LED/MAX7219 Stuff <--------------- */
#define Din 8
#define CS 9
#define CLK 10
LedControl lc = LedControl(Din,CLK,CS,1);

/* ---------------> Speaker Stuff <--------------- */
#define speakerPin 12

void setup()
{
int i = 0;

// for verification of ping result to serial monitor
Serial.begin(115200);

// initialise the LEDs
lc.shutdown(0,false);
// Intensity between 0 (lowest) and 16 (highest)
lc.setIntensity(0,10);
lc.clearDisplay(0);

// Bit of fancy "I'm powering on, running setup()" indication
// print 0123 on LED
for (i=0;i<=3;i++)
{
lc.setChar(0,i,i,false);
delay(100);
lc.setChar(0,i,' ',false);
}
// print 3210 on LED
for (i=3;i>=0;i--)
{
lc.setChar(0,i,i,false);
delay(100);
lc.setChar(0,i,' ',false);
}

// initialise speaker output
pinMode(speakerPin, OUTPUT);

// setup done
playTone(500,700);
}

void loop()
{
// pause between sonar pings
delay(pingDelay);

// send a ping
int uS = sonar.ping();

// calculate distance in cm
int distance = uS / US_ROUNDTRIP_CM;

// print distance on the LED
printDistanceOnLED(distance);

// object closer than minimum distance?
if (triggerDistance > distance)
{
// closer the object, the faster the 'beeps'
int toneDelay = distance * 5;
// turn on LEDs
lc.shutdown(0,false);
playTone(toneDelay,500); // beep
delay(toneDelay); // pause
playTone(toneDelay,500); // beep
}
else if (250 < distance)
{
lc.shutdown(0,true);
}
}

void printDistanceOnLED(int distance)
{
int metres = distance / 100;
distance = distance - metres * 100;
int cms_tens = distance / 10;
int cms_ones = distance % 10;

// only display digits if non-zero
// no need for thousands digit
lc.setChar(0,0,' ',false);

// display hundreds digit?
// yes if it is non-zero
if (metres)
{
lc.setDigit(0,1,(byte)metres,false);
}
else
{
lc.setChar(0,1,' ',false);
}

// display tens digit?
// yes if it is non-zero or we already have displayed the hundreds digit
if ((cms_tens) || (metres))
{
lc.setDigit(0,2,(byte)cms_tens,false);
}
else
{
lc.setChar(0,2,' ',false);
}

// display ones digit?
// yes if it is non-zero, or we already have displayed the hundreds or tens digit
if ((cms_ones) || (cms_tens) || (metres))
{
lc.setDigit(0,3,(byte)cms_ones,false);
}
else
{
lc.setChar(0,3,' ',false);
}

// for verification to serial monitor
Serial.print(metres); Serial.print("."); Serial.print(cms_tens); Serial.print(cms_ones); Serial.println("m");
}

// duration in milliseconds, frequency in Hertz
// http://michael.thegrebs.com/2009/03/23/playing-a-tone-through-an-arduino-connected-piezo/
void playTone(long duration, int freq)
{
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(speakerPin,HIGH);
delayMicroseconds(period / 2);
digitalWrite(speakerPin, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}

Bike Sonar, part 4

So this is what I've ended up with for mounting on my bike - bit of wood, a lot of cable ties, a bit of galvanised steel and some bolts (that has holes that perfectly lined up with where my red reflector was).

2016-01-16 15.17.33

Bike Sonar

2016-01-16 15.18.05

The display is mounted so that the distance is captured on video by my Cycliq Fly6.

I made the mistake of running the LeoStick from a 9V battery - whoa, that smelt bad when it blew! Silly mistake - I'd earlier used an Arduino Nano clone that happily ran off a 9V and had assumed the LeoStick was the same (when you assume, you make an ass out of u and me … but just me in this case).

So down to Jaycar to grab another LeoStick. But how to power it? There's no 5V batteries - could I used 6V directly? Probably not - I'd have to add a voltage regulator to my circuit to knock it down to 5V - a bit of a re-design after all that fiddly soldering I did!

But then got the idea to use one of those USB battery banks you can recharge your phone with.

Unfortunately, the battery bank I got is too clever … it can tell a phone isn't plugged in and so switches off. As a workaround, I have to plug my phone into the second USB output socket (shaking head).

I took it for a test ride … and it worked! Unfortunately, the cycling infrastructure around where I live is pretty good - lots of bike paths, so I didn't really get a chance to ride on the road. But I simulated by riding up close to parked cars.

First thing I realised … an LED display is not much use in the middle of the day! Not bright enough. Anyway, made some tweaks and did a static test after I got home.

Bike Sonar, part 3

Now, the idea seems to work on a breadboard.

To properly test it, I need to move it to something that can be attached to a bike and powered off a battery.

My original idea was to have the Arduino, ultrasonic sensor, LED display driver mounted on one circuit board at the back of the bike and the LED display mounted remotely on the handlebars.

Bike sonar, original plan

Slept on it, then decided to use a Freetronics LeoStick with the ultrasonic sensor mounted above it on a ProtoStick. The piezo buzzer, LED display and driver IC would then be mounted separately and I'd use my Cycliq Fly6 to record the results.

Bike sonar, new plan


This is what I ended up with - my original breadboard prototype at the top and the bike-ready prototype at the bottom:

2016-01-16 11.53.52

I had an old DSLAM serial-port cable handy with a handy ten-pin connector so I used that to link the two circuit boards.

Moving to the LeoStick required some port changes … note to self … solder the components to the ProtoStick first … and THEN solder in the male header pins (damn amateur).

Anyway, it worked pretty much straight away! Phew.

Next step - somehow mounting it on my bike!

Bike Sonar, part 2

The Arduino is coded up and it seems to be working!

Here's the Arduino code - pretty simple.

(sorry, I don't know how to display code all fancy-like at the moment!)


#include "LedControl.h"
#include "NewPing.h"

/* ---------------> Sonar Stuff <--------------- */
#define triggerPin 12
#define echoPin 10
#define maxDistance 400
NewPing sonar(triggerPin,echoPin,maxDistance);

/* ---------------> LED Stuff <--------------- */
#define Din 7
#define CLK 8
#define CS 9
LedControl lc = LedControl(Din,CLK,CS,1);

/* ---------------> speaker Stuff <--------------- */
#define speakerPin 11

#define triggerDistance 100 // cm
int i = 0;

void setup()
{
Serial.begin(115200);

// LEDs
lc.shutdown(false,0);
lc.setIntensity(0,8);
lc.clearDisplay(0);
for (i=0;i<=3;i++)
{
lc.setChar(0,i,i,false);
delay(100);
lc.setChar(0,i,' ',false);
}
for (i=3;i>=0;i--)
{
lc.setChar(0,i,i,false);
delay(100);
lc.setChar(0,i,' ',false);
}

pinMode(speakerPin, OUTPUT);

}

void loop()
{
delay(50);
int uS = sonar.ping();
int distance = 0;
int toneDelay = 0;

distance = uS / US_ROUNDTRIP_CM;
printDistanceOnLED(distance);
toneDelay = distance * 4;


if (triggerDistance > distance)
{
playTone(toneDelay,500);
delay(toneDelay);
playTone(toneDelay,500);
delay(toneDelay);
}
}

void printDistanceOnLED(int distance)
{
int metres = 0;
int cms = 0;
int cms_tens = 0;
int cms_ones = 0;

metres = distance / 100;
distance = distance - metres * 100;
cms_tens = distance / 10;
cms_ones = distance % 10;

// only display digits if non-zero
if (0 != metres)
{lc.setDigit(0,1,(byte)metres,false);}
else
{lc.setDigit(0,1,' ',false);}

if ((0 != cms_tens) || (0 != metres))
{lc.setDigit(0,2,(byte)cms_tens,false);}
else
{lc.setDigit(0,2,' ',false);}

if ((0 != cms_ones) || ((0 != cms_tens) || (0 != metres)))
{lc.setDigit(0,3,(byte)cms_ones,false);}
else
{lc.setDigit(0,3,' ',false);}

lc.setDigit(0,0,' ',true);

Serial.print(metres); Serial.print("."); Serial.print(cms_tens); Serial.print(cms_ones); Serial.println("m");
}

// duration in mSecs, frequency in hertz
// http://michael.thegrebs.com/2009/03/23/playing-a-tone-through-an-arduino-connected-piezo/
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(speakerPin,HIGH);
delayMicroseconds(period / 2);
digitalWrite(speakerPin, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}

Bike Sonar

Hi! This is my first attempt at a blog, so bear with me!

The easiest way I find of learning something new is to have an idea of something you want to create and then go about implement it, learning the pitfalls and how to solve them. I've never been any good at just reading a book and then creating some software.

So where I live in Australia, the government is introducing new laws this year regarding safe passing distances for cars & bicycles. Simply, allow a 1m gap. It's obviously not something you need to get out a ruler and measure but rather to get the mindset that pedestrians are a lot easier to kill than cyclist, and cyclists are a lot easier to kill than motorists. So just think and be courteous to other road users, regardless of their means of transport … no one person owns the road or has any greater rights.

Anyway, this gave me an idea to implement a simple little sonar for my bike. Essentially it's just a 'rear parking sensor' for a bike! The idea is if a car gets too close then an audible warning can be given to the cyclist. It also has a display so that the actual distance can be captured by a video camera, like the Cycliq Fly6.

Maybe this will be of interest to someone else. Like I said, it's pretty simple. And there's no doubt similar things already out there - this was just something so I could practise going from initial idea to prototype and then refine.

Step one. Get all the parts and put it together on a breadboard for testing to see if it'll actually work.

I used the following:

  • Adafruit USB-Boarduino
  • HR-SC04 ultrasonic sensor
  • four-digit seven-segment LED display (labelled "CPS02841AR", common cathode)
  • Maxim MAX7219 LED display driver (plus 68kΩ resistor, 10μF electrolytic and 100nF ceramic capacitors)
  • Freetronics piezo buzzer

First step was just wiring it all up. Here is the result:

Bike Sonar, prototype 1

Next step is to write the code for the Arduino to run it all and test.