Ви не увійшли.
Всем всего доброго!
Суть проблемы такова:
делаем с сыном модель солнечного трекера из конструкторов для солнечной батареи, все собрали, спаяли, но что-то с отладкой не клеится.
По замыслу платформа должна нацелиться на источник света и остановиться, когда показания датчиков примерно сравняются - сначала по горизонтали, потом - по вертикали. (программу писал не с нуля - сборная со всего союза)
Но она не останавливается.
Когда подключены оба мотора, они работают одновременно и вся конструкция "гуляет" во всех направлениях, но правда видно, что на лампу реагирует.
В случае отключения вертикального мотора - тоже непрерывно крутится около лампы.
пример того, что происходит:
https://yadi.sk/i/dJFeeY463QDtyN (пардон, около 100 Мб, но суть видна уже на первых секундах)
код программы (два варианта):
solar_2 - использую if..else
solar_3 - использую цикл while с условием (dhoriz > tol)
Поведение в обоих случаях одинаковое.
О системе:
Датчики - четыре фоторезистора с подстроечными переменными резисторами, подключенные к аналоговым портам ардуино по схеме делителя напр.. Их я предварительно примерно уравнял в показаниях через монитор серийного порта. Тут же протестировал, но без моторов.
Управление моторами - через драйвер моторов (Н-мост). Схема во вложении. Моторы постоянного тока с редукторами, использованы шестерни и червячные передачи.
Опыта в этой части не хватает.
Прошу помощи с отладкой: идеи, как отловить ошибку кончились.
Гуглил на тему трекеров, но везде использованы сервомоторы. В нашем случае - моторы постоянного тока: есть напряжение - крутит, поменял полярность - обратно крутит, нет напр. - стоп. Все просто, только СТОП - нет.
Товарищи, помогите сохранить авторитет в семье!
Да и стыдно своей рукож...ти ((
Остання редакція Денис_К (2017-12-04 00:14:19)
Неактивний
ТЕКСТ ПРОГРАММЫ SOLAR_2
//SOLAR_2
//датчики
int ldrlt = A1; //LDR top left - верх лево
int ldrrt = A2; //LDR top rigt - верх право
int ldrld = A4; //LDR down left - низ лево
int ldrrd = A3; //ldr down rigt - низ право
int tol = 50; //чувствительность 100
//motors
int ENA = 9; //мотор А - горизонталь
int IN1 = 7;
int IN2 = 6;
int IN3 = 5; // Input1 подключен к выводу 5
int IN4 = 4;
int ENB = 3; //мотор В - вертикаль
int i=150; // speed motor
//
void setup()
{
//moto
pinMode (ENA, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (ENB, OUTPUT);
pinMode (IN4, OUTPUT);
pinMode (IN3, OUTPUT);
Serial.begin(300);
}
void loop()
{
//получаем показания с датчиков
int lt = analogRead(ldrlt); // top left верх лево
int rt = analogRead(ldrrt); // top right верх пр
int ld = analogRead(ldrld); // down left низ лево
int rd = analogRead(ldrrd); // down rigt низ право
//вычисляем средние значения по четырем сторонам
int avt = (lt + rt) / 2; // average value top - среднее верх
int avd = (ld + rd) / 2; // average value down- -- низ
int avl = (lt + ld) / 2; // average value left - -- левое
int avr = (rt + rd) / 2; // average value right -- правое
// вычисляем разницу между верхом и низом, правой и левой сторонами
int dvert = abs(avt - avd); // check the diffirence of up and down
int dhoriz = abs(avl - avr);// check the diffirence of left and right
/*
*
*
Serial.print("avt: ");
Serial.print(avt);
Serial.print(" ");
Serial.print("avd: ");
Serial.print(avd);
Serial.print(" ");
Serial.print("avl: ");
Serial.print(avl);
Serial.print(" ");
Serial.print("avr: ");
Serial.println(avr);
*/
//вывод показаний на серийный порт
Serial.print("up left lt/A1: ");
Serial.print(lt);
Serial.print(" ");
Serial.print(" dwn left ld/A4: ");
Serial.print(ld);
Serial.print(" ");
Serial.print(" up rigt rt/A2: ");
Serial.print(rt);
Serial.print(" ");
Serial.print(" dwn rigt rd/A3: ");
Serial.println(rd);
Serial.print(" ");
Serial.print(" ");
//принимаем решение по горизонтали
if (dhoriz > tol) //
{
if (avl > avr) //левое больше правого
{
digitalWrite (IN2, HIGH);
digitalWrite (IN1, LOW);
analogWrite(ENA, i);
//delay(30);
}
else if (avl < avr) //правое больше левого
{
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite(ENA, i);
//delay(30);
}
}
else // иначе = стоп по горизонтали
{
analogWrite (ENA, 0);
digitalWrite (IN2, LOW);
digitalWrite (IN1, LOW);
delay(1000);
// движение по вертикали начинаю , когда по вертикали СТОП
//принимаем решение по вертикали
if (dvert > tol)
{
if (avt > avd) //верх больше низа
{
digitalWrite (IN4, HIGH);
digitalWrite (IN3, LOW);
analogWrite(ENB, i);
//delay(30);
}
else if (avt < avd) //низ больше верха
{
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite(ENB, i);
}
}
else // иначе = стоп по вертикали
{
// analogWrite (ENB, 0);
digitalWrite (IN4, LOW);
digitalWrite (IN3, LOW);
delay(1000);
}
} //-- от раздела СТОП по горизонтали
}
Неактивний
SOLAR_3
//датчики
int ldrlt = A1; //LDR top left - верх лево
int ldrrt = A2; //LDR top rigt - верх право
int ldrld = A4; //LDR down left - низ лево
int ldrrd = A3; //ldr down rigt - низ право
int tol = 50; //чувствительность 100
//motors
int ENA = 9; //мотор А - горизонталь
int IN1 = 7;
int IN2 = 6;
int IN3 = 5; // Input1 подключен к выводу 5
int IN4 = 4;
int ENB = 3; //мотор В - вертикаль
int i=150; // speed motor
//
int lt; // top left верх лево
int rt ;// top right верх пр
int ld ;// down left низ лево
int rd ;// down rigt низ право
// средние значения по четырем сторонам
int avt; // average value top - среднее верх
int avd; // average value down- -- низ
int avl; // average value left - -- левое
int avr; // average value right -- правое
// разницу между верхом и низом, правой и левой сторонами
int dvert; // check the diffirence of up and down
int dhoriz;// check the diffirence of left and right
void setup()
{
//moto
pinMode (ENA, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (ENB, OUTPUT);
pinMode (IN4, OUTPUT);
pinMode (IN3, OUTPUT);
Serial.begin(300);
}
void loop()
{
// первая итерация
//получаем показания с датчиков
lt = analogRead(ldrlt); // top left верх лево
rt = analogRead(ldrrt); // top right верх пр
ld = analogRead(ldrld); // down left низ лево
rd = analogRead(ldrrd); // down rigt низ право
//вычисляем средние значения по четырем сторонам
avt = (lt + rt) / 2; // average value top - среднее верх
avd = (ld + rd) / 2; // average value down- -- низ
avl = (lt + ld) / 2; // average value left - -- левое
avr = (rt + rd) / 2; // average value right -- правое
// вычисляем разницу между верхом и низом, правой и левой сторонами
dvert = abs(avt - avd); // check the diffirence of up and down
dhoriz = abs(avl - avr);// check the diffirence of left and right
//дальше все происходит в цикле, пока разница по горизонтали менгше порога tol
//принимаем решение по горизонтали
while (dhoriz > tol) {
analogWrite(ENA, i);
if (avl > avr) //левое больше правого
{
digitalWrite (IN2, HIGH);
digitalWrite (IN1, LOW);
//delay(30);
}
else if (avl < avr) //правое больше левого
{
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
//analogWrite(ENA, i);
//delay(30);
}
//получаем показания с датчиков
lt = analogRead(ldrlt); // top left верх лево
rt = analogRead(ldrrt); // top right верх пр
ld = analogRead(ldrld); // down left низ лево
rd = analogRead(ldrrd); // down rigt низ право
//вычисляем средние значения по четырем сторонам
avt = (lt + rt) / 2; // average value top - среднее верх
avd = (ld + rd) / 2; // average value down- -- низ
avl = (lt + ld) / 2; // average value left - -- левое
avr = (rt + rd) / 2; // average value right -- правое
// вычисляем разницу между верхом и низом, правой и левой сторонами
dvert = abs(avt - avd); // check the diffirence of up and down
dhoriz = abs(avl - avr);// check the diffirence of left and right
/*
Serial.print("avt: ");
Serial.print(avt);
Serial.print(" ");
Serial.print("avd: ");
Serial.print(avd);
Serial.print(" ");
Serial.print("avl: ");
Serial.print(avl);
Serial.print(" ");
Serial.print("avr: ");
Serial.println(avr);
*/
//вывод показаний на серийный порт
Serial.print("up left lt/A1: ");
Serial.print(lt);
Serial.print(" ");
Serial.print(" dwn left ld/A4: ");
Serial.print(ld);
Serial.print(" ");
Serial.print(" up rigt rt/A2: ");
Serial.print(rt);
Serial.print(" ");
Serial.print(" dwn rigt rd/A3: ");
Serial.println(rd);
Serial.print(" ");
Serial.print(" ");
}
// if // иначе = стоп по горизонтали
// {
//после выхода из цикла безусловный стоп по горизонтали
analogWrite (ENA, 0);
digitalWrite (IN2, LOW);
digitalWrite (IN1, LOW);
// delay(1000);
// }
/*
//////////////////////////////////// ЭТО НЕ ТЕСТИРОВАЛОСЬ, т.к. ПО ГОРИЗОНТАЛИ НЕТ СТОПА
///принимаем решение по вертикали///
if (dvert > tol)
{
if (avt > avd) //верх больше низа
{
digitalWrite (IN4, HIGH);
digitalWrite (IN3, LOW);
analogWrite(ENB, i);
//delay(30);
}
else if (avt < avd) //низ больше верха
{
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite(ENB, i);
}
}
else // иначе = стоп
{
// analogWrite (ENB, 0);
digitalWrite (IN4, LOW);
digitalWrite (IN3, LOW);
delay(1000);
}
// } //-- от раздела СТОП по горизонтали
*/
}
Неактивний
Вячеслав прав - доработайте до рабочего состояния горизонталь, потом идите дальше.
кстати, не увидел мёртвой зоны в которой нет движения.
на сколько шумные у вас датчики освещённости, как плящут значения.
датчики на одной оси откалиброваны ?
Неактивний
Может вы и правы насчёт расположения датчиков. Но проверил монитором , что на датчиках в момент поворота: башня трекера продолжала двигаться , когда разница была меньше порога - должна была остановиться.
Неактивний
Про мертвую зону:
Разве это не она?
dhoriz > tol
Tol - Это порог , если разница по горизонтали или по вертикали больше него, то включаю соответствующие моторы, иначе - выключаю.
Только они не выключаются
Неактивний
Может вы и правы насчёт расположения датчиков. Но проверил монитором , что на датчиках в момент поворота: башня трекера продолжала двигаться , когда разница была меньше порога - должна была остановиться.
так отключите нафиг моторы и крутите руками, в мониторе смотрите что показывают ваши датчики.
Неактивний
Коллеги, добавил отладочную часть:
Serial.print("end loop while");
Serial.print(" ");
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(500); // wait for a second
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW
delay(500); // wait for a second
кручу руками, вижу, что из цикла while выход есть
видимо что-то не так в этой части:
analogWrite (ENA, 0);
digitalWrite (IN2, LOW);
digitalWrite (IN1, LOW);
может быть неправильно использую analogWrite ?
Неактивний
Ура! заработала
обнаружил, что когда вручную кручу башню, выход из цикла есть, но при автоматическом повороте от мотора из цикла не выходит, хотя по показаниям датчиков вижу, что условие dhoriz > tol должно выполниться
добавил в цикл
if (dhoriz > tol) {break;}
теперь есть и выход и остановка точно под лампой.
дальше буду отлаживать вертикаль
ПС: почему не работает выход из цикла по while (dhoriz > tol) ???
Может быть дело в скорости, типа контроллер не успевает послать команду СТОП вовремя и моторы продолжают крутиться, проходя "мертвую зону"?
Остання редакція Денис_К (2017-12-05 08:16:50)
Неактивний
замеряем освещённость двумя датчиками.
если оба в мёртвой зоне - стоим.
если нет - поползли в сторону показаний с большими значениями.
как оба оказались в мёртвой зоне - встали.
пока этого не добьётесь - дальше идти безполезно.
Неактивний
Уважаемый ВР, я уже в финале!
Модель работает.
Дальше можно говорить лишь об оптимизации, но это уже вопрос развития, а не школьного проекта первоклассника.
Но я не оспариваю ваше право на свой вариант и не против обсудить преимущества разных подходов.
Неактивний
Подозрительная ссылка
Даже пытаться не буду открыть
правильно! чего открывать? - если там что то неизвестное )
например
4 декабря 2017 г.
50 лет программированию для детей
Today, during Computer Science Education Week, we celebrate 50 years since kids programming languages were first introduced to the world with a very special creation (and furry friend): our first ever kids focused coding Google Doodle! Today’s Doodle was developed through the close teamwork of not one or two but THREE teams: the Google Doodle team, Google Blockly team, and researchers from MIT Scratch!
Неактивний
Приветствую с удачей. У меня такое самое ,только у меня идётодна ось ,горизонтальная ,если можете поделитесь уже рабочим скетчем ,заранее спасибо
SOLARSAN-GPS V17 (WiFi MQTT)
Комплекс слежения за солнцем на основе расчета данных,
полученных от GPS приемника. Данная система состоит из
базового модуля SOLARSAN-GPS который может работать
самостоятельно и SOLARSAN-SLAVE работающие только
как исполнительное устройство. С помощью SOLARSAN-
GPS можно ориентировать солнечные концентраторы,
коллекторы или панели под прямым углом к солнечному
свету. Управление осуществляется с помощью актуаторов
или поворотных приводов в двух плоскостях и имеет
точность один градус. Модуль имеет вход для подключения
«анемометра» для защиты от сильного ветра, вход «датчика
града и снега» и вход «фото-датчика» для режима сна при
низкой солнечной активности. Встроенный WiFi модуль
позволяет конфигурировать трекер через WEB страницу по локальной сети или через точку доступа.
Встроенный MQTT брокер позволяет управлять и получать данные через сеть интернет по всему миру.
Питание от 12V до 30V (и версию HV с питанием от 12V до 55V). Защита по току. Защита от короткого
замыкания. Встроенный радио-модем 433.92(315.00)мГц мощностью 100 мВт для передачи данных в радиусе
до 100 метров модулям SOLARSAN-SLAVE. Работает как в одной так и в двух осях. Корпус IP66 позволяет
устанавливать солнечный трекер под открытым небом.
https://drive.google.com/file/d/1tmIqvCqQfWALVugp9yhP492vGjQXV3hX/view?usp=sharing
Всем привет !
Лучше поздно, чем никогда - поделиться полезной информацией.
Читая тему, "сильно щурился" от сенсора на фоторезисторах как таковых.
В любительских условиях очень эффектно использовать излучающие светодиоды как датчики освещенности.
Прозрачная "линза" зеленых или желтых светодиодов - приемлемая оптическая система.
ФотоЭДС светодиодов - от вольта и более, в зависимости от нагрузки.
И самое приятное - диаграмма направленности с раскрывом +- 10...12 градусов. (направьте свет на стену)
Разведя два светодиода на 20 градусов, получаем хороший датчик для суммарно-разностной обработки.
В результате точность измерения направления на Солнце - 15 угловых минут !
Еще полезно блендой от бликов защищаться.
Всем успехов !
Неактивний
https://youtu.be/GH9MweuUv-s
Вот оно что Михалыч!
Неактивний
У меня проблема с резисторами
т.е. я не поставил резисторы а результат ноль. Резисторы обязательно
Дайте угадаю.
Что-то мне подсказывает кофейная гуща, что в алгоритмах SOLAR_2 и SOLAR_3 по вертикали моторчик остановится тогда и только тогда, когда моторчик по горизонтали будет стоять. Иными словами, если движение начинается с вертикального моторчика, и в это время показания по горизонту изменятся больше положенного, до вся конструкция начнет двигаться сразу в двух направлениях. Причем отслеживать в это время будет только горизонт. А когда выставится горизонт (вертикаль все еще движется и наверняка уже проскочила сою отметку), изменение по вертикали может привести к тому, что горизонт опять немного уплывет.
Попробуйте управление вертикалью сделать не привязанным к горизонту, либо добавьте остановку вертикального мотора при движении горизонтального.