(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 ответ
С этим кодом связано много проблем:
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. Сюда вы отслеживаете правильное положение и вам не нужно все переделывать угловое сканирование каждый раз. Кроме того, это не сработает по трем причинам:
- Вы имеете в виду
TranslateAnalogR==TranslateAnalogL
, а неTranslateAnalogR=TranslateAnalogL
TranslateAnalogR
иTranslateAnalogL
не обновляются внутри цикле вам необходимо явно выполнить аналоговое чтение.- Цикл будет выполняться слишком быстро, чтобы сервоприводы могли следовать запрошенному позиции.
Позже:
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 мс в секунду. итерация.
- Возможно, вы захотите добавить некоторый гистерезис, чтобы избежать дрожание, когда он нашел оптимум.
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Он компилируется? Это работает?, @Chad G
TranslateAnalogR=TranslateAnalogL
должен бытьTranslateAnalogR==TranslateAnalogL
(==
равно;=
— присваивание). ВTranslateAnalogR=!TranslateAnalogL && TranslateAnalogR>TranslateAnalogL
вам не нужна первая часть. Если одно значение больше другого, они не могут быть одинаковыми. Так что первая часть лишняя., @Gerbenfor (pos=0; pos>=40; pos=pos-1){
ничего не делает (пока)., @Gerbenзапустите его и проверьте с помощью фонарика (факела), @jsotola