af Jeppe Bukh Madsen, Jacob Eithz Bauer og Bjarke Mejlvang

Navn på robotten: Ploven

             

Oversigt

Denne tutorial består af fem overordnede punkter:

  1. Målet
  2. Opbygning af LEGO bil
  3. Hardware
  4. Software
  5. Konklusion og perspektivering

Vi vil gennemgå alle punkterne, så du også har mulighed for at bygge en selvkørende LEGO bil.

Målet

Målet er at bygge en kørende robot med LEGO og Arduino. I denne tutorial konstruerer vi en autonom kørende Arduino LEGO robot, der ved hjælp af et Arduino-board og Motor-shield, kan styre 2 lego motorer. Det er vigtigt at bygge ens lego-køretøj, så det kan bære både Arduino, Motor-shield og batterier batterier. Lego robotten skal ved hjælp af Arduino-styringen og sensorer kunne følge en mørk streg på et lyst gulv og køre udenom en mur. Der er ikke ét endeligt facit på hvordan man laver sådan et køretøj, men i denne tutorial vil vi vise, hvordan vi har bygget vores.

På billedet ses banen, som vores køretøj skal gennemføre uden nogen form for hjælp. Det første stykke af vejen skal køretøjet følge den sorte linje, uden at ramme de røde streger. Når den sorte linje ophører vil der på den røde streg forude stå en mur, som bilen skal køre udenom og over målstregen.

Bane:

Opbygning af LEGO bil

Der er mange måder at bygge LEGO bilen på, men man skal være opmærksom på, at køretøjets udseende også har indflydelse på hvordan man skal styre det. Ting som omdrejningspunkt, gearing, vægt og bredde har alle indflydelse på hvor godt køretøjet vil kunne gennemføre banen.

Vores opbygning:

Lego digital designer, se zip fil:

Download (ZIP, 15KB)

Til at justerer på køretøjets hastighed kan man blandt andet ændre på gearingen. Vores gearing går fra et lille tandhjul på 8 tænder til et stort på 40 tænder.

Hardware

For at bygge køretøjet skal man bruge disse hardware dele:

1 x Arduino Uno
1 x MotorShield
1 x Knap
1 x Modstand (til knappen)
1 x HC-SR04 Ultrasonic Range Finder
2 x QRE1113 SparkFun Line Sensor Breakout 
1 x Breadboard
8 x 1,5V batterier
2 x batteriholdere med plads til 4 i hver
2x Motorer Electric Technic Mini-Motor 9v + tandhjul

og en masse ledninger til at sætte det hele sammen og skabe en serieforbindelse imellem batterierne.

På dette billede ses opbygning af vores kredsløb:

Oversigts billede:

Sensorer

HC-SR04 Ultrasonic Range Finder

Ultralyd sensoren udsender lyd med en frekvens på 40.000Hz, som bevæger sig igennem luften og hvis lyden rammer et objekt på dens vej, vil lyden komme tilbage til sensoren, som illustreret på billedet. Ved hjælp af tiden det tager for lyden at komme frem og tilbage, og konstanten for lydens hastighed kan vi udregne distancen mellem sensoren og objektet den rammer. Vores ultralydsensor er placeret oven på ploven ude på fronten. For det første har denne position en passende højde i forhold til muren, og for det andet er sonaren placeret ude foran for at bilen kan tage svinget rundt om muren, så skarpt som muligt.(Den opdager at muren slutter og begynder og dreje hurtigere i forhold til hvis sensoren sad bagpå.)

SparkFun Line Sensor Breakout – QRE1113 (Analog)

Linje sesnorne vi har brugt består af to dele, en IR emitting LED og en IR sensitiv photo-transistor. IR emitting LED’en sender infrarødt lys ud, og IR photo-transistoren modtager den mængde IR lys, som reflekterer tilbage fra objektet som rammes. Sensorens output værdier ændre sig afhængigt af hvor meget lys der reflekterer tilbage til sensoren. Linje sensorerne er monteret ude foran på ploven, så de kan registrerer hvornår stegen drejer, desuden er de placeret helt nede ved jorden for at få mere præcise værdier. Der er tilføjet ekstra vægt ude på fronten for at holde ploven og sesnorne nede.

 

Software

Vi har brugt Arduinos egen kompiler Arduino IDE, den kan hentes på: https://www.arduino.cc/en/Main/Software

I selve koden styrer vi de to motorer, og hvordan de skal køre baseret på inputs fra vores sensorer.

Den første del af banen, hvor man skal følge den sorte streg, gennemfører vi ved hjælp af ”refleksions sensorerne”. I koden har vi programmeret, at hvis begge sensorer ser ”hvidt”, så kører begge motorer fremad med samme hastighed. Hvis den ene sensor ser ”sort”, så sættes hastigheden på tilhørende motor ned indtil begge sensorer igen ser ”hvidt”. Det samme sker, hvis det kun er den anden sensor, som ser ”sort”. På den måde, vil køretøjet hele tiden forsøge at rette ind efter linjen. Hvis begge sensorer ser sort, så aktiveres koden for den anden del af banen.

Den anden del af banen, hvor man skal uden om muren, gennemfører vi ved hjælp af ultralyd sensoren HC-SR04. I koden har vi programmeret en minimum- og maksimumafstand, som køretøjet skal holde til muren. Hvis den kommer for langt fra muren, vil motorernes hastighed blive justeret, så den kører tættere på, og omvendt hvis den er for tæt på.

 

const int startButtonPin = 2; // the number of the button pin

int buttonState = 0; // variable for reading the pushbutton status
int sort = 750;
int hvid = 600;
int drive = 200;
int noDrive = 40;

//ultra
const int trigPin = 5;
const int echoPin = 6;

//Motor 1
int motorSpeedL = 3;
int driveL = 12;
int brakeL = 9;

// MOtor 2
int motorSpeedR = 11;
int driveR = 13;
int brakeR = 8;

// Sensorinput 
int sensorR = A4;
int sensorL = A5;
int valueR;
int valueL;


long duration;
int distance;
int lineEnd = 0;
int near = 6;
int far = 12;

void setup() {
 Serial.begin(9600);
 // initialize 
 pinMode(startButtonPin, INPUT);
 pinMode(motorSpeedL, OUTPUT);
 pinMode(motorSpeedR, OUTPUT);
 pinMode(sensorR, INPUT);
 pinMode(sensorL, INPUT);


 pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
 pinMode(echoPin, INPUT); // Sets the echoPin as an Input
 Serial.begin(9600); // Starts the serial communication
}

void loop() {
 // read the state of the button value:
 buttonState = digitalRead(startButtonPin);
 valueR = analogRead(sensorR);
 valueL = analogRead(sensorL);


 // Hvis den er tændt
 if (buttonState == 0) {

  if (lineEnd == 0) {
   if (valueR < hvid && valueL < hvid) { //ligeud
    digitalWrite(brakeL, LOW);
    analogWrite(motorSpeedL, drive);
    digitalWrite(driveL, HIGH);

    digitalWrite(brakeR, LOW);
    analogWrite(motorSpeedR, drive);
    digitalWrite(driveR, HIGH);
   } else if (valueR < hvid && valueL > sort) { //drej til venstre
    digitalWrite(brakeL, LOW);
    analogWrite(motorSpeedL, noDrive);
    digitalWrite(driveL, LOW);

    digitalWrite(brakeR, LOW);
    analogWrite(motorSpeedR, drive);
    digitalWrite(driveR, HIGH);
   } else if (valueL < hvid && valueR > sort) { //drej til højre
    digitalWrite(brakeR, LOW);
    analogWrite(motorSpeedR, noDrive);
    digitalWrite(driveR, LOW);

    digitalWrite(brakeL, LOW);
    analogWrite(motorSpeedL, drive);
    digitalWrite(driveL, HIGH);
   } else if (valueL > sort && valueR > sort) {
    digitalWrite(brakeL, LOW);
    analogWrite(motorSpeedL, drive - 170);
    digitalWrite(driveL, HIGH);

    digitalWrite(brakeR, LOW);
    analogWrite(motorSpeedR, drive + 50);
    digitalWrite(driveR, HIGH);
    delay(1500);
    lineEnd = 1;
   }
  } else if (distance > far) {
   digitalWrite(brakeR, LOW);
   analogWrite(motorSpeedR, drive - 190);
   digitalWrite(driveR, HIGH);

   digitalWrite(brakeL, LOW);
   analogWrite(motorSpeedL, drive);
   digitalWrite(driveL, HIGH);
  } else if (distance < near) {
   digitalWrite(brakeL, LOW);
   analogWrite(motorSpeedL, noDrive);
   digitalWrite(driveL, LOW);

   digitalWrite(brakeR, LOW);
   analogWrite(motorSpeedR, drive);
   digitalWrite(driveR, HIGH);
  } else if (distance < far && distance > near) {
   digitalWrite(brakeL, LOW);
   analogWrite(motorSpeedL, drive);
   digitalWrite(driveL, HIGH);

   digitalWrite(brakeR, LOW);
   analogWrite(motorSpeedR, drive);
   digitalWrite(driveR, HIGH);
  }

 }

 // Hvis den er slukket
 else {

  digitalWrite(brakeL, HIGH);
  analogWrite(motorSpeedL, 0);
  digitalWrite(driveL, LOW);

  digitalWrite(brakeR, HIGH);
  analogWrite(motorSpeedR, 0);
  digitalWrite(driveR, LOW);

 }
 Serial.print(buttonState);
 Serial.print(",");
 Serial.print(analogRead(sensorR));
 Serial.print(",");
 Serial.println(analogRead(sensorL));

 if (lineEnd == 1) {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  // Calculating the distance
  distance = duration * 0.034 / 2;
  // Prints the distance on the Serial Monitor
  Serial.print("Distance: ");
  Serial.println(distance);
 }
 delay(0);
}

 

Hvordan er samspillet mellem mekanik, elektronik og software?

Det er en større opgave at få samspillet mellem mekanik, elektronik og software til at fungere. Det har krævet mange testruns, hvor vi har indstillet på flere forskellige parametre i softwaren, flyttet fysisk på sensorerne og ændret på bilens design. Afsluttende har vi opnået et sammenspil, batterierne leverer strøm til vores Arduino, som indholder vores software programmering, som modtager og behandler data fra sensorerne, og ud fra disse data bliver motorerne informeret om hvilken hastighed og retning, de skal køre med. For at bilen kan klare banen, kræver det at alle delene i samspillet virker.

Konklusion

Vi har bygget en autonom kørende robot. Robotten kan gennemføre banen i en forholdvis hurtig tid. Robotten er bygget af lego, programmet er blevet uploadet til en arduino og strømkilden kommer fra 8 x 1.5 volt batterier i en serieforbindelse. På robotten har vi monteret to sensor foran bilen (ploven), som sidder tæt ned til banen. Disse to sensor registrer stregen og får bilen til at følge linjen. På siden af ploven har vi monteret vores sonar som registrer muren.

Løbstider – i denne forbindelse hedder vores hold JJB (Jeppe, Jacob, Bjarke):

Perspektivering

En af de ting som kunne forbedres ved vores robot er selve opbygningen af bilen. Bilen er meget skrøbelig, og skal samles op på en bestemt måde. Dvs. opbygningen af bilen skulle være mere robust.

Et andet problem er at bilen helst ikke skal kører for skabt imod højre inden den når til muren. Dette gør at svinget den fortager inden muren ikke kan være skarpt nok til den når at registrer muren. Dette kunne vi have løst ved at sænke hastigheden på motoren eller sat et delay på.

En sidste ting vi kunne have tilføjet til robotten er en funktion som stoppede bilen når den var nået i mål.

 

Vindervideo

Leave a Reply