Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2023:vstoica:andradacojocaru [2023/05/27 18:28]
andrada.cojocaru [Software Design]
pm:prj2023:vstoica:andradacojocaru [2023/05/30 08:22] (current)
andrada.cojocaru [Software Design]
Line 1: Line 1:
-====== Solar tracker - Andrada Cojocaru ======+====== Solar tracker - Andrada Cojocaru ​☀️======
 ===== Proiect PM - 2023 ===== ===== Proiect PM - 2023 =====
 Student: ​    ​Andrada-Ioana Cojocaru\\ Student: ​    ​Andrada-Ioana Cojocaru\\
Line 69: Line 69:
 Descrierea codului aplicaţiei (firmware): Descrierea codului aplicaţiei (firmware):
   * **mediu de dezvoltare**:​ Arduino IDE 2.1.0   * **mediu de dezvoltare**:​ Arduino IDE 2.1.0
-  * **librării**: Wire.h, LiquidCrystal_I2C.h,​ servo.h (initial, dupa am facut propriile functii)+  * **biblioteci**: Wire.h, LiquidCrystal_I2C.h,​ servo.h (initial, dupa am facut propriile functii)
 </​note>​ </​note>​
  
-Declararea ​librariilor+Declararea ​bibliotecilor
 <code c> <code c>
 #include <​Wire.h> ​ #include <​Wire.h> ​
Line 81: Line 81:
 <code c> <code c>
 LiquidCrystal_I2C lcd(0x27, 16, 2);  // set the LCD address to 0x27 for a 16 chars and 2 line display LiquidCrystal_I2C lcd(0x27, 16, 2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
 +</​code>​
 +
 +
 </​code>​ </​code>​
  
 Declararea define urilor Declararea define urilor
 <code c> <code c>
-#define SERVO_RIGHT_LEFT_PIN 9 // servo dreapta-stanga +#define SERVO_RIGHT_LEFT_PIN 9 
-#define SERVO_UP_DOWN_PIN 10 // servo sus-jos+#define SERVO_UP_DOWN_PIN 10
  
 #define SERVO_RIGHT_LEFT_REG OCR1A #define SERVO_RIGHT_LEFT_REG OCR1A
Line 99: Line 102:
 </​code>​ </​code>​
  
 +Declararea variabilelor globale pentru miscarea servo-motoarelor - de aici pornesc
 +<code c>
 +int servoRightLeftPos = 35;
 +int servoUpDownPos = 76;
 +</​code>​
 +
 +Functie pentru miscarea servomotoarelor in functie de pin si valoare
 +<code c>
 +void setServoAngle(int servoPin, int angle)
 +{
 +  float pulseWidthMs = 1.0 + (float)angle / 180.0 * 1.0;  // Map angle to pulse width between 1ms and 2ms
 +  int pulseWidthTicks = pulseWidthMs * 20000 / 20;  // Convert pulse width to ticks for 20ms period
 +  if (servoPin == SERVO_RIGHT_LEFT_PIN) {
 +    SERVO_RIGHT_LEFT_REG = pulseWidthTicks;​
 +  } else if (servoPin == SERVO_UP_DOWN_PIN) {
 +    SERVO_UP_DOWN_REG = pulseWidthTicks;​
 +  }
 +}
 +</​code>​
 +
 +**Setup** - configuram lcd ul sa afiseze masajul de pe primul rand, configuram registri corespunzatori si pozitionam servo-motoarele in pozitia de start
 +<code c>
 +void setup()
 +{
 +  // write message on lcd
 +  lcd.init();
 +  lcd.backlight();​
 +  lcd.setCursor(3,​ 0);
 +  lcd.print("​Hello"​);​
 +
 +  analogReference(DEFAULT);​
 +
 +  // Configure Timer1 for servo control
 +  // Set OC1A/OC1B on compare match, clear OC1A/OC1B at BOTTOM (inverting mode)
 +
 +  TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);
 +
 +  // clkI/O/8 (from prescaler)
 +  TCCR1B = _BV(WGM13) | _BV(CS11);
 +  ICR1 = 20000; ​ // 20ms period for PWM
 +  DDRB |= _BV(PB1) | _BV(PB2); ​ // Set servo pins as outputs
 +  PORTB &= ~(_BV(PB1) | _BV(PB2)); ​ // Set servo pins low
 +
 +  // set where the servo start
 +  servoRightLeftPos = 35;
 +  servoUpDownPos = 76;
 +  setServoAngle(SERVO_RIGHT_LEFT_PIN,​ servoRightLeftPos);​
 +  setServoAngle(SERVO_UP_DOWN_PIN,​ servoUpDownPos);​
 +
 +  delay(1000);​
 +}
 +</​code>​
 +
 +**Loop** - citim ldr-urile si in functie de valorile obtinute calculam media celor de sus, de jos, dreapta, stanga si apoi diferenta dreapta-stanga,​ sus-jos si observam daca valoarea e mai mare decat toleranta, caz in care trebuie sa mutam pozitia ansamblului.\\
 +Am determinat experimental valorile intre care trebuie servo-motoarele mutate:
 +  *  pt cel dreapta-stanga -10 - 60
 +   ​* ​  pt cel sus-jos 76 - 96
 +In functie de pozitia soarelui sau absenta lui am afisat mesaje relevante pe lcd:
 +  * Est jos -> dimineata
 +  * Est sus -> zi
 +  * Vest jos -> amiaza
 +  * lipsa soare -> noapte
 +<code c>
 +void loop()
 +{
 +  // read data from ldr 
 +  int topl = analogRead(LDR_TOP_LEFT_PIN);​
 +  int topr = analogRead(LDR_TOP_RIGHT_PIN);​
 +  int botl = analogRead(LDR_BOTTOM_LEFT_PIN);​
 +  int botr = analogRead(LDR_BOTTOM_RIGHT_PIN);​
 +
 +  // calculating average
 +  int avgtop = (topr + topl) / 2;     // average of top LDRs
 +  int avgbot = (botr + botl) / 2;     // average of bottom LDRs
 +  int avgleft = (topl + botl) / 2;    // average of left LDRs
 +  int avgright = (topr + botr) / 2;   // average of right LDRs
 +
 +  // Get the differences
 +  int difftopbottom = avgtop - avgbot; ​     // difference between average of top LDRs and bottom LDRs
 +  int diffrightleft = avgright - avgleft; ​   // difference between average of right LDRs and left LDRs
 +
 +  // left-right movement of solar tracker
 +  if (abs(diffrightleft) >= TOLERANCE) {
 +    if (diffrightleft < 0) {
 +      if (servoRightLeftPos <= 60) {
 +        servoRightLeftPos++;​
 +        setServoAngle(SERVO_RIGHT_LEFT_PIN,​ servoRightLeftPos);​
 +      }
 +    } else if (diffrightleft > 0) {
 +      if (servoRightLeftPos >= -10) {
 +        servoRightLeftPos--;​
 +        setServoAngle(SERVO_RIGHT_LEFT_PIN,​ servoRightLeftPos);​
 +      }
 +    }
 +  }
 +
 +  // up-down movement of solar tracker
 +  if (abs(difftopbottom) >= TOLERANCE) {
 +    if (difftopbottom < 0) {
 +      if (servoUpDownPos <= 96) {
 +        servoUpDownPos+=5;​
 +        setServoAngle(SERVO_UP_DOWN_PIN,​ servoUpDownPos);​
 +      }
 +    } else if (difftopbottom > 0) {
 +      if (servoUpDownPos >= 76) {
 +        servoUpDownPos-=5;​
 +        setServoAngle(SERVO_UP_DOWN_PIN,​ servoUpDownPos);​
 +      }
 +    }
 +  }
 +
 +  // get time of the day by sun position
 +  String direction, position;
 +  if (topr > topl) {
 +    direction = "​East";​
 +  } else {
 +    direction = "​West";​
 +  }
 +
 +  if (botr > topr) {
 +    position = "​High";​
 +  } else {
 +    position = "​Low";​
 +  }
 +
 +  // display to the lcd the day time
 +  lcd.setCursor(0,​ 1);
 +  lcd.print(" ​               ");
 +  if (direction == "​East"​ and position == "​Low"​) {
 +    lcd.setCursor(8,​ 1);
 +    lcd.println("​Morning!"​);​
 +  } else if ( direction == "​West"​ and position == "​Low"​) {
 +    lcd.setCursor(8,​ 1);
 +    lcd.println("​Evening!"​);​
 +  } else if (direction == "​East"​ and position == "​High"​) {
 +    lcd.setCursor(9,​ 1);
 +    lcd.println("​Midday!"​);​
 +  } else {
 +    lcd.setCursor(5,​ 1);
 +    lcd.println("​Good night!"​);​
 +  }
 +
 +  delay(100);
 +}
 +</​code>​
  
  
Line 120: Line 268:
 Proiectul a fost unul cat se poate de interesant, ce m-a facut sa ma adaptez in diverse situatii. \\ Proiectul a fost unul cat se poate de interesant, ce m-a facut sa ma adaptez in diverse situatii. \\
 \\ \\
-Initial mi-am dorit sa integrez o analiza de date a valorilor obtinute de panoul solar de-a lungul zilei, insa am avut dificultati cu cardul sd (ce afisa caractere random) si a trebuit sa renunt la idee pentru ca nu m-as fi incadrat in timp, insa am incercat sa compensez prin afisarea pe display a momentului zilei in functie de pozitia soarelui. \\+Initial mi-am dorit sa integrez o analiza de date a valorilor obtinute de panoul solar de-a lungul zilei, insa am avut dificultati cu cardul sd (ce afisa caractere random) si a trebuit sa renunt la idee pentru ca nu m-as fi incadrat in timp, insa am incercat sa compensez prin afisarea pe display a momentului zilei in functie de pozitia soarelui.\\ 
 +\\ 
 +O alta problema intampinata a fost pozitionarea ansamblului panou solar - fotorezistoare ce initial a fost pozitionat prea jos, astfel ca servo-motorul sus-jos avea probleme in deplasare blocandu-se in partea de jos.\\
 \\ \\
 Pe viitor as vrea sa continui proiectul prin studiul valorilor obtinute de acest timp de ansamblu comparativ cu varianta fixa si sa gandesc o varianta si mai eficienta. De asemenea, mi-ar placea sa conectez niste acumulatori pentru a putea folosi in mod practic.\\ Pe viitor as vrea sa continui proiectul prin studiul valorilor obtinute de acest timp de ansamblu comparativ cu varianta fixa si sa gandesc o varianta si mai eficienta. De asemenea, mi-ar placea sa conectez niste acumulatori pentru a putea folosi in mod practic.\\
Line 127: Line 277:
  
 ===== Download ===== ===== Download =====
- +{{:pm:prj2023:vstoica:andrada_solar_tracker.zip|}}
-<note warning>​ +
-O arhivă (sau mai multe dacă este cazul) cu fişierele obţinute în urma realizării proiectului:​ surse, scheme, etc. Un fişier README, un ChangeLog, un script de compilare şi copiere automată pe uC crează întotdeauna o impresie bună ;-). +
- +
-Fişierele se încarcă pe wiki folosind facilitatea **Add Images or other files**. Namespace-ul în care se încarcă fişierele este de tipul **:​pm:​prj20??:​c?​** sau **:​pm:​prj20??:​c?:​nume_student** (dacă este cazul). **Exemplu:​** Dumitru Alin, 331CC -> **:pm:prj2009:cc:dumitru_alin**. +
-</​note>​+
  
 ===== Jurnal ===== ===== Jurnal =====
Line 148: Line 293:
   * **27.05** - documentatie finala   * **27.05** - documentatie finala
 </​note>​ </​note>​
 +
 +{{ :​pm:​prj2023:​vstoica:​andrada_solar_tracker.jpg?​400 |}}\\
 +\\
 +{{ :​pm:​prj2023:​vstoica:​andrada_circuit_rotit.jpg?​400 |}}
 +
 +Video functionare:​
 +
 +<​html>​
 +  <​iframe ​
 +    src="​https://​www.youtube.com/​embed/​0ZkXvNzDzfs" ​
 +    title="​YouTube video player" ​
 +    frameborder="​0" ​
 +    allow="​accelerometer;​ autoplay; clipboard-write;​ encrypted-media;​ gyroscope; picture-in-picture;​ web-share" ​
 +    allowfullscreen
 +    style="​aspect-ratio:​ 16/9; width: 100%;"
 +  ></​iframe>​
 +</​html>​
 +
  
 ===== Bibliografie/​Resurse ===== ===== Bibliografie/​Resurse =====
pm/prj2023/vstoica/andradacojocaru.1685201285.txt.gz · Last modified: 2023/05/27 18:28 by andrada.cojocaru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0