Prototype de suiveur solaire

Réalisation d’un prototype de suiveur solaire piloté par un Arduino, destiné à recevoir un panneau photovoltaïque et à l’orienter en permanence vers le maximum de lumière.

Le cahier des charges était le suivant :

  • orientation face à la source de lumière
  • Arrivé à l’Ouest (un peu plus en fait), il n’y a plus d’orientation
  • Lorsque la nuit tombe, le panneau tourne vers l’est et reprend son cycle dès que la lumière est suffisante.

Le matériel

  • des planches, boulons, vis
  • 2 petites équerres
  • Un moteur
  • 2 boutons poussoir voir photos
  • 2 photo-résistances
  • 2 résistances 10 kΩ
  • Une bread-board
  • un arduino
  • plein de fils pour faire les connexions
  • et bien sûr un ordinateur avec le logiciel arduino
  • deux relais pour piloter le moteur

La mécanique

Pour la réalisation matérielle, chute de planche, récupération d’un moteur 12V dans un ventilateur de voiture, récupération de fil électrique, élastique…

On distingue, au centre, l’élément qui mesure la lumière reçue à droite et à gauche de la séparation. Évidemment, lorsqu’un panneau solaire sera posé sur le plateau, cet élément changera de place.

Le truc en noir, c’est le moteur qui fait tourner dans un sens ou dans l’autre.

On distingue deux boutons poussoirs qui sont actionnés par les petites équerres et limitent la rotation vers l’Est et l’Ouest (un peu plus en fait,parce qu’à nos latitude, en été, le soleil va du nord-est au sud-ouest.

Avec seulement un axe, le plateau n’était pas assez stable, alors je me suis inpiré du four à micro-onde pour bricoler un roulement avec un plaque de contreplaqué et des roues de voitures miniatures.

 

Afin que l’axe du moteur qui entraîne le plateau soit en pression sur celui-ci, voilà le montage réalisé.

 

 

Faut tout brancher maintenant

Voilà ce que ça donne !

Pas très lisible ? Vous croyez ?

La programmation de l’arduino

Je ne suis pas un grand spécialiste de la programmation et débutant avec l’arduino. Je vous mets ce que j’ai fait parce que ça marche. Il y a sûrement plus élégant, plus optimisé…

Mais pour arriver à ce code, il est peut-être intéressant de décrire les étapes intermédiaires. Je me suis beaucoup servi du port série, qui permet de lire dans le moniteur série (une fonctionnalité du logiciel arduino) un certain nombre de valeur, voir un bout de texte qui me prouve que les conditions des boucles fonctionnent. J’écrivais des petits bouts de code pour tester fonction par fonction, condition par condition.

C’est notamment comme ça que j’ai déterminé la valeur d’écart entre les deux photo-résistances qui déclenche un action du moteur.

Vous n’êtes pas obligé de lire ce code. Je pense que l’intérêt, c’est de tatonner, puis de venir voir ensuite, comment j’avais résolu les problèmes qu’on peut rencontrer.

Licence Creative Commons
Suiveur solaire de Éric APFFEL est mis à disposition selon les termes de la
licence Creative Commons Attribution – Pas d’Utilisation Commerciale – Partage dans les Mêmes Conditions 4.0 International.

/* SUIVEUR SOLAIRE POUR PANNEAU SOLAIRE

**************************************
* ERIC APFFEL *
* Le Maillet de Joigny *
* Fablab *
**************************************

2 capteurs photorésistance sur broches A0 et A1
2 capteurs de bout de course sur broches 13 pour l'ouest et 12 pour l'est
1 moteur piloté par 2 relais sur broche 2 pour aller vers l'ouest
et broche 3 pour aller vers l'est

Montage du moteur :

+ 12V ------------|
borne 1 moteur----| Relais 1
Gnd --------------|

+12V -------------|
borne 2 moteur ---| Relais 2
Gnd --------------|
*/

// Constantes
const int moteurOuest = 2; // broche du relais ouest
const int moteurEst = 3; // broche du relais est

const int buteeOuest = 13; // broche de la butee ouest. 1 = relache, 0 = enfonce
const int buteeEst = 12; // broche de la butee est

const int pvOuest = A0; // broche analogique pour cellule pv ouest
const int pvEst = A1; // broche analogique pour cellule pv est

const int nuit = 100; // Valeur en-dessous de laquelle on considère qu'il fait nuit
const int ecart = 50; // Écart d'éclairement qui déclenche le mouvement

// Variables
boolean atteintEst = true ; // Butées atteintes. Si rebond sur la butée, évite les actions répétitives
boolean atteintOuest = true ;

int lumiereEst = 0 ; // Lecture lumière capteur est
int lumiereOuest = 0; // Lecture lumière capteur ouest

//initialisation
void setup() {
// broche de commande moteur
pinMode (moteurOuest, OUTPUT);
pinMode (moteurEst, OUTPUT);

// broche de détection butée
pinMode (buteeOuest, INPUT);
digitalWrite (buteeOuest, HIGH); //activer résistance pull-up
pinMode (buteeEst, INPUT);
digitalWrite (buteeEst, HIGH); //activer pull-up

}

void loop() {
lumiereEst = analogRead(pvEst);
lumiereOuest = analogRead(pvOuest);

//Si il ne fait pas nuit
if (lumiereEst > nuit){
//======================================================================
// Si Ouest plus éclairé, boucle pour tourner vers l'ouest jusqu'à butee
while ((lumiereOuest - lumiereEst > ecart) && (atteintOuest)) {
digitalWrite(moteurOuest, HIGH); // mettre un coup de moteur vers l'ouest
atteintEst = true; // relacher butée est

lumiereEst = analogRead(pvEst); // Relire les éclairements
lumiereOuest = analogRead(pvOuest);

atteintOuest = digitalRead(buteeOuest); // Tester la butee et sortir de la boucle
if (!atteintOuest) {
break;
}
}
digitalWrite(moteurOuest, LOW); // Eteindre le moteur

//==================================================================
// Si Est plus éclairé, boucle pour tourner vers l'est jusqu'a butee
while ((lumiereEst - lumiereOuest > ecart) && (atteintEst)) {
digitalWrite(moteurEst, HIGH); //Mettre un coup de moteur à l'est
atteintOuest = true; // Libérer butee ouest

lumiereEst = analogRead(pvEst); // Relire les éclairements
lumiereOuest = analogRead(pvOuest);

atteintEst = digitalRead(buteeEst); // Lire si la butee est atteinte pour arret
if (!atteintEst){
break;
}
}
digitalWrite(moteurEst, LOW); // Eteindre le moteur

}
//===============================================
// S'il fait nuit, retour à l'est
else{
while (atteintEst){
digitalWrite(moteurEst, HIGH);
atteintOuest = true ; //Libérer butee ouest
atteintEst = digitalRead(buteeEst);
}
digitalWrite(moteurEst, LOW);

}

}