1. Arduino Bil Arduino bilen er en selvgående liten robot. Roboten består av: En Robot base som er 3D printet 3 Litium-ion batterier En Arduino Uno Kodegenets Motorkontrollerkort Fire likestrømsmotorer og fire hjul En Ultrasonisk avstandssensor. Fire infrarøde lamper og mottakere for at roboten skal kunne følge en linje Roboten finnes i tre variasjoner: 1. Alle hoveddeler på bilen er 3D printet. Dette gjelder basen, motorholdere, batteripakke og linjesensor-holder. (ca. 5 timer print-tid) 2. Noen av hoveddelene er 3D printet. Her er basen og motorholderne byttet ut med henholdsvis laserkuttet akrylplast og aluminium. (ca. 2,5 timer print-tid) 3. Enkelte 3D printede deler Her er også batteriholderen byttet ut med en ferdig model i støpt plast. (ca 80 minutter print tid) I Teknoboksen ligger den tredje modellen. Sammenbyggingen av roboten er ganske lik for alle modellene. 2. Bygge sammen roboten Vi skal starte med å bygge sammen robotens base. Basen er en rektangulær del med hull til både skruer og muttere slik at alle delene til roboten kan moteres enkelt. På den 3D printede basen festes motorholderne på siden av basen, mens motorholderne i metall festes på undersiden av basen. På undersiden sitter en batteripakke som tar 3 Litium-ion batterier av typen 18650. Byggeprosessen består av 5 steg, og vi skal starte med å fullføre de første 3 nå før vi skal programmere Arduinoen litt. Pass på at skruene ikke festes så godt at plastdelene skrus i stykker eller knekker. Fingerfast er et godt nøkkelord her.
Dokumentet er et foreløpig utkast 2.1. Steg 1, 3D printet base Vi starter med å skru motorfestene til basen. Til det trenger vi: 3D printede basen 4 stk. Motorfester 8 stk M3 muttere og 8 stk M3x16mm skruer. Motorfestene monterer vi fast på siden av robot-basen, og de skal skrus fast slik at den helt flate siden av motorholderne peker utover på høyre og venstre side. Pass på at robotbasen er helt flat på undersiden av roboten. 1 8 stk 8 stk M3 M3x16 Figur 1 Vi starter med å skru motor-festene til basen Muttere Skruer
Dokumentet er et foreløpig utkast 2.2. Steg 1, base i akrylplast Vi starter med å skru motorfestene til basen. Til det trenger vi 4 stk. Motorfester i metal (i egne poser med skruer og fester) Robotbasen i akrylplast Motorfestene monterer vi fast på undersiden av robot-basen. Det er ingen opp eller ned på platen. 1 8 stk 8 stk M3 M3x16 Figur 2 Vi starter med å skru motor-festene til basen Muttere Skruer
Dokumentet er et foreløpig utkast 2.3. Steg 2 3D printet base Det neste steget er å montere motorene fast i motorfestene. Til det trenger vi: 8 M3 muttere og 8 M3x25mm skruer 4 motorer Her er det viktig at motorene festes slik at de er på utsiden av roboten, og at lederne/ledningene på motorene peker utover (og ikke inn mot midten av robotbasen). 2 8 stk 8 stk M3 M3x25 Figur 3 Vi skrur motorene til motorfestene Muttere Skruer
Dokumentet er et foreløpig utkast 2.4. Steg 2 base i akrylplast Det neste steget er å montere motorene fast i motorfestene. Til det trenger vi: 8 M3 muttere og tilhørende lange skruer (i posen sammen med motorfestene) 8 stk motorer Her er det viktig at motorene festes slik at de er på utsiden av roboten, og at lederne på motorene peker utover (og ikke inn mot midten av robotbasen). 2 8 stk 8 stk M3 M3x25 Figur 3 Vi skrur motorene til motorfestene Muttere Skruer
Dokumentet er et foreløpig utkast 2.5. Steg 3, 3D printet batteriholder Batteriholderen monteres på undersiden av roboten. Vi trenger: Batteriholderen 2 lange ledninger og 2 korte ledninger 3 fjærer og 3 mottakere 3 M3 muttere og 3 M3x10mm skruer Batteriholderen festes med 3 stk. M3x10 skruer og 4stk M3 mutteren. Det spiller ingen rolle hvilken side mutteren og skruen er på. Batteriene skal seriekobles, slik at man lodder positiv til negativ mellom batteri 1 og batteri 2, og batteri 2 og batteri 3. De lange ledningene går fra hver sin ende, og sammenkobles med den røde pluggen. 3 2 stk 2 stk M3 M3x10 Figur 4 Vi monterer på batteriholderen Muttere Skruer
Dokumentet er et foreløpig utkast 2.6. Steg 3, Støpt batteriholder Batteriholderen monteres på undersiden av roboten. Vi trenger: Batteriholderen 2 3D printede deler for å feste batteripakken til undersiden av basen 6 M3 muttere og 6 M3x10mm skruer Batteriholderen festes første til de 3D printede delene. Det er en egen del for høyre side og en for venstre side (de passer bare én vei). Disse festes med 2 muttere og skuer. Deretter festes de 3D printede delene til undersiden av roboten med 4 M3 muttere og skruer. 3 2 stk 2 stk M3 M3x10 Figur 4 Vi monterer på batteriholderen Muttere Skruer
Dokumentet er et foreløpig utkast 2.7. Steg 4 - Koblinger 4 Figur 5 Vi monterer motorkontrollerkortet på toppen av Arduinoen, samt alle ledninger
2.7.1. Steg 4,5 Koble motorene riktig 4.5 Figur 6 Ledningen fra motorene kobles på hver sin kolonne på kortet
2.7.2. Steg 5 - hjul Figur 1.1 Arduino Robot
3. Programmere roboten til å unngå hindringer Den første oppgaven, etter at alle ledningene er koblet på, er å få bilen til å kjøre rett fremover. For å gjøre programmeringen enklere, skal vi programmere roboten ved hjelp av Blockuino.no. Blockuino er det relativt enkelt å komme i gang med. Klosslisten - her finnes alle klossene vi kan bruke Scriptområdet - Her finnes alle klossene vi har lagt til i programmet vårt Kodeområdet - Her lages koden som vi skal overføre til Arduinoen Knapperad - Her finnes alle funksjonsknappene Figur 1.2 Vi bruker Blockuino.no for å programmere roboten Bilen styres ved at vi slår av og på signal-strømmen til portene som er koblet til kretskortet. Her må vi fortelle Arduinoen hvilke 6 porter som benyttes for å prate med motorkontrolleren, samt hvilke 2 porter som vi bruker for å kommunisere med avstandsmåleren. I tillegg må vi fortelle hvor raskt vi ønsker at bilen skal kjøre. Aller først må vi legge til 2 klosser, setup-klossen og loop-klossen. Disse klossen må vi alltid ha med når vi skal programmere Arduino.
Vi trekker ut en Setup-kloss og en Loop-kloss fra Klosslisen til Scriptområdet Legg merke til at vi får generert Arduino-koden automatisk i Kodeområdet. Figur 1.3 Vi trekker ut en Setup og en loop kloss Deretter må vi initialisere både motorkontrolleren og avstandssensoren. Det gjør vi ved å trekke ut initialiser-klossene fra Sensorer -> Ultrasonisk Sensor og Motorer -> Arduino Bil. Figur 1.3 Vi trekker ut initialiser-klosser for motorkontrolleren og avstandssensoren
Deretter må vi fortelle hvilke porter kontrolleren og sensoren er koblet til. Denne informasjonen finner vi printet på fremsiden av Arduino-tilleggskortet. Vi trekker ut en verdi-klosser til alle hullene i initialiserklossene Figur 1.5 Vi forteller hvilke porter komponentene våre er koblet til Vi har nå fortalt Arduinoen hvilke porter vi har koblet komponentene våre til. Deretter må vi inne i setup-klossen trekke ut to setup-klossser. En for motorkontrolleren og en for avstandssensoren. Vi trekker ut en setup kloss for hver av komponentene. Disse plasserer vi inne i setup-klossen Figur 1.6 Vi trekker ut en setup-kloss for hver av komponentene våre
Nå er vi ferdig med oppsettet av Arduino roboten. Det neste vi skal gjøre da er å få bilen til å kjøre fremover. Til det trenger vi faktisk kun 2 klosser. En kloss som forteller at roboten skal kjøre fremover, og en kloss som forteller at roboten skal vente litt før den fortsetter til neste kloss. Vi forteller motrokontrolleren at den skal kjøre fremover, før lar Arduinoen venter i 50 millisekunder på neste kommando Figur 1.7 Vi lar bilen kjøre fremover Nå kjører bilen vår fremover, men målet er jo at den skal unngå hindringer. Vi må dermed lese fra avstandssensoren og avgjøre om bilen skal svinge eller ikke. Til det trenger vi en hviskloss, og en sammenlikningskloss. Hvis-ellers-klossen finner vi under Styring-overskriften og sammenlikningsklossen under Operatorer-overskriften. Vi starter med å trekke ut en hvis-ellers-kloss fra styringoverskriften Trekk ut en er lik-kloss Velg mindre-enn i stedet for er lik Figur 1.7 Vi trekker ut en hvis-ellers-kloss og en sammenlikningskloss
Inne i sammenlikningsklossen skal vi sjekke om avstanden vi leser fra avstandssensoren er mindre enn 45 cm. Til det trenger vi å trekke ut en les Ultrasonisk avstand-kloss og en verdi-kloss. Trekk ut en Les Ultrasonisk Avstand-kloss til første hullet i sammenlikningsklossen Trekk ut en verdi-kloss og skriv tallet 45 i andre hullet i sammenlikningsklossen Figur 1.8 Vi sjekker om avstanden er mindre enn 45 cm Nå kan vi bestemme hva som skal skje når avstanden er mindre enn 45 cm. For at bilen ikke skal kollidere kan vi gjøre følgende: Fortelle motorkontrolleren at den skal kjøre bakover Vente litt så bilen får kjørt bakover Fortelle motorkontrolleren at den skal rotere til høyre Vente litt så bilen får rotert Som du ser er det vent-klossene som bestemmer hvor langt bilen skal rygge og hvor lenge bilen skal rotere. Vi plasserer disse fire klossen inne i hvis-delen av hvis-ellers-klossen.
Når avstanden er mindre enn 45 cm, får vi bilen til å rygge litt før vi roterer til høyre Figur 1.9 Vi rygger og roterer til høyre når avstanden fremover er mindre enn 45 cm Helt til slutt må vi fortelle bilen hva den skal gjøre inne i ellers-delen av hvis-ellersklossen. Her kan vi rett og slett flytte de to nederste klossen inn i ellers-delen.
Vi flytter kjør fremover og vent-klossen inn i ellersdelen av hvis-ellers-klossen Den endelige koden. Nå får vi bilen til å kjøre fremover til den møter en hindring. Da kjører bilen litt bakover og roterer litt til høyre. Her må vi velge hvor lenge vi ønsker at bilen skal kjøre bakover, og hvor lenge i ønsker at bilen skal rotere. Prøv deg frem med forskjellige verdier inne i vent-klossene for å se hvordan det påvirker bilen. Etterpå kan du forsøke å få bilen til å rotere enten til høyre eller til venstre når den møter en hindring. Hva må du gjøre for å få til det, tror du?
4. Programmere roboten til å følge en linje Når i skal få motoren til å følge en linje på bakken er det viktig at forskjellen mellom underlaget og linjen er stor. For eksempel fungerer sort tape godt på et lyst parkettgulen, eller en hvit tape godt på sorte fliser. Men det er viktig å huske på at sensoren måler motsatt enn i eksemplene i dette heftet dersom tapen er hvit og underlaget sort. Kodegenet har laget en video som viser hvordan linjesensoren kalibreres. Denne videoen er tilgjengelig på Kodegenets YouTube kanal. Dersom du ikke har benyttet en avstandssensor før, kan det være lurt å se gjennom videoen før du fortsetter å lese i dette dokumentet: https://www.youtube.com/watch?v=femow3bwd3s&t=1s. Nå når sensoren er ferdig kalibrert for underlaget og tapen, kan vi begynne å programmere bilen. Det er lurt å starte med en enkel bane som ikke har for mange svinger i seg. Faktisk kan det lønne seg å starte med en bane som er en enkel sirkel. Pass på at banen ikke er for liten, slik at svingen i banen ikke blir for liten/krapp. Da blir det enklere å programmere bilen til å gå rundt banen i starten. Vi kan teste at bilen klarer å følge tapen ved å la den kjøre både med klokken, og mot klokken. Her tar vi utgangspunkt at vi leser HIGH (eller 1) fra sensorene dersom de er over gulvet, og at de leser 0 dersom de er over tapen. Det forutsetter at tapen er sort og at gulvet reflekterer lyset fra de infrarøde lampene tilbake til mottakeren. Vi starter med et nytt prosjekt i Blockuino, hvor vi initialiserer motorkontrollerkortet. Vi starter med følgende klosser som setter opp motorkontrolleren med riktige porter på Arduinoen Vi starter med å initialisere motorkontrolleren
Deretter må vi legge til en ny variabel for hver av de fire linjesensorene, samtidig som vi må definere alle pinnene som INPUT. Linjesensorene har vi koblet til pin 4, 5, 6 og 7 på Arduinoen. Vi definerer en ny variabel for hver av de fire linjesensorene Linje-pinnene definerer vi som INPUT Vi definerer variabler for linjesensorene og definerer pinnene som INPUT Nå er vi ferdig med oppsettet vi trenger for å følge en linje. Det neste vi skal gjøre er å legge til følgende inne i loop: Vi starter med å velge at bilen skal svinge mot høyre. Dette er det vi ønsker at bilen skal gjøre dersom den ikke finer noen linje under sensorene i det hele tatt Dersom linje1 er over gulvet, mens linje4 er over tapen, så skal vi svinge til høyre Dersom linje4 er over gulvet, mens linje1 er over tapen, så skal vi svinge til venstre Dersom både linje1 og linje4 er over tapen, så skal vi kjøre rett frem Dette er den enkleste måten å programmere bilen til å følge en linje på. Her benytter vi oss bare av 2 av 4 sensorer, så det er mulig å programmere roboten til å være mye mer nøyaktig når den skal følge linjen på bakken. Men koden over gir oss en god start for å eksperimentere med å få roboten til å følge en linje.
Vi starter med å fortelle at bilen skal svinge mot høyre. Dette overskriver vi raskt nedenfor, avhengig av hva vi leser fra linjesensorene Vi skal ta tre avgjørelser, og legger dermed ut tre tomme hvis klosser med hver sin sammenlikning Vi starter med å få bilen til å svinge til høyre, før vi legger på tre sammenlikninger Inne i hvis-klossene kan vi nå starte å legge til sammenlikningene våre. I hvis-klossene skal vi ha følgende sammenlikninger fra toppen til bunnen: Dersom linje1 og linje4 er over tapen Dersom linje1 er over tapen, men ikke linje4 Dersom linje1 ikke er over tapen, men linje4 er det Da ender vi opp med følgende kode. Til slutt venter vi 50 millisekunder mellom hver gang vi leser fra linjesensorene
Dersom både linje1 og linje4 er over tapen, skal vi kjøre fremover Dersom kun linje4 er over tapen, skal vi svinge til høyre Dersom kun linje1 er over tapen, skal vi svinge til venstre Vi sjekker hvilke sensorer som er over tapen Nå kan vi enkelt og greit sette inn bevegelsene inne i hver av hvis-klossene ved å sette hastigheten til motorene på venstre og høyre side av roboten. Dersom både linje1 og linje4 er over tapen, skal vi kjøre fremover Dersom kun linje4 er over tapen, skal vi svinge til høyre Dersom kun linje1 er over tapen, skal vi svinge til venstre Vi får roboten til å svinge
Som du ser, har vi nå fått roboten til å svinge til høyre og venstre når den skal. Dersom du lager en bane til roboten på bakken, kan vi få roboten til å følge linjen.
5. Styre roboten vie en radiolink Kommer snart som video. 5.1. Koden til roboten //https://github.com/zeitgeist87/rfreceiver //https://github.com/zeitgeist87/pinchangeinterrupthandler #include <PinChangeInterruptHandler.h> #include <RFReceiver.h> // Listen on digital pin 2 RFReceiver receiver(4); int ena = 11; int in1 = 12; int in2 = 13; int enb = 10; int in3 = 9; int in4 = 8; int hastighet = 0; void setup() { Serial.begin(9600); receiver.begin(); } pinmode(ena, OUTPUT); pinmode(in1, OUTPUT); pinmode(in2, OUTPUT); pinmode(enb, OUTPUT); pinmode(in3, OUTPUT); pinmode(in4, OUTPUT); void venstremotorer(int hastighet) { analogwrite(ena, abs(hastighet)); digitalwrite(in1, hastighet > 0); digitalwrite(in2, hastighet < 0); } void hoyremotorer(int hastighet) { analogwrite(enb, abs(hastighet)); digitalwrite(in3, hastighet > 0); digitalwrite(in4, hastighet < 0);
} int gyldighastighet(int vurderhastighet) { int hastighet = 0; if (vurderhastighet >= 7) { hastighet = 255; } else if (vurderhastighet >= 5) { hastighet = 150; } else if (vurderhastighet >= 3) { hastighet = 0; } else if (vurderhastighet >= -3) { hastighet = 0; } else if (vurderhastighet >= -5) { hastighet = -150; } else { hastighet = -250; } } return hastighet; void loop() { char msg[max_package_size]; byte senderid = 0; byte packageid = 0; byte len = receiver.recvpackage((byte *)msg, &senderid, &packageid); } int hastighetx = msg[1] - '0'; hastighetx = map(hastighetx, 0, 9, -9, 9); int hastighety = msg[3] - '0'; hastighety = map(hastighety, 0, 9, -9, 9); Serial.print(hastighetX); Serial.print(","); Serial.print(hastighetY); Serial.print(" === "); int hastighethoyre = gyldighastighet(hastighety + hastighetx); int hastighetvenstre = gyldighastighet(hastighety - hastighetx); Serial.print(hastighetHoyre); Serial.print(","); Serial.println(hastighetVenstre); venstremotorer(hastighetvenstre); hoyremotorer(hastighethoyre);
5.2. Koden til senderen //https://github.com/zeitgeist87/rftransmitter #include <RFTransmitter.h> int NODE_ID = 1; int OUTPUT_PIN = 4; int joystickx = 0; int joysticky = 1; // Send on digital pin 11 and identify as node 1 RFTransmitter transmitter(output_pin, NODE_ID, 100, 100, 0); void setup() { pinmode(joystickx, INPUT); pinmode(joysticky, INPUT); Serial.begin(9600); } void loop() { int xval = analogread(joystickx); int yval = analogread(joysticky); xval = map(xval, 0, 1024, 0, 9); yval = map(yval, 0, 1024, 9, 0); char radiopacket[4]; sprintf(radiopacket, "%s%d%s%d", "R", xval, "L", yval); Serial.println(radiopacket); transmitter.send((byte *)radiopacket, strlen(radiopacket) + 1); }