Prvi koraki v Arduino – vožnja po črti in izogibanje oviri
Milan
Gaberšek in Slavko Kocijančič
V trinajstem zaporednem prispevku na temo Prvi koraki v Arduino bomo obstoječi avtomobilček s krmilnikom Arduino nadgradili tako, da se bo poleg vožnje po črti izogibal oviram na poti. Konstrukcijo avtomobilčka bi lahko pustili nespremenjeno, a da ne bomo samo programirali, bomo z majhnim dodatkom dosegli lažje gibanje.
Programsko kodo si preko kopiraj/prilepi prenesite v Arduino IDE, da vam ne bo treba pretipkavati.
//
// Program Arduino -
// Vožnja po črti in izogibanje oviri
// Pini za tipki za zaznavanje ovire
const int pinTipkaLeva = 2;
const int pinTipkaDesna = 4;
// Led bela lučka na D8
const int led = 8;
// Svetlobno spremenljivi upor na A0
const int senzorSvetlobe = A0;
// Vrednost jakosti odbite svetlobe
// bomo shranili v spremenljivko
int jakostSvetlobe = 0;
// S testnim programom smo izmerili jakost
// na črni in beli podlagi, vnesemo ju
// v jakostCrna in jakostBela
int jakostCrna = 100; // Jakost na crni podlagi
int jakostBela = 400; // Jakost na beli podlagi
// Povprečje obeh vrednosti shranimo v refSvetloba
float refSvetlobe = (jakostCrna + jakostBela) / 2;
// Pini za oba motorčka (preko modula L9110)
const int pinMotorA1 = 9;
const int pinMotorA2 = 10;
const int pinMotorB1 = 11;
const int pinMotorB2 = 12;
// Nastavitev vhodov in izhodov krmilnika Arduina
void setup() {
// Branje podatkov preko
// serijskega vmesnika USB
Serial.begin(9600);
pinMode(led, OUTPUT);
// Nastavitev tipk
pinMode(pinTipkaLeva, INPUT_PULLUP);
pinMode(pinTipkaDesna, INPUT_PULLUP);
// svetleča dioda bo vklopljena ves čas
digitalWrite(led, HIGH);
// Nastavitev izhodov za motorčka
pinMode(pinMotorA1, OUTPUT);
pinMode(pinMotorA2, OUTPUT);
pinMode(pinMotorB1, OUTPUT);
pinMode(pinMotorB2, OUTPUT);
}
// Prva parametra povesta, katera pina poganjata motor
// tretji parameter pove smer:
// -1 kolo se vrti nazaj, 0 miruje, 1 kolo se vrti naprej
void motor(int pinMotor1, int pinMotor2, int nSmer) {
if (nSmer == 1) { // Naprej
digitalWrite(pinMotor1, HIGH);
digitalWrite(pinMotor2, LOW);
}
else if (nSmer == -1) { // Nazaj
digitalWrite(pinMotor1, LOW);
digitalWrite(pinMotor2, HIGH);
}
else { // Se ne vrti
digitalWrite(pinMotor1, LOW);
digitalWrite(pinMotor2, LOW);
}
}
void vrtiVDesno(){
motor(pinMotorA1, pinMotorA2, 1);
motor(pinMotorB1, pinMotorB2, -1);
}
void vrtiVLevo(){
motor(pinMotorA1, pinMotorA2, -1);
motor(pinMotorB1, pinMotorB2, 1);
}
void peljiNaprej(){
motor(pinMotorA1, pinMotorA2, 1);
motor(pinMotorB1, pinMotorB2, 1);
}
void peljiNazaj(){
motor(pinMotorA1, pinMotorA2, -1);
motor(pinMotorB1, pinMotorB2, -1);
}
void ustavi(){
motor(pinMotorA1, pinMotorA2, 0);
motor(pinMotorB1, pinMotorB2, 0);
}
// Spremenljivka za vklop(true)
// oziroma izklop(false) sledenja po črti
int voznjaPoCrti = true;
void loop() {
// Z ukazom analogRead preberemo
// digitalno jakost odbite svetlobe
jakostSvetlobe = analogRead(senzorSvetlobe);
// Dobljeni podatek izpišemo na zaslon
Serial.println(jakostSvetlobe);
delay(10); // Počakamo na podatke
// Preverimo, ali je pritisnjena tipka tipalk
if ( (digitalRead(pinTipkaLeva) == LOW)
|| (digitalRead(pinTipkaDesna) == LOW) ) {
// Koda za izogibanje oviri
peljiNazaj(); delay(100);
vrtiVLevo(); delay(400);
peljiNaprej(); delay(500);
vrtiVDesno(); delay(280);
peljiNaprej(); delay(820);
vrtiVDesno(); delay(350);
peljiNaprej(); delay(400);
vrtiVLevo(); delay(350);
// Za lažje nastavljanje časov
// avtomobilček še ustavimo
ustavi();
} else {
// Vklop kode za vožnjo po črti
if (voznjaPoCrti == true) {
// Iskanje črte:
// Če je jakost odbite svetlobe
// manjša od referenčne, zavrtimo
// v levo, drugače v desno
if (jakostSvetlobe <= refSvetlobe) {
vrtiVLevo(); delay(20);
} else {
vrtiVDesno(); delay(20);
}
peljiNaprej(); delay(10);
ustavi(); // Ustavi
}
}
}
|