Close

Test Platform

A project log for Open Autonomous Domestic Robots

Open Autonomous Domestic Robots – An open source system for domestic cleaning robots using low-cost hardware

keith-elliottKeith Elliott 05/29/2016 at 23:440 Comments

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
#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;
}

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

#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);	
}

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]);
  }
}

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!

Discussions