Добрый день! У меня задача написать скетч для ардуино уно для автоматического поворота солнечных панелей вслед за солнцем. Вся конструкция уже смонтирована и пока зафиксирована в стационарном положении. Поворот будет осуществляться с помощью актуатора со встроенным датчиком холла. Его я уже приобрел, у него такие характеристики: 24 V двигатель, направление движения штока меняется изменением полярности питания, в конечных точках автоостановка до смены полярности, время полного хода штока 750мм в холостую 40 сек, 4 провода с датчика холла (два из них- питание датчика 5V и два на сигнал), усилие 100 кг, 1 сигнал датчика на 1 оборот двигателя. Есть еще модуль реального времени DS1302 и 3 реле. Одно из реле под № 1 подает питание на двигатель актуатора, два других под номерами 2 и 3 меняют полярность на линии 24 V, для смены полярности нужно включить их оба.
Алгоритм работы такой: при включении установить шток в крайнее положение, далее получаем с модуля часов текущий час, находим сколько оборотов должен сделать двигатель в зависимости от текущего часа, включаем реле 1 до того момента, когда текущие обороты сравняются с количеством оборотов, найденным на предидущем шаге. Как только они сравнялись отключаем реле 1 и делаем паузу в 1 час. Это делаем в период с 9 до 16 часов. В 23 часа меняем полярность включив реле 2 и 3 (у них включение при напряжении на управляющем контакте 0, в отличии от реле 1, где нужно на управляющий контакт подать 5V) и включаем реле 1 на 40 сек для возврата штока в начальное положение. Далее пауза 10 часов, до 9-ти утра и так по циклу.
Я ни разу не программист, поэтому сразу решил, что закажу это дело фрилансерам, но после того, как меня там дважды просто развели на деньги пришлось самому попробовать разобраться. Пока получилось вот так:
#include<iarduino_RTC.h>//Подключаем библиотеку для работы с часами
iarduino_RTC time(RTC_DS1302, 8, 6, 7); //Назначаем пины модулю часов
const byte hallPin = 2; //контакт к которому подключен датчик холла
volatile long int rot;//переменная для хранения количества оборотов
const int ob9 = 134; //кол-во оборотов в 9часов
const int ob10 = 254; //кол-во оборотов в 10часов
const int ob11 = 367; //кол-во оборотов в 11часов
const int ob12 = 420; //кол-во оборотов в 12часов
const int ob13 = 378; //кол-во оборотов в 13часов
const int ob14 = 272; //кол-во оборотов в 14часов
const int ob15 = 159; //кол-во оборотов в 15часов
const int ob16 = 74; //кол-во оборотов в 16часов
const int relay1Pin = 3; //Пин для первого реле
const int relay2Pin = 5; //Пин для второго реле
const int relay3Pin = 4; //Пин для третьего реле
const int pitHall = 9; //Пин питания датчика холла
void detect() { //функция-обработчик,которая вызывается во время прерывания
rot++;
}
void setup() {
pinMode(relay3Pin, OUTPUT); //пин реле 3 как выход
pinMode(relay2Pin, OUTPUT); //пин реле 2 как выход
pinMode(relay1Pin, OUTPUT); //пин реле 1 как выход
digitalWrite(relay3Pin, LOW); //Включаем реле 3
delay(100);
digitalWrite(relay2Pin, LOW); //Включаем реле 2
delay(100);
digitalWrite(relay1Pin, HIGH); //Включаем реле 1
delay(40000);//Задержка40сек
digitalWrite(relay1Pin, LOW); //Выключаем реле 1
delay(100);
digitalWrite(relay2Pin, HIGH); //Выключаем реле 2
delay(100);
digitalWrite(relay3Pin, HIGH); //Выключаем реле 3
delay(5000);
}
void loop() {
rot = 0; //Обнуляем количество оборотов
int h;//Переменная для хранения текущего часа
int obStop;//Переменная для определения оборотов для отключения мотора
pinMode(relay1Pin, OUTPUT); //пин реле 1 как выход
pinMode(relay2Pin, OUTPUT); //пин реле 2 как выход
pinMode(relay3Pin, OUTPUT); //пин реле 3 как выход
pinMode(pitHall, OUTPUT); //пин питания датчика как выход
time.begin();//Инициируем работу с модулем реального времени
h = time.Hours; //Получаем текущий час
if (h == 9) obStop = ob9; //Определяем нужное кол-во оборотов в зависимости от текущего часа
else if (h == 10) obStop = (ob9 + ob10);
else if (h == 11) obStop = (ob9 + ob10 + ob11);
else if (h == 12) obStop = (ob9 + ob10 + ob11 + ob12);
else if (h == 13) obStop = (ob9 + ob10 + ob11 + ob12 + ob13);
else if (h == 14) obStop = (ob9 + ob10 + ob11 + ob12 + ob13 + ob14);
else if (h == 15) obStop = (ob9 + ob10 + ob11 + ob12 + ob13 + ob14 + ob15);
else if (h == 16) obStop = (ob9 + ob10 + ob11 + ob12 + ob13 + ob14 + ob15 + ob16);
else obStop = 0;
if (h >= 9 && h < 23) { // Если время от 9 до 23 часов
digitalWrite(pitHall, HIGH); // Включаем питание датчика холла
delay(100);
pinMode(hallPin, INPUT_PULLUP); // настроим пин 2 на вход, с подтяжкой к питанию
attachInterrupt(digitalPinToInterrupt(hallPin), detect, RISING); // активируем прерывание и свяжем его с функцией detect
if (rot < obStop) digitalWrite(relay1Pin, HIGH);
if (rot == obStop) digitalWrite(relay1Pin, LOW);
rot = 0; // Обнуляем количество оборотов
digitalWrite(pitHall, LOW); // Отключаем питание датчика
}
delay (3600000); // Ждем 1 час
if (h == 23) {
digitalWrite(relay3Pin, LOW); //Включаем реле 3
delay(100);
digitalWrite(relay2Pin, LOW); //Включаем реле 2
delay(100);
digitalWrite(relay1Pin, HIGH); //Включаем реле 1
delay(40000);//Задержка40сек
digitalWrite(relay1Pin, LOW); //Выключаем реле 1
delay(100);
digitalWrite(relay2Pin, HIGH); //Выключаем реле 2
delay(100);
digitalWrite(relay3Pin, HIGH); //Выключаем реле 3
}
delay (36000000); // Ждем 10 часов
}
Setup отрабатывает нормально, а вот дальше мне видимо без помощи не разобраться. Сразу после загрузки скетча шток уходит в начальное положение, текущий час видимо присваивается переменной h и вычисляется переменная obStop т.к. включается реле 1 и шток идет вперед. Но реле 1 не отключается и он не останавливается до самого крайнего переднего положения. При повторной загрузке скетча уже реле 1 не включается. Оказывается модуль часов сбрасывается в 0, причем так, что установить в нем время другим скетчем не удается пока его не отключишь от питания и не снимешь батарейку. После этого время удается залить, но до следующего запуска моего скетча, все повторяется.
Я думаю проблема в обработке сигнала датчика холла, видимо когда он выдает сигналы мой скетч не работает как я задумал, происходит что то для меня непонятное.
Помогите пожалуйста, кому не трудно разобраться.