« Processing 3.3.4 のインストール | Main | Arduinoで(太陽)光の方向を追いかける2軸サーボ(New Algorithm) »

07/04/2017

Arduinoで作る太陽光の方向を向く2軸サーボ

Img_20170704_203131 Img_20170629_224615 Arduino Nano (ATmega328)を使って、(太陽)光のある方向を向く2軸サーボ装置を作ってみた。
・Arduinoは、 Nano を
・ServoMotorは、 SG92R を 2個使い
・フォトレジスターは、 手元にあったものを 4個使った。はじめは、抵抗値の基本値を選ぶ必要があるのか・・・と思ったが、ロットが揃っているものなら、それを使って良さそうだ。

Webで見つけたサイト「Arduino Solar Tracker(http://www.electronicshub.org/arduino-solar-tracker/
」などを参考に製作した。

Img_20170704_090341 Img_20170704_090529 Img_20170704_090634 フォトレジスタと抵抗の固定は、小型のユニバーサル基板の上に半田付けし、光の方向を捉え易くするために、写真のように十字型の覆いを設けた。この部分の回路図は、参考にさせてもらったブログの通りであると思う。

基板の後ろから見て、右下(赤色の配線⇒A0)、右上(黄色の配線⇒A1)、左上(緑色の配線⇒A2)、左下(青色の配線⇒A3)とした。

サーボモーターは、水平方向の制御線を水色⇒D10へ、垂直方向の制御線を白⇒D9へと繋いだ。

Solar_trackerflow_chart_20170704 最初、スケッチは参考にしたブログのものをそのまま使ったが、収束に時間がかかる事と、収束した状態でもサーボを動かしているので、左図のようにフローチャートを作成して、収束時間を短縮し、収束したらサーボモータを停めるようにスケッチを変更した。細かな所は、左図を確認すれば解るだろうと思う。


スケッチは、制御の状態を確認したかったので、オリジナルのスケッチに対してシリアルモニターに途中の状態を出力するように追記した。

出力結果を確認し、光源の位置から離れていると思われる場合には、光源に向かうサーボモータ回転角の刻み幅を大きくし、光源に近づいてくると、刻み幅を小さくするようにした。


閾値は明るさの差 eps を”5”としたが、動き方を見て調整するのが良いだろう。

稼働させてみると、光のある方向への収束時間は随分早くなったように思う。

スケッチは、下記のようである。

// The Sunlight Tracker 2017.07.04
//
#include <Servo.h>
Servo servohori;
int servoh = 90;
int servohLimitHigh = 170;
int servohLimitLow = 10;
int hstep = 1;
int eps = 5;

Servo servoverti; 
int servov = 30; 
int servovLimitHigh = 120;
int servovLimitLow = 10;
int vstep = 1;

//Assigning LDRs
int ldrtopl = 2; //top left LDR Green wiring
int ldrtopr = 1; //top right LDR Yellow wiring
int ldrbotl = 3; // bottom left LDR Blue wiring
int ldrbotr = 0; // bottom right LDR Red wiring

 void setup () {
  Serial.begin(9600);   // to check the sketch, print out to the monitor
  servohori.attach(10); // horizontal motor servo  (Blue wiring)
  servohori.write(servoh);
  servoverti.attach(9); // vertical motor servo  (Green wiring)
  servoverti.write(servov);
  delay(500);
 }

void loop(){
  servoh = servohori.read();
  servov = servoverti.read();
  Serial.print("Location of Servo   Horizontal:");
  Serial.print(servoh);
  Serial.print("deg,  Vertical:");
  Serial.print(servov);
  Serial.println("deg");
  
  //capturing analog values of each LDR
  int topl = analogRead(ldrtopl);
  int topr = analogRead(ldrtopr);
  int botl = analogRead(ldrbotl);
  int botr = analogRead(ldrbotr);
  Serial.println(" ");
  Serial.println("Captured LDR value ");
  Serial.print("TL:");
  Serial.print(topl);
  Serial.print("  TR:");
  Serial.println(topr);
  Serial.print("BL:");
  Serial.print(botl);
  Serial.print("  BR:");
  Serial.println(botr);
  
  // calculating average
  int avgtop = (topl + topr) / 2;   //average of top LDRs
  int avgbot = (botl + botr) / 2;   //average of bottom LDRs
  int avgleft = (topl + botl) / 2;  //average of left LDRs
  int avgright = (topr + botr) / 2; //average of right LDRs

  if (avgtop < avgbot) {
    Serial.print("Average Value  ");
    Serial.print("Top:");Serial.print(avgtop);
    Serial.print(" < ");
    Serial.print("Bottom:");Serial.println(avgbot);
    
    vstep = abs(avgtop-avgbot);
    if( vstep < eps ){
      Serial.println("Top is lighter than Bottom =< turn Up");
      vstep = 1 + vstep/4;
      Serial.print("servov = ");Serial.print(servov);Serial.print("+");
      Serial.println(vstep);
      servoverti.write(servov + vstep); 
      }
    else {  // to stabilize the servo-motor
      Serial.print("|Top-Bottom|=<");Serial.print(eps);
      Serial.println(" then Stop the Vertical servo");     
    }
    if (servov > servovLimitHigh) { 
      servov = servovLimitHigh;
     }
    delay(10);
  }
  else if (avgbot < avgtop) {
      Serial.print("Average Value of LDR  ");
      Serial.print("Bottom:");Serial.print(avgbot);
      Serial.print(" < ");
      Serial.print("Top:");Serial.println(avgtop);

    vstep = abs(avgtop-avgbot); 
    if( vstep > eps ){   
      Serial.println("Bottom is lighter than Top => turn Down");
      vstep = 1 + vstep/4;
      Serial.print("servov = ");Serial.print(servov);Serial.print("-");
      Serial.println(vstep);     
      servoverti.write(servov - vstep);
    }
    else {  // to stabilize the servo-motor
      Serial.print("|Top-Bottom|=<");Serial.print(eps);
      Serial.println(" then Stop the Vertical servo");       
    }
    if (servov < servovLimitLow) {
    servov = servovLimitLow;
    }
    delay(10);
  }
  else {
  }
  
  if (avgleft > avgright) {
      Serial.print("Average Value of LDR  ");
      Serial.print("Left:");Serial.print(avgleft);
      Serial.print(" > ");
      Serial.print("Right:");Serial.println(avgright);

      hstep = abs(avgleft-avgright);
    if( hstep > eps ){  
      Serial.println("Right is lighter than Left => turn Right");
      hstep = 1 + hstep/4;
      Serial.print("servoh = ");Serial.print(servoh);Serial.print("+");
      Serial.println(hstep);
      servohori.write(servoh + hstep);
    }
    else {   // to stabilize the servo-motor
      Serial.print("|Left-Right|=<");Serial.print(eps);
      Serial.println(" then Stop the Horizontal servo");         
    }
    if (servoh > servohLimitHigh) {
    servoh = servohLimitHigh;
    }
    delay(10);
  }
  else if (avgright > avgleft) {
      Serial.print("Average Value of LDR  ");
      Serial.print("Right:");Serial.print(avgright);
      Serial.print(" > ");
      Serial.print("Left:");Serial.println(avgleft);    

    hstep = abs(avgleft-avgright);
    if( hstep > eps ){   
      Serial.println("Left is lighter than Right => turn Left");
      hstep = 1 + hstep/4;
      Serial.print("servoh = ");Serial.print(servoh);Serial.print("-");
      Serial.println(hstep);     
      servohori.write(servoh - hstep);
    }
    else {  // to stabilize the servo-motor
      Serial.print("|Left-Right|=<");Serial.print(eps);
      Serial.println(" then Stop the Horizontal servo");
    }
    if (servoh < servohLimitLow) {
      servoh = servohLimitLow;
     }
    delay(10);
  }
  else  {
  }
  delay(50);
}


《備考》
ここに、
 hstep : 水平方向回転サーボモータの回転刻み角度
  vstep : 垂直方向回転サーボモータの回転刻み角度
 esp : 左右、上下のフォトレジスタから読取った値を比較した際のサーボモータの停止判定値

問題は、周囲が暗くなると、灯りを探し回るので、この動きを止める必要がありそうだ。
多分、フォトレジスタで計測した際の明るさが、ある程度大きくなったら、サーボモータの動きを止めれば良いと思う。これは、次にソーラーパネルと組み合わせる計画があるので、その際に改造するつもりだ。

« Processing 3.3.4 のインストール | Main | Arduinoで(太陽)光の方向を追いかける2軸サーボ(New Algorithm) »

PC and PC troubles」カテゴリの記事

Comments

Post a comment

Comments are moderated, and will not appear on this weblog until the author has approved them.

(Not displayed with comment.)

TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/540128/65491978

Listed below are links to weblogs that reference Arduinoで作る太陽光の方向を向く2軸サーボ:

« Processing 3.3.4 のインストール | Main | Arduinoで(太陽)光の方向を追いかける2軸サーボ(New Algorithm) »

July 2017
Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

Recent Trackbacks

無料ブログはココログ