Часы на городской ратуше

Тема в разделе "Arduino & Shields", создана пользователем technomag, 3 июл 2016.

  1. technomag

    technomag Нуб

    Здравствуйте! Делаю проект запуска часов на городской ратуше, использовал плату Arduino Mini и шаговый двигатель NEMA-17 с драйвером Easy driver 4.4
    Вот скетч для работы движка:

    #include <Stepper.h>

    #define STEPS 200 // 1 шаг = 1 градус

    Stepper stepper(STEPS, 3, 4); // пины на ардуино

    void setup()
    {
    stepper.setSpeed(500); // скорость движения вала
    }

    void loop()
    {
    stepper.step(3200); // выполняет пол оборота вала согласно расчетам редуктора стрелок часов (секундной стрелки нет)
    delay(58000);

    }

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

    Vetrinus Гик

    Вам нужно отслеживать факт прохождения минуты. В лупе запрашивайте минуту, сравниваете с сохраненной переменой, если не сошлось - значит прошла минута и надо делать дела. Как дела сделаете, не забудьте сохранить в переменную значение текущей минуты.
     
  3. technomag

    technomag Нуб

    С ардуино пришлось познакомиться по причине разработки проекта, но я не очень силен в программировании на этом языке, как максимум удалось написать данный скетч, помогите пожалуйста с кодом.
     
  4. Vetrinus

    Vetrinus Гик

    Вам нужна библиотека для работы с RTC.
    В примерах есть описание функций. Вам нужно будет установить время на модуль, статей по этому полно.
    Предположим, что у вас уже все установлено:
    Код (C++):
    #include <Stepper.h>
    #include <RTC.h>
    #define STEPS 200 // 1 шаг = 1 градус
    Stepper stepper(STEPS, 3, 4); // пины на ардуино
    byte current_minute;
    RTC time;

    void setup()
    {
      stepper.setSpeed(500); // скорость движения вала
      time.begin(RTC_DS3231); //Либо другой
      current_minute=atoi(time.gettime("i"));
    }

    void loop()
    {
      if(atoi(time.gettime("i"))!=current_minute){//Сравниваем текущую минуту с записанной, если не сошлось
        stepper.step(3200); // выполняет пол оборота вала согласно расчетам редуктора стрелок часов (секундной стрелки нет)
        current_minute=atoi(time.gettime("i"));//Обновляем текущее значение минуты.
      }
    }
     
    Последнее редактирование: 3 июл 2016
  5. technomag

    technomag Нуб

    Тоесть так? ( модуль у меня на базе чипа DS3231)

    #include <RTC.h>
    RTC time;
    void setup() {
    delay(300);
    Serial.begin(9600);
    // инициализация модуля RTC
    time.begin(RTC_DS3231); // на базе чипа DS3231 модуль подключается к аппаратным выводам I2C
    // запись даты и времени
    // time.settime(0,17,20,3,97,16,7); // 0 сек, 17 мин, 20 час, 3, июля, 2016 года, восресенье
    // time.settime(35,17,20); // 35 сек, 10 мин, 20 час, дату оставить без изменений
    // time.settime(-1,-1,-1,03,07,16); // 31, декабря, 2015 года, время и день недели оставить без изменений
    }
    #include <Stepper.h>
    #define STEPS 200 // 1 шаг = 1 градус
    Stepper stepper(STEPS, 3, 4); // пины на ардуино
    byte current_minute;

    void setup()
    {
    stepper.setSpeed(500); // скорость движения вала
    time.begin(DS1307);
    current_minute=atoi(time.gettime("m"));
    }

    void loop()
    {
    if(atoi(time.gettime("m"))!=current_minute){//Сравниваем текущую минуту с записанной, если не сошлось
    stepper.step(3200); // выполняет пол оборота вала согласно расчетам редуктора стрелок часов (секундной стрелки нет)
    current_minute=atoi(time.gettime("m"));//Обновляем текущее значение минуты.
    }
    }
     
    Последнее редактирование: 3 июл 2016
  6. Vetrinus

    Vetrinus Гик

    Код (C++):
    #include <Stepper.h>
    #include <RTC.h>
    #define STEPS 200 // 1 шаг = 1 градус
    Stepper stepper(STEPS, 3, 4); // пины на ардуино
    byte current_minute;
    RTC time;

    void setup()
    {
      stepper.setSpeed(500); // скорость движения вала
      time.begin(RTC_DS3231); //Либо другой
      current_minute=atoi(time.gettime("i"));
    }

    void loop()
    {
      if(atoi(time.gettime("i"))!=current_minute){//Сравниваем текущую минуту с записанной, если не сошлось
        stepper.step(3200); // выполняет пол оборота вала согласно расчетам редуктора стрелок часов (секундной стрелки нет)
        current_minute=atoi(time.gettime("i"));//Обновляем текущее значение минуты.
      }
    }
     
    technomag нравится это.
  7. technomag

    technomag Нуб

    Большое спасибо, завтра попробую, кстати если нужна помощь по программировании и ремонту планшетов и мобильных телефонов обращайтесь, помогу с удовольствием)
     
  8. Vetrinus

    Vetrinus Гик

    Программирование мобильных телефонов и планшетов? Не расскажете поподробнее?
     
  9. technomag

    technomag Нуб

    В основном прошивки оригинальных и кастомных прошивок на планшеты и отвязка от оператора телефонов на базе андроид, Бада, Симбиан, виндовс мобайл, а также установки карт на GPS навигаторы, видоизменение скинов, добавление кнопок меню
     
  10. DIYMan

    DIYMan Guest

    У DS3231 есть ножка SQW, на которой генерируется прерывание каждую секунду. Можно подцепить эту ногу на пин 2 дуины и по прерыванию инкрементировать переменную. Досчитали до 60 - прошла минута, запускаем шаговый.

    Плюс такого подхода: прерыванию пофиг, в каких delay висит библиотека Stepper - код будет работать внятно. Ну и будет более простым. Навскидку:

    Код (C++):
    volatile int seconds = 0;

    void secs()
    {
    seconds++;
    }

    void setup()
    {
    attachInterrupt(digitalPinToInterrupt(2),FALLING,secs);
    }

    void loop()
    {
      if(secs > 59)
      {
       secs = 0;
       startStepper():
      }
    }
    Вот как выставить на пине SQW частоту в 1Гц: http://arduino.ru/forum/programmirovanie/ds3231-intsqw#comment-187005

    В той же теме пример, как получить прерывание каждую минуту ;)
     
    Последнее редактирование модератором: 3 июл 2016
    Tomasina и technomag нравится это.
  11. technomag

    technomag Нуб

    Как то так?

    #include <Stepper.h>
    #include <RTC.h>
    #define STEPS 200 // 1 шаг = 1 градус
    Stepper stepper(STEPS, 3, 4); // пины на ардуино
    byte current_minute;
    RTC time;
    void setup()
    {
    stepper.setSpeed(500); // скорость движения вала
    time.begin(RTC_DS3231);

    volatile int seconds = 0;
    void secs()
    {
    seconds++;
    }
    void setup()
    {
    attachInterrupt(digitalPinToInterrupt(2),RAISING,secs);
    }
    void loop()
    {
    if(secs > 59)
    {
    secs = 0;
    startStepper():
    stepper.step(3200); // выполняет пол оборота вала согласно расчетам редуктора стрелок часов (секундной стрелки нет)
    }
    }
     
  12. ostrov

    ostrov Гуру

    Ох, я тоже делал часы, только башенные. В 90х годах. На базе ПК. Время подводил по сигналам точного времени записывая их и сверяя с матрицей. Мда, жаль не было тогда Ардуин. )

    До сих пор ходят, правда не уверен, что начинка оригинальная.

    [​IMG]
     
    DIYMan, technomag и sys нравится это.
  13. technomag

    technomag Нуб

    И до сих пор этот ПК работает? 20 с лишним лет все таки прошло :)
     
  14. ostrov

    ostrov Гуру

    Не знаю что теперь там. я первые лет 5 после запуска обслуживал.
     
  15. technomag

    technomag Нуб

    Код заработал, но только дергает двигателем 1 раз в секунду и то на несколько шагов


    #include <Stepper.h>
    #include <RTC.h>
    #define STEPS 200 // 1 шаг = 1 градус
    Stepper stepper(STEPS, 3, 4); // пины на ардуино
    byte current_minute;
    RTC time;

    void setup()
    {
    stepper.setSpeed(500); // скорость движения вала
    time.begin(RTC_DS3231); //Либо другой
    current_minute = atoi(time.gettime("i"));
    }

    void loop()
    {
    if(atoi(time.gettime("i"))!=current_minute); //Сравниваем текущую минуту с записанной, если не сошлось
    stepper.step(3200); // выполняет пол оборота вала согласно расчетам редуктора стрелок часов (секундной стрелки нет)
    current_minute = atoi (time.gettime("i")); //Обновляем текущее значение минуты.
    }
     
  16. technomag

    technomag Нуб

    С етим кодом пока разбираюсь, много не понятного - например куда прописывать функцию - обработчика прерывания?
    1. SQW присоединил к пину, на который можно посадить attachInterrupt

    2. В библиотеку DS3231 добавил такой метод

    1 void DS3231::EnableMinuteInterrupt(void) {
    2 setA2Time(1, 1, 1, 0x70, 0, 0, 0);
    3 turnOnAlarm(2);
    4 byte cb = readControlByte(1);
    5 cb &= (~2);
    6 writeControlByte(cb, 1);
    7 writeControlByte(readControlByte(0) | 4, 0);
    8 }
    3. А в коде написал:

    1 Clock.turnOffAlarm(2); // Выключить будильник, если он там есть
    2 Clock.EnableMinuteInterrupt(); // Установить прерывание раз в минуту
    3 pinMode(PIN_SQW, INPUT); // Пин на чтение
    4 attachInterrupt(PIN_SQW - 2, everyMinuteAlarm, FALLING); // Установить обработчик прерываний
    Функция - обработчик прерывания выглядит так:

    1 void everyMinuteAlarm(void) {
    2 const byte oldSReg = SREG;
    3 sei();
    4 RefreshClockScreen();
    5 Clock.clearAlarmSignal(2);
    6 SREG = oldSReg;
    7 }
     
  17. Vetrinus

    Vetrinus Гик

    Честно говоря, не понимаю, зачем вам это. Вам привели 2 варианта абсолютно работоспособного кода, решающего ваши задачи. Зачем усложнять?
     
  18. technomag

    technomag Нуб

    На данный момент стоит Ваш код но только дергает двигателем 1 раз в секунду вместо раз в минуту и то на несколько шагов, а не на пол оборота вала. Помогите пожалуйста :rolleyes:
     
  19. Vetrinus

    Vetrinus Гик

    Вот с этого и следовало начинать. Помнится, я редактировал выложенный код из-за ошибок, и вполне возможно, что вы взяли версию с ошибкой. Приведите, пожалуйста, что крутится на вашей машине непосредственно.
     
  20. technomag

    technomag Нуб

    Arduino Leonardo, шаговый двигатель NEMA-17 с драйвером Easy driver 4.4,
    часы - DS3231