Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Plateforme de suivi solaire à servos de précision pour une capture d'énergie optimale

Composants et fournitures

Photorésistance × 4
LED RGB NeoPixel Adafruit Flora (lot de 4) ou équivalent × 1
Bouton poussoir 12 mm SparkFun ou équivalent (normalement ouvert) × 2
Capteur de température × 1
Arduino UNO × 1
Servo 180° RobotGeek ou équivalent (Futaba S3003 utilisés) × 2
Résistance 10 kΩ × 6
Résistance 221 Ω (220 Ω utilisé) × 1
Condensateur 100 µF × 2
Panneau solaire (80 mm × 80 mm) × 1

Outils et machines nécessaires

Applications et services en ligne

À propos du projet

Cette implémentation utilise deux servos 180° et quatre photorésistances pour orienter un petit panneau solaire vers la zone de plus forte intensité lumineuse.

Les moteurs effectuent de petits mouvements pour pointer le panneau vers la lumière la plus brillante.

Une LED multicolore indique si le système est activé ou non. Deux boutons poussoirs permettent d'activer/désactiver les moteurs.

Quelques routines permettent de déplacer les moteurs vers des positions commandées. Les commandes passent par l'interface série et une série de codes numériques envoyés à l'Arduino Uno.

Les commandes de déplacement indépendant sont programmées pour fournir des mouvements (relativement) fluides au lieu de commandes de position immédiates qui feraient bouger violemment le mécanisme mécanique.

Code

Code Q2 (Arduino)

// Scott Mangiacotti
// Tucson, Arizona USA
// Mai 2018
// Q2 Version 2.0

#include <Servo.h>

// Constantes
const int GIVE_BACK_TIME = 125;

// Constantes entrées
const int I_RED_BUTTON_PIN = 4;
const int I_GREEN_BUTTON_PIN = 2;
const int I_LDR1_PIN = A3; // haut gauche
const int I_LDR2_PIN = A2; // haut droite
const int I_LDR3_PIN = A1; // bas gauche
const int I_LDR4_PIN = A0; // bas droite

// Constantes sorties
const int O_RED_LED_PIN = 9;
const int O_GREEN_LED_PIN = 11;
const int O_BLUE_LED_PIN = 10;
const int O_TWIST_SERVO_PIN = 5;
const int O_TILT_SERVO_PIN = 6;

// Variables globales
bool gRunning = false;
bool gTrackToLightEnabled = false;
bool gVerboseDiagMode = false;
Servo gServoTwist;
int gServoTwistPositionCommand;
bool gServoTwistMoveIP;
Servo gServoTilt;
bool gServoTiltMoveIP;
int gServoTiltPositionCommand;
int gLDR1, gLDR2, gLDR3, gLDR4;

void setup() {
  Serial.begin(9600);
  pinMode(I_RED_BUTTON_PIN, INPUT);
  pinMode(I_GREEN_BUTTON_PIN, INPUT);
  pinMode(O_RED_LED_PIN, OUTPUT);
  pinMode(O_GREEN_LED_PIN, OUTPUT);
  pinMode(O_BLUE_LED_PIN, OUTPUT);
  startup();
}

void loop() {
  // Traitement messages série
  if (Serial.available() > 0) {
    int iControlCode = Serial.parseInt();
    processSerialMessage(iControlCode);
  }

  // Bouton vert (activation)
  int iGreenButton = digitalRead(I_GREEN_BUTTON_PIN);
  if (iGreenButton == HIGH && gRunning == false) {
    enableTracking();
    gTrackToLightEnabled = true;
  }

  // Bouton rouge (désactivation)
  int iRedButton = digitalRead(I_RED_BUTTON_PIN);
  if (iRedButton == HIGH && gRunning == true) {
    disableTracking();
  }

  // Lecture photorésistances
  readPhotoResistors();
  averageTopTwoSensors();
  averageBottomTwoSensors();

  // Ajustement positions servos selon lumière
  if (gRunning == true) {
    if (gTrackToLightEnabled == true) {
      trackToLightSensors();
    } else {
      smoothMoveTwist();
      smoothMoveTilt();
    }
  }

  delay(GIVE_BACK_TIME);
}

void enableTracking() {
  gRunning = true;
  gServoTwist.attach(O_TWIST_SERVO_PIN);
  gServoTilt.attach(O_TILT_SERVO_PIN);
  digitalWrite(O_GREEN_LED_PIN, HIGH);
  digitalWrite(O_RED_LED_PIN, LOW);
  Serial.println("servos enabled");
}

void disableTracking() {
  gRunning = false;
  gTrackToLightEnabled = false;
  gServoTwist.detach();
  gServoTilt.detach();
  gServoTwistPositionCommand = gServoTwist.read();
  gServoTwistMoveIP = false;
  gServoTiltPositionCommand = gServoTilt.read();
  gServoTiltMoveIP = false;
  digitalWrite(O_RED_LED_PIN, HIGH);
  digitalWrite(O_GREEN_LED_PIN, LOW);
  Serial.println("servos disabled");
}

void trackToLightSensors() {
  float fTop, fBottom, fLeft, fRight;
  int iTwistMoveCommand, iTiltMoveCommand, iMoveAmount = 5;

  iTwistMoveCommand = gServoTwist.read();
  iTiltMoveCommand = gServoTilt.read();

  fTop = averageTopTwoSensors();
  fBottom = averageBottomTwoSensors();
  fLeft = averageLeftTwoSensors();
  fRight = averageRightTwoSensors();

  // Rotation (twist)
  if (fLeft > fRight) iTwistMoveCommand += iMoveAmount;
  else if (fRight > fLeft) iTwistMoveCommand -= iMoveAmount;

  // Inclinaison (tilt)
  if (fTop > fBottom) iTiltMoveCommand += iMoveAmount;
  else if (fBottom > fTop) iTiltMoveCommand -= iMoveAmount;

  // Limites twist
  if (iTwistMoveCommand < 0) iTwistMoveCommand = 0;
  if (iTwistMoveCommand > 179) iTwistMoveCommand = 179;

  // Limites tilt
  if (iTiltMoveCommand < 45) iTiltMoveCommand = 45;
  if (iTiltMoveCommand > 135) iTiltMoveCommand = 135;

  gServoTwist.write(iTwistMoveCommand);
  gServoTilt.write(iTiltMoveCommand);

  if (gVerboseDiagMode) {
    Serial.println("tl, tr, bl, br, top avg, bottom avg, left avg, right avg, twist move, tilt move: ");
    Serial.print(gLDR1); Serial.print(", ");
    Serial.print(gLDR2); Serial.print(", ");
    Serial.print(gLDR3); Serial.print(", ");
    Serial.print(gLDR4); Serial.print(", ");
    Serial.print(fTop); Serial.print(", ");
    Serial.print(fBottom); Serial.print(", ");
    Serial.print(fLeft); Serial.print(", ");
    Serial.print(fRight); Serial.print(", ");
    Serial.print(iTwistMoveCommand); Serial.print(", ");
    Serial.println(iTiltMoveCommand);
  }
}

void readPhotoResistors() {
  gLDR1 = analogRead(I_LDR1_PIN);
  gLDR2 = analogRead(I_LDR2_PIN);
  gLDR3 = analogRead(I_LDR3_PIN);
  gLDR4 = analogRead(I_LDR4_PIN);
}

void smoothMoveTwist() {
  int iCurrentPos = gServoTwist.read();
  if (iCurrentPos == gServoTwistPositionCommand) {
    gServoTwistMoveIP = false; return;
  } else gServoTwistMoveIP = true;

  int iMoveAmountPerScan = 1;
  int iNewMoveCommand = iCurrentPos;

  if (iCurrentPos < gServoTwistPositionCommand) iNewMoveCommand += iMoveAmountPerScan;
  else iNewMoveCommand -= iMoveAmountPerScan;

  if (iNewMoveCommand < 0) iNewMoveCommand = 0;
  if (iNewMoveCommand > 179) iNewMoveCommand = 179;

  gServoTwist.write(iNewMoveCommand);

  if (gVerboseDiagMode) {
    Serial.print(iNewMoveCommand); Serial.print(", "); Serial.println(gServoTwistPositionCommand);
  }
}

void smoothMoveTilt() {
  int iCurrentPos = gServoTilt.read();
  if (iCurrentPos == gServoTiltPositionCommand) {
    gServoTiltMoveIP = false; return;
  } else gServoTiltMoveIP = true;

  int iMoveAmountPerScan = 1;
  int iNewMoveCommand = iCurrentPos;

  if (iCurrentPos < gServoTiltPositionCommand) iNewMoveCommand += iMoveAmountPerScan;
  else iNewMoveCommand -= iMoveAmountPerScan;

  if (iNewMoveCommand < 0) iNewMoveCommand = 0;
  if (iNewMoveCommand > 179) iNewMoveCommand = 179;

  gServoTilt.write(iNewMoveCommand);

  if (gVerboseDiagMode) {
    Serial.print(iNewMoveCommand); Serial.print(", "); Serial.println(gServoTiltPositionCommand);
  }
}

float averageTopTwoSensors() { return (gLDR1 + gLDR2) / 2.0; }
float averageBottomTwoSensors() { return (gLDR3 + gLDR4) / 2.0; }
float averageLeftTwoSensors() { return (gLDR1 + gLDR3) / 2.0; }
float averageRightTwoSensors() { return (gLDR2 + gLDR4) / 2.0; }

void processSerialMessage(int iControlCode) {
  int iControlCommand = iControlCode / 1000;
  int iControlValue = iControlCode % 1000;

  Serial.print("control code: "); Serial.println(iControlCode);
  Serial.print("control command: "); Serial.println(iControlCommand);
  Serial.print("control value: "); Serial.println(iControlValue);

  if (iControlCommand == 10) { // Divers
    if (iControlValue == 0) { gVerboseDiagMode = true; digitalWrite(O_BLUE_LED_PIN, HIGH); Serial.println("diagnostics mode started"); }
    else if (iControlValue == 1) { gVerboseDiagMode = false; digitalWrite(O_BLUE_LED_PIN, LOW); Serial.println("diagnostics mode stopped"); }
    else if (iControlValue == 2) { reportProductInfo(); }
    else if (iControlValue == 3) { digitalWrite(O_RED_LED_PIN, HIGH); Serial.println("red led on"); }
    else if (iControlValue == 4) { digitalWrite(O_RED_LED_PIN, LOW); Serial.println("red led off"); }
    else if (iControlValue == 5) { digitalWrite(O_GREEN_LED_PIN, HIGH); Serial.println("green led on"); }
    else if (iControlValue == 6) { digitalWrite(O_GREEN_LED_PIN, LOW); Serial.println("green led off"); }
    else if (iControlValue == 7) { digitalWrite(O_BLUE_LED_PIN, HIGH); Serial.println("blue led on"); }
    else if (iControlValue == 8) { digitalWrite(O_BLUE_LED_PIN, LOW); Serial.println("blue led off"); }
    else if (iControlValue == 9) { Serial.print("LDR1 value: "); Serial.println(gLDR1); }
    else if (iControlValue == 10) { Serial.print("LDR2 value: "); Serial.println(gLDR2); }
    else if (iControlValue == 11) { Serial.print("LDR3 value: "); Serial.println(gLDR3); }
    else if (iControlValue == 12) { Serial.print("LDR4 value: "); Serial.println(gLDR4); }
    else if (iControlValue == 13) { enableTracking(); }
    else if (iControlValue == 14) { disableTracking(); }
    else if (iControlValue == 19) {
      if (gRunning && !gServoTwistMoveIP && !gServoTiltMoveIP) {
        gServoTwistPositionCommand = 90; gServoTiltPositionCommand = 90;
        Serial.println("twist and tilt servos commanded to 90 degrees");
      }
    }
    else if (iControlValue == 21) { if (gRunning) { gTrackToLightEnabled = true; Serial.println("Track to light source enabled"); } }
    else if (iControlValue == 22) { gTrackToLightEnabled = false; Serial.println("Track to light source disabled"); }
    else { Serial.print("invalid control value: "); Serial.println(iControlValue); }
  }

  if (iControlCommand == 11) { // Servo 1 (twist)
    if (iControlValue >= 0 && iControlValue <= 179) {
      if (gRunning && !gServoTwistMoveIP) {
        gServoTwistPositionCommand = iControlValue;
        gServoTwistMoveIP = true;
        Serial.print("Move twist servo command: "); Serial.println(gServoTwistPositionCommand);
      }
    } else { Serial.print("invalid control value: "); Serial.println(iControlValue); }
  }

  if (iControlCommand == 12) { // Servo 2 (tilt)
    if (iControlValue >= 0 && iControlValue <= 179) {
      if (gRunning && !gServoTiltMoveIP) {
        gServoTiltPositionCommand = iControlValue;
        gServoTiltMoveIP = true;
        Serial.print("Move tilt servo command: "); Serial.println(gServoTiltPositionCommand);
      } else {
        Serial.print("tilt servo not enabled or move in progress, "); Serial.print(gRunning); Serial.print(", "); Serial.println(gServoTiltMoveIP);
      }
    } else { Serial.print("invalid control value: "); Serial.println(iControlValue); }
  }

  Serial.println("-----");
}

void startup() {
  int iDelay = 500;
  reportProductInfo(); delay(iDelay);
  processSerialMessage(10003); delay(iDelay);
  processSerialMessage(10004); processSerialMessage(10005); delay(iDelay);
  processSerialMessage(10006); processSerialMessage(10007); delay(iDelay);
  processSerialMessage(10008); processSerialMessage(10009);
  processSerialMessage(10010); processSerialMessage(10011); processSerialMessage(10012); delay(iDelay);
  enableTracking(); delay(iDelay);
  processSerialMessage(10019); delay(iDelay);
  disableTracking();
  Serial.println("startup sequence completed");
}

void reportProductInfo() {
  Serial.println("q version 2");
  Serial.println("tucson, arizona usa");
  Serial.println("may 2018");
  Serial.print("checksum "); Serial.println("58BA-D969-2F82-08FD-2078-2777-396D-E1AA");
}

Pièces personnalisées et boîtiers

Fichier d'assemblage : q2_assembly_details_RCbi893qzA.zip

Schémas

Schéma Fritzing : q2_schematic_TVp7kakwNa.fzz

Processus de fabrication

  1. Systèmes de chauffage solaire : des solutions passives aux actives pour un chauffage domestique durable
  2. Cellules solaires : des premières expériences au photovoltaïque moderne – Technologie, production et perspectives
  3. Surveillance temps réel de panneau solaire avec Arduino : Acquisition de données bas coût
  4. Stores intelligents : contrôle automatisé de la lumière avec Arduino et énergie solaire
  5. Suiveur Solaire IoT : Gestion Intelligente de l'Énergie avec Arduino
  6. SmartPostBox : Boîte aux lettres intelligente connectée IoT (Sigfox)
  7. Exploiter l'énergie solaire : guide complet pour une énergie propre et fiable
  8. Qualité des panneaux solaires : points de contrôle essentiels pour une performance optimale
  9. Comment sont fabriqués les panneaux solaires : guide étape par étape pour une production d'énergie solaire de haute qualité