OpenADR: Test Platform

The second round of the Hackaday Prize ends tomorrow so I’ve spent the weekend hard at work on the OpenADR test platform.  I’ve been doing quite a bit of soldering and software testing to streamline development and to determine what the next steps I need to take are.  This blog post will outline the hardware changes and software testing that I’ve done for the test platform.

Test Hardware

While my second motion test used an Arduino Leonardo for control, I realized I needed more GPIO if I wanted to hook up all the necessary sensors and peripherals.  I ended up buying a knockoff Arduino Mega 2560 and have started using that.

2016-05-28 19.00.22

2016-05-28 19.00.07I also bought a proto shield to make the peripheral connections pseudo-permanent.

2016-05-29 11.47.13Hardwiring the L9110 motor module and the five HC-SR04 sensors allows for easy hookup to the test platform.

HC-SR04 Library

The embedded code below comprises the HC-SR04 Library for the ultrasonic distance sensors.  The trigger and echo pins are passed into the constructor and the getDistance() function triggers the ultrasonic pulse and then measures the time it takes to receive the echo pulse.  This measurement is then converted to centimeters or inches and the resulting value is returned.


#ifndef HCSR04_H
#define HCSR04_H
#include "Arduino.h"
#define CM 1
#define INCH 0
class HCSR04
{
public:
HCSR04(uint8_t triggerPin, uint8_t echoPin);
HCSR04(uint8_t triggerPin, uint8_t echoPin, uint32_t timeout);
uint32_t timing();
uint16_t getDistance(uint8_t units, uint8_t samples);
private:
uint8_t _triggerPin;
uint8_t _echoPin;
uint32_t _timeout;
};
#endif

view raw

HCSR04.h

hosted with ❤ by GitHub


#include "Arduino.h"
#include "HCSR04.h"
HCSR04::HCSR04(uint8_t triggerPin, uint8_t echoPin)
{
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
_triggerPin = triggerPin;
_echoPin = echoPin;
_timeout = 24000;
}
HCSR04::HCSR04(uint8_t triggerPin, uint8_t echoPin, uint32_t timeout)
{
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
_triggerPin = triggerPin;
_echoPin = echoPin;
_timeout = timeout;
}
uint32_t HCSR04::timing()
{
uint32_t duration;
digitalWrite(_triggerPin, LOW);
delayMicroseconds(2);
digitalWrite(_triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(_triggerPin, LOW);
duration = pulseIn(_echoPin, HIGH, _timeout);
if (duration == 0)
{
duration = _timeout;
}
return duration;
}
uint16_t HCSR04::getDistance(uint8_t units, uint8_t samples)
{
uint32_t duration = 0;
uint16_t distance;
for (uint8_t i = 0; i < samples; i++)
{
duration += timing();
}
duration /= samples;
if (units == CM)
{
distance = duration / 29 / 2 ;
}
else if (units == INCH)
{
distance = duration / 74 / 2;
}
return distance;
}

view raw

HCSR04.cpp

hosted with ❤ by GitHub

L9110 Library

This library controls the L9110 dual h-bridge module.  The four controlling pins are passed in.  These pins also need to be PWM compatible as the library uses the analogWrite() function to control the speed of the motors.  The control of the motors is broken out into forward(), backward(), turnLeft(), and turnRight() functions whose operation should be obvious.  These four simple motion types will work fine for now but I will need to add finer control once I get into more advanced motion types and control loops.


#ifndef L9110_H
#define L9110_H
#include "Arduino.h"
class L9110
{
public:
L9110(uint8_t A_IA, uint8_t A_IB, uint8_t B_IA, uint8_t B_IB);
void forward(uint8_t speed);
void backward(uint8_t speed);
void turnLeft(uint8_t speed);
void turnRight(uint8_t speed);
private:
uint8_t _A_IA;
uint8_t _A_IB;
uint8_t _B_IA;
uint8_t _B_IB;
void motorAForward(uint8_t speed);
void motorABackward(uint8_t speed);
void motorBForward(uint8_t speed);
void motorBBackward(uint8_t speed);
};
#endif

view raw

L9110.h

hosted with ❤ by GitHub


#include "Arduino.h"
#include "L9110.h"
L9110::L9110(uint8_t A_IA, uint8_t A_IB, uint8_t B_IA, uint8_t B_IB)
{
_A_IA = A_IA;
_A_IB = A_IB;
_B_IA = B_IA;
_B_IB = B_IB;
pinMode(_A_IA, OUTPUT);
pinMode(_A_IB, OUTPUT);
pinMode(_B_IA, OUTPUT);
pinMode(_B_IB, OUTPUT);
}
void L9110::forward(uint8_t speed)
{
motorAForward(speed);
motorBForward(speed);
}
void L9110::backward(uint8_t speed)
{
motorABackward(speed);
motorBBackward(speed);
}
void L9110::turnLeft(uint8_t speed)
{
motorABackward(speed);
motorBForward(speed);
}
void L9110::turnRight(uint8_t speed)
{
motorAForward(speed);
motorBBackward(speed);
}
void L9110::motorAForward(uint8_t speed)
{
digitalWrite(_A_IA, LOW);
analogWrite(_A_IB, speed);
}
void L9110::motorABackward(uint8_t speed)
{
digitalWrite(_A_IB, LOW);
analogWrite(_A_IA, speed);
}
void L9110::motorBForward(uint8_t speed)
{
digitalWrite(_B_IA, LOW);
analogWrite(_B_IB, speed);
}
void L9110::motorBBackward(uint8_t speed)
{
digitalWrite(_B_IB, LOW);
analogWrite(_B_IA, speed);
}

view raw

L9110.cpp

hosted with ❤ by GitHub

Test Code

Lastly is the test code used to check the functionality of the libraries.  It simple tests all the sensors, prints the output, and runs through the four types of motion to verify that everything is working.


#include <L9110.h>
#include <HCSR04.h>
#define HALF_SPEED 127
#define FULL_SPEED 255
#define NUM_DISTANCE_SENSORS 5
#define DEG_180 0
#define DEG_135 1
#define DEG_90 2
#define DEG_45 3
#define DEG_0 4
uint16_t AngleMap[] = {180, 135, 90, 45, 0};
HCSR04* DistanceSensors[] = {new HCSR04(23, 22), new HCSR04(29, 28), new HCSR04(35, 34), new HCSR04(41, 40), new HCSR04(47, 46)};
uint16_t Distances[NUM_DISTANCE_SENSORS];
L9110 motors(9, 8, 3, 2);
void setup()
{
Serial.begin(9600);
pinMode(29, OUTPUT);
pinMode(28, OUTPUT);
}
void loop()
{
updateSensors();
motors.forward(FULL_SPEED);
delay(1000);
motors.backward(FULL_SPEED);
delay(1000);
motors.turnLeft(FULL_SPEED);
delay(1000);
motors.turnRight(FULL_SPEED);
delay(1000);
motors.forward(0);
delay(6000);
}
void updateSensors()
{
for (uint8_t i = 0; i < NUM_DISTANCE_SENSORS; i++)
{
Distances[i] = DistanceSensors[i]->getDistance(CM, 5);
Serial.print(AngleMap[i]);
Serial.print(":");
Serial.println(Distances[i]);
}
}

view raw

basicTest.ino

hosted with ❤ by GitHub

As always, all the code I’m using is open source and available on the OpenADR GitHub repository.  I’ll be using these libraries and the electronics I assembled to start testing some motion algorithms!

Desk Fume Extractor

In my ongoing, multi-year effort to clean my office and upgrade it to the ultimate make-station, I decided that I needed a fume extractor since inhaling solder fumes probably isn’t too good for my health.  Of course, being me, I decided a basic fume extractor was too simple and set about building one into the cheap Ikea tables I use as desks.

Right off the bat I knew I needed at least four components: a fan to move the air, a filter to absorb smoke and particulates, a porous tabletop, and a power switch to turn the system on and off.  For the fans I bought a few cheap pc fans.  They’re about 5 inches in diameter, run off 12V, and move a decent amount of air quietly.  The filters are just a few solder fume extractor filter replacements.  The porous tabletop surface was a bit harder to find.  I wanted something with large enough holes to let plenty of air through, but small enough that I wouldn’t constantly be losing pieces into them.  I settled on a one foot by two foot piece of sheet metal with 3/16 inch holes.  The on/off switch was just something I picked up from Radioshack.

For the placement of the fume extractor, the two desks, when placed next to each other on the long axis, take up almost the entire width of the office with nine inches to spare.  I decided to place the fume extractor into that space to save myself the trouble of cutting into the desk.

2015-09-13 14.23.22

The first step in the process of building the fume extractor was to create the structure to hold the fans and filters.  Originally I was going to 3D print elaborate fan and filter holds but decided that cutting into some foam core board I had laying around would be much easier.  Since I had no idea about what kind of airflow is necessary to draw in solder smoke I decided to try and fit as many fans as I could into the fume hood and cut out holes for four of the PC fans I bought.2015-09-13 14.23.33

Once that I was done, I designed and printed out some simple brackets to hold the carbon filters.

2015-09-13 14.58.12

I hot glued them all together to make mounting easier.

2015-09-13 15.09.41

And taped them onto the foam core board.  (Huzzah for Duct Tape!)

2015-09-13 15.22.33

The filters fit in snugly and are easy to pop out and replace.

2015-09-13 21.07.57

Next was mounting the fans.2015-09-13 21.59.26

The fans had holes in the corners so mounting them was a simply a matter of poking holes in the foam core board and mounting them with M3 screws and nuts.

2015-09-13 22.25.20

The fans came with PC fan electrical connectors so I had to cut that off, strip the wires, and solder them together in parallel.
2015-09-13 20.38.50

I printed out 1″ brackets to mount onto the desks.  The foam core board assembly will lay on top of these.2015-09-13 22.25.54

I taped these brackets onto the desk as a proof of concept and because I like to avoid drilling/cutting/sawing if at all possible.  If I’m feeling ambitious at some point in the future, I will probably screw these in to make the assembly more permanent.2015-09-13 22.24.40

After some fidgeting with the placement of the desks, the foam core assembly sits in the gap pretty nicely.  My original intention was to attach the assembly directly onto both of the desks via the brackets, but decided against it for two reasons.  First, with the board sitting gently on top of the brackets, it’s much easier to pull it out.  This will make pulling the assembly out and replacing the filters much easier.  Second, the 3D printer can produce a lot of vibration and usually shakes the entire table.  If the foam core assembly was rigidly attached to both desks the vibrations would shake both tables and the computer monitors on the left desk would vibrate whenever the 3D printer was in use.  With the foam core laying in the gap it will probably get a little more beat up being hit by right desk, but foam core is cheap and it would be easy to replace.

fumehood

This is the basic wiring diagram for the electrical side of things

2015-09-19 08.50.07

For the power I just wired up an old Power Wheels charger I had lying around.  Originally I intended to add another switch and some 10W resistors to be able to select two speeds for the fume hood.  I thought that the four fans would be excessively loud and I’d want to run the fume extractor at half speed most of the time.  Fortunately, running the four fans together turned out to be surprisingly quiet, so I simplified and decided to only wire up an On/Off switch.

2015-09-17 21.11.23

2015-09-17 21.11.15

I mounted the button on the front of the foam core assembly in a 3D printed panel.  Cutting precision circles in foam core board turned out to be pretty difficult, so using a 3D printed front was simpler.

2015-08-27 18.57.57

I was a little unhappy with the metal surface I purchased.  The surface was pretty scratched and stained.  It also had a curvature to it from being rolled up, something which I didn’t anticipate.  I laid it flat and put my two heaviest books on top to flatten it out.

2015-09-19 14.02.18

However, after several days of flattening there was still a slight curvature to the metal so I had to screw it into the desk to keep it flat.

2015-09-19 14.06.18

The edges of the metal surface were also pretty sharp so after fastening the metal into position I taped down the edges with the black Duct Tape i used earlier.  This provided both a nice finish and a way to not cut myself.

2015-09-19 14.06.31

Overall I’m happy with how this turned out.  It looks pretty nice, and while it could do with some polish it’s simple and sturdy.  And best of all it works!

DIY Smartwatch: Soldering SMD

Going into this project I knew I would have to do a lot of surface mount soldering to save space and money.  I used the smallest SMD hand-solderable packages and still ran out of space!  I’ve never been particularly good at soldering, but knew that I would have to become much better to tackle the types of projects I’m interested in.  In anticipation of this, I splurged and bought a very nice soldering iron from Radioshack.  I cannot express how great this iron is!  I’m used to using cheap, $10 irons that just need to get the job done, but with the fine tip on my new one, SMD wasn’t difficult at all!  Below is a picture of the board with most of the components soldered on.

{INSERT IMAGE}

You’ll notice that I haven’t yet soldered on the accelerometer.  That’s because QFN packages are much smaller than I anticipated, even with a fine tipped iron.  In order to solder this, I’d probably need solder paste and a hot air station, something I’m not quite ready to drop $100 on yet.  Not sure what I’m going to do about that, especially since I’m going to need the accelerometer to minimize power usage.