Arduino:如何在不知道伺服需要移动到的确切位置的情况下移动伺服

问题描述

我正在尝试通过比较 4 个光敏电阻的电阻来制作跟踪太阳的太阳能电池板。我已经对决定光敏电阻电阻的部分进行了编码(我目前只测试 2 个),但我正在努力使伺服运动部分正确。我不知道太阳在天空中的确切位置,我只知道舵机需要移动到哪个方向才能使太阳能电池板面向太阳。我需要告诉伺服器向某个方向移动,直到光敏电阻的电阻在一定范围内(我已经创建了这个)。有人知道怎么做吗?

这是我所拥有的。

const int sensorPin = A0;
const int sensorPin1 = A1;
int sensorValue = 0;
int sensorValue1 = 0;
float Vin = 5;
float Vout = 0;
float Vout1 = 0;
float Rref = 2180;
float R = 0;
float R1 = 0;

#include <Servo.h>

Servo myservo;

int pos = 0;

void setup() {
  Serial.begin(9600);
  myservo.attach(9);
}
void loop() {
  sensorValue = analogRead(sensorPin);
  Vout = (Vin * sensorValue) / 1023;
  R = Rref * (1 / ((Vin / Vout) - 1));
  Serial.print("R: ");
  Serial.println(R);
  delay(500);

  sensorValue1 = analogRead(sensorPin1);
  Vout1 = (Vin * sensorValue1) / 1023;
  R1 = Rref * (1 / ((Vin / Vout1) -1));
  Serial.print("R1: ");
  Serial.println(R1);
  delay(500);
  
if ((R1 > R) && ((R1 -R) > 1000)){
  for (pos = 0; pos <= 180; pos += 1) {
    myservo.write(pos);
    delay(15);
  }
}
if ((R > R1) && ((R -R1) > 1000)) {
  for (pos = 180; pos >= 0; pos -= 1) {
    myservo.write(pos);
    delay(15);
  }
}  
}

我还看到了 GreatScott 的视频! (链接https://www.youtube.com/watch?v=_6QIutZfsFs)他是在哪里做的。他的设计与我的不同,但我想看看他的代码。他没有展示所有内容,但这是我设法复制的内容。我对 C++ 了解不多,所以我真的不知道他在做什么。有人可以给我解释一下吗?

int topleft = 0;
int topright = 0;
int bottomleft = 0;
int bottomright = 0;



void setup() {
 pinMode(9,OUTPUT);
 pinMode(10,OUTPUT);
 TCCR1A = 0;
 TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
 TCCR1B = 0;
 TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11);
 ICR1 = 40000;
 OCR1A = 3000;
 OCR1B = 3600;

}

void loop() {
  topleft = analogRead(A0);
  topright = analogRead(A1);
  bottomleft = analogRead(A2);
  bottomright = analogRead(A3);
  if (topleft > topright) {
    OCR1A = OCR1A + 1;
    delay(15);
  }
   if (bottomleft > bottomright) {
    OCR1A = OCR1A + 1;
    delay(15);
  }
   if (topleft < topright) {
    OCR1A = OCR1A - 1;
    delay(15);
   }
    if (bottomleft < bottomright) {
    OCR1A = OCR1A - 1;
    delay(15);
    }
    if (OCR1A > 4000) {
      OCR1A = 4000;
    }
    if (OCR1A < 2000) {
      OCR1A = 2000;
    }
   
}

解决方法

您不需要一次性知道(或找出)舵机的pos;您只需将它移近每个循环中需要放置的位置,直到太阳能电池板正确对齐。

您可以尝试这样的操作,这也是将您引用的代码的最底层粗略翻译成您的程序条款。

注意:非常粗略的代码,没有处理所有细节,未经测试,但你懂的。

const int sensorPin0 = A0;
const int sensorPin1 = A1;
int pos = 90;              // Start with centered servo

void setup() {
  Serial.begin(9600);
  myservo.attach(9);
}

void loop() {
  analogRead(sensorPin0);                // Do measurements twice and use second one
  sensorValue0 = analogRead(sensorPin0); // No need to calculate R values;
  analogRead(sensorPin1);                // the raw values can also be used.
  sensorValue1 = analogRead(sensorPin1); 
  
  if (sensorValue0 > sensorValue1) {     // If value 0 > value 1,then
    pos++;                               // move one degree towards 180 degrees
    if (pos > 180) pos = 180;            // Limit pos to 0 - 180
  }

  if (sensorValue0 < sensorValue1) {     // If value 0 < value 1,then
    pos--;                               // move one degree towards 0 degrees
    if (pos < 0) pos = 0;                // Limit pos to 0 - 180
  }

  myservo.write(pos);                    // Let servo go to pos
  delay(200);                            // Wait a bit and do it all again
}

每次循环时,伺服器都会向正确对齐的太阳能电池板靠近一度。只要两个 LDR 显示相同的值,它就会保持在那里。

请注意,LDR 速度较慢,而且为了获得良好的区分度,您可能需要在其上放置小防护罩或管子,以防止它们始终获得相同数量的阳光。

,

您可以在计算的方向稍微移动伺服器,再次检查该方向的光线是否变强,然后再次移动...直到光线变暗,然后移回。