Skrevet af Mathias Winnard, Nikolai Emil Damm og Stephan Sørensen

Hvordan ser systemet ud, og hvordan er det opbygget?

solceller
Billede 2 – Et meget traditionelt solcelleanlæg der kan bevæge sig efter hvor solen står højest.
Billede 1 – Gruppens endelige system.

Gruppens endelige system er at se i billede 1. Systemet (herefter benævnt “robotten”) er bygget med en DC-motor forneden, hvor en stabil pind, der holder resten af robotten, er monteret på motoren, således at hele den øvre halvdel af robotten kan drejes af motoren i bunden. Ud over det er der de to vinger med sensorer og muren/kassen der holder Arduino, breadboard og batteri, og samtidigt skygger for sensorerne, hvilket er vitalt for hvordan robotten interagerer ift. lyspåvirkninger. Det er også muren/kassen der tillader robotten at være mobil.

Robottens design er inspireret af hvordan de fleste moderne bevægelige solcelleanlæg ser ud (se billede 2).

Tanken var derfor at bygge en robot med en motor, der kunne dreje om sig selv, og i koden behandle data, der tillod robotten at finde og følge den kraftigste lyskilde. Komponenterne til det fysiske design har været omplaceret flere gange, for at finde det mest optimale design inden for tidsperioden. Det nuværende design har haft sine fordele og ulemper.
At arbejde mod et allerede kendt design har fjernet behovet for at idégenerere selv.

Det har dog samtidigt givet os rigtig mange udfordringer, blandt andet med DC-motorens trækkraft, grundet den vægt motoren her har skulle trække.

Første designudkast var nemlig blevet tiltænkt med brug af en stepper motor frem for en DC-motor, som endte med at blive brugt i stedet for, grundet mangel på stepper motor. Hovedkomponenterne (Arduino Uno, breadboard og batteri) er blevet placeret i muren/kassen som er mellem de to lyssensorer; dette har givet mere mobilitet, men samtidigt problemer med ledningen mellem Arduinoen og motoren, da denne ville blive viklet ind og sidde i klemme mellem top og motor.

Hovedkomponenterne er blevet placeret netop dér, for at minimere ledninger der kan blive viklet ind i hinanden (mellem lyssensorer, Arduinoen, breadboard og batteripakken) når robotten er i bevægelse. Fladen med lyssensorerne er blevet vinklet til ca. 55 grader, for at få omtrentligt optimalt lysindtag ift. dens position på den nordlige halvkugle. Grundet tidspres har et fysisk redesign ikke været en realistisk mulighed – hvorfor gruppen har insisteret på at finde en løsning i koden og vha. mindre ændringer/tilføjelser i det oprindelige fysiske design.

Hvordan er robottens hardware sammensat?

Billede 5 – Defekten på Arduino motorshieldet.
Billede 4 – Robotten set fra siden, med benyttede komponenter markeret.
Billede 3 – Robotten set i fugleperspektiv, med benyttede komponenter markeret.

Udviklingsprocessen har ikke været problemfri, da vi i gruppen har oplevet en del fejl, og udfordringer i at overkomme disse. Den mest mærkbare var at vores Arduino Motorshield havde en defekt Vin-indgang, som skyldtes at en fastlimet komponent på undersiden af motorshieldet var brændt af (se billede 5). Det tog gruppen et stykke tid at finde ud af, da det krævede en del debugging i koden, før vi kom frem til det var en hardware fejl. Løsningen var dog ret simpel, da der er en en anden Vin-indgang på Motorshieldet, som vi kunne benytte. Denne kørte udenom om den afbrændte komponent, og robotten fungerede igen.

Billede 6 – Fritzing sketch af kredsløbet, der kører gruppens endelige robot

Hvordan er robottens opførsel implementeret?

Robotten vi har lavet fungerer igennem en række if/else-statements der bestemmer og afgør om robotten skal skifte retning, stoppe, eller bare fortsætte i nuværende retning. For at dette fungerer, bruger vi fire metoder.

void setup() {...}

void loop() {...}

void changeDirection(int pins[]) {...}

void changeSpeed(int pins[]) {...}

Før den første metode har vi alle de benyttede variable i programmet, som hhv. er benyttede pinde, sensorens grænseværdi, hastigheden og booleans.

const int pins[] = {11, 13}; //11 is PWM and 13 is dirB
const int brakePin = 8;
const int leftSensorPin = A0;
const int rightSensorPin = A1;
int sensorThreshold = 30;
int mySpeed;
bool fullStop = false;
bool left = false;
bool right = false;

Vigtigt at bemærke er at vi har benyttet et array til at holde pindene. Det tillod os lidt hurtigere at kunne analogWrite og digitalWrite til pindene, men med den ulempe at man skal huske at pind 11 er PWM og har array plads 0, og pind 13 er retningen og har array plads 1. Det tillader os dog at give alle pindene som parameter til en metode, og så i metoden bestemme hvilke pinde der skulle påvirkes. Derudover er det sensorens grænseværdi (sensorThreshold) som bestemmer den maksimale forskel der må være mellem de to sensorer, før programmet tager handling.

setup()

Den første metode i programmet er setup metoden. Den sørger for at initialisere de benyttede pinde i motorshieldet, og at starte serial monitoren.

void setup() {
    pinMode(pins[1], OUTPUT);
    pinMode(brakePin, OUTPUT);
    Serial.begin(9600);
}

loop()

Den anden metode er vores loop. Den består af et if/else-statement der sørger for logikken i flow diagrammet (Se billede 7).

Billede 7 – Flow-diagram over programmets logik.

Det fungerer ved at der checkes hvorvidt der er en væsentlig forskel mellem højre og venstres sensor værdier, og hvis der er sættes booleans til true for den respektive retning der er ønsket, og false for fuldt stop og den retning der ikke er ønsket. Hvis ikke der er en væsentlig forskel sættes retnings booleans til false, og fuldt stop boolean til true. Til sammen skaber dette tre scenarier.

  1. Et retningsskift der kører metoden changeDirection efterfulgt af metoden changeSpeed.
  2. En bibeholdt retning der kun kører metoden changeSpeed.
  3. Et fuldt stop der kun kører metoden changeDirection.

changeDirection()

changeDirection har tre if-statements, et for hver retning, og et for fuldt stop. Det er de satte booleans der afgør hvilket statement der skal udføres. Hvis der f.eks. sker et retningskift, køres statement for venstre eller højre drejning, hvor et while-loop først decelerere motoren, hvilket går ret stærkt af eget ønske. Dernæst ændres retningen robotten skal dreje, vha. af en digitalWrite til direction pinden, hvor LOW er venstre og HIGH er højre.

if (left) //eller right
  {
      while (mySpeed > 0) {
          mySpeed -= 5;
          analogWrite(pins[0], constrain(mySpeed, 0, 255));
      }
      digitalWrite(pins[1], LOW);
      digitalWrite(brakePin, LOW);
  }

Hvis booleans i stedet er sat til fuldt stop, køres det tredje statement i changeDirection, der kun decelerere motoren, for så at hvile.

if (fullStop)
{
    digitalWrite(brakePin, HIGH);
    while (mySpeed > 0) {
        mySpeed -= 5;
    }
    analogWrite(pins[0], constrain(mySpeed, 0, 255));
}

changeSpeed()

changeSpeed sørger i alt sin simpelthed for at accelerere motoren. Her har vi i gruppen dog valgt at benytte constrain() for at sikre motorens start PWM værdi er over 50, eftersom vores robotten er tungt og det kræver en del PWM for at dreje det.

void changeSpeed(int pins[]) {
    if (mySpeed < 250) {
        mySpeed += 5;
        delay(50);
    }
    analogWrite(pins[0], constrain(mySpeed, 50, 255));
}

Grundet muligheden for at styre robottens rotationshastighed gennem kode, er gearing derfor helt undladt fra det endelige design.

Hvilke udfordringer har der været ift. til at få koden til at virke?

I gruppen har vi haft lidt problemer med at kode i Arduino. Det er ikke et fantastisk program at debugge i, og man skal være meget varsom med hvad man får skrevet. Dette var tydeligt da vi havde en slåfejl, der tog alt for lang tid at finde, fordi den ikke havde en måde at indikere fejlen på, og samtidigt ikke var let at debugge sig frem til fejlen. En anden udfordring var at ledninger af og til faldt ud, og hvis vi ikke satte dem korrekt i var det svært at holde styr på retningerne for motoren. Dette var især problematisk, hvis det skete mens vi udviklede programmet, fordi det der var svært at afgøre om det var koden den var gal med eller ledningerne. En tredje udfordring har været at styre PWM for motoren. Vores robot er ret tung, og det har medvirket at vi har været nødsaget til at have motoren kørende på høje PWM-værdier. Af samme årsag har vi også været nødsaget til at have ret bratte opbremsninger, fordi når motoren først kørte, kørte den stærkt, og en langsom opbremsning, ville gøre det umuligt at følge den stærkeste lyskilde.

Konklusion

Den endelig robot, som gruppen har valgt at kalde for “Tarkus”, opfylder opgaveformuleringen det meste af vejen, men har dog enkelte problemer som gruppen ikke har kunne nå at enten redesigne eller implementere. På grund af tidspres har gruppen ikke fået testet Tarkus særligt meget i naturlige omgivelser ift. normalt sollys. Robotten kan dog ved brug af LDR-modstande bestemme hvilken retning det kraftigste lys kommer fra og opfylder derfor den del af opgaveformuleringen. Fladen er ikke direkte vinkelret på solens lys, men er vinklet 55 grader, så den opnår en nær-optimal indfaldsvinkel. Tarkus er ikke programmeret til at vende tilbage til den oprindelige rotation efter solnedgang, men vil grundet vinklingen være i stand til at vende sig tilbage mod solen, når lyset falder på Tarkus fra en optimal vinkel/retning. 

En eventuelt forbedring til robotten kunne have været at motoren var placeret i toppen af robotten og monteret på en fod, i modsætning til nu, hvor motoren er del af foden. Herved kunne problemet med at den blev viklet ind i egne ledninger ved rotation undgås. Dette ville dog kræve en betydeligt tungere og mere stabil fod, eftersom motorens egen vægt ville blive tilføjet til robottens øvre, dynamiske halvdel. 

Robottens størrelse og vægt betyder også at den kræver mere energi for at rotere, da der er en større belastning på motoren, og en reduktion i vægt ville derfor mindske energiforbruget. Dette ville eventuelt kunne gøres ved primært at bygge den øvre halvdel som et “skelet”, der holdt sammen på Arduino, breadboard og motor, frem for at bygge den så solid som den er på nuværende tidspunkt. Dertil kunne tilføjes smallere mure til at separere LDR-modstandene. Yderligere ville det være muligt at mindske belastningen på motoren, hvis vægten fra robottens øvre halvdel blev fordelt ud på et eller flere hjulbesatte støtteben, der kunne rotere med den rundt. Dette ville potentielt både kunne mindske energiforbruget og den påkrævede kraft tilført for at rotere robotten. Under forudsætning af at robotten skal bruges som en solcellestyring, ville det bestemt være optimalt, hvis den forbrænder mindre energi end solcellen producerer.

Video

Leave a Reply