Часы на ардуине сходят с ума

Тема в разделе "Arduino & Shields", создана пользователем Василий, 12 фев 2012.

  1. Всем доброго времени суток. Первый день тружусь над ардуинкой, подключили lcd 16x2, написал скетч часов, запускаю... но после 33 секунд часы сходят с ума и идут очень быстро.
    Посмотрите, пожалуйста, в чем проблема:

    Код (Text):
    /* Подключаем библиотеку для работы с LCD */
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    class Time
    {
     public:
     long int seconds,minutes;
     short int hours;
       Time()
       {
         seconds=minutes=hours=0;
       }
    void  operator++()
    {
      seconds++;
      if(seconds==60)
        {
          seconds=0;
          minutes++;
        }
       if(minutes==60)
         {
           hours++;
           minutes=0;
         }
        if(hours>23)
          hours=0;
    }
    };
    Time time;

    void setup()
    {
     lcd.begin(16, 2);
    }
    int prevmillis=0;
    void loop()
    {
     if(millis()-prevmillis>=999)
      {
       prevmillis=millis();
       ++time;
       lcd.setCursor(6, 1);
       lcd.print(":");
       lcd.setCursor(9, 1);
       lcd.print(":");
       lcd.setCursor(4, 1);
       lcd.print(time.hours);
       lcd.setCursor(7, 1);
       lcd.print(time.minutes);
       lcd.setCursor(10, 1);
       lcd.print(time.seconds);
       }
    }
    Подключал моник так:
    http://robocraft.ru/blog/arduino/503.html
     
  2. может, кто знает, как реализовать часы на прерывании? не обязательно на прерывании внутр. таймера - можно и внешний: кварц помедленнее+ д-триггер в качестве делителя частоты, но как реализовать само прерывание по одному из портов?
     
  3. Понял в чем беда: millis - int, происходило переполнение. Теперь работает.

    Код (Text):
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    class Time
    {
    public:
      unsigned short int seconds,minutes;
      unsigned short int hours;
      Time()
      {
        seconds=minutes=hours=0;
      }
      void  operator++()
      {
        seconds++;
        if(seconds==60)
        {
          seconds=0;
          minutes++;
        }
        if(minutes==60)
        {
          hours++;
          minutes=0;
        }
        if(hours>23)
          hours=0;
      }
    };
    Time time;

    void setup()
    {
      lcd.begin(16, 2);
    }
    unsigned long long int prevmillis=0;
    void loop()
    {
      if(millis()-prevmillis>=999)
      {
        prevmillis=millis();
        ++time;
        lcd.setCursor(6, 1);
        lcd.print(":");
        lcd.setCursor(9, 1);
        lcd.print(":");
        lcd.setCursor(4, 1);
        lcd.print(time.hours);
        lcd.setCursor(7, 1);
        lcd.print(time.minutes);
        lcd.setCursor(10, 1);
        lcd.print(time.seconds);
      }
    }
     
    Но все-же: с прерыванием можно сделать часы???
     
  4. Ну вот. Буду теперь знать, что вопрос задавать надо, только если информацию нигде найти не удалось... пол часа работы в сети и нашел:
    Код (Text):
    /* Подключаем библиотеку для работы с LCD */
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    class Time
    {
    public:
      unsigned int seconds,minutes;
      unsigned short int hours;
      Time()
      {
        seconds=minutes=hours=0;
      }
      void  operator++()
      {
        seconds++;
        if(seconds==60)
        {
          seconds=0;
          minutes++;
        }
        if(minutes==60)
        {
          hours++;
          minutes=0;
        }
        if(hours>23)
          hours=0;
      }
    };
    Time time;
    unsigned long long int prevmillis=0;
    volatile unsigned int tcnt2;
    void setup()
    {
      lcd.begin(16, 2);
       TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2
       TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
       TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
       ASSR &= ~(1<<AS2);  //Выбор источника синхронизации таймера если AS2=0 от системного генератора
       tcnt2 = 1000000000; //переменная для переполнения счетчика, дающая 1000 переполнений в секунду
       TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.

    }
    unsigned int t=0;
    void MyInterupt()
    {
      ++t;
      if(t>=1000)
      {
        t=0;
        ++time;
      }
    }
     ISR(TIMER2_OVF_vect)
    {
        TCNT2 = tcnt2;
        MyInterupt();
    }
    void loop()
    {
       lcd.setCursor(6, 1);
       lcd.print(":");
       lcd.setCursor(9, 1);
       lcd.print(":");
       lcd.setCursor(4, 1);
       lcd.print(time.hours);
       lcd.setCursor(7, 1);
       lcd.print(time.minutes);
       lcd.setCursor(10, 1);
       lcd.print(time.seconds);
    }
     
     
  5. Dmitriy Kunin

    Dmitriy Kunin Гик

    Огромное спасибо за проделаный поиск, и что не поленились выложить сюда.
    Часы реального времени удобнее, но иногда нужно сделать так как вы написали.