(Arduino Uno) Действителен ли мой код для проекта Follow the Sun? Мы хотим, чтобы двигатель остановился, когда оба фоторезистора получат одинаковое количество света.

int RlightPin=0;  //контакт для правого фоторезистора
int LlightPin=1;  //контакт для левого фоторезистора
int TranslateAnalogR=0;
int TranslateAnalogL= 1; 
#include <Servo.h> //Библиотека сервоприводов.
int pos=90; //Объявляем и инициализируем переменную pos.
int servoPin=9; //Сервопривод подключен к контакту 9
int servoDelay=10; //Время ожидания двигателя перед возобновлением работы.
Servo myArms; //Объект сервопривода с именем myArms


void setup() {
Serial.begin(9600); //Начать последовательную связь.
pinMode(7,OUTPUT);
pinMode(servoPin,OUTPUT);
myArms.attach(servoPin);

}

void loop() {

Serial.println(analogRead(RlightPin));   //Запишите значение правого фоторезистора в последовательный монитор.
TranslateAnalogR=analogRead(RlightPin); //Читаем правильное значение фоторезистора

Serial.println(analogRead(LlightPin));    //Записываем значение левого фоторезистора в последовательный монитор.
TranslateAnalogL=analogRead(LlightPin);  //Читаем значение левого фоторезистора

if(TranslateAnalogR=TranslateAnalogL){        //Если значение фоторезистора превышает 355, двигатель остановится
myArms.write(pos); // устанавливает положение сервопривода в соответствии с масштабированным значением
delay(servoDelay);//ждет, пока он достигнет позиции

}

if(TranslateAnalogR=!TranslateAnalogL && TranslateAnalogR>TranslateAnalogL) { //Если фоторезистор R не равен L и выше L, перемещаем до тех пор, пока он не станет равным
for (pos=0; pos>=40; pos=pos+1)  {
  myArms.attach(servoPin);
  myArms.write(pos); //отправляем сервопривод в позицию
  if(TranslateAnalogR=TranslateAnalogL){
  myArms.detach();}
}
}

if(TranslateAnalogL=!TranslateAnalogR && TranslateAnalogL>TranslateAnalogR){    //Если фоторезистор L не равен R и выше R, перемещайте до тех пор, пока он не станет равным
for (pos=0; pos>=40; pos=pos-1){
   myArms.attach(servoPin);
   myArms.write(pos); //отправляем сево на позицию
   if(TranslateAnalogL=TranslateAnalogR){
   myArms.detach(); }

}
}




}

, 👍1

Обсуждение

Он компилируется? Это работает?, @Chad G

TranslateAnalogR=TranslateAnalogL должен быть TranslateAnalogR==TranslateAnalogL (== равно; = — присваивание). В TranslateAnalogR=!TranslateAnalogL && TranslateAnalogR>TranslateAnalogL вам не нужна первая часть. Если одно значение больше другого, они не могут быть одинаковыми. Так что первая часть лишняя., @Gerben

for (pos=0; pos>=40; pos=pos-1){ ничего не делает (пока)., @Gerben

запустите его и проверьте с помощью фонарика (факела), @jsotola


1 ответ


2

С этим кодом связано много проблем:

pinMode(7,OUTPUT);

Для чего нужен этот значок? Почему вы устанавливаете его на OUTPUT, а потом никогда вообще что-нибудь вывести? Если вывод используется, вы должны объявить константа для него, например

const int fooPin = 7;

а затем используйте константу вместо простого числа 7.

Serial.println(analogRead(RlightPin));   //Запишите значение правого фоторезистора в последовательный монитор.
TranslateAnalogR=analogRead(RlightPin); //Читаем правильное значение фоторезистора

analogRead() — медленная функция, и ее выполнение совершенно неэффективно. аналого-цифровое преобразование дважды. Вместо этого вы можете

TranslateAnalogR = analogRead(RlightPin);
Serial.println(TranslateAnalogR);

Из соображений стиля я бы удалил комментарии. Код комментирования вообще считается хорошей практикой, если судить по комментариям что-то неочевидное, например, представление «общей картины» или обоснования для совершения чего-либо определенным образом. Перефразируя по-английски что код, написанный на C++, уже говорит, что он бесполезен.

Serial.println(analogRead(RlightPin));   //Запишите значение правого фоторезистора в последовательный монитор.
//...
Serial.println(analogRead(LlightPin));    //Записываем значение левого фоторезистора в последовательный монитор.

Вы не будете знать, какое значение соответствует левому, а какое значение соответствует правому. Вместо этого я бы сделал что-то вроде:

Serial.print("L: ");
Serial.print(TranslateAnalogL);
Serial.print(", R: ");
Serial.println(TranslateAnalogR);

Тогда:

if(TranslateAnalogR=TranslateAnalogL){        //Если значение фоторезистора превышает 355, двигатель остановится

Вы имеете в виду ==.

if(TranslateAnalogR=!TranslateAnalogL && TranslateAnalogR>TranslateAnalogL) { //Если фоторезистор R не равен L и выше L, перемещайте до тех пор, пока он не станет равным

Первый тест является излишним. Если R>L, то, очевидно, R≠L.

    for (pos=0; pos>=40; pos=pos+1)  {
        myArms.attach(servoPin);
        myArms.write(pos); //отправляем сервопривод в позицию
        if(TranslateAnalogR=TranslateAnalogL){
            myArms.detach();
        }
    }

Это очень надуманный способ поиска оптимума. Обычно ты прикрепите сервопривод один раз и держите его подключенным все время. Затем вы настраиваете положение до тех пор, пока не увидите одинаковое освещение на обоих LDR. Сюда вы отслеживаете правильное положение и вам не нужно все переделывать угловое сканирование каждый раз. Кроме того, это не сработает по трем причинам:

  1. Вы имеете в виду TranslateAnalogR==TranslateAnalogL, а не TranslateAnalogR=TranslateAnalogL
  2. TranslateAnalogR и TranslateAnalogL не обновляются внутри цикле вам необходимо явно выполнить аналоговое чтение.
  3. Цикл будет выполняться слишком быстро, чтобы сервоприводы могли следовать запрошенному позиции.

Позже:

    for (pos=0; pos>=40; pos=pos-1){

Цикл выполняется в обратном направлении. Вы, наверное, имеете в виду

    for (pos=40; pos>=0; pos=pos-1){

Вот мой взгляд на это, совершенно непроверенный:

#include <Servo.h>

// Распиновка.
const int PIN_LDR_R = 0;  // правый фоторезистор
const int PIN_LDR_L = 1;  // левый фоторезистор
const int PIN_SERVO = 9;  // сервопривод

const int SERVO_DELAY = 20; // время ожидания двигателя перед возобновлением работы

int pos = 90; // положение сервопривода в градусах
Servo servo;  // сервообъект

void setup() {
    Serial.begin(9600);
    pinMode(PIN_SERVO, OUTPUT);
    servo.attach(PIN_SERVO);
}

void loop() {
    // Чтение и отчет об уровнях освещенности.
    int level_L = analogRead(PIN_LDR_L);
    int level_R = analogRead(PIN_LDR_R);
    Serial.print("L: ");
    Serial.print(level_L);
    Serial.print(", R: ");
    Serial.println(level_R);

    // Отрегулируйте положение сервопривода.
    if (level_R > level_L && pos < 180)
        ++pos;
    if (level_R < level_L && pos > 0)
        --pos;

    // Обновляем сервопривод.
    servo.write(pos);
    delay(SERVO_DELAY);
}

Несколько вещей, на которые стоит обратить внимание:

  • Константы квалифицируются как const (это помогает компилятору оптимизировать и ловить ошибки) и пишется полными заглавными буквами (распространенное стилистическое соглашение).
  • Положение сервопривода регулируется шаг за шагом, на один градус за цикл. итерация. Нет необходимости каждый раз выполнять полную проверку.
  • Программа не делает ничего особенного, когда уровень освещенности равны, потому что в этом случае делать особо нечего.
  • Я увеличил задержку между обновлениями сервоприводов до 20 мс, так как только последовательная связь может занять около 19 мс в секунду. итерация.
  • Возможно, вы захотите добавить некоторый гистерезис, чтобы избежать дрожание, когда он нашел оптимум.
,