suntracker

salve
utilizzando 4 fotoresistenze disposte a croce (nord est sud ovest) e 2 servi standard (rotazione 0° -180°)
ho realizzato un inseguitore solare
Il movimento verticale (nord sud ) rimane centrato al contrario il movimento orrizzontale (est oest)si centra dopodichè il servo orrizzontale riceve inspiegabilmente un nuovo comando e si sposta , e cosi via senza mai raggiungere l’equilibrio
per le fotoresistenze (connesse su ingressi analogici) ho usato resistenze da 220 ohm
quando è perfettamente centrato le letture sono
nord 335
est 265
sud 276
ovest 332
quindi |265-332|=67 il ciclo for per azionare il servo si ferma quando <= 70
|335-276|= 59
Ma è evidente non basta dovrei controreazionarlo per stabilizzare il sistema
Qualcuno ha mai affrontato un problema simile?
Sotto il codice che ho scritto
// Project 1 - sun tracker
#include <Servo.h>
Servo servo1; // create servo horizontal object to control a servo
Servo servo2; // create servo vertical object to control a servo
byte ldr = {
0, 1, 2, 3}; // Create byte (0-255) array for LDR pins
unsigned int ldrValue[4]; // array where store value (0-65535) read from the LDR
unsigned int minimo = 0; // store the min LDR value
byte direzione = 0; // store the direction 0=nord 1=est 2=sud 3=ovest
byte pos = 90;// (0-255) for cycle position variable for servo
byte servo1pos = 90;// store position for servo horizontal
byte servo2pos = 90;// store position for servo vertical
void setup() {
servo1.attach(3); // servo orrizzontale al pin 3
servo1.write(90); // servo orrizzontale centrato
servo2.attach(5); // servo verticale al pin 5
servo2.write(90); // servo verticale centrato
Serial.begin(9600);// serial communication
}
void loop() {
// Call the function to check the sun lights level
checksun();
// find the direction of sun
minimo = ldrValue[0];
direzione = 0; // nord
if ( minimo >= ldrValue[1] ) {
minimo = ldrValue[1];
direzione = 1; //est
}
if ( minimo >= ldrValue[2] ) {
minimo = ldrValue[2];
direzione = 2; //sud
}
if ( minimo >= ldrValue[3] ) {
minimo = ldrValue[3];
direzione = 3; //ovest
}
Serial.print("minimo: ");
Serial.println(minimo);
Serial.print("direzione: ");
Serial.println(direzione);
Serial.print("nord: ");
Serial.println(ldrValue[0]);
Serial.print("est: ");
Serial.println(ldrValue[1]);
Serial.print("sud: ");
Serial.println(ldrValue[2]);
Serial.print("ovest: ");
Serial.println(ldrValue[3]);
Serial.print("servo1pos: ");
Serial.println(servo1pos);
Serial.print("servo2pos: ");
Serial.println(servo2pos);
delay(5000); // wait 5 sec

switch (direzione) {
case 0:// nord
// lo specchio si muove in direzione nord quindi il servo verso 105
for(pos = servo2pos; pos < 105; pos += 1) { // goes from 90 degrees to 105 degrees
// in steps of 1 degree
servo2.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
checksun(); // Call the function to check the sun lights level again
if ( abs((ldrValue[0]) - (ldrValue[2])) <= 70 || pos == 105){
delay(60000);
break;
}
servo2pos = servo2.read();
}
break;
case 1://est
// lo specchio si muove in direzione est quindi il servo verso 40
for(pos = servo1pos; pos >= 40; pos -= 1) { // goes from 90 degrees to 0 degrees
// in steps of 1 degree
servo1.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
checksun(); // Call the function to check the sun lights level again
if ( abs((ldrValue[1]) - (ldrValue[3])) <= 70 || pos == 40){
delay(60000);
break;
}
servo1pos = servo1.read();
}
break;
case 2://sud
// lo specchio si muove in direzione sud quindi il servo verso 55
for(pos = servo2pos; pos >= 55; pos -= 1) { // goes from 90 degrees to 55 degrees
// in steps of 1 degree
servo2.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
checksun(); // Call the function to check the sun lights level again
if ( abs((ldrValue[0]) - (ldrValue[2])) <= 70 || pos == 55){
delay(60000);
break;
}
servo2pos = servo2.read();
}
break;
case 3://ovest
// lo specchio si muove in direzione ovest quindi il servo verso 130
for(pos = servo1pos; pos < 130; pos += 1) { // goes from 90 degrees to 130 degrees
// in steps of 1 degree
servo1.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position
checksun(); // Call the function to check the sun lights level again
if ( abs((ldrValue[1]) - (ldrValue[3])) <= 70 || pos == 130){
delay(60000);
break;
}
servo1pos = servo1.read();
}
}
}

void checksun() {
for (int x=0; x<5; x++) { // store the value from the LDR
ldrValue = analogRead(ldr);
}
}

Stacca il servo dell'orizzontale e vedi se così funziona.

si ci sono 2 modi per stabilizzare un sistema, uno e smorzare le oscillazzioni e l'altro è staccare il componente affetto d instabilità in questo caso il servo orrizzontale....soluzione più o meno ottima Su altri post inglesi ho letto di soluzioni con gps e bussole...molto geniali C'è un certo risensuns che ha risolto con un PID solartracker puntroppo c'è solo un video poco chiaro, usa potenziometri al posto di resistenze fisse

oops :stuck_out_tongue: volevo dire verticale, sorry…
stai usando servi standard o microservi?

BrainBooster: oops :P volevo dire verticale, sorry... stai usando servi standard o microservi?

salve sono servi standard uso la rotazione da 0° a 180° apposta per non usare finecorsa il verticale (nord sud) rimane fisso dopo che ha trovato l'equilibrio ma i servi non sono il problema. Arduino riceve letture dalle fotoresistenze orrizzontali e continuamente comanda il servo orrizzontale Ho pensato a delle riflessioni che disturbano ma non ce ne sono

come alimenti i servi?

...mi hai preceduto :) pensavo ach'io alla stessa cosa ed era per quello che avevo chiesto di staccarne uno.

BrainBooster: ...mi hai preceduto :) pensavo ach'io alla stessa cosa ed era per quello che avevo chiesto di staccarne uno.

anche uno sarebbe troppo se l'alimenta dai 5V di arduino ;)

alimentati con batteria 6 V differente da quella che alimenta arduino,avevo già notato che arduino diventa instabile quando la stessa batteria alimenta servi e arduino, lo spunto dei servi abbassa troppo la tensione solo le fotoresistenze sono alimentate con i 5 V di arduino e il negativo di questi e dei 6 V dei servi e messo a comune

direi che i collegamenti sono ok.
ma le batterie sono ancora cariche?
con il verticale stccato si verifica comunque il problema?

rimane una falla nel codice.

potresti ripostarlo tra i tag (code) e (/code) (parentesi quadre al posto delle tonde) anche l'ultima parte (funzione checksun()) ha qualche carattere strano

inoltre potresti postare un paio di foto?

so che sono tante richieste ma vediamo di capire prima per bene il problema e la struttura ;)

... questo thread mi ricorda qualcosa :D http://www.gioblu.com/community/forum/topic?id=49

BrainBooster: ... questo thread mi ricorda qualcosa :D http://www.gioblu.com/community/forum/topic?id=49

molto interessante questo link grazie mille

superlol:
rimane una falla nel codice.

potresti ripostarlo tra i tag (code) e (/code) (parentesi quadre al posto delle tonde)
anche l’ultima parte (funzione checksun()) ha qualche carattere strano

inoltre potresti postare un paio di foto?

so che sono tante richieste ma vediamo di capire prima per bene il problema e la struttura :wink:

// Project 1 - sun tracker
#include <Servo.h> 
Servo servo1;  // create servo horizontal object to control a servo 
Servo servo2;  // create servo vertical object to control a servo
byte ldr[] = {
  0, 1, 2, 3}; // Create byte (0-255) array for LDR pins
unsigned int ldrValue[4]; // array where store value (0-65535) read from the LDR
unsigned int minimo = 0; // store the min LDR value
byte direzione = 0; // store the direction 0=nord 1=est 2=sud 3=ovest
byte pos = 90;// (0-255) for cycle position variable for servo 
byte servo1pos = 90;// store position for servo horizontal
byte servo2pos = 90;// store position for servo vertical
void setup() {
  servo1.attach(3);   // servo orrizzontale al pin 3
  servo1.write(90);  // servo orrizzontale centrato 
  servo2.attach(5);   // servo verticale al pin 5
  servo2.write(90);  // servo verticale centrato 
  Serial.begin(9600);// serial communication
}
void loop() {
  // Call the function to check the sun lights level
  checksun();
  // find the direction of sun
  minimo = ldrValue[0]; 
  direzione = 0; // nord
  if ( minimo  >= ldrValue[1] ) {
    minimo = ldrValue[1];
    direzione = 1; //est
  }
  if ( minimo >= ldrValue[2] ) {
    minimo = ldrValue[2];
    direzione = 2; //sud
  }
  if ( minimo >= ldrValue[3] ) {
    minimo = ldrValue[3];
    direzione = 3; //ovest
  }
  Serial.print("minimo: ");
  Serial.println(minimo);
  Serial.print("direzione: ");
  Serial.println(direzione);
  Serial.print("nord: ");
  Serial.println(ldrValue[0]);
  Serial.print("est: ");
  Serial.println(ldrValue[1]);
  Serial.print("sud: ");
  Serial.println(ldrValue[2]);
  Serial.print("ovest: ");
  Serial.println(ldrValue[3]);
  Serial.print("servo1pos: ");
  Serial.println(servo1pos); 
  Serial.print("servo2pos: ");
  Serial.println(servo2pos); 
  delay(5000); // wait 5 sec 



  switch (direzione) {
  case 0:// nord
    // lo specchio si muove in direzione nord quindi il servo verso 105
    for(pos = servo2pos; pos < 105; pos += 1) { // goes from 90 degrees to 105 degrees 
      // in steps of 1 degree 
      servo2.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
      checksun(); // Call the function to check the sun lights level again
      if ( abs((ldrValue[0]) - (ldrValue[2])) <= 70 || pos == 105){
        delay(60000);
        break;
      }  
      servo2pos = servo2.read(); 
    }
    break;
  case 1://est
    // lo specchio si muove in direzione est quindi il servo verso 40
    for(pos = servo1pos; pos >= 40; pos -= 1) { // goes from 90 degrees to 0 degrees 
      // in steps of 1 degree 
      servo1.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
      checksun(); // Call the function to check the sun lights level again
      if ( abs((ldrValue[1]) - (ldrValue[3])) <= 70 || pos == 40){
        delay(60000);
        break;
      }  
      servo1pos = servo1.read(); 
    }
    break;
  case 2://sud
    // lo specchio si muove in direzione sud quindi il servo verso 55
    for(pos = servo2pos; pos >= 55; pos -= 1) { // goes from 90 degrees to 55 degrees 
      // in steps of 1 degree 
      servo2.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
      checksun(); // Call the function to check the sun lights level again
      if ( abs((ldrValue[0]) - (ldrValue[2])) <= 70 || pos == 55){
        delay(60000); 
        break;
      }  
      servo2pos = servo2.read(); 
    }
    break;
  case 3://ovest
    // lo specchio si muove in direzione ovest quindi il servo verso 130
    for(pos = servo1pos; pos < 130; pos += 1) { // goes from 90 degrees to 130 degrees 
      // in steps of 1 degree 
      servo1.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
      checksun(); // Call the function to check the sun lights level again
      if ( abs((ldrValue[1]) - (ldrValue[3])) <= 70 || pos == 130){
        delay(60000);
        break;
      }  
      servo1pos = servo1.read();
    }
  }
}

void checksun() {
  for (int x=0; x<5; x++) { // store the value from the LDR
    ldrValue[x] = analogRead(ldr[x]);
  }
}

superlol: rimane una falla nel codice.

potresti ripostarlo tra i tag (code) e (/code) (parentesi quadre al posto delle tonde) anche l'ultima parte (funzione checksun()) ha qualche carattere strano

inoltre potresti postare un paio di foto?

so che sono tante richieste ma vediamo di capire prima per bene il problema e la struttura ;)

sopra ho ripostato il codice ora sembra più leggibile di prima per le immagini ho un video provo a inserirlo spero sia chiaro ...si vede come continuamente si muove orrizzontalmente nonostante aveva già trovato prima il punto

ho 2 batterie 6V distinte per servi e arduino ma stavo leggendo che alimentare arduino con 6 V si è al limite ....provo a alimentarlo con una batteria da 12V

http://it.netlog.com/go/widget/videoID=it-6225569

12V a monte del regolatore spero... sennò friggi tutto!!! ed anche i servi non più di 6.5V senno li cucini....

ratto93: 12V a monte del regolatore spero... sennò friggi tutto!!! ed anche i servi non più di 6.5V senno li cucini....

si 12 V sul jack e 6 V stabilizzati per i servo

Non ho guardato il tuo codice però ti chiedo: le fotoresistenze sono tutte allineate sullo stesso piano? Se così fosse devi inclinarle in modo che i loro assi formino tra loro un certo angolo altrimenti entrambe le fotoresistenze relative ad un movimento (Alto-basso o SX-DX) leggerebbero sempre lo stesso valore del sole.

Mi spiego. Prendiamo le fotoresistenze per la lettura dello spostamento Est-Ovest del sole. Guardandole dall'alto dovrebbero essere così: \ /

Se sono così: | |

non vanno bene. Non avrai mai una differenza sostanziale fra le 2 resistenze

@leo72 ci sono in mezzo ai LDR delle divisorie che fanno ombra.

@nikel Per determinare la direzione cerchi il valore minimo delle 4 direzioni. Il sensore ha un problema costruttivo. Le alette che fanno ombra sono troppo lunghe e un movimento in una direzione puó oscurare i sensore rivolto verso il sole nel caso il sensore é troppo basso o troppo alto.

Cambia logica Cerca l' equilibro di destra-sinistra e sopra-sotto separatamente.

Modifica il sensore in modo da non avere 4 quadranti ma 2 sensori separati con ciascuno 2 quadranti uno per sopra sotto e uno per destra sinistra in modo che sopra sotto non influenzi destra sinistra. sensore destra sinistra con 2 LCD in inea orizontale con un separatore verticale in mezzo; sensore sopra-sotto con 2LCD in linea verticale con un separatore orizontale in mezzo.

Ralenta i movimenti dei motori mettendo al posto di delay(15) un delay di mezzo o un secondo. non fare pause tra i spostamenti delay(60000); Controlla una volta raggiunto la posizione se l' inclinazione cambia e sposta solo a scatti ogni 5 o 10 minuti aggiornando nel fratempo i valori.

Sappi che l' anglo sopra sotto va da 0 a 90 al massimo l' angolo destra -sinistra va un po di piú di 180 gradi (se non abiti spora il circolo polare con il sole a mezzanotte) ma la sera e il mattino il sole é piú debole e percui un panello solare rende poco che non ha senso un orientamento.perché nel tuo codice i servo vanno da o a 90 e da 90 a 130 ( e non 180) e da 90 a 105 e da 90 a 55 gradi. Vivi in Norvegia? ;) ;)

Ciao Uwe

@Uwe:
sì, ma le paratie dovrebbero servire per evitare l’arrivo di illuminazione parassita.
Inclinare tra loro le fotoresistenze aumenta comunque l’accuratezza delle letture.

Inoltre il sole non compie un arco max di 180° in cielo ma può arrivare a compiere un arco maggiore (anche superiore ai 200°) dato che d’estate, in prossimità del solstizio d’estate, sorge a ENE e tramonta a ONO.