Jonathan Navntoft Lundstrøm & Holger Nordgaard Roland – 21-04-2020

I dette blogindlæg vil vi beskrive hvordan udvikling af Wacky Tower To Praise The Sun. Vi har lavet et simpelt tårn, der vil kunne følge solens stråler ved hjælp af 2 LDR-modstande.

Wacky Tower to Praise the Sun

Tårnets funktion skulle være at følge solen, for at optimere hvor meget sol dette kan nå at fange, i løbet af en dag. Når tårnet havde drejet 180 grader om sig selv i løbet af en dag, ville dette dreje sig selv tilbage til dettes udgangspunkt.
Måden hvorpå vi ville få det til at flytte sig var, at hvis tårnet måler at dette burde flytte sig, drejer det sig 15 grader mod lyset, hvorefter tårnet går i dvale indtil næste måling. 

Tekniske detaljer

Tårnet, og dennes dele

Vi har placeret to LDR-modstande på toppen af tårnet oppe på et breadboard. De to LDR-modstande sidder modsat hinanden (180 grader) og fungerer ved, at de måler hvor der er mest lys og herefter sammenligner hinandens værdier. Herefter vil tårnet dreje efter det sted hvor der er mest lys. Grunden til at vi valgte at benytte to LDR-modstandene er begrundet ved, at vi gerne ville have mulighed for at sammenligne de to værdier med hinanden for at opnå et mere præcist resultat.

Vi har valgte at placere motoren i bunden af vores tårn, fordi vi gerne ville have en solid underlag, samt det er den part der vejer mest, så det kræver et lavere tyngdepunkt. 

Lego gear

Under vores opbygning af gearing har vi valgt en gearratio 84:1, fordi vi gerne ville have en høj gearing. Vi opnåede dette tal ved hjælp af gearene på ovenstående billede. Vi begyndte opbygning af gearing og udregnede derefter gearrationen for at finde ud af motorens omdrejninger og dermed rette det til indtil vi havde en passende gearing. 

Udregning af omdrejninger:

Motoren vi har brugt har ifølge dette specsheet (https://www.philohome.com/motors/motorcomp.htm) en Rounds Per Minute (RPM) på omkring 75 ved 5V, som er den mængde strøm vores Arduino giver den. Men vores gear ratio på 84 betyder dette at toppen af tårnet har en RPM på 0.89. Det vil sige at vores tårn drejer sig 320,4 grader pr. Minut når motoren får strøm. Hvis vi regner dette om til millisekunder får vi at den drejer sig 0,00534 grader pr. ms. Da vi regner med at tårnet skal dreje sig 15 grader pr. måling vil det sige at vi ifølge vores udregning skal give motoren strøm i 2808,99 ms hver time. 

Vi har taget udgangspunkt i følgende hjemmeside som beskriver legomotorens specifikationer: https://www.philohome.com/motors/motorcomp.htm

Grundet fejl i enten vores konstruktion, vores udregning eller det specsheet vi har taget udgangspunkt i, viste dette sig dog at give et forkert resultat. Efter 33.707,88 (12 * 2808,99) ms havde tårnet drejet sig lidt over 200 grader, og vi har derfor valgt at tage udgangspunkt i fysisk testing af produktet, for at komme nærmere på at finde ud af hvor meget vi skal dreje tårnet. Specsheetet vi har fulgt oplyser motorens omdrejningshastighed uden belastning, men da dette teoretisk set burde give tårnet en langsommere hastighed end det vi målte os frem til. Vi har i koden taget udgangspunkt i 2600 ms hver time, men dette er ikke præcist og burde forbedres ved yderligere, og mere præcise målinger.

H-bro

I dette projekt havde vi ikke mulighed for at bruge en h-bro, vi vil dog kort gå ind og beskrive hvad en h-bro er og hvordan vi ville have brugt denne i vores projekt. En h-bro er en parallelforbindelse af transistorer (normalt 4), som for eksempel kan bruges til at ændre kørselsretningen på en motor, ved at ændre på strømmens retning igennem motoren. I koden til vores arduino har vi simuleret dette, ved at skrive at strømmen skal være enten High eller Low. Hvis strømmen følger High kører strømmen igennem motoren én vej, og motoren drejer sig efter dette, og ved Low går strømmen modsat, og motoren ligeledes. Siden vi skulle bygge et tårn der følger solen, ville det have været godt at bruge en h-bro, fordi så ville den have mulighed for at rotere efter lyset, men også havde muligheden for at rotere den modsatte vej til tårnets originale position.    

På billedet nedenfor kan et eksempel på en h-bro ses. I dette tilfælde vil motoren køre med urets retning hvis den venstre knap bliver trykket ned, og vice verca. Vi ville have styret retningen med arduino i stedet for fysiske knapper hvis vi faktisk havde lavet dette, men da vi ikke havde mulighed for det, vælger vi at vise det her.

H-bro

Ved at bruge en tidsstyring vil vi teoretisk set kunne opnå at robotten kører samme mængde omdrejninger frem og tilbage hver gang. Vi løb dog ind i problemer med stabiliteten af vores konstruktion. Jo flere gange vi målte, jo større afvigelse kunne vi måle fra vores teoretiske udregninger, givet eftergivelse i legokonstruktionen. Vi ville have kunnet forbedre dette, men da vi fandt ud af dette problem var karantænen allerede gået i gang, og vi kunne ikke skaffe flere komponenter til at lave et alternativt system.
Et system vi dog overvejede at lave i stedet for tidsbestemt var, at have to knapper 180 grader fra hinanden på konstruktionen (se billede nedenfor). Disse ville være statiske, og ikke rotere med solpanelerne. Toppen der roterer ville hertil have et spir, der ville trykke på knapperne når konstruktionen har kørt 180 grader, hvilket ville forsage at tårnet kører tilbage til det rammer knappen ved dettes originale position. Dette ville resultere i at vi ville få konstruktionen til at starte og slutte præcis samme sted hver gang, og dermed give dette større præcision.

Originale idé til rotation til originale position

Diagramtegninger og opsætning

Nedenfor ses 2 billeder af vores opsætning af Wacky Tower to praise the sun, samt et diagrambillede af hardwaren.

Opsætning på breadboard

Dette billede illustrerer opsætning af vores komponenter ovenpå lego konstruktionen i følgende rækkefølge: breadboard, motor shield og arduino uno.

Selve konstruktionen

Dette billede illustrerer hvordan hele vores robot er opbygget med lego, breadboard, motor shield og arduino uno.

Opsætning af LDR-modstande
Diagramtegning over opsætning af LDR-modstande

Dette billede illustrerer en diagramtegning af vores projekt. Vi har to LDR-modstande, to resistorer på 10k Ω, samt et motorskjold. På denne tegning agerer motorskjoldet både som selve mikrocontrolleren og strømforsyningen.

Udregninger af strøm og modstande

En arduino måler forskellen i volt, hvorimod måling af modstand er svært. I dette projekt brugte vi en LDR-modstand, som er en variabel modstand. Jo mere lys der er til stede desto mindre modstand er der, derfor skulle vi finde en metode hvorpå vi kunne udregne volt. Grunden til at arduinoen har svært ved at måle modstand er begrundet i, at den indeholder et lille system ved navn “Analog to Digital Converter (ADC)”. Siden en ADC er designet til at måle volt og vi fx gerne ville se LDR-modstandens målinger via “analogRead”, så bliver vi nød til at kunne konvertere den varierende modstand til volt som arduinoen kan læse. Dette gør vi ved hjælp af en spændingsdeler. Vi lavede en spændingsdeler ved hjælp at indsætte en modstand, hvorpå vi fik et referencepunkt, så vi kunne måle volt forandringerne. For at kunne måle værdien (Vout), målt af LDR-modstandene bliver vi nød til at starte ved ohms lov. Først skal vi finde strømstyrken igennem vores kredsløb og det gør vi ved følgende:

I = Vin / (R1+R2)

I vores tilfælde var Vin = 5V, R1 var vores LDR-modstand som havde en min modstand på 6,5kohm og en max modstand på 13.5K ohm og R2 valgte vi at benytte 10K ohm på baggrund af følgende hjemmeside, som anbefalede 10K ohm (https://www.instructables.com/id/How-to-Use-a-Light-Dependent-Resistor-LDR/?fbclid=IwAR1y4NyYJvHT6n7_Msk5Gt3PhJ_yr2lD_bbDA_5nxKEBTSzVU6HaXH6H5hI)

Der kan vi udlede følgende ved Vout:

Vout = I * R2

Dermed kan vi nu udlede følgende formel for Vout:

Vout = Vin * R2/(R1+R2)

Ved at bruge tidligere nævnte værdier vil vores udregning for max modstand ved LDR-modstanden (Vout):

Vout = 5 * 10000/(13500+10000)
Vout = 2.13V

Vi kan også finde udregningen for min modstand ved LDR-modstanden (Vout):

Vout = 5 * 10000/(6500+10000)
Vout = 3.03V
Simuleret måling af spænding med en teoretisk LDR-modstand på 13500 ohm

Efter at have bygget kredsløbet op, kunne vi måle Vout ved vores LDR-modstandes minimale og maksimale modstand, henholdsvis 2,13V og 3,03V. Arduinoen tager disse resultater og bearbejder dem i dennes ADC, hvorefter den giver os de digitale resultater. Vi har i koden optimeret programmet så disse resultater kan bruges, og ved fysiske tests kan vi konkludere at systemet virker.

Kode

Koden nedenfor er uredigeret, men er beskrevet med kommentarer.

int sensorPin1 = A2; Definerer hvilke sensorpins vi benytter på motorskjoldet i vores tilfælde A2 og A3  
int sensorPin2 = A3;   

int sensorValue1 = 0; // Pladsholder for sensorværdien fra de to LDR-modstande
int sensorValue2 = 0;  

int error = 70; // Vores fejlmargen er på 70, så hvis forskellen mellem de to LDR-modstande er mindre end 70 sker der ikke noget, men hvis den er større end 70 roterer robotten 

int resetTime = 0; // Nulstillingstiden starter på 0 og hele robottens rotation bliver nulstillet, når den har målt 12 gange  

void setup() {  
  //Setup Channel A  
  pinMode(12, OUTPUT); // Arduino Uno udgang 12 og 9 
  pinMode(9, OUTPUT);   
  Serial.begin(9600);  //Registrerer vores værdier  
}  

void loop() {  
    sensorValue1 = analogRead(sensorPin1);  // Måler  på de to LDR-modstande  
    sensorValue2 = analogRead(sensorPin2);   

    Serial.print("Values: "); //Udksriver de målte værdier i form af sensorValue 1 og sensorValue 2 
    Serial.print(sensorValue1);   
    Serial.print(" | ");  
    Serial.println(sensorValue2);  

    int diff1= abs(sensorValue1 - sensorValue2); //Her beregner vi differensen  
    int diff2= abs(sensorValue2 - sensorValue1);  

    Serial.print("Difference: "); // Her udskriver vi differensen for at se om den er over eller under 70 

    Serial.println(diff1);  

    if((diff1 <= error) || (diff2 <= error)) {  

        //Hvis differensen er mindre end 70 så bremser vi rotationen. Hvis pin 12 er High vil den roterer med urets retning, og er den Low roterer den mod uret  
        //Er pin 9 High bremser den rotation og er 9 Low roterer den afhængig af pin 12 
        digitalWrite(12, HIGH);   
        digitalWrite(9, HIGH);   
        analogWrite(3, 255);  
    } else {      
        if(sensorValue1 > sensorValue2) //Hvis sensorValue1 er større end sensorValue2 så roterer med urets retning  
        {  
          digitalWrite(12, HIGH);   
          digitalWrite(9, LOW);   
          analogWrite(3, 255);   

          // Vi roterer robotten i 2600 millisekunder, eller 2,6 sekunder
          delay(2600);  

          //Vi har en nulstillingstid hvor vi ligger 2600 millisekunder til, for hvor gang robotten har kørt en gang med urets retning
          resetTime += 2600;  

          // Vi bremser rotationen efter 2,6 sekunder
          digitalWrite(12, HIGH);   
          digitalWrite(9, HIGH);     
          analogWrite(3, 255);  
        }  

        // Præcis det samme princip som overstående, bare hvor robotten kører mod uret
        if(sensorValue1 < sensorValue2)   
        {  
          digitalWrite(12, LOW);   
          digitalWrite(9, LOW);   
          analogWrite(3, 255);   

          delay(2600);  

          resetTime -= 2600;  

          digitalWrite(12, HIGH);   
          digitalWrite(9, HIGH);     
          analogWrite(3, 255);  
        }  
      }  

      Serial.print("Reset time = "); //Her printer vi den samlede nulstillingstid 

      Serial.println(resetTime);  
      //Hvis nulstillingstiden er 12*2,6 sekunder så skal robotten nulstille sig selv til dennes oprindelige position  

      if(resetTime >= (12 * 2600))
    {  
        int resetTimer = resetTime;  
        //Vi nulstiller også nulstillingstiden til 0 igen 
        resetTime = 0;  

        digitalWrite(12, HIGH);   
        digitalWrite(9, LOW);   
        analogWrite(3, 255);   

        delay(resetTimer); 
 
        digitalWrite(12, HIGH);   
        digitalWrite(9, HIGH);    
        analogWrite(3, 255);  

      }    delay(3537600); //Dette beskriver hvor længe den venter imellem hver måling, og svarer til en time med omdrejningstiden trukket fra
}

Statuslysdioder

I vores første aflevering havde vi ikke benyttet nogle statuslysdioder. Efterfølgende har vi diskuteret hvordan vi ville have inkluderet statuslysdioder og kom frem til følgende: 
Vi gerne ville have haft en grøn LED der skulle lyse op, når vores tårn drejede, og når tårnet ikke drejede skulle der være en rød LED der skulle lyse op. Herefter ville vi indsætte ovennævnte LED’er i vores kredsløb samt en modstand på 100ohm. Modstandens størrelse er begrundet ud fra ohms lov(R = V / I), hvori  “Vf – Forward Voltage = 2V” og “If – Forward Current = 20 mA”. Disse værdier er fundet på følgende hjemmeside  (https://www.sparkfun.com/products/9592), (https://www.sparkfun.com/products/9590). Nedenstående er hypotetisk kode til LED’erne, som vi ville indsætte i den egentlige kode.

//Definerer hvilket pin de hører til 
Int ledPin = 12; //RØD
int ledPin1 = 13; //GRØN

//Definerer dem som “output”
void setup(){  pinMode(ledPin, OUTPUT);
PinMode(ledPin1, OUTPUT);}

//Herefter ville vi indsætte følgende i et “if-statement”, så når tårnet roterer, så lyser den grønne LED.  
digitalWrite(ledPin1, HIGH);  
digitalWrite(ledPin, LOW);

// Herefter ville vi indsætte følgende i et “if-statement”, så når tårnet ikke roterer, så lyser den røde LED.
digitalWrite(ledPin, HIGH);
digitalWrite(ledPin1, LOW);

Blød opstart og nedbremsning af motor, og spændingsregulator

Opsat version af motor med blød opstart og nedbremsning samt spændingsregulator

I den originale aflevering havde vi heller ikke benyttet en blød opstart eller nedbremsning af vores motor. Vi har dog efterfølgende arbejdet i TinkderCad og opsat hvordan vi ville have gjort det, hvis vi havde haft mulighed for at hente komponenter til projektet. På overstående billede er der en illustration af, hvordan vi ville have sat det op ved hjælp af en såkaldt “H-bridge motor driver”. Denne h-bro fungerer på samme måde som den tidligere opsat h-bro af NPN og PNP transistorerne. Nedenfor har vi skrevet en kodedel der sørger for at motoren har en blød opstart samt en nedbremsning.

// Vi definerer de pins vi vil benytte og siden vi skal indstille på acceleration så bruger vi Digital PWM som bruger pins(3,5,6,9,10,11). Her valgte vi at bruge pin 5 og 6. 
const int motorPin1  = 5;  
const int motorPin2  = 6;  

void setup(){
    //Definerer pin værdiens udgang
    pinMode(motorPin1, OUTPUT);
    pinMode(motorPin2, OUTPUT);   
}
void loop(){
// Her bruger vi et loop der starter ved nul og forøges med 10 hvert 50 minisekund indtil k ikke længere er mindre end 255. Hermed drejer motoren med urets retning og der er en forholdsvis blød opstart.

  for(int k = 0; k<255; k+=10)
  {
      analogWrite(motorPin1,k);
    delay(50);
  }
  delay(2000);
// Her bruger vi et loop der starter ved 255 og mindskes med 10 hvert 50 minisekund indtil k ikke længere er større end 0. Hermed drejer motoren med urets retning og der er en forholdsvis blød nedbremsning.

  for(int k = 255; k>0; k-=10)
  {
      analogWrite(motorPin1,k);
    delay(50);
  }

   for(int k = 0; k<255; k+=10)
  {
      analogWrite(motorPin2,k);
    delay(50);
  }
  delay(2000);
  for(int k = 255; k>0; k-=10)
  {
      analogWrite(motorPin2,k);
    delay(50);
  }
}

Da lego motorerne kører mest effektivt ved 9V, i stedet for de 5V en arduino kan levere vil det være mere effektivt at køre disse på en anden strømkilde. På billedet ovenfor kan en implementation af et sådanne kredsløb ses. I dette kredsløb får motorerne 9V leveret, mens samme strøm kører igennem en spændingsregulator (LM7805) som reducerer strømmen til 5V. De 5V leverer herefter strøm til arduinoen.

Konklusion

Lige pt. måler vores robot kun 1 gang i timen, hvorefter den flytter sig afhængig af lyset. Når robotten har målt 1 gang vil den enten dreje sig 15 grader eller blive det samme sted. Efter robotten har målt 12 gange, vil den dreje 180 tilbage til dens originale position og være klar til at måle når solen står op. Vi mener at robottens funktioner lever op til opgavebeskrivelsen, ved at den måler solens position. Grundet coronavirussen er der dog stadig mange komponenter vi ikke havde mulighed for at inkludere i robottens endelig form. Efterfølgende har vi dog lavet de ekstra mangler i TinkerCad og prøvet at illustrere hvordan vi ville have brugt det i vores projekt.

Perspektivering

Vi ville ved videreudvikling af tårnet have forbedret det ved, at give det mulighed for at følge solen på 2 akser. Ved at følge solen på både x- og y-aksen vil tårnet kunne følge solen mere effektivt, og dermed optimere mængden af sol der falder på tårnet.

Vi ønskede også at bygge selve tårnet op stærkere og mere robust. Vi kunne have opnået mere præcis omdrejninger og målinger, hvis vi havde haft mulighed for at bygge videre på vores konstruktion. Vores konstruktion er forholdsvist stabil, men da der er en vids mængde fleksibilitet i bygningen vil vores rotationer og udregninger ikke være helt præcise. Ved at bygge tårnet stærkere ville vi kunne opnå et mere konsistent målingsresultat.

Tårnet er også i toppen holdt sammen af tape, hvilket fungerer fint så længe der ikke er vibrationer i underlaget, men ved skub og slag kunne dette hurtigt blive et problem. Ved at sætte toppen bedre fast kunne tårnet fungere i længere tid med færre variationer.

Video af tårnets funktion

Test af tårnet, der her kører en måling hver 5. sekund

Litteraturliste

Hurbain, P.  (2020)  LEGO® 9V Technic Motors compared characteristics Lokaliseret d. 25. marts 2020 på: https://www.philohome.com/motors/motorcomp.htm

Ukendt (Ukendt) LED – Basic Green 5mm Lokaliseret d. 13. April 2020 på: https://www.sparkfun.com/products/9592

Ukendt (Ukendt) LED – Basic Red 5mm Lokaliseret d. 13. April 2020 på: https://www.sparkfun.com/products/9590

Akellyirl (Ukendt) How to Use a Light Dependent Resistor (LDR) Lokaliseret d. 10. april 2020 på: https://www.instructables.com/id/How-to-Use-a-Light-Dependent-Resistor-LDR/

Leave a Reply