Прошу помощи (проблема с одновременной работой шаговых двигателей)

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Чет не понял - зачем калибровать верхнюю и нижнюю точки если количество шагов нам известно.
Калибруем одну нижнюю нулевую точку а верхняя и так понятна (например 7700шагов)
Поэтому я и предложил в режиме калибровки (одна кнопка опускает 1ю штору в 0 а вторая опускает 2ю в 0 /т.е. полное закрытие)
 
2- У Вас я видел стоят сенсорные кнопки - им не нужен АНТИДРЕБЕЗГ? 
sheff
Offline
Зарегистрирован: 14.11.2017

vosara пишет:

Чет не понял - зачем калибровать верхнюю и нижнюю точки если количество шагов нам известно.
Калибруем одну нижнюю нулевую точку а верхняя и так понятна (например 7700шагов)
Поэтому я и предложил в режиме калибровки (одна кнопка опускает 1ю штору в 0 а вторая опускает 2ю в 0 /т.е. полное закрытие)
 
2- У Вас я видел стоят сенсорные кнопки - им не нужен АНТИДРЕБЕЗГ? 

Я только одну точку и калибрую, только верх...когда штора поднята полностью, это и будет "0". Я думаю, что с двумя кнопками получится путаница. Кнопка UP - это всегда вверх, а DOWN всегда вниз.
Антидребезг я делал, нужен обязательно....много ложных было срабатываний.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Както не логично получается
"когда штора поднята полностью, это и будет "0"." 
Как по мне то - нулевой этаж все что выше это уже 1, 2, 3,- Уровень моря, все что в верху это число больше.
Кнопки собрал начал привязывать и не вижу логики - спускаемся вниз а цыфры растут.
Можт 0 всетаки внизу сделать? 
И еще если 0 то свет не проникает - а чем больше число тем больше света
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Как раз логично. 0 это когда все смотано. Mеньше смотать не получится. А вот удлинять можно до бесконечности, по крайней мере пока хватит длины шторы или максимальной величины переменной. Вот только полностью в реальности шторы не сматываются. Не красиво так. Вот и выходит надо отматывать от min (шторы подняты) до max (шторы опущены, но не валяются до пола). Но все равно вы пишите- вам и вводить понятия. А понятия различны у каждого человека.  ПС: не делайте min равным нулю. путь это будет некое число.

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

Назначая "0" вверху, я руководствовался тем, что штора практически всегда открыта, т.е. смотана и калибровать в этом положении "0" быстрей, чем полностью опускать штору, утанавливать нулевое положение и потом снова поднимать...но это моё личное мнение, хотя с другой стороны делаться это будет не так часто. 
Насчет того, чтобы не делать min равным "0" хочу поспорить, а как полностью открыть штору, ну например, чтобы помыть окно? Или тогда делать три позиции...min, max, "0"(это я так, просто предположил).

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

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

P.S. Прошу прощения....уменьшил скорость в скетче и, оказывается, всё работает верно.

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

vosara пишет:

Кнопки собрал начал привязывать и не вижу логики - спускаемся вниз а цифры растут.
Может 0 всетаки внизу сделать? 
И еще если 0 то свет не проникает - а чем больше число тем больше света

Я забыл уточнить.....моторы должны крутиться в разные стороны(особенность монтажа. у одной шторы мотор слева, у другой справа). Т.е. для 1 шторы мах будет, например "7000" шагов,  а для 2 шторы "-7000" шагов.
И еще одна деталь:
Если шторы остановлены в разных промежуточных положениях (1-3000, 2-4500), при одновременном закрытии или открытии как они будут двигаться? Я делал уравнивание (одна из штор движется в направлении второй шторы, а потом они обе продолжают движение к заданной позиции). Но наверно легче дать команду шторам на движение, а потом по достижении каждой шторой заданной позиции - останавливать движение. 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
Переделать пришлось практически 80 процентов кода. Выкладую проверяйте, для работы Вам нужно установит библиотеку #include <CyberLib.h> - она работает с портами на пямую через макросы, очень полезная для увеличения скорости обработки команд. По мимо этого у неё есть еще много поленых фишек. Вот ссылка ( http://cyber-place.ru/showthread.php?t=550 )
Я сделал так (Но наверно легче дать команду шторам на движение, а потом по достижении каждой шторой заданной позиции - останавливать движение.)
Память пока не задействовал испытаете потом посмотрим
Для пробы поставил 500 и 340 шагов. Если надо изменить, то там в 2х местах для каждой шторы поменяете
По подключению кнопок и светиков в самом верху скет. написано

//**********  (РЕЖИМ 1-ШАГ) Крутим с помощью сдвига --рабочая - крутит туда сюда без потери шагов - ускоряет - отключает катушки после бездействия
//PORTB - 8, 9, 10, 11 - Шаговик. && 12-кнопка Menu \ 13-Светодиод 1й штор.
//PORTD - 4, 5, 6, 7 - Шаговик. && 2-кнопка UP \ 3-кнопка DOWN
// А0-Светодиод 2й штор..

#include <CyberLib.h>
#define uskor 3 //Задаем ускорение
byte n1 = 1;// Сдвигаем 1 бит
byte n3 = 0x10;
byte f_tim = 0;
//long int perem_X = 0;
//long int perem_Z = 0;
byte sped_Xt = uskor;//Начальная скорость
byte sped_X = 0; //Ускорение
byte sped_Zt = uskor;//Начальная скорость
byte sped_Z = 0; //Ускорение

bool f_run1X = 0;//Сброс после остановки 2 переменные.
bool f_run2X = 0;
unsigned long no_runX; //Переменная для прошедшего периода

bool f_run1Z = 0;//Сброс после остановки 2 переменные.
bool f_run2Z = 0;
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;

uint32_t sbros;
bool f_sbros;

int Shtora1 = 500;//3592 количество шагов для полного закрытия шторы 1;
int Shtora2 = 340;//3475 количество шагов для полного закрытия шторы 2

void setup() {
  // DDRB пин, 8,9,10,11 - Шаговик, pin 12- вход, 13- Выход
  DDRB = DDRB | B00101111;
  // pin 8,9,10,11,13 - выход в 0 а входы pin 12, - подтягивающий резистор
  PORTB = PORTB | 0x10;
  //  DDRD, подключенный к двигателю pin 4,5,6,7 как выход,pin2,3 Выход
  DDRD = DDRD | B11110000;
  // pin 4,5,6,7 - выход в 0 а входы pin 2,3 - подтягивающий резистор
  PORTD = PORTD | B00001100;//x0F;
  D14_Out;  // Led_2
  D14_Low;
  Serial.begin(9600);

  // Инициализировать TIMER1
  noInterrupts (); // отключить все прерывания
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 125; // сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)
  TCCR1B |= (1 << WGM12); // Режим СТС
  TCCR1B |= (1 << CS12); // 256 делитель
  TIMSK1 |= (1 << OCIE1A ); // включить таймер сравнить прерываний
  interrupts(); // включить все прерывания
}

ISR (TIMER1_COMPA_vect) // Функция прерывания таймера
{
  // Serial.println(f_tim);
  f_tim = B1111;
}

//Функция вращения  dvigatel 1
void RunX (bool perem_X)
{
  f_tim &= B1110;
  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_tim &= B1011;
  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() {

  static bool tem_UP;
  if (_UP != tem_UP) {
    tem_UP = _UP;
    Serial.print("UP- "); Serial.println(_UP);
  }
  static bool tem_Down;
  if (_Down != tem_Down)
  {
    tem_Down = _Down;
    Serial.print("Down- "); Serial.println(_Down);
  }
  ///////////Проверка кнопки МЕНЮ - АНТИДРЕБЕЗГ
  if (D12_Read != f_menu) { //Если сигнал изменился
    f_menu = !f_menu;
    menu_dreb = millis();
  }
  if (kn_menu == D12_Read && millis() - menu_dreb > 20) kn_menu = !D12_Read;
  //static bool f_stop;
  //Проверка кнопки МЕНЮ -клик или нажатие
  if (kn_menu) {

    if (!f_Mpush && !f_Md) {
      menu_klik = millis();
      f_Mpush = 1;
    }
  }
  else {
    f_menu = 0;
    f_Md = 0;
  }
  // Если клик
  if (f_Mpush && !kn_menu && millis() - menu_klik < 500) {
    if (_UP || _Down) {
      _UP = 0;
      _Down = 0;
    }
    else Menu++;     // Меняем
    if (Menu > 3) Menu = 1;
    f_Mpush = 0;
  }
  //Длинное нажатие
  else if (!f_Md && kn_menu && millis() - menu_klik > 1000) {
    kalib = !kalib; // Включаем калибровку
    Serial.print("kalib -"); Serial.println(kalib);
    f_Md = 1;
    f_Mpush = 0;
  }
  ///////////////////////Проверка кнопки UP - АНТИДРЕБЕЗГ
  if (D2_Read != f_Up) { //Если сигнал изменился
    f_Up = !f_Up;
    Up_dreb = millis();
  }
  if (kn_Up == D2_Read && millis() - 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 = millis();
  }
  if (kn_Down == D3_Read && millis() - 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 (Menu != temp_Menu) {
    temp_Menu = Menu;
    Serial.print("Menu- "); Serial.println(Menu);
    switch (Menu) {
      case 1: D13_High; D14_Low; break;
      case 2: D13_Low; D14_High; break;
      case 3: D13_High; D14_High; break;
    }
  }

  /////////////////////////// Запуск 1го двигателя если " perem_X != 0 "
  //if (!kalib) {
  if (_UP || _Down) {
    if (Menu != 2) {
      if (f_tim & (1 << 0)) {
        if (!sped_X) {

          if (!kalib)//Калибровка отк.
          {
            if (_UP && Shtora1 < 500) {//3592
              RunX(0);
              Serial.print("Shtora1- "); Serial.println(Shtora1);
            }
            if (_Down && Shtora1 > 0) {
              RunX(1);
              Serial.print("Shtora1- "); Serial.println(Shtora1);
            }
          }
          else { //Калибровка вкл.
            if (_UP) {
              Shtora1 = 0;
              RunX(0);
              Serial.print("Shtora1- "); Serial.println(Shtora1);
            }
            if (_Down) {
              Shtora1 = 1;
              RunX(1);
              Serial.print("Shtora1- "); Serial.println(Shtora1);
            }
          }

          if (sped_Xt > 0) {
            --sped_Xt;
            sped_X = sped_Xt;
          }
        }
        else {
          --sped_X;
          f_tim &= B1110;
        }
      }////
      else {
        f_run2X = 1;
        no_runX = millis();
      }
    }
  }
  else {
    sped_Xt = uskor;
    sped_X = 0; // для пропуска 1го тика
  }
  //}

  /////////////////Запуск 3го двигателя если " perem_Z != 0 "
  //if (!kalib) {
  if (_UP || _Down) {
    if (Menu != 1) {
      if (f_tim & (1 << 2)) {
        if (!sped_Z) {

          if (!kalib)//Калибровка отк.
          {
            if (_UP && Shtora2 < 340) {//3475
              RunZ(0);
              Serial.print("Shtora2- "); Serial.println(Shtora2);
            }
            if (_Down && Shtora2 > 0) {
              RunZ(1);
              Serial.print("Shtora2- "); Serial.println(Shtora2);
            }
          }
          else {//Калибровка Вкл.
            if (_UP) {
              Shtora2 = 0;
              RunZ(0);
              Serial.print("Shtora2- "); Serial.println(Shtora2);
            }
            if (_Down) {
              Shtora2 = 1;
              RunZ(1);
              Serial.print("Shtora2- "); Serial.println(Shtora2);
            }
          }

          if (sped_Zt > 0) {
            --sped_Zt;
            sped_Z = sped_Zt;
          }
        }
        else {
          --sped_Z;
          f_tim &= B1011;
        }
      }////
      else {
        f_run2Z = 1;
        no_runZ = millis();
      }
    }
  }
  else {
    sped_Zt = uskor;
    sped_Z = 0; // для пропуска 1го тика
  }

  //Если достигли конца сбрасуем UP\Down
  if (f_tim != 15)
  {
    sbros = millis();
    f_sbros = 0;
  }
  if (!f_sbros && millis() - sbros > 1500)
  {
    f_sbros = 1;
    _UP = 0;
    _Down = 0;
  }

  //Снимаеммаем напряжение с катушек двигателя X
  if (f_run2X && millis() - no_runX >= 1000)// закончилось ли время
  {
    f_run2X = 0;
    PORTB &= 0xF0;
  }

  //Снимаеммаем напряжение с катушек двигателя Z
  if (f_run2Z && millis() - no_runZ >= 1000)// закончилось ли время
  {
    f_run2Z = 0;
    PORTD &= 0xF;
  }
}

 

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Да и еще, если включите сериал то увидете отработку команд. Количество тех шагов что у Вас была не будет соответствовать на этом коде, гдето на половину нужно меньше. Посмотрите в сериале

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

Добрый вечер. Огромное спасибо, за то что уделяете столько внимания! Сейчас буду пробывать.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

sheff пишет:

Я забыл уточнить.....моторы должны крутиться в разные стороны(особенность монтажа. у одной шторы мотор слева, у другой справа). Т.е. для 1 шторы мах будет, например "7000" шагов,  а для 2 шторы "-7000" шагов.

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

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

vosara пишет:

Переделать пришлось практически 80 процентов кода. Выкладую проверяйте, для работы Вам нужно установит библиотеку #include <CyberLib.h> - она работает с портами на пямую через макросы, очень полезная для увеличения скорости обработки команд. По мимо этого у неё есть еще много поленых фишек. Вот ссылка ( http://cyber-place.ru/showthread.php?t=550 )
Я сделал так (Но наверно легче дать команду шторам на движение, а потом по достижении каждой шторой заданной позиции - останавливать движение.)
Память пока не задействовал испытаете потом посмотрим
Для пробы поставил 500 и 340 шагов. Если надо изменить, то там в 2х местах для каждой шторы поменяете
По подключению кнопок и светиков в самом верху скет. написано

Итак, переподключил все проводочки как написано в скетче, понажимал кнопочки...:
1. Меню работает не так как задумывалось, а именно - короткое нажатие на меню происходит смена режима (калибровка 0/1). 2 коротких нажатия - вторая штора, 3 коротких нажатия - обе шторы. Кажется так.
2. Не понял что происходит в режиме калибровки.....кнопки вверх и вниз работают одинаково и в калибровке 0 и в калибровке 1.
3. Моторы стали ездить очень медленно, намного медленнее даже чем было у меня. Сейчас записал пробный скетч, который Вы давали вчера - шторы крутятся наверно раза в два быстрее чем было у меня.
Сейчас произвел замер, с моим скетчем полное закрытие шторы - 1м24сек, с Вашим вчерашним скетчем - 50 сек, а с новым скетчем - 5м34сек. При этом сильно греется кренка (я взял 9вольт с блока питания и через КРЕН5Б пустил 6 вольт на драйверы моторов).
Пока всё, может позже еще что нибудь вспомню.

Да, еще по количеству шагов...500 шагов это реальное расстояние - около 1 сантиметра.
У меня было 130 см - 7000 шагов.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Там не 2 раза надо нажимать а по условии - если есть движение шторы то нажатие любой кнопки сначала должно остановить движение и только потом они переходят в рабочий режим. И к стати переход в режим калибровки и выход из него я поставил 1500 (1.5сек) Можете поменять.

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

Я специально снял видео, сейчас закину на диск и выложу ссылку. Может я что то не так подключил, но работает совсем не так, как в симуляторе.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

А у Вас в симуляторе как работает?

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

Я в симуляторе не пробывал, мне еще полночи рисовать нужно :)

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Ну по картинке которую Вы выложили -Нужно добавить кнопочку, 2 диода и схема готова

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

я вот что подумал, в пробном скетче я изменил обработку кнопок....if ((PIND & (1 << 2))) вот здесь убрал "!", а в новом скетче не изменял. может в этом косяк? ну посмотрите видео может что нибудь подскажете....

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

вот ссылка https://youtu.be/LLuEhdOS05M

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

vosara пишет:

Ну по картинке которую Вы выложили -Нужно добавить кнопочку, 2 диода и схема готова

Залил скетч в протеус, тоже самое как на ардуинке.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Вот теперь смотрю по картинке  - у Вас КНОПКИ подключены НЕ ПРАВИЛЬНО. Вы при замыкании кнопки подаете ПЛЮС а надо МИНУС и никакой подтяжки из сопротивлений делать не надо, подтяжка стоит програмная. О таком подключении я писал еще в первом скет. Строчка № 90  //Кнопки 1 и 2 служат для демонстрации работы. Считается замкнутой при подаче МИНУСА

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

vosara пишет:

Вот теперь смотрю по картинке  - у Вас КНОПКИ подключены НЕ ПРАВИЛЬНО. Вы при замыкании кнопки подаете ПЛЮС а надо МИНУС   //Кнопки 1 и 2 служат для демонстрации работы. Считается замкнутой при подаче МИНУСА

нету там никакова минуса, GND есть и +5В есть

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

vosara пишет:

Вот теперь смотрю по картинке  - у Вас КНОПКИ подключены НЕ ПРАВИЛЬНО. Вы при замыкании кнопки подаете ПЛЮС а надо МИНУС и никакой подтяжки из сопротивлений делать не надо, подтяжка стоит програмная. О таком подключении я писал еще в первом скет. Строчка № 90  //Кнопки 1 и 2 служат для демонстрации работы. Считается замкнутой при подаче МИНУСА

В протеусе переделал, заработало. А можно в скетче изменить, чтобы кнопки считались замкнутыми при подаче плюса?

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Вот на кнопку которая замыкает на ПЛЮС. Но здесь надо ставить подтяжку из резистора - на МИНУС


//**********  (РЕЖИМ 1-ШАГ) Крутим с помощью сдвига --рабочая - крутит туда сюда без потери шагов - ускоряет - отключает катушки после бездействия
//PORTB - 8, 9, 10, 11 - Шаговик. && 12-кнопка Menu \ 13-Светодиод 1й штор.
//PORTD - 4, 5, 6, 7 - Шаговик. && 2-кнопка UP \ 3-кнопка DOWN
// А0-Светодиод 2й штор..

#include <CyberLib.h>
//Задаем ускорение
#define uskor 3 
byte n1 = 1;// Сдвигаем 1 бит
byte n3 = 0x10;
byte f_tim = 0;
byte sped_Xt = uskor;//Начальная скорость
byte sped_X = 0; //Ускорение
byte sped_Zt = uskor;//Начальная скорость
byte sped_Z = 0; //Ускорение

bool f_run1X = 0;//Сброс после остановки 3 переменные.
bool f_run2X = 0;
unsigned long no_runX; //Переменная для прошедшего периода

bool f_run1Z = 0;//Сброс после остановки 3 переменные.
bool f_run2Z = 0;
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;

uint32_t sbros;
bool f_sbros;

int Shtora1 = 3592;// количество шагов для полного закрытия шторы 1;
int Shtora2 = 3475;// количество шагов для полного закрытия шторы 2


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_2
  D14_Low;
  Serial.begin(9600);
  // Инициализировать TIMER1
  noInterrupts (); // отключить все прерывания
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 125; // сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)
  TCCR1B |= (1 << WGM12); // Режим СТС
  TCCR1B |= (1 << CS12); // 256 делитель
  TIMSK1 |= (1 << OCIE1A ); // включить таймер сравнить прерываний
  interrupts(); // включить все прерывания
}

ISR (TIMER1_COMPA_vect) // Функция прерывания таймера
{
  // Serial.println(f_tim);
  f_tim = B1111;
}

//Функция вращения  dvigatel 1
void RunX (bool perem_X)
{
  f_tim &= B1110;
  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_tim &= B1011;
  if (perem_Z) {
    n3 = (n3 >> 1) | (n3 << 3); //Сдвигаем
    --Shtora2;
  }
  else {
    n3 = (n3 << 1) | (n3 >> 3); //Сдвигаем
    ++Shtora2;
  }
  n3 = 0xF0 & n3;//Маскируем
  PORTD = (PORTD & 0xF) | n3; //Очищаем старшие биты и пишем туда n3
  //Serial.println(n3);
}

void loop() {

  static bool tem_UP;
  if (_UP != tem_UP) {
    tem_UP = _UP;
    Serial.print("UP- "); Serial.println(_UP);
  }
  static bool tem_Down;
  if (_Down != tem_Down)
  {
    tem_Down = _Down;
    Serial.print("Down- "); Serial.println(_Down);
  }
  ///////////////////Проверка кнопки МЕНЮ - АНТИДРЕБЕЗГ
  if (D12_Read && !f_menu)
  {
    menu_dreb = millis();
    f_menu = 1;
  }
  if (!D12_Read)
  {
    kn_menu = 0;
    f_menu = 0;
  }

  if (f_menu && millis() - menu_dreb >= 20)
  {
    kn_menu = 1;
    if (!f_Mpush) {
      menu_klik = millis();
      f_Mpush = 1;
    }
  }

  if (f_Mpush && !kn_menu && millis() - menu_klik < 500) {
     if (_UP || _Down) {
      _UP = 0;
      _Down = 0;
    }
    else Menu++;     // Меняем
    if (Menu > 3) Menu = 1;
    f_Mpush = 0;
  }

  else if (f_Mpush && !kn_menu && millis() - menu_klik > 500) {
    kalib = !kalib; // Включаем калибровку
    Serial.print("kalib- "); Serial.println(kalib);
    f_Mpush = 0;
  }
  
  ///////////////////////Проверка кнопки UP - АНТИДРЕБЕЗГ
  if (D2_Read != f_Up) { //Если сигнал изменился
    f_Up = !f_Up;
    Up_dreb = millis();
  }
  if (kn_Up == D2_Read && millis() - 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 = millis();
  }
  if (kn_Down == D3_Read && millis() - 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 (Menu != temp_Menu) {
    temp_Menu = Menu;
    Serial.print("Menu- "); Serial.println(Menu);
    switch (Menu) {
      case 1: D13_High; D14_Low; break;
      case 2: D13_Low; D14_High; break;
      case 3: D13_High; D14_High; break;
    }
  }

  /////////////////////////// Запуск 1го двигателя если " perem_X != 0 "
  if (!kalib) {
    if (_UP || _Down) {
      if (Menu != 2) {
        if (f_tim & (1 << 0)) {
          if (!sped_X) {

            if (_UP && Shtora1 < 3592) {
              Serial.print("Shtora1- "); Serial.println(Shtora1);
              RunX(0);
            }
            if (_Down && Shtora1 > 0) {
              Serial.print("Shtora1- "); Serial.println(Shtora1);
              RunX(1);
            }

            if (sped_Xt > 0) {
              --sped_Xt;
              sped_X = sped_Xt;
            }
          }
          else {
            --sped_X;
            f_tim &= B1110;
          }
        }////
        else {
          f_run2X = 1;
          no_runX = millis();
        }
      }
    }
    else {
      sped_Xt = uskor;
      sped_X = 0; // для пропуска 1го тика
    }
  }

  /////////////////Запуск 3го двигателя если " perem_Z != 0 "
  if (!kalib) {
    if (_UP || _Down) {
      if (Menu != 1) {
        if (f_tim & (1 << 2)) {
          if (!sped_Z) {

            if (_UP && Shtora2 < 3475) {
              Serial.print("Shtora2- "); Serial.println(Shtora2);
              RunZ(0);
            }
            if (_Down && Shtora2 > 0) {
              Serial.print("Shtora2- "); Serial.println(Shtora2);
              RunZ(1);
            }

            if (sped_Zt > 0) {
              --sped_Zt;
              sped_Z = sped_Zt;
            }
          }
          else {
            --sped_Z;
            f_tim &= B1011;
          }
        }////
        else {
          f_run2Z = 1;
          no_runZ = millis();
        }
      }
    }
    else {
      sped_Zt = uskor;
      sped_Z = 0; // для пропуска 1го тика
    }
  }
  //Если достигли конца сбрасуем UP\Down
  if (f_tim != 15)
  {
    sbros = millis();
    f_sbros = 0;
  }
  if (!f_sbros && millis() - sbros > 1500)
  {
    f_sbros = 1;
    _UP = 0;
    _Down = 0;
  }

  //Снимаеммаем напряжение с катушек двигателя X
  if (f_run2X && millis() - no_runX >= 1000)// закончилось ли время
  {
    f_run2X = 0;
    PORTB &= 0xF0;
  }

  //Снимаеммаем напряжение с катушек двигателя Z
  if (f_run2Z && millis() - no_runZ >= 1000)// закончилось ли время
  {
    f_run2Z = 0;
    PORTD &= 0xF;
  }
}

 

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

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

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

Ещё заметил, что с моторов не сбрасывается питание, и сильно греется КРЕНка.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Даже не знаю Вы в симулятор заливаете - все работает или нет? У меня в симуляторе все работает и крутится - могу снять видео. Вы возьмите за правило - сначала загрузить в симулятор, проверить и только тогда использовать плату.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

sheff пишет:

Ещё заметил, что с моторов не сбрасывается питание, и сильно греется КРЕНка.

И снова тоже самое - смотрите в симуляторе, у меня сбрасует.

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

В симуляторе моргает исправно, поэтому я перепаял кнопки, залил в плату и попробовал.... вот о результатах и сообщаю.

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

vosara пишет:

sheff пишет:

Ещё заметил, что с моторов не сбрасывается питание, и сильно греется КРЕНка.

И снова тоже самое - смотрите в симуляторе, у меня сбрасует.

Если в симуляторе после моргания светодиодов, тобишь моторов, один остается гореть - это значит не сбрасывает?

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Да если в симуляторе после остановки горит - значит не выключает

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

Закинул новый скетч в симулятор. Кнопки работают, моторы бегают, по одному - всё нормально, питание сбрасывается. А одновременно - питание не сбрасывается.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Они не должны одновременно сбрасываться - Сброс происходит через 1 секунду после остановки а остановитьс они могут сначала один (сбросили через 1с) а второй - когда свое докрутит

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

vosara пишет:

Они не должны одновременно сбрасываться - Сброс происходит через 1 секунду после остановки а остановитьс они могут сначала один (сбросили через 1с) а второй - когда свое докрутит

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

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

А что делают кнопки UP и DOWN в режиме калибровки? По замыслу они должны двигать штору вверх и вниз, чтобы приехать в нулевое положение, а при нажатии на них моторы стоят.

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014
vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Да в том ск. они работали а здесь исправлял кнопки и наверное чтото зацепил, надо посмотреть

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

Ага, понял.....попробуйте остановить движение двух моторов ЭТОЙ ЖЕ кнопкой.
Когда останавливаешь другой кнопкой всё работает правильно.

Причем только с одной кнопкой такая фигня(когда цифры уменьшаются)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

sheff пишет:

А что делают кнопки UP и DOWN в режиме калибровки? По замыслу они должны двигать штору вверх и вниз, чтобы приехать в нулевое положение, а при нажатии на них моторы стоят.

Вот почему я предлагал писать через классы. Очень сложно писать и отлаживать такие программы. Их структура и архитектура становится рассыпающей. 

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

qwone пишет:

sheff пишет:

А что делают кнопки UP и DOWN в режиме калибровки? По замыслу они должны двигать штору вверх и вниз, чтобы приехать в нулевое положение, а при нажатии на них моторы стоят.

Вот почему я предлагал писать через классы. Очень сложно писать и отлаживать такие программы. Их структура и архитектура становится рассыпающей. 

Я бы с радостью, только увы, не научился :(

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

//**********  (РЕЖИМ 1-ШАГ) Крутим с помощью сдвига --рабочая - крутит туда сюда без потери шагов - ускоряет - отключает катушки после бездействия
//PORTB - 8, 9, 10, 11 - Шаговик. && 12-кнопка Menu \ 13-Светодиод 1й штор.
//PORTD - 4, 5, 6, 7 - Шаговик. && 2-кнопка UP \ 3-кнопка DOWN
// А0-Светодиод 2й штор..

#include <CyberLib.h>
//Задаем ускорение
#define uskor 3 
byte n1 = 1;// Сдвигаем 1 бит
byte n3 = 0x10;
byte f_tim = 0;
byte sped_Xt = uskor;//Начальная скорость
byte sped_X = 0; //Ускорение
byte sped_Zt = uskor;//Начальная скорость
byte sped_Z = 0; //Ускорение

bool f_run1X = 0;//Сброс после остановки 3 переменные.
bool f_run2X = 0;
unsigned long no_runX; //Переменная для прошедшего периода

bool f_run1Z = 0;//Сброс после остановки 3 переменные.
bool f_run2Z = 0;
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;

uint32_t sbros;
bool f_sbros;

int Shtora1 = 3592;// количество шагов для полного закрытия шторы 1;
int Shtora2 = 3475;// количество шагов для полного закрытия шторы 2


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_2
  D14_Low;
  Serial.begin(9600);
  // Инициализировать TIMER1
  noInterrupts (); // отключить все прерывания
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 12500; // сравнить регистр (скорость!!!(2ms=125 - если медлиннее - УВЕЛИЧУЕМ)
  TCCR1B |= (1 << WGM12); // Режим СТС
  TCCR1B |= (1 << CS12); // 256 делитель
  TIMSK1 |= (1 << OCIE1A ); // включить таймер сравнить прерываний
  interrupts(); // включить все прерывания
}

ISR (TIMER1_COMPA_vect) // Функция прерывания таймера
{
  // Serial.println(f_tim);
  f_tim = B1111;
}

//Функция вращения  dvigatel 1
void RunX (bool perem_X)
{
  f_tim &= B1110;
  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_tim &= B1011;
  if (perem_Z) {
    n3 = (n3 >> 1) | (n3 << 3); //Сдвигаем
    --Shtora2;
  }
  else {
    n3 = (n3 << 1) | (n3 >> 3); //Сдвигаем
    ++Shtora2;
  }
  n3 = 0xF0 & n3;//Маскируем
  PORTD = (PORTD & 0xF) | n3; //Очищаем старшие биты и пишем туда n3
  //Serial.println(n3);
}

void loop() {

  static bool tem_UP;
  if (_UP != tem_UP) {
    tem_UP = _UP;
    Serial.print("UP- "); Serial.println(_UP);
  }
  static bool tem_Down;
  if (_Down != tem_Down)
  {
    tem_Down = _Down;
    Serial.print("Down- "); Serial.println(_Down);
  }
  ///////////////////Проверка кнопки МЕНЮ - АНТИДРЕБЕЗГ
  if (D12_Read && !f_menu)
  {
    menu_dreb = millis();
    f_menu = 1;
  }
  if (!D12_Read)
  {
    kn_menu = 0;
    f_menu = 0;
  }

  if (f_menu && millis() - menu_dreb >= 20)
  {
    kn_menu = 1;
    if (!f_Mpush) {
      menu_klik = millis();
      f_Mpush = 1;
    }
  }

  if (f_Mpush && !kn_menu && millis() - menu_klik < 500) {
     if (_UP || _Down) {
      _UP = 0;
      _Down = 0;
    }
    else Menu++;     // Меняем
    if (Menu > 3) Menu = 1;
    f_Mpush = 0;
  }

  else if (f_Mpush && !kn_menu && millis() - menu_klik > 500) {
    kalib = !kalib; // Включаем калибровку
    Serial.print("kalib- "); Serial.println(kalib);
    f_Mpush = 0;
  }
  
  ///////////////////////Проверка кнопки UP - АНТИДРЕБЕЗГ
  if (D2_Read != f_Up) { //Если сигнал изменился
    f_Up = !f_Up;
    Up_dreb = millis();
  }
  if (kn_Up == D2_Read && millis() - 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 = millis();
  }
  if (kn_Down == D3_Read && millis() - 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 (Menu != temp_Menu) {
    temp_Menu = Menu;
    Serial.print("Menu- "); Serial.println(Menu);
    switch (Menu) {
      case 1: D13_High; D14_Low; break;
      case 2: D13_Low; D14_High; break;
      case 3: D13_High; D14_High; break;
    }
  }

  /////////////////////////// Запуск 1го двигателя если " perem_X != 0 "
  //if (!kalib) {
  if (_UP || _Down) {
    if (Menu != 2) {
      if (f_tim & (1 << 0)) {
        if (!sped_X) {

          if (!kalib)//Калибровка отк.
          {
            if (_UP && Shtora1 < 500) {//3592
              RunX(0);
              Serial.print("Shtora1- "); Serial.println(Shtora1);
            }
            if (_Down && Shtora1 > 0) {
              RunX(1);
              Serial.print("Shtora1- "); Serial.println(Shtora1);
            }
          }
          else { //Калибровка вкл.
            if (_UP) {
              Shtora1 = 0;
              RunX(0);
              Serial.print("Shtora1- "); Serial.println(Shtora1);
            }
            if (_Down) {
              Shtora1 = 1;
              RunX(1);
              Serial.print("Shtora1- "); Serial.println(Shtora1);
            }
          }

          if (sped_Xt > 0) {
            --sped_Xt;
            sped_X = sped_Xt;
          }
        }
        else {
          --sped_X;
          f_tim &= B1110;
        }
      }////
      else {
        f_run2X = 1;
        no_runX = millis();
      }
    }
  }
  else {
    sped_Xt = uskor;
    sped_X = 0; // для пропуска 1го тика
  }
  //}

  /////////////////Запуск 3го двигателя если " perem_Z != 0 "
  //if (!kalib) {
  if (_UP || _Down) {
    if (Menu != 1) {
      if (f_tim & (1 << 2)) {
        if (!sped_Z) {

          if (!kalib)//Калибровка отк.
          {
            if (_UP && Shtora2 < 340) {//3475
              RunZ(0);
              Serial.print("Shtora2- "); Serial.println(Shtora2);
            }
            if (_Down && Shtora2 > 0) {
              RunZ(1);
              Serial.print("Shtora2- "); Serial.println(Shtora2);
            }
          }
          else {//Калибровка Вкл.
            if (_UP) {
              Shtora2 = 0;
              RunZ(0);
              Serial.print("Shtora2- "); Serial.println(Shtora2);
            }
            if (_Down) {
              Shtora2 = 1;
              RunZ(1);
              Serial.print("Shtora2- "); Serial.println(Shtora2);
            }
          }

          if (sped_Zt > 0) {
            --sped_Zt;
            sped_Z = sped_Zt;
          }
        }
        else {
          --sped_Z;
          f_tim &= B1011;
        }
      }////
      else {
        f_run2Z = 1;
        no_runZ = millis();
      }
    }
  }
  else {
    sped_Zt = uskor;
    sped_Z = 0; // для пропуска 1го тика
  }

  //Если достигли конца сбрасуем UP\Down
  if (f_tim != 15)
  {
    sbros = millis();
    f_sbros = 0;
  }
  if (!f_sbros && millis() - sbros > 1500)
  {
    f_sbros = 1;
    _UP = 0;
    _Down = 0;
  }

  //Снимаеммаем напряжение с катушек двигателя X
  if (f_run2X && millis() - no_runX >= 1000)// закончилось ли время
  {
    f_run2X = 0;
    PORTB &= 0xF0;
  }

  //Снимаеммаем напряжение с катушек двигателя Z
  if (f_run2Z && millis() - no_runZ >= 1000)// закончилось ли время
  {
    f_run2Z = 0;
    PORTD &= 0xF;
  }
}

 

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

sheff пишет:

Ага, понял.....попробуйте остановить движение двух моторов ЭТОЙ ЖЕ кнопкой.
Когда останавливаешь другой кнопкой всё работает правильно.

Причем только с одной кнопкой такая фигня(когда цифры уменьшаются)

Этой же это - какой?

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

На Pin3

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

А что изменилось в этом скетче?

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Работает калибровка

vosara
vosara аватар
Offline
Зарегистрирован: 08.02.2014

Смотрите по условию которое Вы поставили - Если есть движение - нажатие любой кнопки должно остановить движение. Так вот в даной программе так и происходит - остановка и сброс питания любой кнопкой. Мне что еще снять одно видео что все так и работает. 

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

vosara пишет:

Смотрите по условию которое Вы поставили - Если есть движение - нажатие любой кнопки должно остановить движение. Так вот в даной программе так и происходит - остановка и сброс питания любой кнопкой. Мне что еще снять одно видео что все так и работает. 

А какой программой снимать видео? Я же не обманываю....когда запускаешь движение двух моторов кнопкой DOWN и потом останавливаешь ей же, в большинстве случаев питание не сбрасывается. Это в симуляторе.

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

Может это глюки симулятора? На маленькой скорости вроде без ошибок, а на большой не сбрасывает питание.