Часы ds 3231

Тема в разделе "Arduino & Shields", создана пользователем greck, 21 мар 2015.

  1. rf68

    rf68 Нерд

    вынул батарею, вставил, включил. Кнопки не нажимал. Отстают.
     

    Вложения:

    • libraries.zip
      Размер файла:
      22 КБ
      Просмотров:
      117
  2. fogary

    fogary Гик

    Если в часах изначально выставлено не точное время, то они конечно будут отставать.
    Как Вы выставляли время в часах?
    Можете заново выставить время способом, описанным на первой странице этой темы (пост №5), по времени компиляции скетча?
    Код (C++):
    char compileTime[] = __TIME__;

    void setup() {
      . . .
      byte h = getInt(compileTime, 0);
      byte m = getInt(compileTime, 3);
      byte s = getInt(compileTime, 6);
      Clock.setHour(h);
      Clock.setMinute(m);
      Clock.setSecond(s);
    }
    Если не против, попробуйте такую библиотеку.
     
  3. rf68

    rf68 Нерд

    Установил Вашу библиотеку. Скетч без изменений (как Автор написал)
    :77: error: 'cur_time' was not declared in this scope
    :77: error: 'class DS3231' has no member named 'getTime'
    : In function 'void loop()':
    'class DS3231' has no member named 'setHour'
    :126: error: 'class DS3231' has no member named 'setMinute'
    :127: error: 'class DS3231' has no member named 'setSecond'
    Я понимаю надо вносить изменения в 'void loop()'?
     
  4. rf68

    rf68 Нерд

    По поводу времени: время не устанавливал. Вынул батарею, вставил батарею, включил часы и таймер.
     
  5. fogary

    fogary Гик

    Код установки времени, расчитан на Вашу библиотеку libraries.zip. С другой библиотекой он работать не будет.

    Да, под другую библиотеку изменения потребуются, но не такие уж и большие. Только напишите какую библиотеку Вы будите использовать.
     
  6. rf68

    rf68 Нерд

    Давайте попробуем libraries.zip
     
  7. fogary

    fogary Гик

    Хорошо, с библиотекой определились.
    Теперь хочу уточнить, с первым куском кодом из поста цифры на индикаторе светятся?
    Еще вопрос, Вы сами собирали схему? Соединить еще один выход модуля RTC с пином Ardduino сможите?
     
    Последнее редактирование: 25 мар 2017
  8. fogary

    fogary Гик

    Попробуйте такой тестовый код. Делает следующее: при запуске - устанавливает время в RTC; в основном цикле - читает показания RTC, выводит значение минут и секунд на индикатор, выводит время на терминал (в serial порт).
    Код (C++):
    #include <DS3231.h>
    #include <Wire.h>

    const uint8_t OUT1 = A3;
    const uint8_t OUT2 = A1;
    const uint8_t OUT4 = A0;
    const uint8_t OUT8 = A2;

    const uint8_t LED1 = 11;

    DS3231 Clock;

    byte Hour;
    byte Minute;
    byte Second;

    char getInt(const char* string, int startIndex) {
      return int(string[startIndex] - '0') * 10 + int(string[startIndex+1]) - '0';
    }

    void setup() {
      // установить частоту ШИМ 30кГц на выводе 9
      TCCR1B = TCCR1B & 0b11111000 | 0x01;
      analogWrite(9, 130);

      Serial.begin(9600);
      Wire.begin();

      char compileTime[] = __TIME__;
      Hour = getInt(compileTime, 0);
      Minute = getInt(compileTime, 3);
      Second = getInt(compileTime, 6);
      // установить время в RTC
      Clock.setClockMode(false);
      Clock.setHour(Hour);
      Clock.setMinute(Minute);
      Clock.setSecond(Second);
    }

    void ReadDS3231() {
      bool h12;
      bool PM;

      // Метод getHour установит значения переменных h12, PM
      // в зависимости от установок RTC, для 24 часового формата
      // значением этих переменных можно принебречь
      Hour = Clock.getHour(h12, PM);
      Minute = Clock.getMinute();
      Second = Clock.getSecond();
    }

    void loop() {
      static unsigned long currentTime = 0;

      if (millis() - currentTime >= 1000) {
        currentTime = millis();
        // мигнуть светодиодом
        digitalWrite(LED1, !digitalRead(LED1));

        // получить значение времени
        ReadDS3231();

        // вывести время на индикатор
    //    setNumber(Hour / 10);
    //    setNumber(Hour % 10);
        setNumber(Minute / 10);
        setNumber(Minute % 10);
        setNumber(Second / 10);
        setNumber(Second % 10);

        // вывести время на терминал
        Serial.print(Hour);
        Serial.print(":");
        Serial.print(Minute);
        Serial.print(":");
        Serial.println(Second);
      }
    }

    // передача цифры на дешифратор
    void setNumber(byte num) {
      switch (num) {
        case 0:
        digitalWrite (OUT1,LOW);
        digitalWrite (OUT2,LOW);
        digitalWrite (OUT4,LOW);
        digitalWrite (OUT8,LOW);
        break;
        case 1:
        digitalWrite (OUT1,HIGH);
        digitalWrite (OUT2,LOW);
        digitalWrite (OUT4,LOW);
        digitalWrite (OUT8,LOW);
        break;
        case 2:
        digitalWrite (OUT1,LOW);
        digitalWrite (OUT2,HIGH);
        digitalWrite (OUT4,LOW);
        digitalWrite (OUT8,LOW);
        break;
        case 3:
        digitalWrite (OUT1,HIGH);
        digitalWrite (OUT2,HIGH);
        digitalWrite (OUT4,LOW);
        digitalWrite (OUT8,LOW);
        break;
        case 4:
        digitalWrite (OUT1,LOW);
        digitalWrite (OUT2,LOW);
        digitalWrite (OUT4,HIGH);
        digitalWrite (OUT8,LOW);
        break;
        case 5:
        digitalWrite (OUT1,HIGH);
        digitalWrite (OUT2,LOW);
        digitalWrite (OUT4,HIGH);
        digitalWrite (OUT8,LOW);
        break;
        case 6:
        digitalWrite (OUT1,LOW);
        digitalWrite (OUT2,HIGH);
        digitalWrite (OUT4,HIGH);
        digitalWrite (OUT8,LOW);
        break;
        case 7:
        digitalWrite (OUT1,HIGH);
        digitalWrite (OUT2,HIGH);
        digitalWrite (OUT4,HIGH);
        digitalWrite (OUT8,LOW);
        break;
        case 8:
        digitalWrite (OUT1,LOW);
        digitalWrite (OUT2,LOW);
        digitalWrite (OUT4,LOW);
        digitalWrite (OUT8,HIGH);
        break;
        case 9:
        digitalWrite (OUT1,HIGH);
        digitalWrite (OUT2,LOW);
        digitalWrite (OUT4,LOW);
        digitalWrite (OUT8,HIGH);
        break;
      }
    }
    Потестировать не смог, так что могут быть ошибки и опечатки.
     
  9. rf68

    rf68 Нерд

    При замене void loop() в кодом из поста цифры не светятся, только моргает светодиод. Добавил в void setup()
    digitalWrite(key1,HIGH);
    digitalWrite(key2,HIGH);
    digitalWrite(key3,HIGH);
    digitalWrite(key4,HIGH);
    засветились единицы часов и минуты. Идут 1_:11; 2_:22; 3_:33 и т.д.
     
  10. fogary

    fogary Гик

    В исходном коде, часы и минуты выводились так же или по другому?

    Точно светятся единицы часов, а не десятки часов как в примере?
    Поправил тестовый код (во вложении).

    Посмотрите, что будет выводиться в порт следующими строчками:
    Код (C++):
    Serial.print(Second / 10);
    Serial.print(Second % 10);
    На предмет, будет выводиться незначащий ноль в значениях секунд или нет?
     

    Вложения:

  11. rf68

    rf68 Нерд

    В исходном коде часы, минуты выводились в двузначном формате, секунд нет (4 лампы) . В тестовом коде цифры по порядку меняются раз в секунду. Монитор порта выдал:
    5
    25:165:16. Или я что-то не так сделал?
     
  12. rf68

    rf68 Нерд

    Разобрался, время в формате 13:22:1. Выводится на лампы, как сказано выше, одинаковые цифры, меняющиеся примерно через секунду. Т. е. 11:11; 22;22; 33: 33 и т.д.
     
  13. rf68

    rf68 Нерд

    ЗАРАБОТАЛО!!!!! Надо было прошивать вместе с модулем часов!!!! :) Теперь бы перебор цифр для антиатравления вставить.....
     
  14. fogary

    fogary Гик

    Поздравляю!

    "Перебор цифр для антиатравления" - это что за процесс, можете описать порядок действий?
     
  15. rf68

    rf68 Нерд

    Код (C++):
    #include <DS1302.h> // библиотека для RTC модуля
    //DS1302 rtc(СЕ, IO, SCLK);
    DS1302 rtc(4, 2, 5);
    // выводы для дешифратора
    //defPin[out1,out2,out4,out8];
    int defPin[]={A4, A2, A1, A3};
    //словарь цифр
    char dictionary[10][4] = {
      {1, 0, 0, 1},//0
      {0, 0, 0, 1},//1
      {0, 0, 0, 0},//2
      {1, 0, 1, 0},//3
      {0, 1, 1, 0},//4
      {1, 1, 0, 0},//5
      {0, 1, 0, 0},//6
      {1, 1, 1, 0},//7
      {0, 0, 1, 0},//8
      {1, 0, 0, 0},//9
      };
    // выводы для транзисторных ключей
    int keysPin[] = {12, 8, 7, 6, 0, 1};
    //массив для состояние кнопок
    int buttonPin = 13;
    int massBut[] = {0, 0, 0, 0, 0, 0};
    //  выходы для светодиодов
    int redPin = 9, greenPin = 10, bluePin = 11;
    int colorRed = 0, colorGreen = 0, colorBlue = 0;
    //переменные для времени
    Time t;
    int TimeDate[] = {0, 0, 0, 0, 0, 0}; // массив где хранится временя или дата
    //переменные для меню
    bool flag = true, settingFlag = false;
    long but1 = 0;
    //переменные для счетчиков
    int v = 0, p = 7, k = 0, lock = 0;
    //-------------------------------------------------------
    void setup() {
      // задаем частоту ШИМ на 3 выводе 30кГц
      TCCR2B = TCCR2B & 0b11111000 | 0x01;
      analogWrite(3, 80); //если запитывать от блока питания 9в
      //analogWrite(3, 190); //если запитывать от порта ардуины 5в

      //задаем режим работы выходов микроконтроллера
      for (int i = 0; i < 4; i++) {
        pinMode(defPin[i], OUTPUT);
      }
      for (int i = 0; i < 6; i++) {
        pinMode(keysPin[i], OUTPUT);
      }
      pinMode(buttonPin, INPUT);

      rtc.halt(false);//устанавливаем режим запуска rtc модуля
      rtc.writeProtect(false);//отключаем защиту от записи rtc модуля

    }

    void loop() {
      k++;//счетчик для мигания цифрами
      v++;//счетчик для пебора всех цифр
      setColor();
      checkTimeDate();
      button();
      if (v >= 32760) {//делам прогон всех цифр во избежание "Отравление" катодов ламп
        scroll(25);
        v = 0;
      }
      show(TimeDate);
    }

    void show(int a[])
    {
      for (int i = 0; i < 6; i++)
      {
        setNumber(a[i]);//передаем сигналы для a[i] цифры
        digitalWrite(keysPin[i], HIGH);//подаем сигнал на keysPin[i] индикатор
        if (!((i == p || i == p - 1) && (k > 50))) {//задержка между лампами
          delay(2);
        }
        massBut[i] = digitalRead(buttonPin);//опрос кнопок i-й кнопки  
        digitalWrite(keysPin[i], LOW);//потушим keysPin[i] индикатор
        if ((i == p) && (k > 50)) {//задержка для мигания отдельных разрядов
          delay(2);
        }

        if (k > 100) {
          k = 0;
        }
      }
    }

    //пебора всех цифр
    void scroll(int pause) {
      for (int i = 0; i < 9; i++) {
        int a[] = {i, i, i, i, i, i};
        show(a);
        delay(pause);
      }
    }
    //меню
    void button() {
      if (massBut[1] || massBut[2]) {//организация долгово зажатия 2й и 3й кнопки
        bool doIt = false;
        but1++;//счетчик будет увеличиваться пока кнопка зажата
        if (but1 > 200) {
          if ((but1 % 10) == 0) {
            doIt = true;
          }
        }
        else if (but1 >= 60) {
          if ((but1 % 50) == 0) {
            doIt = true;
          }
        }
        else if (but1 == 4) {
          doIt = true;
        }
        if (doIt && settingFlag && massBut[1] && !massBut[2]) { //кнопка "+"
          TimeDate[p]++;
          configPlus();//проверка допустимых значение
        }
        if (doIt && settingFlag && massBut[2] && !massBut[1]) {//кнопка "-"
          TimeDate[p]--;
          configMinus();//проверка допустимых значение
        }
      }
      if (!lock) {
       
        if (massBut[0]) {
          if (!settingFlag) {//кнопка переключение  между датой и временем
            flag = !flag;
            v = 32760;
          }
          else {//если часы находятся в режиме настройке, то кнопка переключает разряды
            p -= 2;
            if (p < 0) p = 5;
          }
        }
        //кнопка входа в режим настройки
        else if (massBut[3]) {
          p = 5; k = 0;
          settingFlag = !settingFlag;
          if (!settingFlag) {//после того как кнопка была нажата повторна
            updateTimeDate();
            p = 7;
          }
        }
      }
      lock = massBut[0] || massBut[3];//чтобы ардуина считала одно нажатие даже при зажатой кнопки
    }

    void configPlus() {
      int SecYear = TimeDate[4] * 10 + TimeDate[5];//сек и года
      int MinMon = TimeDate[2] * 10 + TimeDate[3];//мин и месеца
      int HourDays = TimeDate[0] * 10 + TimeDate[1];//часы и дни
      //если младший разряд больше 9 то увеличить на 1 старший разряд и младший обнулить
      if (TimeDate[p] > 9) {
        TimeDate[p - 1]++;
        TimeDate[p] = 0;
      }
      if (flag) { //ограничения для времени
        if (HourDays > 23) {
          TimeDate[0] = 0; TimeDate[1] = 0;
        }
        if (MinMon > 59) {
          TimeDate[2] = 0; TimeDate[3] = 0;
        }
        if (SecYear > 59) {
          TimeDate[4] = 0; TimeDate[5] = 0;
        }
      }
      else { //ограничение для даты
        //ограничение по годом не больше 99
        if (SecYear > 99) {
          TimeDate[4] = 0; TimeDate[5] = 0;
        }
        //ограничение по месецам не больше 12
        if (MinMon > 12) {
          TimeDate[2] = 0; TimeDate[3] = 0;
        }
        //ограничение для дней не больше 31 или 30 или 29 дней в определенные месяца
        if ((MinMon == 1 || MinMon == 3 || MinMon == 5 || MinMon == 6 || MinMon == 7 || MinMon == 8 || MinMon == 10 || MinMon == 12) && HourDays > 31) {
          TimeDate[0] = 0; TimeDate[1] = 0;
        }
        else if (( MinMon == 4 || MinMon == 6 || MinMon == 9 || MinMon == 11) && HourDays > 30) {
          TimeDate[0] = 0; TimeDate[1] = 0;
        }
        else if (MinMon == 2 && HourDays > 29) {
          TimeDate[0] = 0; TimeDate[1] = 0;
        }
      }
    }

    void configMinus() {
      int SecYear = TimeDate[4] * 10 + TimeDate[5];//сек и года
      int MinMon = TimeDate[2] * 10 + TimeDate[3];//мин и месеца
      int HourDays = TimeDate[0] * 10 + TimeDate[1];//часы и дни
      //если младший разряд мешьше 0 то уменьшить на 1 старший разряд и младший передать 9
      if (TimeDate[p] < 0) {
        TimeDate[p - 1]--;
        TimeDate[p] = 9;
      }
      if (flag) { //ограничения для времени
        if (HourDays < 0) {
          TimeDate[0] = 2; TimeDate[1] = 3;
        }
        if (MinMon < 0) {
          TimeDate[2] = 5; TimeDate[3] = 9;
        }
        if (SecYear < 0) {
          TimeDate[4] = 5; TimeDate[5] = 9;
        }
      }
      else { //ограничения для даты
        //ограничение по годом
        if (SecYear < 0) {
          TimeDate[4] = 9; TimeDate[5] = 9;
        }
        //ограничение по месецам если меньше нуля по выводить 12й месяц
        if (MinMon < 0) {
          TimeDate[2] = 1; TimeDate[3] = 2;
        }
        //ограничение для дней не больше 31 или 30 или 29 дней в определенные месяца
        if ((MinMon == 1 || MinMon == 3 || MinMon == 5 || MinMon == 6 || MinMon == 7 || MinMon == 8 || MinMon == 10 || MinMon == 12) && HourDays < 0) {
          TimeDate[0] = 3; TimeDate[1] = 1;
        }
        else if (( MinMon == 4 || MinMon == 6 || MinMon == 9 || MinMon == 11) && HourDays < 0) {
          TimeDate[0] = 3; TimeDate[1] = 0;
        }
        else if (MinMon == 2 && HourDays < 0) {
          TimeDate[0] = 2; TimeDate[1] = 9;
        }
      }
    }

    //вывод времени для каждой лампы
    void checkTimeDate() {
      t = rtc.getTime();//считываем время и дату с DS1302
      int temp;
      if (!settingFlag) {//если вышли из режима настройки
        if (flag) {//если мы отображали время то и будем настраивать время иначе будем настраивать дату
          TimeDate[0] = t.hour / 10;
          TimeDate[1] = t.hour % 10;
          TimeDate[2] = t.min / 10;
          TimeDate[3] = t.min % 10;
          TimeDate[4] = t.sec / 10;
          TimeDate[5] = t.sec % 10;
        }
        else {
          TimeDate[0] = t.date / 10;
          TimeDate[1] = t.date % 10;
          TimeDate[2] = t.mon / 10;
          TimeDate[3] = t.mon % 10;
          temp = t.year % 100;
          TimeDate[4] = temp / 10;
          TimeDate[5] = temp % 10;
        }
      }
    }
    //обновления врмени и даты
    void updateTimeDate() {
      if (flag) {
        rtc.setTime(TimeDate[0] * 10 + TimeDate[1], TimeDate[2] * 10 + TimeDate[3], TimeDate[4] * 10 + TimeDate[5]);
      }
      else {
        rtc.setDate(TimeDate[0] * 10 + TimeDate[1], TimeDate[2] * 10 + TimeDate[3], 2000 + TimeDate[4] * 10 + TimeDate[5]);
      }
    }

    void setColor()
    {
        //считываем данные с потенциометров
      int newColorBlue = map(analogRead(A5), 0, 1023, 0, 255);
      int newColorGreen = map(analogRead(A6), 0, 1023, 0, 255);
      int newColorRed = map(analogRead(A7), 0, 1023, 0, 255);

      //если значение с потенциометров не изменились, то ни чего не делаем иначе поменять цвет и записать новые цвет
      if ((newColorRed != colorRed) || (newColorGreen != colorGreen) || (newColorBlue != colorBlue)) {
        analogWrite(redPin, newColorRed);
        analogWrite(greenPin, newColorGreen);
        analogWrite(bluePin, newColorBlue);
        colorRed = newColorRed;
        colorGreen = newColorGreen;
        colorBlue = newColorBlue;
      }
    }

    //вывод опеределенной цифры
    void setNumber(int num) {
      for (int i = 0; i < 4; i++) {//цикл по словарю и взависимости от цифры в словаре подаем сигнал на к155ид1
        digitalWrite(defPin[i], ((dictionary[num][i] == 0) ? LOW : HIGH));
      }
    }
    Для продления жизни газоразрядных индикаторов (лампы, которые показывают время) периодически, например раз в 1, 5 или 10 минут, делать "прогон" всех цифр лампы. Для примера прилагаю подобный проект. Жаль, откопал после сборки своей схемы.
     
  16. fogary

    fogary Гик

    Общий принцип понятен. Возвращаюсь к вопросу, дополнительный провод от RTC к Arduino (для реализации прерывания от будильника часов) подключить сможете?

    Если интересно и не лень, попробуйте такую замену функции setNumber():
    Код (C++):
    void setNumber(byte num) {
      digitalWrite(OUT1, (num & 0x1));
      digitalWrite(OUT2, ((num & 0x2) >> 1));
      digitalWrite(OUT4, ((num & 0x4) >> 2));
      digitalWrite(OUT8, ((num & 0x8) >> 3));
    }
     
  17. rf68

    rf68 Нерд

    при замене ошибка
    :221: error: 'OUT1' was not declared in this scope
    :222: error: 'OUT2' was not declared in this scope
    :223: error: 'OUT4' was not declared in this scope
    :224: error: 'OUT8' was not declared in this scope
    :226: error: expected declaration before '}' token
    exit status 1
    'OUT1' was not declared in this scope
    провод подтянуть смогу.
     
  18. rf68

    rf68 Нерд

    Код (C++):
    //Подключаем библиотеки для работы часов реального времени

    #include <DS3231.h>
    #include <Wire.h>

    // выводы для дешифратора
      int out1 = A3;
      int out2 = A1;
      int out4 = A0;
      int out8 = A2;
    // выводы для транзисторных ключей
      int key1= 4;
      int key2 = 6;
      int key3 = 7;
      int key4 = 8;

      int led1=11;// вывод светодиода
      int keyb=A6;// пин для клавиатуры


      int keynum=0; //номер нажатой кнопки
      int mode =0; //0 - отображение текущего времени 1- установка времени
      int currentdigit = 0; //0 - установка часов 1- установка минут
      bool blinkflag = 0; // флаг для мигания цифр при установке времени
      bool timeout=false; // таймаут после нажатия кнопки (для устраниния дребезга)
      unsigned long startTime; //для мигания светодиода
      unsigned long startTime2; // для опроса нажатых кнопок
      int sec; //переменная увеличивается каждые 500мс на единицу. Нужна для мигания секундных светодиодов, бывает в двух значениях 0 - светодиоды не горят, 1 - горят, если больше 1, то сбрысывается в 0
        //переменные для счетчиков
        int v = 0, p = 7, k = 0, lock = 0;
      // переменные, необходимые для работы ds3231
      DS3231 Clock;
      bool Century=false;
      bool h12;
      bool PM;
      byte ADay, AHour, AMinute, ASecond, ABits;
      bool ADy, A12h, Apm;

      //определяем глобальные переменные для различных параметров часов
      int second,minute,hour,date,month,year,temperature;


    void setup() {
      // put your setup code here, to run once:
      // задаем частоту ШИМ на 9 выводе 30кГц
      TCCR1B=TCCR1B&0b11111000|0x01;
      analogWrite(9,130);

        // Start the I2C interface
      Wire.begin();
      // Start the serial interface
      Serial.begin(9600);
     
      //задаем режим работы выходов микроконтроллера
      pinMode(out1,OUTPUT);
      pinMode(out2,OUTPUT);
      pinMode(out4,OUTPUT);
      pinMode(out8,OUTPUT);

      pinMode(key1,OUTPUT);
      pinMode(key2,OUTPUT);
      pinMode(key3,OUTPUT);
      pinMode(key4,OUTPUT);

      pinMode(led1,OUTPUT);

      startTime = millis();
      startTime2=startTime;
      sec = 0;
      // считываем текущее вермя
      ReadDS3231();
    }

    void ReadDS3231()   //функция считывает в глобальные переменные minute и hour текущие значения
    {
      minute=Clock.getMinute();
      hour=Clock.getHour(h12, PM);
    }


    void loop() {
      // put your main code here, to run repeatedly:
     
      v++;//счетчик для пебора всех цифр

      if (v >= 32760) {//делам прогон всех цифр во избежание "Отравление" катодов ламп
        scroll(25);
        v = 0;
      }
      int digits[3]; // массив для текущего значения времени на четыре цифры
      int keyval= analogRead(keyb); // считываем значение с клавиатуры
     
      unsigned long currentTime = millis(); //текущее время с момента запуска рограммы
       if (currentTime>=(startTime2+200)) // если прошло 200мс посмотрим какая кнопка была нажата
       {
          timeout=false;
         //проверим нажатие кнопок
          if (keynum==3) // кнопка переключения между режимами "время" и "настройка"
          {
            timeout=true; // запрещаем считывать нажатия кнопок
            if (mode==0) mode=1; // если отображалось время, переходим в режим настроек
            else
              if (mode==1) mode=0; //если был режим настроек, переключаемся на текущее время
          }
          if (keynum==2) // кнопка переключения между часами и минутами
          {
            timeout=true; // запрещаем считывать нажатия кнопок
            // currentdigit либо 0 - настройка часов, либо 1 - настройка минут
            currentdigit++;
            if (currentdigit==2) currentdigit=0;
          }
          if (keynum==1) // кнопка увеличения количества часов или минут(при настройке)
          {
            blinkflag=true; // прекращаем мигать цифрами
            startTime=millis();
            timeout=true;  // запрещаем считывать нажатия кнопок
            if (currentdigit==0) // если меняем часы
            {
              if (hour<=22) hour++;
              else
                hour=0;
              Clock.setHour(hour);
            }
            if (currentdigit==1) // если меняем минуты
            {
              if (minute<=58) minute++;
              else
                minute=0;
             Clock.setMinute(minute);//Set the minute
             Clock.setSecond(0);
            }
          }
          keynum=0; //сбрасываем нажатую кнопку
          startTime2=millis();
       }

      if (currentTime>=(startTime+500)) // если прошло 500мс
      {
        blinkflag=!blinkflag; // инвертируем флаг мигающей цифры
         
        if(sec<1) // светодиоды не горят
        {
          // зажечь светодиоды
          digitalWrite(led1,HIGH);
          Serial.println(blinkflag);
         
        }
        if(sec>=1) // светодиоды горят
        {
          // потушить светодиоды
          digitalWrite(led1,LOW);
        }
        startTime = currentTime;
        ReadDS3231();
        sec = (sec+1);
        if(sec>=2) sec=0;

      }
        digits[0] = hour/10;
        digits[1] = hour%10;
        digits[2] = minute/10;
        digits[3] = minute%10;

        show(digits); // вывести цифры на дисплей

      //проверяем нажатые кнопки
      if(!timeout) //если разрешено, считываем нажатую кнопку
      {
        /*keyval - значение функции analogread
         * если нажата первая кнопка, то принимает значение около 200
         * если нажата вторая кнопка то значение около 700
         * если третяя кнопка, то значение будет около 1000
         * эти значения зависят от выбранных резисторов в клавиатуре
        */

        if (keyval>150 && keyval<400) keynum=1;
        if (keyval>700 && keyval<900) keynum=2;
        if (keyval>960) keynum=3;
      }

    }
    //пебора всех цифр
    void scroll(int pause) {
      for (int i = 0; i < 9; i++) {
        int a[] = {i, i, i, i, i, i};
        show(a);
        delay(pause);
      }}
    void show(int a[])
    {
        //выведем цифру a[0] на первый индикатор
      setNumber(a[0]);
      if (!(mode==1&&currentdigit==0&&blinkflag==false)) //если мы в режиме настройки и происходит настройка часов, то в первая цифра будет мигать
      {
        digitalWrite(key1,HIGH);
        delay(2);
        //потушим первый индикатор
        digitalWrite(key1,LOW);
        delay(1);
      }
     
      //цифра a[1] на второй индикатор
      setNumber(a[1]);
      if (!(mode==1&&currentdigit==0&&blinkflag==false))
      {
      digitalWrite(key2,HIGH);
      delay(2);
      //потушим второй индикатор
      digitalWrite(key2,LOW);
      delay(1);
      }

      //цифра a[2] на третий индикатор
      setNumber(a[2]);
      if (!(mode==1&&currentdigit==1&&blinkflag==false))
      {
      digitalWrite(key3,HIGH);
      delay(2);
      //потушим третий индикатор
      digitalWrite(key3,LOW);
      delay(1);
      }

      //выведем цифру a[3] на четвертый индикатор
      setNumber(a[3]);
      if (!(mode==1&&currentdigit==1&&blinkflag==false))
      {
      digitalWrite(key4,HIGH);
      delay(2);
      //потушим четвертый индикатор
      digitalWrite(key4,LOW);
      delay(1);
      }
    }
    // передача цифры на дешифратор
    void setNumber(int num)
    {
      switch (num)
      {
        case 0:
        digitalWrite (out1,LOW);
        digitalWrite (out2,LOW);
        digitalWrite (out4,LOW);
        digitalWrite (out8,LOW);
        break;
        case 1:
        digitalWrite (out1,HIGH);
        digitalWrite (out2,LOW);
        digitalWrite (out4,LOW);
        digitalWrite (out8,LOW);
        break;
        case 2:
        digitalWrite (out1,LOW);
        digitalWrite (out2,HIGH);
        digitalWrite (out4,LOW);
        digitalWrite (out8,LOW);
        break;
        case 3:
        digitalWrite (out1,HIGH);
        digitalWrite (out2,HIGH);
        digitalWrite (out4,LOW);
        digitalWrite (out8,LOW);
        break;
        case 4:
        digitalWrite (out1,LOW);
        digitalWrite (out2,LOW);
        digitalWrite (out4,HIGH);
        digitalWrite (out8,LOW);
        break;
        case 5:
        digitalWrite (out1,HIGH);
        digitalWrite (out2,LOW);
        digitalWrite (out4,HIGH);
        digitalWrite (out8,LOW);
        break;
        case 6:
        digitalWrite (out1,LOW);
        digitalWrite (out2,HIGH);
        digitalWrite (out4,HIGH);
        digitalWrite (out8,LOW);
        break;
        case 7:
        digitalWrite (out1,HIGH);
        digitalWrite (out2,HIGH);
        digitalWrite (out4,HIGH);
        digitalWrite (out8,LOW);
        break;
        case 8:
        digitalWrite (out1,LOW);
        digitalWrite (out2,LOW);
        digitalWrite (out4,LOW);
        digitalWrite (out8,HIGH);
        break;
        case 9:
        digitalWrite (out1,HIGH);
        digitalWrite (out2,LOW);
        digitalWrite (out4,LOW);
        digitalWrite (out8,HIGH);
        break;
      }
    }
     
  19. rf68

    rf68 Нерд

    Загрузил, может там что лишнее, но работает...
     
  20. fogary

    fogary Гик

    Извиняюсь не доглядел, для Вашего кода нужно поменять регистр в именах переменных. Вместо OUT1…OUT4, подставить out1…out4, т. е. по образу как в оригинальной версии функции.
    Если не затруднит, попробуйте еще такой вариант:
    Код (C++):
    void setNumber(byte num) {
      digitalWrite(out1, (num & 0x1));
      digitalWrite(out2, (num & 0x2));
      digitalWrite(out4, (num & 0x4));
      digitalWrite(out8, (num & 0x8));
    }
    Доп. провод: от выхода "INT/SQW" модуля RTC, на пин D2 платы Arduino.

    Попробую набросать тестовый вариант, без кнопок, с периодическим "прогоном" всех цифр.