Robotsystem Solfølger

lavet af: Ellen Lorenzen og Lærke Bøg

Opbygning

Systemet bliver styret af 2 lyssensorer, der er placeret på et breadboard. Lyssensorerne sidder på hver side af en skygge-mur, hvis formål er at kaste skygge over den sensor der er længst væk fra solen. Breadboardet er placeret på en skrå legoopsætning. Den er skrå for at vinkle solcellerne, som skal placeres på breadboardet, mod solen. Breadboardet er forbundet med motoren via flere tandhjul, for at opnå en gearing der får pladen til at bevæge sig langsommere. Derfor går det fra små tandhjul til store tandhjul.  Dette blev tilføjet da motoren kørte for hurtigt og havde for lidt kræft.

Opsætningen er også via tandhjul forbundet med et potentiometer der bruges til at måle hvor meget pladen er drejet. Her sidder tandhjulene så der opnås en gearing der sikrer samme drejning af potentiometert som breadboardet. Idet potentiometeret kan dreje 270 grader, muliggør dette, at boardet kan følge solen hele dagen på alle tider af året. Monitoreringen af positionen gør det muligt, at køre til udgangsposition når solen går ned, så solcellerne står klar til at fange morgensolen.

Se opsætningen på billedet herunder.

 

Hardware

Robotten kan elektronisk opdeles i tre områder. Der er selve arduinoen med motor shielded, en del der registrerer lysretning og en del der registrerer motorens position.

Selve arduinoen med motor shield, bruges dels som spændingskilde til både motoren og de elektroniske kredsløb. Den har tilsluttet 5V fra batterier, ud over det den får fra computeren. Desuden bruges den til analog måling af signalerne, fra de andre områder, gennem sine analoge porte.

Lysretningen registreres ved hjælp af to light dependent resistors (LDR). De ses både på billedet og i diagrammerne. De virker ved, at modstanden i dem ændres afhængigt af lysstyrken de bliver påvirket af. Da de to sensorer er adskilt af muren, der kaster skygge, vil den ene sensor opfange mere sollys end den anden, og dermed vil der blive registreret en forskel. Måden det måles på, er ved at have en spændingsdeler for hver af lyssensorerne, således at det kan måles hvor stor en del af spændingsfaldet der sker over den faste modstand, og hvor stor en del der sker over sensoren.

Potentiometeret er monteret så det drejes sammen med motoren. Når der drejes på potentiometeret ændres dets modstand, og dermed kan det registrere en position. Elektronisk er det opbygget lig lyssensorerne ved, at der tages en analog måling ud fra en spændingsdeler. Måden der er opbygget kan ligeledes ses på billedet og i diagrammerne.

Der er valgt modstande på 5,1 kΩ til både LDR og potentiometeret som den faste modstand i spændingsdelingen. Grunden til der er valgt 5,1 kΩ, er at det ligger nogenlunde midt i begge deles interval, og dermed er med til at give størst mulig spredning i de målte værdier.

 

Software

Robotten er programmeret så den løbende sammenligner inputtet fra de to lyssensorer. Hvis deres værdi afviger signifikant drejes pladen mod den sensor der måler den højeste lysmængde. Hvis potentiometeret indikerer at pladen er nået til en yderposition drejes den ikke yderliger.

For at sikre at pladen bliver kørt tilbage til udgangspositionen efter solnedgang er følgende blevet skrevet ind i programmet. En tæller tæller op for hvert gennemløb af programmet. Når tælleren når en fastlagt værdi, registreres den aktuelle position. Positionen sammenlignes med den foregående positions. Hvis disse to positioner er ens, opfattes det som om, at solen er gået ned og pladen køres tilbage til udgangspositionen.

Toleranceværdier for forskellen mellem lyssensor og positions ændringer er fundet ud fra test i sollys.

Koden for programmet og et flowchat over koden, kan ses herunder.

// pinde til motoren 
const int retningPin= 12;     // Pinden der styre retningen 
const int bremsPin = 9 ;      // Pind der aktivere bremsen
const int PWM = 3 ;           // Pind der bruges til at indstille PVM  


// pinde til lyssensore 
const int lyssensorHPin= 0;   // Pind der modtager input fra højre lyssensor 
const int lyssensorVPin= 1;   // Pind der modtager input fra venster lyssensor 
const int margen = 4;         // Værdi for signafikant forskel mellem de to sensorer 
const int hastighed=250;      // Hastighed til motoren 

int tid= 0 ;                  // Tidstæller 
int TidForTjek=19200;         // Antal gennemløb før tjek af position 

int PositionPin=2;            // Pind for input fra potentionsmeter 
int Position ;                // Variabel til positionens værdi 
int PositionTidligere;        // Variabel til tidligere positions værdi 
const int Positionbegin=353;  // Værdi for udgangsposition 
int PositionT=0;              // Variabel til positionstjek 



void setup() 
{
  //Setup af pind mode 
 pinMode(retningPin, OUTPUT);   // Sæt retningspind til udgangspind 
 pinMode(bremsPin, OUTPUT);     // Sæt brems pind til udgangspind 
 pinMode(lyssensorHPin, INPUT); // Sæt lyssensor 1 pind til input 
 pinMode(lyssensorVPin, INPUT); // Sæt lyssensor 2 pind til input 
 PositionTidligere=analogRead(PositionPin);     // Sæt tidligere pindvariable til positionssensorens værdi 
 Serial.begin(9600);            // Klargør til at skrive på skrærm 
  
}

void loop(){

// Læs lyssensors værdig, og sæt variable til den. 

int HLys = analogRead(lyssensorHPin);
int VLys = analogRead(lyssensorVPin);

// Udskriv sensorværdier til motitor
Serial.print("h");
Serial.print(HLys);
Serial.print("  v");
Serial.println(VLys);


// Aflæs position 

Position=analogRead(PositionPin); // Aflæs positionssensors værdig og sæt til variablen Position 
  Serial.print("Position");       // Skriv position i monitor 
  Serial.println(Position);       // Skriv Positionsvariables værdi i monitor 

  

if(VLys-HLys < margen && VLys-HLys > - margen ) // Tjek om lyssensores værdier ikke er signifikat forskellige 
{
  // brems 
   digitalWrite(bremsPin, HIGH); // Aktiver bremse 
   analogWrite(PWM, 0);          // Sæt motor kraft til 0 
}


else if ( HLys > VLys  )   // Tjek om der er mere lys på Højre end vestere sensor      
  {
    if (Position< 357)  // Tjek om den er kørt helt til højre 
    {
      digitalWrite(bremsPin, HIGH); // Aktiver bremse 
      analogWrite(PWM, 0);          // Sæt motorkraft til 0 
    
    }
    else 
      {
      digitalWrite(retningPin, HIGH); // Sæt retning til Højre 
      digitalWrite(bremsPin, LOW);   // Slå bremsen fra 
      analogWrite(PWM, hastighed);   // Sæt hastighed til den valgte hastighed 
      }
  }

else if (HLys < VLys)// Tjek om der er mere lys på venstre end på højre 
{
  if (Position> 1020)// Tjek om den er kørt helt til venstre 
  {
   digitalWrite(bremsPin, HIGH); // Aktiver bremse 
   analogWrite(PWM, 0);          // Sæt motorkraft til 0 
  }
  else
  {
  digitalWrite(retningPin, LOW); // Sæt retning til venstre 
  digitalWrite(bremsPin, LOW);   // Slå bremsen fra 
  analogWrite(PWM, hastighed);   // Sæt hastighed til valgte hastighed 
  }
}


delay(10); // Delay for at kunne holde styr på tiden 

  // Håndtering af solnedgange 

tid +=1 ;                 // Tæl tid eller antal gennemløb en op 
Serial.print("tid  ");
Serial.println(tid);      // Udskriv antal omgange eller tid i monitoren 

if( tid > TidForTjek)     // Tjek om det valgte antal omgange (tid) er gået 
{
  tid =0 ;                // Nulstil tidstæller 
  PositionTidligere=PositionT;                // Sæt tidligere målte position til PositionTidligere
  PositionT=analogRead(PositionPin);          // Aflæs ny position 

  if ((PositionT-PositionTidligere>(-5) && PositionT-PositionTidligere<5) && PositionT>Positionbegin+5 )      // Tjek at position er over 10 enheder forskellig for tidligere position og forskellige fra udgangs positionen  
  {
    while (PositionT>Positionbegin+2)         // Forsæt indtil position er ved begyndelsespositionen 
    {
      digitalWrite(retningPin, HIGH); // Sæt retning til højre 
      digitalWrite(bremsPin, LOW);    // Slå bremsen fra 
      analogWrite(PWM, hastighed);    // Sæt PWM til valgte hastighed 
      
      PositionT=analogRead(PositionPin);      // Aflæs positionssensor 
      
    }
    
  } 
    
 }

}

Problematikker

Hardware

En af de største udfordringer i forhold til hardware, har været at bevægelige og ikke-bevægelige dele har skulle være forbundet med ledninger. Desuden har der været problemer med en motor der ikke virkede, og tidspunkter hvor der ikke er blevet registreret det der blev forventet, hovedsageligt fordi der var blevet byttet rundt på nogle ledninger. Det har virket overskueligt at skulle opsætte kredsløbene.

Solnedgang

Først blev det overvejet at opfatte en solnedgang når der ikke længere var lys på sensoren, men hvis solcellen står tæt på kunstigt lys ville denne metode ikke virke. Det antages at kunstigt lys fx en gadelygte ikke bevæger sig derfor opfattes en solnedgang som det tidspunkt hvor pladen ikke har bevæget sig i en givet periode.

For at solcellepladen skal kunne køre tilbage til samme position, er det nødvendigt at kunne holde øje med dens position. Dette problem blev løst med potentiometeret.

For at afgøre hvor mange omgange programmet skal køre, før den ønskede tid mellem positionstjekkene er gået, er følgende gjort. Først tages der tid på 250 omgange. Den tid deles så med 250 for at finde frem til, hvor lang tid en omgang tager. Den ønskede tid deles så med tiden for en omgang. Herved er antal gennemløb af programmet i løbet af den ønskede tid fundet. Den værdi bruges i variablen TidForTjek i koden.

Interval

Det har været en udfordring at få robotten til at reagere på en værdi indenfor et interval. For eksempel skal den stoppe hvis de to lyssensorer giver sammen værdi. Det er urealistisk at de er præcis ens og derfor er der lavet en margen, der bestemmer at de bare skal være tæt på hinanden.

Det er løst ved at trække de to værdier fra hinanden og måle om forskellen er mindre end margen. Her opstod et nyt problem med at fjerne fortegnet, da det er lige meget om sensoren havde drejet sig lidt i den ene eller anden retning. Første blev en unsigned kommando brugt. Dette havde dog ikke den ønskede effekt da outputtet var en tilfældig værdi. Derfor blev det valgt først at tjekke om forskellen lå under den positive marven og derefter om den lå over den negative marven.    

Forbedringsmuligheder  

Tandhjulene og positionsmålerens position kan nemt rykke sig i forhold til hinanden, for eksempel ved flytning af robotten. Derfor er yderpositionen ikke fast fra test til test. Det kan give nogle problemer i forhold til ledningerne, som lettere vikles ind i hinanden og sætter sig fast. Dette kunne være løst ved at have en knap på robotten der blev trykket ind hvis en fast yderposition blev nået.

Når robotten kører rykker tandhjulene sig i forhold til hinanden så de ikke længere drejes. Dette kunne løses med en bedre fastspænding af tandhjulene.

En forbedring kunne være at solcelleholderen ikke kun drejer om en horisontal akse, men også om en vertikal akse.

Ledningerne sidder frit mellem robottens bevægelige dele og de dele der er placeret på jorden. Dette kan give problemer ved at ledningerne sætter sig fast og bremser robottens bevægelser. Dette problem kunne fjernes ved at sætte ledningerne bedre.  

Konklusion

Robotten opfylder de overordnede mål ved at følge lysets bevægelser og har en strategi for at komme tilbage til udgangspunktet efter solnedgang.

Ved en to-timers test udendørs med vekslende skydække levede robotten op til forventningerne ved at vende sig mod det sted på himlen hvor der slap mest lys igennem.

Ved en test af simuleret nat hvor sensoren over en længere periode målte det samme kørte pladen som forventet tilbage til udgangspositionen.  

Leave a Reply