Рулонные шторы на ардуино.

sheff
Offline
Зарегистрирован: 14.11.2017

Управление шторами при помощи ардуино и шаговых моторов. 

http://www.youtube.com/watch?v=P_dk7K4_4fI&t

sandr4
sandr4 аватар
Offline
Зарегистрирован: 11.02.2015

Как это всё реализовано? Особенно заинтересовали "кнопки".

sheff
Offline
Зарегистрирован: 14.11.2017

Кнопки использовал TTP223, вот ссылка на али.
Моторчики 5v с драйвером, еще ссылка.
 

sheff
Offline
Зарегистрирован: 14.11.2017

Сделал несколько фоток монтажа моторчиков к шторам...

Знакомый токарь выточил втулки вместо родного механизма.

Разбираем штору и вместо механизма вставляем втулку.

Собираем боковую часть и тонким сверлом делаем отверстие, для того чтобы отметить центр.

Замеряем диаметр той части втулки, под которую будем делать отверстие в боковой крышке.

Делаем отверстие.

Прикладываем моторчик и отмечаем где будет крепление.

Собираем всё на место...

Устанавливаем штору, подключаем и радуемся.

sir_kimas
Offline
Зарегистрирован: 01.08.2016

sheff пишет:

Сделал несколько фоток монтажа моторчиков к шторам...

Знакомый токарь выточил втулки вместо родного механизма.

Разбираем штору и вместо механизма вставляем втулку.

Собираем боковую часть и тонким сверлом делаем отверстие, для того чтобы отметить центр.

Замеряем диаметр той части втулки, под которую будем делать отверстие в боковой крышке.

Делаем отверстие.

Прикладываем моторчик и отмечаем где будет крепление.

Собираем всё на место...

Устанавливаем штору, подключаем и радуемся.

 

Молоток! :)

evgta
Offline
Зарегистрирован: 02.09.2016
sheff
Offline
Зарегистрирован: 14.11.2017

Согласен, моторчик крутит медленно, но солидно и зрелищно :)
Сейчас сделал замер - 50 сек полное открытие или закрытие.
Торопиться некуда, можно и не ждать....сама доедет и остановится.

pozdnyakov
Offline
Зарегистрирован: 16.01.2018

Фотки не грузятся, перезалей плз

sheff
Offline
Зарегистрирован: 14.11.2017

sheff пишет:

Управление шторами при помощи ардуино и шаговых моторов. 

http://www.youtube.com/watch?v=P_dk7K4_4fI&t

Видео доступно по ссылке: https://youtu.be/1ZVcHS72KFg

Схема подключения

//**********  (РЕЖИМ 1-ШАГ) Крутим с помощью сдвига --рабочая - крутит туда сюда без потери шагов - ускоряет - отключает катушки после бездействия
//PORTB - 8, 9, 10, 11 - Шаговик. && 12-кнопка Menu \ 13-Светодиод 1й штор.
//PORTD - 4, 5, 6, 7 - Шаговик. && 2-кнопка UP \ 3-кнопка DOWN
// А0-Светодиод 2й штор..
#include <EEPROM.h> 
#include <CyberLib.h>
#define uskor 3 //Задаем ускорение
//Здесь устанавливаем максимальное кол. шагов для штор
#define max_Sht1 28900
#define max_Sht2 27500
 
byte n1 = 1;// Сдвигаем 1 бит
byte n3 = 0x10;
bool f_timX = 0;
bool f_timZ = 0;
 
byte sped_Xt = uskor;//Начальная скорость
byte sped_X = 0; //Ускорение
byte sped_Zt = uskor;//Начальная скорость
byte sped_Z = 0; //Ускорение
 
bool f_run1X = 0;//Сброс после остановки 2 переменные.
unsigned long no_runX; //Переменная для прошедшего периода
 
bool f_run1Z = 0;//Сброс после остановки 2 переменные.
unsigned long no_runZ; //Переменная для прошедшего периода
// Переменные для кн.Menu
bool kn_menu;
bool f_menu;
bool f_Mpush;
bool f_Md;
uint8_t Menu = 1;
uint8_t temp_Menu;
bool kalib;
unsigned long menu_dreb;
unsigned long menu_klik;
// Переменные для кн.Up
bool kn_Up;
bool f_Up;
bool state_Up;
bool _UP;
uint32_t Up_dreb;
// Переменные для кн.Down
bool kn_Down;
bool f_Down;
bool state_Down;
bool _Down;
uint32_t Down_dreb;
//сбрасываем UP\Down
bool f_sbrosZ = 1;
bool f_sbrosX = 1;
 
uint32_t cur_time;//Миллис читаем один раз
uint32_t blink_time;//Мигаем в режиме калибровки
 
int Shtora1;
int Shtora2;
const int ton = 16;//пищалка
// чтение
int EEPROM_int_read(int addr) {   
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}
// запись
void EEPROM_int_write(int addr, int num) {
  if (EEPROM_int_read(addr)!= num){//если сохраняемое отличается
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
}
 
void setup() {
  // DDRB пин, 8,9,10,11 - Шаговик, pin 12- вход, 13- Выход
  DDRB = DDRB | B00101111;
  // pin 8,9,10,11,13 - выход в 0 а входы pin 12, - 0
  PORTB = B00000000;
  //  DDRD, подключенный к двигателю pin 4,5,6,7 как выход,pin2,3 Выход
  DDRD = DDRD | B11110000;
  // pin 4,5,6,7 - выход в 0 а входы pin 2,3 - 0
  PORTD = B00000000;//;
  D14_Out;  // Led_1
  D14_Low;
  D15_Out;  // Led_2
  D15_Low;
    pinMode(ton,OUTPUT);//пищалка
  //Serial.begin(9600);
  // Инициализировать TIMER1
  StartTimer1(Time_Closk, 2200);
      Shtora1 = EEPROM_int_read(0);
      Shtora2 = EEPROM_int_read(2);
}
void Beep() //короткий звук, переключение шторы
{
  tone(ton,500,500);
  delay(200);
  noTone(ton);
}
void Beep_long()  //длинный звук, вход и выход из режима калибровки "0"
{
  tone(ton,200,1000);
  delay(200);
  noTone(ton);
}
 
void Time_Closk() // Функция прерывания таймера
{
  f_timX = 1;
  f_timZ = 1;
}
 
//Функция вращения  dvigatel 1
void RunX (bool perem_X)
{
  f_sbrosX = 0;
  f_timX = 0;
  if (perem_X) {
    n1 = (n1 >> 1) | (n1 << 3); //Сдвигаем
    --Shtora1;
  }
  else {
    n1 = (n1 << 1) | (n1 >> 3); //Сдвигаем
    ++Shtora1;
  }
  n1 = 0x0F & n1; //Маскируем кнопки
  PORTB = (PORTB & 0xF0) | n1; //Очищаем Младшие биты и пишем туда n1
}
 
//Функция dvigatel 3
void RunZ (bool perem_Z)
{
  f_sbrosZ = 0;
  f_timZ = 0;
  if (perem_Z) {
    n3 = (n3 >> 1) | (n3 << 3); //Сдвигаем
    --Shtora2;
  }
  else {
    n3 = (n3 << 1) | (n3 >> 3); //Сдвигаем
    ++Shtora2;
  }
  n3 = 0xF0 & n3;//Маскируем
  PORTD = (PORTD & 0xF) | n3; //Очищаем старшие биты и пишем туда n3
}
 
void loop() {
 
  cur_time = millis();
  ///////////////////Проверка кнопки МЕНЮ - АНТИДРЕБЕЗГ
  if (D12_Read && !f_menu)
  {
    menu_dreb = cur_time;
    f_menu = 1;
  }
  if (!D12_Read)
  {
    kn_menu = 0;
    f_menu = 0;
  }
 
  if (f_menu && cur_time - menu_dreb >= 20)
  {
    kn_menu = 1;
    if (!f_Mpush) {
      menu_klik = cur_time;
      f_Mpush = 1;
    }
 
  }
//Был клик
if (f_Mpush && !kn_menu && cur_time - menu_klik < 1000) {
   if (_UP || _Down) {
    _UP = 0;
    _Down = 0;
  }
  else Menu++, Beep();     // Меняем
  if (Menu > 3) Menu = 1;
  f_Mpush = 0;
}
//Было нажатие
else if (f_Mpush && !kn_menu && cur_time - menu_klik > 1000) {
  Beep_long();
  kalib = !kalib; // Включаем калибровку
  f_Mpush = 0;
}  ///////////////////////Проверка кнопки UP - АНТИДРЕБЕЗГ
  if (D2_Read != f_Up) { //Если сигнал изменился
    f_Up = !f_Up;
    Up_dreb = cur_time;
  }
  if (kn_Up == D2_Read && cur_time - Up_dreb > 20) kn_Up = !D2_Read;
  // Было нажатие
  if (kn_Up && !state_Up) {
    if (_UP || _Down) {
      _UP = 0;
      _Down = 0;
      state_Up = 1;
    }
    else {
      _UP = !_UP;    // Меняем значение
      state_Up = 1;
    }
  }
  if (!kn_Up)state_Up = 0; // Отпустили
  ///////////////////////Проверка кнопки DOWN - АНТИДРЕБЕЗГ
  if (D3_Read != f_Down) { //Если сигнал изменился
    f_Down = !f_Down;
    Down_dreb = cur_time;
  }
  if (kn_Down == D3_Read && cur_time - Down_dreb > 20) kn_Down = !D3_Read;
  // Было нажатие
  if (kn_Down && !state_Down) {
    if (_UP || _Down) {
      _UP = 0;
      _Down = 0;
      state_Down = 1;
    }
    else {
      _Down = !_Down;    // Меняем значение
      state_Down = 1;
    }
  }
  if (!kn_Down)state_Down = 0; // Отпустили
  //////////////////////// С кнопками закончили продолжаем логику
  if (!kalib)
  {
    if (Menu != temp_Menu) {
      temp_Menu = Menu;
      switch (Menu) {
        case 1: D14_High; D15_Low; break;
        case 2: D14_Low; D15_High; break;
        case 3: D14_High; D15_High; break;
      }
    }
  }
  else {
    if (cur_time - blink_time >= 300)
    {
      blink_time = cur_time;
      switch (Menu) {
        case 1: D14_Inv; D15_Low; break;
        case 2: D14_Low; D15_Inv; break;
        case 3: D14_Inv; D15_Inv; break;
      }
    }
  }
  /////////////////////////// Запуск 1го двигателя если " perem_X != 0 "
  if (f_timX) {
    if (_UP || _Down) {
      if (Menu != 2) {
        if (!sped_X) {
          if (!kalib) { //Калибровка отк.
            if (_Down && Shtora1 < max_Sht1) {
              RunX(0);
            }
            if (_UP && Shtora1 > 0) {
              RunX(1);
            }
          }
          else { //Калибровка вкл.
            if (_Down) {
              Shtora1 = 0;
              RunX(0);
            }
            if (_UP) {
              Shtora1 = 1;
              RunX(1);
            }
          }
          //Три поверки для разгона
          if (sped_Xt > 0) {
            --sped_Xt;
            sped_X = sped_Xt;
            // f_timX = 0;
          }
        }
        else {
          --sped_X;
          f_timX = 0;
        }
      }
    }////
    else {
      sped_Xt = uskor;
      sped_X = 0;
    }
  }
  else { //Для снятия напряжения
    f_run1X = 1;
    no_runX = cur_time;
  }
  /////////////////Запуск 3го двигателя если " perem_Z != 0 "
  if (f_timZ) {
    if (_UP || _Down) {
      if (Menu != 1) {
        if (!sped_Z) {
          if (!kalib)//Калибровка отк.
          {
            if (_UP && Shtora2 < max_Sht2) {
              RunZ(0);
            }
            if (_Down && Shtora2 > 0) {
              RunZ(1);
            }
          }
          else {//Калибровка Вкл.
            if (_UP) {
              Shtora2 = 0;
              RunZ(0);
            }
            if (_Down) {
              Shtora2 = 1;
              RunZ(1);
            }
          }
          //Три поверки для разгона
          if (sped_Zt > 0) {
            --sped_Zt;
            sped_Z = sped_Zt;
            f_timZ = 0;
          }
        }
        else {
          --sped_Z;
          f_timZ = 0;
        }
      }
    }////
    else {
      sped_Zt = uskor;
      sped_Z = 0;
    }
  }
  else { //Для снятия напряжения
    f_run1Z = 1;
    no_runZ = cur_time;
  }
  //Возврат по достижению конечной точки
  if (f_sbrosZ && f_sbrosX) {
    _UP = 0;
    _Down = 0;
  }
  //Снимаем напряжение с катушек двигателя X
  if (f_run1X && cur_time - no_runX >= 1000)
  {
    f_run1X = 0;
    PORTB &= 0xF0;
    f_sbrosX = 1;
    if (EEPROM_int_read(0)!=Shtora1)
    {
     EEPROM_int_write(0, Shtora1); // адрес 0 (+2 байта)
    }
  }
  //Снимаем напряжение с катушек двигателя Z
  if (f_run1Z && cur_time - no_runZ >= 1000)
  {
    f_run1Z = 0;
    PORTD &= 0xF;
    f_sbrosZ = 1;
    if (EEPROM_int_read(2)!=Shtora2)
    {
     EEPROM_int_write(2, Shtora2); // адрес 0 (+2 байта)
    }
  }
}

 

adread
Offline
Зарегистрирован: 23.01.2018

Хорошая робота, автор молодец.

yucan
Offline
Зарегистрирован: 20.04.2015

sheff пишет:

Торопиться некуда, можно и не ждать....сама доедет и остановится.

Здравствуйте! Подскажите, по какому событию происходит останов двигателей?

И как прикрутить к проекту фотодатчик для автоматизации процесса? (закат\рассвет)

sheff
Offline
Зарегистрирован: 14.11.2017

yucan пишет:

Здравствуйте! Подскажите, по какому событию происходит останов двигателей?

И как прикрутить к проекту фотодатчик для автоматизации процесса? (закат\рассвет)


Доброй ночи. Двигатели останавливаются при нажатии любой кнопки или по достижении конечного положения.
Я еще новичок в ардуино, с фоторезистором еще не разбирался (видел обзоры на ютубе).
Вот в этой ветке мне помогли с написанием скетча, задайте вопрос там, возможно Вам подскажут.
http://arduino.ru/forum/programmirovanie/proshu-pomoshchi-problema-s-odnovremennoi-rabotoi-shagovykh-dvigatelei

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Супер!
Вопрос:  Хватает ли крутящего момента для поднятия штор.
Почему задаю этот вопрос?
Этот шаговичёк куплен был лет 5 назад.
Даже два.
И даже где-то потерялись дома.
При проверке выяснилось что оба пробуксовывают внутри редуктора,
то есть мотор крутится, а вал можно остановить  при достаточно небольшом усилии.
Такие шаговики видел в кондиционерах на качающемся дефлекторе и понятно что там момент не главное.

Даже помню что один переделывал в биполярник......

Тоже думал сделать, но мои шторы в два раза длиннее.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011
sheff
Offline
Зарегистрирован: 14.11.2017

trembo пишет:

Супер!
Вопрос:  Хватает ли крутящего момента для поднятия штор.
Почему задаю этот вопрос?
Этот шаговичёк куплен был лет 5 назад.
Даже два.
И даже где-то потерялись дома.
При проверке выяснилось что оба пробуксовывают внутри редуктора,
то есть мотор крутится, а вал можно остановить  при достаточно небольшом усилии.
Такие шаговики видел в кондиционерах на качающемся дефлекторе и понятно что там момент не главное.

Даже помню что один переделывал в биполярник......

Тоже думал сделать, но мои шторы в два раза длиннее.

Пробуксовывать может из-за недостатка питания или от большой скорости.

У меня сейчас питание 6 вольт и на входе каждого драйвера стоят кондеры на 1000мкФ, штора едет одинаково вверх и вниз. Когда эксперементировал со скоростью было так, что вниз штора опускается быстро, а вверх даже стронуться не может - подтолкнешь, тогда тянет. Вообщем в скетче оптимальный вариант.

gzp13
Offline
Зарегистрирован: 06.04.2015

А я вот по бырику сварганил вот такой электромеханизм управления обычными шторами под управлением ардуино)

https://www.youtube.com/watch?v=Tx47Dj791JU&feature=youtu.be

sheff
Offline
Зарегистрирован: 14.11.2017

gzp13 пишет:

А я вот по бырику сварганил вот такой электромеханизм управления обычными шторами под управлением ардуино)

Прикольно. Шустренько тянет, только для моих нужд великоват малость.

gzp13
Offline
Зарегистрирован: 06.04.2015

Скорость можно регулировать в скетче, но чем медленнее тем шумнее слышно работу мотора.

sheff
Offline
Зарегистрирован: 14.11.2017

Решил добавить еще парочку фоток.
К драйверу ULN2003 идеально подходит коробочка от телефонной розетки

А вот так выглядит плата под подоконником

С обратной стороны расположилась кренка на 6 вольт

А вот так выглядят кнопки под пластиковым уголком

RizONE
Offline
Зарегистрирован: 22.03.2018

Доброго!

Проект завершен или еще делается? На работающий скетч можно глянуть?

sheff
Offline
Зарегистрирован: 14.11.2017

RizONE пишет:

Доброго!

Проект завершен или еще делается? На работающий скетч можно глянуть?

Пост #8, под схемой работающий скетч.

Bob_
Offline
Зарегистрирован: 13.07.2018

А как запрограммированы кнопки. В режиме кнопки или выключатель с фиксацией? Просто замыкают на землю при нажатии?

sheff
Offline
Зарегистрирован: 14.11.2017

Bob_ пишет:

А как запрограммированы кнопки. В режиме кнопки или выключатель с фиксацией? Просто замыкают на землю при нажатии?


Работает как кнопка, а программа отслеживает длинное или короткое нажатие.

Bob_
Offline
Зарегистрирован: 13.07.2018

А как организовано питание всей системы?

sheff
Offline
Зарегистрирован: 14.11.2017

Bob_ пишет:

А как организовано питание всей системы?

Обычный адаптер на 9 вольт.

Вот ссылка на али https://ru.aliexpress.com/item/1pcs-AC-100V-240V-Converter-Adapter-DC-9V-1A-Power-Supply-EU-Plug-DC-5-5mm/32769484388.html?spm=a2g0s.9042311.0.0.274233ed35FFzP

Bob_
Offline
Зарегистрирован: 13.07.2018

sheff пишет:

Bob_ пишет:

А как организовано питание всей системы?

Обычный адаптер на 9 вольт.

На vin как я понимаю. Тогда получается 9 вольт идет и на контроллеры моторов? 

sheff
Offline
Зарегистрирован: 14.11.2017

Bob_ пишет:

sheff пишет:

Bob_ пишет:

А как организовано питание всей системы?

Обычный адаптер на 9 вольт.

На vin как я понимаю. Тогда получается 9 вольт идет и на контроллеры моторов? 

На моторы питание идет через кренку на 6 вольт.

Bob_
Offline
Зарегистрирован: 13.07.2018

Собрал все по схеме. Все работает, но есть странность. Провожу калибровку обоих штор ноль наверху. Перехожу в рабочий режим. При нажатии вниз - едет только первая штора. Доезжает до низа. Вторая стоит. При нажатии вверх - первая нормально, а вторая заматывается на установленное количество витков. То есть получается что у одной шторы ноль наверху, а у второй ноль внизу. Что то не так в скетче?

sheff
Offline
Зарегистрирован: 14.11.2017

Да, такая "особенность", моторы стоят зеркально. У левой шторы ноль внизу. Один раз то и надо настроить, потом всё работает нормально. 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

sheff пишет:

RizONE пишет:

Доброго!

Проект завершен или еще делается? На работающий скетч можно глянуть?

Пост #8, под схемой работающий скетч.

Добавлю и себе в закладки

Bob_
Offline
Зарегистрирован: 13.07.2018

sheff пишет:

Один раз то и надо настроить, потом всё работает нормально. 

Ну это да. Особо не напрягает. Эх, еще бы фоторезистор прикрутить.

Nickakoi
Offline
Зарегистрирован: 27.07.2018

Хвала автору! Всё прекрасно работает, моторы поставил на 12в. Дайте совет - буду делать второй экземпляр, там где балкон. Окно большое, штора длинная, один мотор не осилит, поставлю два с разных сторон. Как подключать два мотора? 1. Два мотора, два драйвера входы объеденить и к arduino. Или 2. Два мотора запараллелить и к одному драйверу.

Bob_
Offline
Зарегистрирован: 13.07.2018

Прикрутил к скетчу датчик освещенности. Цифровой выход модуля повесил на А3

Опыта мало. Наверняка можно код сделать правильнее, но как получилось. По крайней мере работает. Утром открывает, вечером закрывает. Когда начинает двигатся, если нажать на любую кнопку, то движение остановится и не возобновляется до следующей смены состояния освещенности. И чуть подправил скетч. Нулевая точка обоих штор теперь наверху. Если надо сделать на одном моторе обратное вращение, надо зазеркалить подключение самого мотора.

//**********  (РЕЖИМ 1-ШАГ) Крутим с помощью сдвига --рабочая - крутит туда сюда без потери шагов - ускоряет - отключает катушки после бездействия
//PORTB - 8, 9, 10, 11 - Шаговик.  
//PORTD - 4, 5, 6, 7 - Шаговик.  
// 12-кнопка Menu
// 2-кнопка UP
// 3-кнопка DOWN
// A1-Светодиод 1й штор
// А0-Светодиод 2й штор
// А2-Пищалка
// А3-Фотомодуль, цифровой выход
#include <EEPROM.h> 
#include <CyberLib.h>
#define uskor 3 //Задаем ускорение
//Здесь устанавливаем максимальное кол. шагов для штор
#define max_Sht1 29500
#define max_Sht2 29500
#define PH_PIN 17    //цифровой выход фотомодуля на А3 

byte n1 = 1;// Сдвигаем 1 бит
byte n3 = 0x10;
bool f_timX = 0;
bool f_timZ = 0;
 
byte sped_Xt = uskor;//Начальная скорость
byte sped_X = 0; //Ускорение
byte sped_Zt = uskor;//Начальная скорость
byte sped_Z = 0; //Ускорение

bool f_run1X = 0;//Сброс после остановки 2 переменные.
unsigned long no_runX; //Переменная для прошедшего периода
 
bool f_run1Z = 0;//Сброс после остановки 2 переменные.
unsigned long no_runZ; //Переменная для прошедшего периода
// Переменные для кн.Menu
bool kn_menu;
bool f_menu;
bool f_Mpush;
bool f_Md;
uint8_t Menu = 1;
uint8_t temp_Menu;
bool kalib;
unsigned long menu_dreb;
unsigned long menu_klik;
// Переменные для кн.Up
bool kn_Up;
bool f_Up;
bool state_Up;
bool _UP;
uint32_t Up_dreb;
// Переменные для кн.Down
bool kn_Down;
bool f_Down;
bool state_Down;
bool _Down;
uint32_t Down_dreb;

// переменные для фотомодуля
byte timePh = 100; // время устойчивого состояния фотомодуля
byte  phCount1= 0; 
byte  phCount2= 0;  // счетчики подтверждений состояния  
bool old_Ph;
bool new_Ph; 

//сбрасываем UP\Down 
bool f_sbrosZ = 1;
bool f_sbrosX = 1;

uint32_t cur_time;//Миллис читаем один раз
uint32_t blink_time;//Мигаем в режиме калибровки
 
int Shtora1;
int Shtora2;
const int ton = 16;//пищалка
// чтение
int EEPROM_int_read(int addr) {   
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}
// запись
void EEPROM_int_write(int addr, int num) {
  if (EEPROM_int_read(addr)!= num){//если сохраняемое отличается
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
}
 
void setup() {
  // DDRB пин, 8,9,10,11 - Шаговик, pin 12- вход, 13- Выход
  DDRB = DDRB | B00101111;
  // pin 8,9,10,11,13 - выход в 0 а входы pin 12, - 0
  PORTB = B00000000;
  //  DDRD, подключенный к двигателю pin 4,5,6,7 как выход,pin2,3 Выход
  DDRD = DDRD | B11110000;
  // pin 4,5,6,7 - выход в 0 а входы pin 2,3 - 0
  PORTD = B00000000;//;
/////
  
//////  
  D14_Out;  // Led_1
  D14_Low;
  D15_Out;  // Led_2
  D15_Low;
    pinMode(ton,OUTPUT);//пищалка
  //Serial.begin(9600);
  // Инициализировать TIMER1
  StartTimer1(Time_Closk, 2800);
      Shtora1 = EEPROM_int_read(0);
      Shtora2 = EEPROM_int_read(2);
}
void Beep() //короткий звук, переключение шторы
{
  tone(ton,500,500);
  delay(200);
  noTone(ton);
}
void Beep_long()  //длинный звук, вход и выход из режима калибровки "0"
{
  tone(ton,200,1000);
  delay(200);
  noTone(ton);
}
 
void Time_Closk() // Функция прерывания таймера
{
  f_timX = 1;
  f_timZ = 1;
}
 
//Функция вращения  dvigatel 1
void RunX (bool perem_X)
{
  f_sbrosX = 0;
  f_timX = 0;
  if (perem_X) {
    n1 = (n1 >> 1) | (n1 << 3); //Сдвигаем
    --Shtora1;
  }
  else {
    n1 = (n1 << 1) | (n1 >> 3); //Сдвигаем
    ++Shtora1;
  }
  n1 = 0x0F & n1; //Маскируем кнопки
  PORTB = (PORTB & 0xF0) | n1; //Очищаем Младшие биты и пишем туда n1
}
 
//Функция dvigatel 3
void RunZ (bool perem_Z)
{
  f_sbrosZ = 0;
  f_timZ = 0;
  if (perem_Z) {
    n3 = (n3 >> 1) | (n3 << 3); //Сдвигаем
    --Shtora2;
  }
  else {
    n3 = (n3 << 1) | (n3 >> 3); //Сдвигаем
    ++Shtora2;
  }
  n3 = 0xF0 & n3;//Маскируем
  PORTD = (PORTD & 0xF) | n3; //Очищаем старшие биты и пишем туда n3
}
 
void loop() {
 
  cur_time = millis();
  ///////////////////Проверка кнопки МЕНЮ - АНТИДРЕБЕЗГ
  if (D12_Read && !f_menu)
  {
    menu_dreb = cur_time;
    f_menu = 1;
  }
  if (!D12_Read)
  {
    kn_menu = 0;
    f_menu = 0;
  }
 
  if (f_menu && cur_time - menu_dreb >= 20)
  {
    kn_menu = 1;
    if (!f_Mpush) {
      menu_klik = cur_time;
      f_Mpush = 1;
    }
 
  }
//Был клик
if (f_Mpush && !kn_menu && cur_time - menu_klik < 1000) {
   if (_UP || _Down) {
    _UP = 0;
    _Down = 0;
  }
  else Menu++, Beep();     // Меняем
  if (Menu > 3) Menu = 1;
  f_Mpush = 0;
}
//Было нажатие
else if (f_Mpush && !kn_menu && cur_time - menu_klik > 1000) {
  Beep_long();
  kalib = !kalib; // Включаем калибровку
  f_Mpush = 0;
}  ///////////////////////Проверка кнопки UP - АНТИДРЕБЕЗГ
  if (D2_Read != f_Up) { //Если сигнал изменился
    f_Up = !f_Up;
    Up_dreb = cur_time;
  }
  if (kn_Up == D2_Read && cur_time - Up_dreb > 20) kn_Up = !D2_Read;
  // Было нажатие
  if (kn_Up && !state_Up) {
    if (_UP || _Down) {
      _UP = 0;
      _Down = 0;
      state_Up = 1;
    }
    else {
      _UP = !_UP;    // Меняем значение
      state_Up = 1;
    }
  }
  if (!kn_Up)state_Up = 0; // Отпустили
  ///////////////////////Проверка кнопки DOWN - АНТИДРЕБЕЗГ
  if (D3_Read != f_Down) { //Если сигнал изменился
    f_Down = !f_Down;
    Down_dreb = cur_time;
  }
  if (kn_Down == D3_Read && cur_time - Down_dreb > 20) kn_Down = !D3_Read;
  // Было нажатие
  if (kn_Down && !state_Down) {
    if (_UP || _Down) {
      _UP = 0;
      _Down = 0;
      state_Down = 1;
    }
    else {
      _Down = !_Down;    // Меняем значение
      state_Down = 1;
    }
  }
  if (!kn_Down)state_Down = 0; // Отпустили
  //////////////////////// С кнопками закончили продолжаем логику
  if (!kalib)
  {
    if (Menu != temp_Menu) {
      temp_Menu = Menu;
      switch (Menu) {
          case 1: D14_High; D15_High; break;
          case 2: D14_Low; D15_High; break;
          case 3: D14_High; D15_Low; break;
      }
    }
  }
  else {
    if (cur_time - blink_time >= 300)
    {
      blink_time = cur_time;
      switch (Menu) {
        case 1: D14_Inv; D15_Inv; break;
        case 2: D14_Low; D15_Inv; break;
        case 3: D14_Inv; D15_Low; break;
      }
    }
  }
  /////////////////////////////////
 
  // блок фотомодуля

    new_Ph = D17_Read;
    if ((new_Ph ==LOW)&&(old_Ph != new_Ph)) {
     phCount1++;
     }
     else
     phCount1=0;
     
       if ( phCount1 >= timePh) {    
        old_Ph = new_Ph;
        phCount1 = 0;
        _UP = 1;
        _Down = 0;
       }


  if ((new_Ph ==HIGH)&&(old_Ph != new_Ph)) {
     phCount2++;
     }
     else
     phCount2= 0;
     
       if ( phCount2 >= timePh) {    
        old_Ph = new_Ph;
        phCount2= 0;
        _Down = 1;
        _UP = 0;
       }
  
       
 
  /////////////////////////// Запуск 1го двигателя если " perem_X != 0 "
  if (f_timX) {
       
   if (_UP || _Down) {
      if (Menu != 2) {
        if (!sped_X) {
          if (!kalib) { //Калибровка отк.
            if (_Down && Shtora1 < max_Sht1) {
              RunX(0);
            }
            if (_UP && Shtora1 > 0) {
              RunX(1);
            }
            
          }
            
          else { //Калибровка вкл.
            if (_Down) {
              Shtora1 = 0;
              RunX(0);
            }
            if (_UP) {
              Shtora1 = 1;
              RunX(1);
            }
          }
          //Три поверки для разгона
          if (sped_Xt > 0) {
            --sped_Xt;
            sped_X = sped_Xt;
            // f_timX = 0;
          }
        }
        else {
          --sped_X;
          f_timX = 0;
        }
      }
    }////
    else {
      sped_Xt = uskor;
      sped_X = 0;
    }
  }
  else { //Для снятия напряжения
    f_run1X = 1;
    no_runX = cur_time;
  }
  /////////////////Запуск 3го двигателя если " perem_Z != 0 "
  if (f_timZ){
    if (_UP || _Down) {
      if (Menu != 3) {
        if (!sped_Z) {
          if (!kalib)//Калибровка отк.
          {
            if (_Down && Shtora2 < max_Sht2) {
              RunZ(0);
            }
            if (_UP && Shtora2 > 0) {
              RunZ(1);
            }
            }
             
          else {//Калибровка Вкл.
            if (_Down) {
              Shtora2 = 0;
              RunZ(0);
            }
            if (_UP) {
              Shtora2 = 1;
              RunZ(1);
            }
           }
           //Три поверки для разгона
          if (sped_Zt > 0) {
            --sped_Zt;
            sped_Z = sped_Zt;
            f_timZ = 0;
          }
        }
        else {
          --sped_Z;
          f_timZ = 0;
        }
      }
    }////
    else {
      sped_Zt = uskor;
      sped_Z = 0;
    }
  }
  else { //Для снятия напряжения
    f_run1Z = 1;
    no_runZ = cur_time;
  }
  //Возврат по достижению конечной точки
  if (f_sbrosZ && f_sbrosX) {
    _UP = 0;
    _Down = 0;
    }
  //Снимаем напряжение с катушек двигателя X
  if (f_run1X && cur_time - no_runX >= 1000)
  {
    f_run1X = 0;
    PORTB &= 0xF0;
    f_sbrosX = 1;
    if (EEPROM_int_read(0)!=Shtora1)
    {
     EEPROM_int_write(0, Shtora1); // адрес 0 (+2 байта)
    }
  }
  //Снимаем напряжение с катушек двигателя Z
  if (f_run1Z && cur_time - no_runZ >= 1000)
  {
    f_run1Z = 0;
    PORTD &= 0xF;
    f_sbrosZ = 1;
    if (EEPROM_int_read(2)!=Shtora2)
    {
     EEPROM_int_write(2, Shtora2); // адрес 0 (+2 байта)
    }
  }
}

PS У меня одна штора шире и соответственно тяжелее чем вторая. Поэтому пришлось немного уменьшить скорость, а то были пропуски шагов. В авторском варианте 2,2 мс, у меня 2,8 мс. Тут можно поиграться при желании.

yucan
Offline
Зарегистрирован: 20.04.2015

Bob_ пишет:

Прикрутил к скетчу датчик освещенности. Цифровой выход модуля повесил на А3

На  BH1750 не похож. Что за датчик?

yucan
Offline
Зарегистрирован: 20.04.2015

LPC810 похоже

Bob_
Offline
Зарегистрирован: 13.07.2018

Модуль с Алиэкспресса. https://ru.aliexpress.com/item/Photosensitive-Sensor-Module-Light-Detection-Module-for-Arduino/32248249658.html?spm=a2g0s.9042311.0.0.274233edYVnL7B

Не важно какой модуль. Надо только что бы был цифровой выход. Этот дает 1 - днем, 0 - ночью.

alex1978
alex1978 аватар
Offline
Зарегистрирован: 09.09.2017

Отлично, надо тоже забабахать

ronixx
ronixx аватар
Offline
Зарегистрирован: 20.12.2018

gzp13 пишет:

А я вот по бырику сварганил вот такой электромеханизм управления обычными шторами под управлением ардуино)

https://www.youtube.com/watch?v=Tx47Dj791JU&feature=youtu.be


Как реализовали крепление штор к шаговым ? Сбросьте фото пожалуйста
artur.gromyko@yandex.ru

Vlad55
Offline
Зарегистрирован: 27.03.2019

Двигатели останавливаются по достижении конечного положения.как вы нашли конечное положение шторы

ivankd2
Offline
Зарегистрирован: 24.09.2020

Всем привет.Собираюсь сделать такие же шторы. Купил шаговые 28ИНО-48 на 12вольт,но они тоже как то не айс тянут. По документации эти шаговики на 400 грамм тяги. Вытащил перемычку с драйвера и запитал 12в поставив + на 4-ю ногу драйвера. Стал тянуть 700гр. Но пришла идея установить вместо шаговых горелые микросервоприводы SG90. По тяге они аж на 4кг идут и на 5 вольт крутят довольно таки быстро. На одну минуту работы, думаю их хватит,что бы не перегрелись. Есть еще горелый серво MG995 на 7кг,но он жутко шумный. Только вот осталось крепление и скетч переделать... Подсобите пожалуйста со скетчем)

Xumuk
Xumuk аватар
Offline
Зарегистрирован: 03.03.2016

Vlad55 пишет:
Двигатели останавливаются по достижении конечного положения.как вы нашли конечное положение шторы

как вариант можно считать шаги двигателя. Например задаешь начальное положение, потом ручками до нужного момента открываешь и так же фиксируешь в прошивке и он уже дальше стольки шагов просто не будет ехать. Где-то был проект с похожей функцией. Может у автора так же

Jenz
Offline
Зарегистрирован: 04.02.2021

Здравствуйте а подскажите как происходит процес калибровки. Нигде не могу найти

Nickakoi
Offline
Зарегистрирован: 27.07.2018

Коротким нажатием меню выбрать мотор. Калибровка - длинное нажатие, замигает светодиод и изменится звук сигнала. Кнопками доехать до нужного положения и опять длинное нажатие.

Jenz
Offline
Зарегистрирован: 04.02.2021

Спасибо

Jenz
Offline
Зарегистрирован: 04.02.2021

пришлите пожалуйста архив с рабочим скетчем и библиотеками jenz@list.ru . При загрузке выдает ошибку

 

shtoru:5:5: error: stray '#' in program
 
 005 #include <EEPROM.h>
 
     ^
 
shtoru:6:5: error: stray '#' in program
 
 006 #include <CyberLib.h>
 
     ^
 
shtoru:7:5: error: stray '#' in program
 
 007 #define uskor 3 //Задаем ускорение
 
     ^
 
shtoru:8:1: error: invalid digit "8" in octal constant
 
 008 //Здесь устанавливаем максимальное кол. шагов для штор
 
 ^~~
 
shtoru:9:1: error: invalid digit "9" in octal constant
 
 009 #define max_Sht1 28900
 
 ^~~
 
shtoru:9:5: error: stray '#' in program
 
 009 #define max_Sht1 28900
 
     ^
 
shtoru:10:5: error: stray '#' in program
 
 010 #define max_Sht2 27900
 
     ^
 
shtoru:18:1: error: invalid digit "8" in octal constant
 
 018 byte sped_X = 0; //Ускорение
 
 ^~~
 
shtoru:19:1: error: invalid digit "9" in octal constant
 
 019 byte sped_Zt = uskor;//Начальная скорость
 
 ^~~
 
shtoru:28:1: error: invalid digit "8" in octal constant
 
 028 bool kn_menu;
 
 ^~~
 
shtoru:29:1: error: invalid digit "9" in octal constant
 
 029 bool f_menu;
 
 ^~~
 
shtoru:38:1: error: invalid digit "8" in octal constant
 
 038 bool kn_Up;
 
 ^~~
 
shtoru:39:1: error: invalid digit "9" in octal constant
 
 039 bool f_Up;
 
 ^~~
 
shtoru:48:1: error: invalid digit "8" in octal constant
 
 048 uint32_t Down_dreb;
 
 ^~~
 
shtoru:49:1: error: invalid digit "9" in octal constant
 
 049 //сбрасываем UP\Down
 
 ^~~
 
shtoru:58:1: error: invalid digit "8" in octal constant
 
 058 const int ton = 16;//пищалка
 
 ^~~
 
shtoru:59:1: error: invalid digit "9" in octal constant
 
 059 // чтение
 
 ^~~
 
shtoru:68:1: error: invalid digit "8" in octal constant
 
 068  if (EEPROM_int_read(addr)!= num){//если сохраняемое отличается
 
 ^~~
 
shtoru:69:1: error: invalid digit "9" in octal constant
 
 069  byte raw[2];
 
 ^~~
 
shtoru:78:1: error: invalid digit "8" in octal constant
 
 078  // pin 8,9,10,11,13 - выход в 0 а входы pin 12, - 0
 
 ^~~
 
shtoru:79:1: error: invalid digit "9" in octal constant
 
 079  PORTB = B00000000;
 
 ^~~
 
shtoru:80:1: error: invalid digit "8" in octal constant
 
 080  //  DDRD, подключенный к двигателю pin 4,5,6,7 как выход,pin2,3 Выход
 
 ^~~
 
shtoru:81:1: error: invalid digit "8" in octal constant
 
 081  DDRD = DDRD | B11110000;
 
 ^~~
 
shtoru:82:1: error: invalid digit "8" in octal constant
 
 082  // pin 4,5,6,7 - выход в 0 а входы pin 2,3 - 0
 
 ^~~
 
shtoru:83:1: error: invalid digit "8" in octal constant
 
 083  PORTD = B00000000;//;
 
 ^~~
 
shtoru:84:1: error: invalid digit "8" in octal constant
 
 084  D14_Out;  // Led_1
 
 ^~~
 
shtoru:85:1: error: invalid digit "8" in octal constant
 
 085  D14_Low;
 
 ^~~
 
shtoru:86:1: error: invalid digit "8" in octal constant
 
 086  D15_Out;  // Led_2
 
 ^~~
 
shtoru:87:1: error: invalid digit "8" in octal constant
 
 087  D15_Low;
 
 ^~~
 
shtoru:88:1: error: invalid digit "8" in octal constant
 
 088    pinMode(ton,OUTPUT);//пищалка
 
 ^~~
 
shtoru:89:1: error: invalid digit "9" in octal constant
 
 089  //Serial.begin(9600);
 
 ^~~
 
shtoru:90:1: error: invalid digit "9" in octal constant
 
 090  // Инициализировать TIMER1
 
 ^~~
 
shtoru:91:1: error: invalid digit "9" in octal constant
 
 091  StartTimer1(Time_Closk, 2200);
 
 ^~~
 
shtoru:92:1: error: invalid digit "9" in octal constant
 
 092      Shtora1 = EEPROM_int_read(0);
 
 ^~~
 
shtoru:93:1: error: invalid digit "9" in octal constant
 
 093      Shtora2 = EEPROM_int_read(2);
 
 ^~~
 
shtoru:94:1: error: invalid digit "9" in octal constant
 
 094 }
 
 ^~~
 
shtoru:95:1: error: invalid digit "9" in octal constant
 
 095 void Beep() //короткий звук, переключение шторы
 
 ^~~
 
shtoru:96:1: error: invalid digit "9" in octal constant
 
 096 {
 
 ^~~
 
shtoru:97:1: error: invalid digit "9" in octal constant
 
 097  tone(ton,500,500);
 
 ^~~
 
shtoru:98:1: error: invalid digit "9" in octal constant
 
 098  delay(200);
 
 ^~~
 
shtoru:99:1: error: invalid digit "9" in octal constant
 
 099  noTone(ton);
 
 ^~~
 
shtoru:1:1: error: expected unqualified-id before numeric constant
 
 001//**********  (РЕЖИМ 1-ШАГ) Крутим с помощью сдвига --рабочая - крутит туда сюда без потери шагов - ускоряет - отключает катушки после бездействия
 
 ^~~
 
shtoru:13:1: error: expected unqualified-id before numeric constant
 
 013 byte n3 = 0x10;
 
 ^~~
 
shtoru:14:1: error: expected unqualified-id before numeric constant
 
 014 bool f_timX = 0;
 
 ^~~
 
shtoru:15:1: error: expected unqualified-id before numeric constant
 
 015 bool f_timZ = 0;
 
 ^~~
 
shtoru:16:1: error: expected unqualified-id before numeric constant
 
 016
 
 ^~~
 
shtoru:18:1: error: expected unqualified-id before numeric constant
 
 018 byte sped_X = 0; //Ускорение
 
 ^~~
 
shtoru:19:1: error: expected unqualified-id before numeric constant
 
 019 byte sped_Zt = uskor;//Начальная скорость
 
 ^~~
 
shtoru:20:1: error: expected unqualified-id before numeric constant
 
 020 byte sped_Z = 0; //Ускорение
 
 ^~~
 
shtoru:21:1: error: expected unqualified-id before numeric constant
 
 021
 
 ^~~
 
shtoru:23:1: error: expected unqualified-id before numeric constant
 
 023 unsigned long no_runX; //Переменная для прошедшего периода
 
 ^~~
 
shtoru:24:1: error: expected unqualified-id before numeric constant
 
 024
 
 ^~~
 
shtoru:26:1: error: expected unqualified-id before numeric constant
 
 026 unsigned long no_runZ; //Переменная для прошедшего периода
 
 ^~~
 
shtoru:27:1: error: expected unqualified-id before numeric constant
 
 027 // Переменные для кн.Menu
 
 ^~~
 
shtoru:29:1: error: expected unqualified-id before numeric constant
 
 029 bool f_menu;
 
 ^~~
 
shtoru:30:1: error: expected unqualified-id before numeric constant
 
 030 bool f_Mpush;
 
 ^~~
 
shtoru:31:1: error: expected unqualified-id before numeric constant
 
 031 bool f_Md;
 
 ^~~
 
shtoru:32:1: error: expected unqualified-id before numeric constant
 
 032 uint8_t Menu = 1;
 
 ^~~
 
shtoru:33:1: error: expected unqualified-id before numeric constant
 
 033 uint8_t temp_Menu;
 
 ^~~
 
shtoru:34:1: error: expected unqualified-id before numeric constant
 
 034 bool kalib;
 
 ^~~
 
shtoru:35:1: error: expected unqualified-id before numeric constant
 
 035 unsigned long menu_dreb;
 
 ^~~
 
shtoru:36:1: error: expected unqualified-id before numeric constant
 
 036 unsigned long menu_klik;
 
 ^~~
 
shtoru:37:1: error: expected unqualified-id before numeric constant
 
 037 // Переменные для кн.Up
 
 ^~~
 
shtoru:39:1: error: expected unqualified-id before numeric constant
 
 039 bool f_Up;
 
 ^~~
 
shtoru:40:1: error: expected unqualified-id before numeric constant
 
 040 bool state_Up;
 
 ^~~
 
shtoru:41:1: error: expected unqualified-id before numeric constant
 
 041 bool _UP;
 
 ^~~
 
shtoru:42:1: error: expected unqualified-id before numeric constant
 
 042 uint32_t Up_dreb;
 
 ^~~
 
shtoru:43:1: error: expected unqualified-id before numeric constant
 
 043 // Переменные для кн.Down
 
 ^~~
 
shtoru:45:1: error: expected unqualified-id before numeric constant
 
 045 bool f_Down;
 
 ^~~
 
shtoru:46:1: error: expected unqualified-id before numeric constant
 
 046 bool state_Down;
 
 ^~~
 
shtoru:47:1: error: expected unqualified-id before numeric constant
 
 047 bool _Down;
 
 ^~~
 
shtoru:48:1: error: expected unqualified-id before numeric constant
 
 048 uint32_t Down_dreb;
 
 ^~~
 
shtoru:49:1: error: expected unqualified-id before numeric constant
 
 049 //сбрасываем UP\Down
 
 ^~~
 
shtoru:51:1: error: expected unqualified-id before numeric constant
 
 051 bool f_sbrosX = 1;
 
 ^~~
 
shtoru:52:1: error: expected unqualified-id before numeric constant
 
 052
 
 ^~~
 
shtoru:54:1: error: expected unqualified-id before numeric constant
 
 054 uint32_t blink_time;//Мигаем в режиме калибровки
 
 ^~~
 
shtoru:55:1: error: expected unqualified-id before numeric constant
 
 055
 
 ^~~
 
shtoru:57:1: error: expected unqualified-id before numeric constant
 
 057 int Shtora2;
 
 ^~~
 
shtoru:58:1: error: expected unqualified-id before numeric constant
 
 058 const int ton = 16;//пищалка
 
 ^~~
 
shtoru:59:1: error: expected unqualified-id before numeric constant
 
 059 // чтение
 
 ^~~
 
shtoru:60:1: error: expected unqualified-id before numeric constant
 
 060 int EEPROM_int_read(int addr) {
 
 ^~~
 
shtoru:66:1: error: expected unqualified-id before numeric constant
 
 066  // запись
 
 ^~~
 
shtoru:74:1: error: expected unqualified-id before numeric constant
 
 074
 
 ^~~
 
shtoru:95:1: error: expected unqualified-id before numeric constant
 
 095 void Beep() //короткий звук, переключение шторы
 
 ^~~
 
shtoru:101:1: error: expected unqualified-id before numeric constant
 
 101 void Beep_long()  //длинный звук, вход и выход из режима калибровки "0"
 
 ^~~
 
shtoru:107:1: error: expected unqualified-id before numeric constant
 
 107
 
 ^~~
 
shtoru:113:1: error: expected unqualified-id before numeric constant
 
 113
 
 ^~~
 
shtoru:130:1: error: expected unqualified-id before numeric constant
 
 130
 
 ^~~
 
shtoru:147:1: error: expected unqualified-id before numeric constant
 
 147
 
 ^~~
 
exit status 1
stray '#' in program
 
novig
Offline
Зарегистрирован: 16.03.2021

супер проект!!!
возможно ли реализовать все это на одном микроконтроллере(он же и сенсорные кнопки, и датчик освещенности прикрутить)? какой может подойти?
удалось ли реализовать дистанционное управление?

sheff
Offline
Зарегистрирован: 14.11.2017

У меня на кухне две шторы, управляет ардуино нано, а в зале три шторы - ардуино мега. Датчик освещенности есть, но нужно продумать алгоритм для переменной облачности, слишком часто ездят вверх-вниз. Дистанционное управление не делал, мне не нужно.

Bob_
Offline
Зарегистрирован: 13.07.2018

На датчике освещенности есть регулировка.

novig
Offline
Зарегистрирован: 16.03.2021

летом окна нагреваются как печка, кондиционер не справляется. ваш супер проект натолкнул на мысль сделать выдвижные локтевые маркизы на фасад .
буду подбирать моторы с редуктором, чтобы потянули.
возможно ли сделать их полностью автономными?
добавить датчик температуры, освещенности, вибрации(для ветра), дождя и запитать от солнечной панели?
да и дистанционное управление понадобиться

vvadim
Offline
Зарегистрирован: 23.05.2012

у меня на балконе три шторы с пультом для управления и настроек на одной нане, всё поместилось...

novig
Offline
Зарегистрирован: 16.03.2021

интересно взглянуть!
двигатели у китайцев нашел только такие- думаю потянут
заявлено до 7кг
1 006,66 руб. | Мотор-редуктор бесщеточный, 12/24 В, 14-1550 об/мин
https://a.aliexpress.com/_A3THJa

т.к. маркизы на фасаде - питание соответственно солнечные панели + mppt контроллер 12 в на 18650
и управление актуально дистанционное!
но упор необходимо сделать на открытие и закрытие по датчикам температуры(жара) освещенности(солнце) и вибрации(ветер) т.к. пользоваться будет пожилой человек не дружщий с техникой