295 lines
9.2 KiB
Markdown
295 lines
9.2 KiB
Markdown
+++
|
||
title = "Shy bot – the robot which is scared of the light"
|
||
description = "Creating a shy robot for a school project."
|
||
date = 2022-05-19
|
||
|
||
[taxonomies]
|
||
tags = ["maker", "fablab", "robotics"]
|
||
+++
|
||
|
||
Creating a shy robot for a university project.
|
||
|
||
> This is a translated article of mine, original can be found on
|
||
[Eirlab](https://www.eirlab.net/2022/05/19/robot-timide-le-robot-qui-fuit-la-lumiere/)
|
||
|
||
As part of my computer science engeneering curriculum, I enrolled in an option called
|
||
"Makers" during my fourth year. From this course within
|
||
[ENSEIRB-MATMECA's makerlab](https://www.eirlab.net)
|
||
is born a shy robot, one that hates light and loves the shadows.
|
||
|
||
This article is all about explaining how it works and how you could reproduce our work, in the
|
||
most "maker" spirit.
|
||
|
||
<!-- more -->
|
||
|
||
![A 3/4th view of said robot](images/robot_timide_header.jpg)
|
||
|
||
## Base concept
|
||
|
||
We wanted to create a robot which would be able to detect, in real time,
|
||
the brightness of its surroundings, and would then use it to go in the
|
||
darkest place of the room it would be in, in order to hide (it's a shy one, remember?).
|
||
|
||
Instead of going to the darkest place it can detect, there's also another mode
|
||
available, where instead of moving towards the darkest place, it tries to
|
||
flee the brightest direction. Although looking similar, these two ways of thinking
|
||
yield to different results.
|
||
|
||
![A view of the robot in its final form.](images/robot_timide_enseirb.jpg)
|
||
|
||
## Some hardware
|
||
|
||
Before working on the software part of this project, we needed to have some hardware
|
||
to run our code on.
|
||
|
||
It should be noted that all of the components required for this project were
|
||
supplied by the fablab. We tried to only use parts that were already available,
|
||
without the need to spend a single euro for this project.
|
||
|
||
### Shopping list
|
||
|
||
In order to recreate this project, you would need these components:
|
||
|
||
- 1x Arduino Uno (or an equivalent clone) – it's the brains of this whole project
|
||
- 1x Arduino Motor Shield – to control the motors that will move the robot
|
||
- 2x DC motors (here FT DC 130D) – to actually move the robot
|
||
- 3x ultrasonic distance sensors HC-SR04 – to avoid hitting walls too often
|
||
- 4x photoresistors – one per side, to be able to detect brightness around it
|
||
- 4x 2kΩ resistors – for the photocell circuit, to have a better detection amplitude
|
||
- 1x 9V battery – because it needs power to do anything
|
||
- 1x box for 9V batteries [optional] – so the battery is safely mounted
|
||
|
||
### Chassis
|
||
|
||
The chassis for this robot is a piece of plywood, 5mm thick to be precise. It
|
||
has been machined using a laser cutter, availabe in the fablab. This plank
|
||
is about 17 by 15.5 centimeters, and has two beveled corners, which are useful
|
||
so the robot can see in front of it. The bevels have a 20 degrees angle, going on
|
||
4.5cm.
|
||
|
||
The base plate is then pierced to accomodate for the different components that
|
||
will need to be mounted on the said plate. The lighter components will be pressure
|
||
mounted, using a u-shape that will fit around the plate's side.
|
||
|
||
![The u-shape to pressure-mount the component on the plate.](images/u_shape.jpg)
|
||
|
||
### Power
|
||
|
||
For powering the robot, we want to send 9 volts, from a battery or a power supply,
|
||
in the power input `VIN` of our Arduino board. This tension will then be regulated
|
||
on the PCB to create the different power rails that would be needed. This input is
|
||
connected internally to the barrel jack of the Arduino, which can take power ranging
|
||
from 5 to 9 volts.
|
||
|
||
In this project, we are using a 9V battery which is placed in a case that is bolted
|
||
on the base plate.
|
||
|
||
![A picture of the rechargeable 9 volts battery that we are using.](images/pile9v.jpg)
|
||
|
||
### Motors
|
||
|
||
The motors are bolted to the chassis in this project, because when they were
|
||
mounted just using pressure, they would run away each time the robot made a
|
||
rough acceleration.
|
||
|
||
These motors are directly powered and controlled using the Arduino Motor Shield,
|
||
which lets us select a speed ranging from `0` to `255` using a coding API.
|
||
This API also lets us engage brakes or set the direction in which the wheels
|
||
are turning.
|
||
|
||
The wheels for this project have been 3D printed and pressure-fit on the motors
|
||
themselves, and an O-ring seal is then used to add some grip.
|
||
|
||
### PCB
|
||
|
||
In the beginning of this project, we used a breadboard for electronics prototyping.
|
||
We had a lot of disconnect issues, so as soon as the hardware part could be frozen,
|
||
we migrated the breadboard electronics to a hand-made PCB using a prototyping board.
|
||
This made the robot way more resilient to a sharp acceleration curve.
|
||
|
||
![A top-view of our hand-made PCB.](images/pcb_irl.jpg)
|
||
|
||
On an electronic level, the PCB is routed such as:
|
||
|
||
![The PCB routing on a prototyping breadboard.](images/pcb_fritzing.png)
|
||
|
||
The different components are interfaced with the PCB using a kind of connector that
|
||
lets us connect and disconnect things as we iterated on the sensors without having to
|
||
use a soldering iron.
|
||
|
||
## And finally some software
|
||
|
||
From a software point-of-view, the project is quite simple.
|
||
|
||
On a high-level, the algorithm could be summed up as follows: check all four photocells,
|
||
and move, using rotation and translation, towards the one that has the darkest value, if
|
||
`followDark` is set to `true`. If this value is set to `false`, then the robot will move
|
||
itself in the opposite direction to this brighest value.
|
||
|
||
A distance mesurement is made using the three ultrasonic distance sensor, so the robot is
|
||
able to stop before hitting a wall (hopefully). These sensors act as "kill switches" that
|
||
forbid the robot from ever moving while these sensors are detecting an obstacle.
|
||
|
||
The code is as follow:
|
||
|
||
```cpp
|
||
#define echo1Pin 5
|
||
#define trig1Pin 4
|
||
#define echo2Pin 7
|
||
#define trig2Pin 6
|
||
#define echo3Pin 10
|
||
#define trig3Pin 2
|
||
#define rotMot1Pin 12
|
||
#define brakeMot1Pin 9
|
||
#define vitMot1Pin 3
|
||
#define rotMot2Pin 13
|
||
#define brakeMot2Pin 8
|
||
#define vitMot2Pin 11
|
||
#define photoRes1Pin A2
|
||
#define photoRes2Pin A3
|
||
#define photoRes3Pin A4
|
||
#define photoRes4Pin A5
|
||
|
||
#define followDark false
|
||
|
||
long duration;
|
||
int distance;
|
||
|
||
void setup() {
|
||
Serial.begin(9600);
|
||
pinMode(rotMot1Pin, OUTPUT);
|
||
pinMode(brakeMot1Pin, OUTPUT);
|
||
pinMode(vitMot1Pin, OUTPUT);
|
||
|
||
pinMode(rotMot2Pin, OUTPUT);
|
||
pinMode(brakeMot2Pin, OUTPUT);
|
||
pinMode(vitMot2Pin, OUTPUT);
|
||
|
||
pinMode(photoRes1Pin, INPUT);
|
||
pinMode(photoRes2Pin, INPUT);
|
||
pinMode(photoRes3Pin, INPUT);
|
||
pinMode(photoRes4Pin, INPUT);
|
||
|
||
pinMode(trig1Pin, OUTPUT);
|
||
pinMode(echo1Pin, INPUT);
|
||
pinMode(trig2Pin, OUTPUT);
|
||
pinMode(echo2Pin, INPUT);
|
||
pinMode(trig3Pin, OUTPUT);
|
||
pinMode(echo3Pin, INPUT);
|
||
|
||
delay(3000);
|
||
}
|
||
|
||
void loop(){
|
||
byte echoPins[3] = {echo1Pin,echo2Pin,echo3Pin};
|
||
byte trigPins[3] = {trig1Pin,trig2Pin,trig3Pin};
|
||
long int durations[3] = {};
|
||
long int distances[3] = {};
|
||
|
||
for(int i = 0; i < 3; i++){
|
||
digitalWrite(trigPins[i], LOW);
|
||
delayMicroseconds(2);
|
||
|
||
digitalWrite(trigPins[i], HIGH);
|
||
delayMicroseconds(10);
|
||
digitalWrite(trigPins[i], LOW);
|
||
durations[i] = pulseIn(echoPins[i], HIGH);
|
||
distances[i] = durations[i] * 0.034 / 2;
|
||
}
|
||
|
||
int photoRes[4] = {};
|
||
Serial.print("Capteur infra : 1[");
|
||
photoRes[0] = analogRead(photoRes1Pin);
|
||
Serial.print(photoRes[0]);
|
||
Serial.print("] 2[");
|
||
photoRes[1] = analogRead(photoRes2Pin);
|
||
Serial.print(photoRes[1]);
|
||
Serial.print("] 3[");
|
||
photoRes[2] = analogRead(photoRes3Pin);
|
||
Serial.print(photoRes[2]);
|
||
Serial.print("] 4[");
|
||
photoRes[3] = analogRead(photoRes4Pin);
|
||
Serial.print(photoRes[3]);
|
||
|
||
for(int i = 0; i < 3; i++){
|
||
Serial.print("] - distance(cm) : ");
|
||
Serial.print(distances[i]);
|
||
}
|
||
|
||
Serial.println();
|
||
|
||
bool b = false;
|
||
for(int i = 0; i < 3; i++){
|
||
if (distances[i] < 30) {
|
||
b= true;
|
||
}
|
||
}
|
||
|
||
int photoResRef = photoRes[0];
|
||
bool photoStop = true;
|
||
int photoResMinPos = 0;
|
||
|
||
if (followDark){
|
||
int photoResMin = 1024;
|
||
for (int i = 0; i < 4; i++){
|
||
if (photoResMin > photoRes[i]){
|
||
photoResMin = photoRes[i];
|
||
photoResMinPos = i;
|
||
}
|
||
if (abs(photoResRef - photoRes[i]) > 20){
|
||
photoStop = false;
|
||
}
|
||
}
|
||
} else{
|
||
int photoResMax = 0;
|
||
for (int i = 0; i < 4; i++){
|
||
if (photoResMax < photoRes[i]){
|
||
photoResMax = photoRes[i];
|
||
photoResMinPos = (i + 2)%4;
|
||
}
|
||
if (abs(photoResRef - photoRes[i]) > 20){
|
||
photoStop = false;
|
||
}
|
||
}
|
||
}
|
||
Serial.println(photoResMinPos);
|
||
|
||
if (b || photoStop){
|
||
digitalWrite(brakeMot1Pin, HIGH);
|
||
digitalWrite(brakeMot2Pin, HIGH);
|
||
} else {
|
||
digitalWrite(brakeMot1Pin, LOW);
|
||
digitalWrite(brakeMot2Pin, LOW);
|
||
}
|
||
|
||
if (photoResMinPos == 0){
|
||
digitalWrite(rotMot1Pin, LOW);
|
||
digitalWrite(rotMot2Pin, LOW);
|
||
}
|
||
if (photoResMinPos == 1){
|
||
digitalWrite(rotMot1Pin, LOW);
|
||
digitalWrite(rotMot2Pin, LOW);
|
||
}
|
||
if (photoResMinPos == 2){
|
||
digitalWrite(rotMot1Pin, HIGH);
|
||
digitalWrite(rotMot2Pin, HIGH);
|
||
}
|
||
if (photoResMinPos == 3){
|
||
digitalWrite(rotMot1Pin, HIGH);
|
||
digitalWrite(rotMot2Pin, LOW);
|
||
}
|
||
analogWrite(vitMot1Pin, 150);
|
||
analogWrite(vitMot2Pin, 150);
|
||
}
|
||
```
|
||
|
||
## Thanks
|
||
|
||
We wanted to say thank you to the ENSEIRB-MATMECA, to our fablab, EIRLAB, for
|
||
trusting us, helping us and providing the hardware we used throughout this project.
|
||
|
||
Thank you also to the fab-managers who helped us and answered all of our questions,
|
||
more or less asked under fatigue.
|
||
|
||
In memory of Kaitlin Rooke.
|