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!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s