// global variables
// valdes[0] = 0 - manual, 1 - auto
// valdes[1] = position 0 - 100
// valdes[2] = 0 - manual, 1 - auto - 2 channel
// valdes[3] = position 0 - 100 - 2 channel
static bool motFreqSet = false;
static int falseStep = 0;
static int prevPos1 = -1;
static int prevPos2 = -1;
static int targetAdc[2] = {0,0};
static int leftCycles = 0;
static int rightCycles = 0;
static int direction[2] = {0,0};
static int lastLux = 0;
//static os_timer_t esp_timer[0]; // define timer esp_timer[0]
static os_timer_t esp_timer[2]; // define timer esp_timer array
void ICACHE_FLASH_ATTR setMotFreq()
{
//if(motFreqSet)
// return;
i2c_start();
i2c_writeByte(0x60);
if(i2c_getAck()){falseStep = 1; i2c_stop(); return;}
i2c_writeByte(0x00);
if(i2c_getAck()){falseStep = 2; i2c_stop(); return;}
i2c_writeByte(0x00);
if(i2c_getAck()){falseStep = 3; i2c_stop(); return;}
i2c_writeByte(0x3e);
if(i2c_getAck()){falseStep = 4; i2c_stop(); return;}
i2c_writeByte(0x80);
if(i2c_getAck()){falseStep = 5; i2c_stop(); return;}
i2c_stop();
motFreqSet = true;
os_delay_us(1000);
}
void ICACHE_FLASH_ATTR motorLeft(int motor)
{
setMotFreq();
//falseStep =0;
i2c_start();
i2c_writeByte(0x60);
if(i2c_getAck()){falseStep = 6; return;}
if(motor == 1)
i2c_writeByte(0x10);
else
i2c_writeByte(0x11);
if(i2c_getAck()){falseStep = 7; return;}
i2c_writeByte(0x01);
if(i2c_getAck()){falseStep = 8; return;}
i2c_writeByte(0x01);
if(i2c_getAck()){falseStep = 9; return;}
i2c_writeByte(0x00);
if(i2c_getAck()){falseStep = 10; return;}
i2c_stop();
}
void ICACHE_FLASH_ATTR motorRight(int motor)
{
setMotFreq();
//falseStep =0;
i2c_start();
i2c_writeByte(0x60);
if(i2c_getAck()){falseStep = 6; return;}
if(motor == 1)
i2c_writeByte(0x10);
else
i2c_writeByte(0x11);
if(i2c_getAck()){falseStep = 7; return;}
i2c_writeByte(0x02);
if(i2c_getAck()){falseStep = 8; return;}
i2c_writeByte(0x01);
if(i2c_getAck()){falseStep = 9; return;}
i2c_writeByte(0x00);
if(i2c_getAck()){falseStep = 10; return;}
i2c_stop();
}
void ICACHE_FLASH_ATTR motorStop(int motor)
{
setMotFreq();
//falseStep =0;
i2c_start();
i2c_writeByte(0x60);
if(i2c_getAck()){falseStep = 6; return;}
if(motor == 1)
i2c_writeByte(0x10);
else
i2c_writeByte(0x11);
if(i2c_getAck()){falseStep = 7; return;}
i2c_writeByte(0x03);
if(i2c_getAck()){falseStep = 8; return;}
i2c_writeByte(0x01);
if(i2c_getAck()){falseStep = 9; return;}
i2c_writeByte(0x00);
if(i2c_getAck()){falseStep = 10; return;}
i2c_stop();
}
void ICACHE_FLASH_ATTR motor_proc(unsigned char motor){
// arg = motor number
//int targetAdc[0] = arg;
int curAdc = readADC_ADS(motor - 1);
// check if rotate to desired position
if(direction[motor - 1] == 1)
{
// rotating right
rightCycles++;
if ( curAdc >= targetAdc[motor - 1]) {motorStop(motor); os_timer_disarm(&esp_timer[motor - 1]);}
}
else
{
// rotating left
leftCycles++;
if ( curAdc <= targetAdc[motor - 1]) {motorStop(motor); os_timer_disarm(&esp_timer[motor - 1]);}
}
}
void ICACHE_FLASH_ATTR
startfunc(){
// выполняется один раз при старте модуля.
valdes[0] = 1;
valdes[2] = 1;
}
void ICACHE_FLASH_ATTR
timerfunc(uint32_t timersrc) {
// выполнение кода каждую 1 секунду
// check channel 1 for auto mode
if(valdes[0] == 1)
{
// auto mode
// calculate target position
if(tsllux <= sensors_param.cfgdes[4]/* luxNight */)
{
// night time, full closed DOWN
valdes[1] = 0;
}
else
if(tsllux <= sensors_param.cfgdes[3]/* luxOpened */)
{
// more then dark, full opened
valdes[1] = 50;
}
else
if(tsllux >= sensors_param.cfgdes[2]/* luxClosed */)
{
// very light, full close UP
// valdes[1] = 100;
valdes[1] = 0;
}
else
{
// calculate desired position
valdes[1] = (sensors_param.cfgdes[2]/* luxClosed */ - tsllux)*50/(sensors_param.cfgdes[2]/* luxClosed */ - sensors_param.cfgdes[3]/* luxOpened */);
}
}
// check channel 2 for auto mode
if(valdes[2] == 1)
{
// auto mode
// calculate target position
if(tsllux <= sensors_param.cfgdes[4]/* luxNight */)
{
// night time, full closed DOWN
valdes[3] = 0;
}
else
if(tsllux <= sensors_param.cfgdes[3]/* luxOpened */)
{
// more then dark, full opened
valdes[3] = 50;
}
else
if(tsllux >= sensors_param.cfgdes[2]/* luxClosed */)
{
// very light, full close UP
// valdes[1] = 100;
valdes[3] = 0;
}
else
{
// calculate desired position
valdes[3] = (sensors_param.cfgdes[2]/* luxClosed */ - tsllux)*50/(sensors_param.cfgdes[2]/* luxClosed */ - sensors_param.cfgdes[3]/* luxOpened */);
}
}
int curAdc;
// check if new position isn't equivalent to previous for channel 1
if(prevPos1 != valdes[1])
{
prevPos1 = valdes[1];
// get direction[0] and required sensor postion
curAdc = readADC_ADS(0);
targetAdc[0] = (sensors_param.cfgdes[1] - sensors_param.cfgdes[0])*valdes[1]/100 + sensors_param.cfgdes[0];
direction[0] = 0 ;// 1 - right, 0 - left
if(targetAdc[0] < curAdc)
{
direction[0] = 0;
motorLeft(1);
}
else
{
direction[0] = 1;
motorRight(1);
}
// start timer to check position
os_timer_disarm(&esp_timer[0]);
os_timer_setfn(&esp_timer[0], (os_timer_func_t *)motor_proc, 1);
os_timer_arm(&esp_timer[0], 50, 1);
}
// check if new position isn't equivalent to previous for channel 2
if(prevPos2 != valdes[3])
{
prevPos2 = valdes[3];
// get direction[0] and required sensor postion
curAdc = readADC_ADS(1);
targetAdc[1] = (sensors_param.cfgdes[6] - sensors_param.cfgdes[5])*valdes[3]/100 + sensors_param.cfgdes[5];
direction[1] = 0 ;// 1 - right, 0 - left
if(targetAdc[1] < curAdc)
{
direction[1] = 0;
motorLeft(2);
}
else
{
direction[1] = 1;
motorRight(2);
}
// start timer to check position
os_timer_disarm(&esp_timer[1]);
os_timer_setfn(&esp_timer[1], (os_timer_func_t *)motor_proc, 2);
os_timer_arm(&esp_timer[1], 50, 1);
}
if(timersrc%30==0){
// выполнение кода каждые 30 секунд
}
}
void webfunc(char *pbuf) {
os_sprintf(HTTPBUFF,"
Global Values
"); // вывод данных на главной модуля
}
+35 |
2275
137
|
+350 |
4996
212
|
+23 |
3272
90
|
+43 |
1851
35
|
geektimes.ru/deactivated/
Хотя конечно можно попробовать.
За видео +1.
Как то, тоже хотел собрать, что то подобное, только с роллер-шторами. Но там и движок мощный нужен и с софтом у меня проблемы(
ну и как бы направление как делать — мне кажется понятно.
но у меня уже пару месяцев работает — ничто не так не пошло.
в крайнем случае всегда можно поднять жалюзи вверх :)
2) сколько оборотов из одного крайнего положения в другое?
имхо серва проще и надежнее, может и дешевле…
почти не слышно. там мотор с редуктором. сколько оборотов не знаю,. в доке на движок нет передаточного.
но написано 30RPM. следовательно на 30 процентах оборот за 6 сек делает примерно
для серва все равно датчики конечных позиций надо
переменник проще :)
и у вас 2 крайних положения 20° нижнее и 160° верхнее.
я так себе представляю этот вариант.
правда стоить будет раз в 10 дороже :)
6usd
мое уважение за рукоблудие и за то что не ищете лёгких путей ))
это не сложно
for (; pos > 90; pos -= 1) {
tilt.write(pos);
delay(15);
}
по одному градусу серву крутит с задержкой 15 мс
я голосую за умных не ленивых людей ))
тс молодец в любом случае
Лучше руками открывать/закрывать имхо :)
да и львиная доля времени ушла на разработку.
воплотить это имея все готовое — поделка выходного дня
PS. ESP8266 довольно мощная штука и программировать под нее не сложно, особенно если использовать среду arduino. Для данной статьи делается за вечер. Но проще готовые проекты в инете взять. Их довольно много.
Есть отличное решение, все то же самое, но никаких ограничений полета фантазии:
esp8266.ru/arduino-ide-esp8266/
или первоисточник
github.com/esp8266/Arduino
PS. Все давно придумано. Просто и красиво. А если хотите быстро и без знания программирования, тогда
первая ссылка www.google.com/search?ei=fq62Wu2mMomc_Qad-YuYDA&q=ESP8266+%D0%B6%D0%B0%D0%BB%D1%8E%D0%B7%D0%B8&oq=ESP8266+%D0%B6%D0%B0%D0%BB%D1%8E%D0%B7%D0%B8
Зря Вы думаете что я что-то пиарю, моя сфера деятельности лежит далеко за пределами esp и прочих поделок.
Это просто хобби. А раз хобби, то должно приносить удовольствие именно мне :)
И мой принцип — использовать готовые решения по максимуму для ускорения процесса и получения результата. Это касается и железок и софта.Я попросил Макса встроить в прошивку поддержку I2C шилда для мотора был послан. Потому что это «никому не нужно». Пришлось разбираться самому.
Так что насчет пиара прошивки это Вы зря.
Обидно даже :)
И у меня была проблема — солнце ближе к вечеру светило почти перпендикулярно окну. Поэтому и хотел так настроить жалюзи, чтобы они закрывали слепящее светило.
А вот в моем варианте нет интеграции в Умный Дом — управляю с ИК-пульта или кнопками из переделанного выключателя (мозг-ардуино ессно ))
движок такой:
местный пульт:
с обратной стороны вала потенциометр (хороший, советский — проволочный):
а вообще интеграция с умным домом мне нужна как раз для того чтобы избавиться от пультов.
когда я понял что количество пультов выросло настолько, что половина из них лежала с дохлыми батарейками — я понял, что что-то надо менять.
сейчас я вообще забыл как кнопки нажимать на выключателях, все работает или на движение в зависимости от условий или голосовыми командами через Amazon Echo.
А для управления упрямыми девайсами которым все равно надо ИК пульт есть Broadlink RM 3 управляемый тем же умным домом.
Сейчас работаю над реализацией голосовой команды: «Alexa, could you turn on Home Theater», которая в зависимости от условий освещения будет включать кучу железок, выключать свет, закрывать жалюзи кстати если светло сильно :)
Короче простор для фантазии огромный, вот времени только нет всем этим заниматься :(
Хорошая идея. Я свой экран >3.5м опускаю тоже с пульта (привод от подъемника стекла автомобиля).
Кстати избавился от многих пультов тем, что взял один с большим количеством кнопок >40 и запрограммировал свои устройства на нужные мне кнопки. Управляю всем одним пультом :)
Названия, марки, схема, подключение.
Чего названия?
Марка движка указана на фото.
Схема давно утеряна, но там просто:
1 Ардуино
2 движки
3 потенциометры на аналоговые входы
4 для управления электродвигателями микросхема L293D (содержит сразу два драйвера)
5 ИК-приемник
— Роскомнадзор собирается заблокировать почти 15 миллионов IP-адресов Amazon
IT-эксперт Михаил Климарев опубликовал документы, свидетельствующие о том, что Роскомнадзор приступает к эксперименту по блокировке доступа к двум подсетям облачных веб-сервисов компании Amazon (AWS). Читать дальше → m.geektimes.ru/post/299341/?utm_source=habrahabr&utm_medium=rss&utm_campaign=299341
Будем надеятся что все-таки вашим вовремя мозгов подвезут. :)
Сервис типа Google весьма обращает внимание на местную цензуру.
на тестовых жалюзях работал. На сколько хватит не знаю.
Хочу попробовать сделать с автономным питанием от 18650, Плюс добавить часы (чтобы на ночь жалюзи точно были закрыты), и добавить автоматики в виде двух сенсоров света, чтобы сравнивали освещенность внутри комнаты и на улице. Так как первый этаж и при более ярком свете в комнате с улицы всё видно. Но когда возьмусь не знаю.
Но к сожалению знаний в программировании нету(((
У меня есть такой, в жалюзи не лезет
Загнул ушки для крепления и вставил с торца жалюзи (внутрь не влезло), но за счет загнутых ушек держится.
Для соединения с валом жалюзи выточил муфты (а оказывается можно купить).
Видео youtu.be/N6GRJvhg8Bg
Но если жалюзи уже открыты до конца, то просто щелкает. Может и хорошо, не порвет жалюзи, но может и сдохнет. Пока всё в кучу так и не собрал, поэтому не скажу сколько они проработают.
С шаговым мотором ничего не будет, если механика выдержала, щелкать для него нормально ))
В основном интересуют наработки по аппаратной части. По выбору контроллера и логике работы каждый решает свои задачи согласно возможностям. Кто-то пойдет по пути упрощения, кто-то наоборот.
Для себя вижу так: два фотодатчика (наружный и внутренний) и модуль RTC.
Режим День: в светлое время (два условия: время от RTC + фотодатчик) жалюзи открывается, и в темное время закрывается когда в комнате включено освещение. При наличии только одного фотодатчика засветка его фонариком или фарами будет открывать жалюзи. Можно, конечно, просто ввести расписание по рассвету/закату, но так не интересно :)
Режим Ночь: закрытые жалюзи при внутреннем освещении, но может захотеться посмотреть на ночной город за окном, так что открывание по команде.
Я вот недавно со скуки сделал включение подсветки над умывальником, когда сенсорный смеситель начинает лить водичку.
Жене сказал что магия управляет :)
Может кто что-то хочет услышать из того что интересено или непонятно было по первой части — добавлю.
Видел когда-то реализацию подобного проекта с автономным питанием от солнечной панели.
Кстати, датчик вибрации можно вместе с сенсором на стекло поставить для периметра охраны.
И еще, функционал поднятия жалюзи (не открывания ламелей) у вас остался цел?
потребление померяю сегодня, отпишусь
А если автоматизировать :-), то реле с датчиком освещения.
жена рах в полгода стирает римские шторы, так их хоть легче постирать
Опишите, пжлст, подробней, как вы его там закрепили.
А я надумал датчик оборота конструктивно отделить от двигателя и надевать его на ось жалюзи, которая именно 4 мм. Заодно и угол датчика поворота устанавливать, чтобы мертвая зона не попала в рабочие углы.
Умный дом это хорошо. Но только если он уже есть или строится.
А если нет, то как по мне движка со стопами на концах траектории и переключателя «закрыть-открыть» хватит :)
Я за день могу несколько раз менять положение жалюзи как угол так и % закрытия окна.
И независимо от дня и солнца. То слепит (меняю угол), то печет (закрываю с отражающим углом) то ночью на луну с кровати обозревать охота… в общем ардуина повеситься все мои желания исполнять :), а «умного дома» пока нет.
Вообще больше не буду покупать жалюзи — отстой! Лучше римские шторы (стираются и дешевы), и окна с IR отражением.
А жалюзи даже помыть проблема (мои почти не снимаются, а на окне — грязь развозить). А чуть зацепил — помял — не выровнять — плати за ремонт…
Но пока висят воспользуюсь Вашим проектом. Только переделаю попроще под себя. :)
Спасибо!
Римские шторы классная штука. Но как актуатор туда приделать — пока открытый вопрос. Уж больно тяжело таскать всю конструкцию вверх, Тут нужен солидный движок с редуктором.
Не компилится код в Code designer, пишет ошибки, а железки все уже собрал.
Интересна вторая часть, Mqtt и интеграция.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.