Hardware og Robotteknologi
Foråret 2021
Porteføljeopgave 1

Lars Philip Francisco Allerup
Maria Skougaard Andersen
Rune Philipsen


Vi havde fra starten en tanke om at bygge vores system ved at lave en solfanger ud af to lysfølsomme modstande, som var placeret i hver sin side af et lille breadboard. Solfangeren placerede vi lodret ovenpå en servomoter, for at den lignede en solfanger, der kunne dreje 180 grader, fra den ene side til den anden side.

Afhængig af værdierne fra de to lysfølsomme modstande, ville vi angive hvilke vinkel og retning servomotoren skulle dreje, alt efter hvilken af de lysfølsomme modstande, der fik mest lys, for at lyspanelet hele tiden kunne stå mod solen og opfange mest lys. 
Vi byggede en simpel prototype for at afprøve vores ide og funktionaliteten. Et billede af opsætningen ses nedenfor:

Billede: Første lo-fi forsøgsopsætning

Vi arbejdede videre og i vores endelige opsætning har vi ligeledes placeret vores servomotor så den bærer vores solpanel, hvilket vi har vinklet 40 grader mod syd som ifølge EU’s photovoltaic geographical information system er den optimerede indgangsvinkel for solen i Odense.

Nedenfor er et billede af vores færdige opsætning:

Billede: Opsætning af vores endelige solfangersystem

Som det kan ses på ovenstående billede, har vi i vores endelige opsætning også implementeret en lcd skærm til at give beskeder i forhold til, om det er dag og lyst eller mørkt og nat. Derudover har vi opsat xx status-lysdioder, der lyser alt efter hvilket stadie vores solfangersystem er i.

Vores opstilling i tinkercad

LDR

For at kunne måle vores værdier fra vores to LDR-resistor hhv. den vestlige og østlige. Måtte vi opbygge et spændingsdeler kredsløb. Grunden til dette er at photo-resistoren er en variabel resistor som ændrer sin indre modstanden på baggrund af lysstyrken. For at måle denne ændring med Arduinoens Analog to Digital Converter, som omsætter forskellen i spændingen, og ikke forskellen på resistansen I LDRèn, er det nødvendigt at have et referencepunkt hvorfra man kan måle spændingsfaldet. Hvilket ville havde været fra 0 – 5 V hvis spændingsdeler kredsløbet ikke blev anvendt.

Beregninger af LED

Til beregninger af modstande i vores led signal kredsløb har vi kigget i databladet og fundet at den foreslåede strømstyrke har en værdi mellem 16 – 18 mA.

Det vi havde til rådighed, for at vi kunne finde en tilnærmelse værdig værdi, var en 330 Ω  og 220 Ω  modstand, derfra har vi lavet følgende beregninger

Her kunne vi godt have valgt at bruge 330 Ω  eller 220 Ω  modstanden. Førstnævnte vil ikke være langt fra det ønsket og sidstnævnte modstand vil give en strømstyrke som er lidt over den maksimale strømstyrke man kan have tændt kontinuert, uden at beskadige vores led.

For udfordringens skyld valgte vi at lave en parallel forbindelse, som ville resultere i en værdi som var tættere på de 17 mA. 

Hardware udfordringer 

Undervejs har der været nogle udfordringer med noget at hardwaren. Blandt andet var ledningerne ikke lange lange nok, så opsætningen væltede nemt, når servomotoren begyndte at dreje. Ligeledes har det været svært at få en platform til at passe godt på mini servo motoren, grundet vægt og vinkel fra breadboardet. Dette har vi forsøgt at løse ved at give noget modvægt i den modsatte ende af solcelle-platformen.

Derudover har vi haft lidt problematikker med, hvordan vi skulle få skjult ledningerne bedst muligt. Ligeledes var en af problemerne, hvordan vi kunne få breadboardet med vores indikator led lys skjult på en måde, så det ikke fyldte i det æstetiske udtryk.

Den største udfordring har dog været, at vores lysfølsomme resistorer var så forskellige, på den måde at den ene hele tiden opfangede højere værdier end den anden. Praktisk resulterede det i, at hvis den LDR der opfangede højest værdier var placeret i vores opstilling mod øst, ville vores solfangersystem ikke flytte sig fra startpositionen, fordi denne værdi hele tiden var større end den opfangede værdi mod vest. 

Ligeledes hvis man byttede om på de to lysfølsomme resistorer, så den LDR der hele tiden opfangede lavere værdier, var placeret mod øst, så ville servomotoren ligegyldig hvad solens placering på himlen var dreje mod vest, fordi systemet hele tiden opfangede højere værdier fra den lysfølsomme resistor mod vest og servomotoren ville hurtigt dreje fra startpositionen hele vejen over til slutpositionen. Efter samtlige test og fysiske målinger med multimeter over modstanderne og LDR’erne, kunne vi konstatere at LDR’erne havde forskellig modstand, derfor besluttede vi at bestille nogle nye bedre LDR modstande. For at være sikre på at LDRérne var relativ præcise, målte vi dem efter med mulitmeteret. Her var der er også et mindre udsving i modstanden. Dette har vi taget højde for i vores kode.

Flowdiagram og overordnet opførsel

Billede: Flow-diagram over robottens opførsel.

Vi har lavet vores program så det tager udgangspunkt i 24 timer på et døgn. Programmet kører et loop atten gange af en varighed på en time, hvor solfangersystemet er aktivt om dagen, hvorefter der er et delay på 6 timer, hvor solfangersystemet er i dvale om natten.  

I servomoterens startposition ved solopgang i øst er dens vinkel indstillet til 180 grader. Servomoterens vinkel går mod nul grader, i takt med dagen går, og solen bevæger sig hen over himlen fra øst mod vest. 

Der bliver derudover på vores LCD-skærm, om morgenen skrevet en godmorgen-besked og ligeledes en godnat-besked om aftenen.

Når den lysfølsomme modstands værdi mod vest er større end den mod øst, bliver der trukket en grad fra servomoterens vinkel. En grøn LED lyser, som indikation om at solfangerpanelet bevæger sig den korrekte vej mod vest, og en rød LED lyser hvis panelet drejer den forkerte vej mod øst. Sammenligningen af værdierne fra de to lysfølsomme modstande sker hele tiden, hvis værdien mod vest er størst drejes solpanelet en grad mod vest, og hvis værdien mod øst er størst drejes solpanelet en grad mod øst, og hvis de to værdier er ens bliver servomoteren stående i den position, fordi det betyder at solfangerne er i den optimale position, hvor begge får mest lys. Når begge får lige meget lys, lyser den røde og den gule LED.

Software udfordringer

I udarbejdelsen af vores solfangersystem havde vi to tidskrævende udfordringer. Det første var at vi ønskede at lave nogle timere i programmet til Arduinoen, så det ikke nødvendigvis skulle være tændt og sammenligne værdier fra solfangeren hele tiden. 

Det endte med, at vi undersøgte hvornår solen tidligst var oppe i Danmark og senest nede, for at lave et tidsrum i programmet hvor servomotoren kunne være i en slags dvale, før programmet kunne starte og stoppe dag efter dag.

For at tage højde for at der kan være udsving i værdierne fra vores LDR modstande, har vi valgt at indføre en grænseværdi/difference-værdi mellem de to LDR, hvor solcelle-robotten skal blive i sit passive stadie hvorefter den tjekker værdierne igen.  

Under udviklingen af solcellerobotten eksperimenterede vi med flere muligheder for at robotten var tændt i 18 timer som er det antal af solskin timer på en sommerdag og 6 timer hvor robotten ikke var aktiv.

Her prøvede vi først at lege med Arduinos timer og interupt funktion. Det startede godt med at vi fik timeren til at fungere. Glæden var dog kort for da vi satte servo motoren til og brugte Servo.h biblioteket, opstod der problemer. Her erfarede vi at den også bruger ardunios timer 1, hvilket var den timer vi havde fået til at virke. Her kunne vi så havde prøvet at få timer 2 til at virke i stedet eller andre løsninger, som eksempels nyt servo bibliotek. Vi valgte i stedet at bruge Millis() funktionen, som returnerer den tid, som arduinoen har været aktiv i ms. Denne tid kunne vi så bruge til at styre førnævnte aktiv og inaktive timer.
Vi oplevede derudover at vi i vores timer fik en forkert tid, i det at koden også brugte en smule tid på at udføre signaleringen til de blinkende led’er.

Koden

#include <LiquidCrystal.h>
#include <Servo.h>
Servo myServo;
int servoPin = 3;

const int rs = 12, en = 11, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

int ledRed = 10;
int ledYellow = 9;
int ledGreen = 8;

int startAngle = 180;
int angle =startAngle;
int lightValEast;
int lightPinEast = A0;

int lightPinWest = A1;
int lightValWest;

int lightValDifference;

long downTime = 21600000; // 6 timers downtime til ms
long upTime = 3600000; // 1 timer til ms  --> skal være op til 18 i loop


float counterForPrinter = 0;


unsigned long startMillis;  //some global variables available anywhere in the program
unsigned long currentMillis;
unsigned long period = upTime;  //the value is a number of milliseconds   <------
unsigned long previousMillis = 0; 

void setup() {
  Serial.begin(9600);
  pinMode(ledYellow,OUTPUT);
  pinMode(ledRed,OUTPUT);
  pinMode(ledGreen,OUTPUT);
  
  pinMode(servoPin,OUTPUT);
  myServo.attach(servoPin);
  myServo.write(angle);
  lcd.begin(16, 2);
 
}

void loop() {
  
  currentMillis = millis();  //get the current "time"  the number of milliseconds since the program started
  lcd.clear();          
  lcd.setCursor(4, 0);
  lcd.print("SUNSHINE");
  lcd.setCursor(5, 1);
  lcd.print("REGGAE");
  // Loop When Running Repeat Interval of 1 Hour 18 times
  for(int i = 0; i < 18; i++){
  currentMillis = millis();  
  while (currentMillis - previousMillis <= period)  //test whether the period has elapsed
  { 
  currentMillis = millis();  
 
  lightValEast = analogRead(lightPinEast);
  lightValWest = analogRead(lightPinWest);

  lightValDifference = lightValEast - lightValWest;

  counterForPrinter +=1; 
    if(counterForPrinter == 30){ 
      Serial.println("Val East : ");
      Serial.print(lightValEast);
      Serial.println();
      Serial.println("Val West : ");
      Serial.print(lightValWest);
      
      Serial.println();
      Serial.println("Val angle: ");
      Serial.print(angle);
      Serial.println();
      counterForPrinter = 0; 
    }
  
    delay(1000);  // delay for our  timer

    if(lightValDifference <=10 && lightValDifference >= -10){                  
  
     myServo.write(angle);
     digitalWrite(ledYellow,HIGH);
     delay(10);
     digitalWrite(ledYellow,LOW);
  }

  else if(lightValWest>lightValEast && angle !=0)
 {
     digitalWrite(ledGreen,HIGH);

     angle= angle-1;
     myServo.write(angle);
     delay(10);
     digitalWrite(ledGreen,LOW);
 } 
    else if(lightValWest<lightValEast && angle !=180)    
 {
     digitalWrite(ledRed,HIGH);
     angle= angle+1;
     myServo.write(angle);
     delay(10);
     digitalWrite(ledRed,LOW);
 }
 
  if(angle == 0 || angle == 180){
    
    digitalWrite(ledYellow,HIGH);
    }
      else{
        digitalWrite(ledYellow,LOW);
        }
      }
       previousMillis = currentMillis; /* updating previous Millis so it will be subtracted in the for loop -- Makes sure the loop will run every day and - should prevent overflow after ca 50 days.*/
  }

 /*Setting Night Message */
   lcd.clear();
   lcd.setCursor(6, 0);
   lcd.print("Cya");
   lcd.print("Tomorrow");
   delay(downTime);
   myServo.write(startAngle);
}

Data ved måling og Graf


Video af Turnminatoren med lommelygte


Video af Turnminatoren med rigtig sol


Konklusion

Vi har med dette projekt fået et bedre kendskab til forskellige elektroniske komponenter og fået et lille indblik i hvordan Arduinos internal timers virker. Vi har ligeledes lært hvordan en spændingsdeler kredsløb benyttes i sammenhæng med Arduinoes AC Converter og en LDR-modstand. Vi konkluderer at vi har formået at løse opgaven i og med at vi har kunne få solcellerobotten til at dreje sig efter forskellen i lysstyrke. Vi har dog i målingen og grafen, oplevet at fordi vi vælger at måle bestemte tidspunkter, så ender vi med målinger, der ikke giver helt mening, i sammenhæng med det uforudsigelige vejr i Danmark, og uligheden i LDR-modstandene.

Leave a Reply