Зависают часы на DS1307 и индикаторе 4-чразрядном на TM1650 плюс Arduino UNO.

Dimych70
Offline
Зарегистрирован: 03.02.2022

В общем собрал, написал скетч, вроде работает, но постоянно виснет. Просто останавливается работа и молчек.

Начал ковырять с нуля. Оставил вообще только основу.

#include <Wire.h>
#include <TM1650.h>

#define OUTR 7 //Выход на реле UNO

TM1650 d;

unsigned long timer1 = 0;
bool dot_state = false;
int n = 0;

void setup() {
  pinMode(OUTR, OUTPUT);
  Wire.begin();
  Wire.setClock(400000);
  //RTC_init();
  Serial.begin(115200);
  d.init();
  d.setBrightness(TM1650_MIN_BRIGHT);
  d.displayOn();
}

void loop() {
  if (millis() - timer1 >= 1000){
    char line[5];
    timer1 = millis();
    sprintf(line, "%u", n);
    d.displayString(line);
    dot_state = !dot_state;
    d.setDot(3, dot_state);
    digitalWrite(OUTR, !dot_state);
    Serial.println(n);
    n++;
  }
}

Вот модуль, при включении которого происходит зависание. Это я в свое время взял какую-то библиотеку для RTC и вынул оттуда только 2 функции практически. Уже много где его использую, просто подключаю к скечу. А тут почему-то не работает.

#define I2C_ADDR 0x68

void RTC_init() {
  uint8_t sec;
//  timeClient.begin();
  
  //get second and CH bit
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDR, 1);
  sec = Wire.read();
  Wire.read();

  //set second and clear CH bit
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.write(sec & 0x7F);
  Wire.endTransmission();
}

void get_RTC(uint8_t *sec, uint8_t *min, uint8_t *hour, uint8_t *day, uint8_t *month, uint16_t *year) {
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDR, 7);
  *sec   = bcd2bin(Wire.read() & 0x7F);
  *min   = bcd2bin(Wire.read());
  *hour  = bcd2bin(Wire.read());
           bcd2bin(Wire.read()); //day of week
  *day   = bcd2bin(Wire.read());
  *month = bcd2bin(Wire.read());
  *year  = bcd2bin(Wire.read()) + 2000;

  return;
}

void set_RTC(uint8_t sec, uint8_t min, uint8_t hour, uint8_t day, uint8_t month, uint16_t year)
{
  uint8_t ch, d;

  if(year >= 2000)
  {
    year -= 2000;
  }

  //get CH bit
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDR, 1);
  ch = Wire.read();
  d  = Wire.read();
  
  if(ch & 0x80) //CH set?
  {
    ch = 0x80;
  }
  else
  {
    ch = 0x00;
  }

  //set time and date
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.write(bin2bcd(sec) | ch);
  Wire.write(bin2bcd(min));
  Wire.write(bin2bcd(hour));
  Wire.write(bin2bcd(0));
  Wire.write(bin2bcd(day));
  Wire.write(bin2bcd(month));
  Wire.write(bin2bcd(year));
  Wire.endTransmission();

  return;
}

void set_RTC(int sec, int min, int hour, int day, int month, int year)
{
  return set_RTC((uint8_t)sec, (uint8_t)min, (uint8_t)hour, (uint8_t)day, (uint8_t)month, (uint16_t)year);
}

uint8_t bin2bcd(uint8_t val) {
  return val + 6 * (val / 10);
}

uint8_t bcd2bin(uint8_t val) {
  return val - 6 * (val >> 4);
}

Посмотрите мастера. Я все-таки еще очень слабый программист на таких языках.

Dimych70
Offline
Зарегистрирован: 03.02.2022

Это схема устройства. Две Attiny на схеме для печатной платы. Просто пока буду писать скетч, буду ее в калодку на переходнике вставлять. Идея включать свет по будильнику утром, гасить когда светло станет, включать когда стемнее и выключать по будильнику вечером.

Dimych70
Offline
Зарегистрирован: 03.02.2022

А нет. Зависло и без RTC.

Может конечно контакты... Пока на макетном бредборде собрано. Вечером уже с почти печатные платы заберу и спаяю.

Но может и не контакт, а хрень в программе.

Wire.setClock ставил и по умолчанию 100000 и 50000 и вот сейчас 400000. Не влияет. Хотя при 400000 дольше всего проработало.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Что на дисплее при зависании ?

Dimych70
Offline
Зарегистрирован: 03.02.2022

В принципе последнее число может остаться, а могут какие-то сегменты погаснуть или загорется лишние.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Заем Вы привели два скетча и ничего не пояснили? Первый виснет или нет? В нём есть очевидная ошибка, но, может, и не одна. Та, что я сразу вижу - буфер line слишком маленький, он должен быть как минимум 6 символов, а у Вас только 5.

Dimych70
Offline
Зарегистрирован: 03.02.2022

Первй скетч это основа, которая очень редко, но, как оказалось, таки тоже зависает. Там видите закомментировано RTC_init() - это подключается второй файл с инициализацией RTC. Я уже написал выше, что год или 2 назад бился с RTC библиотеками для DS1307, все не стабильно они работали. В итоге надергал только нужные строки из одно, убрал запуск Wire и так у меня во многих скетчах работает.

Пояснить.

Ну второй ясно - работа с DS1307.

Первый просто вывод на экран с интервалом в 1 секунду числа n, запятой в последнем разряде и мигание светодиодом через релюшку (в конце концов там будет коммутироваться 220В).

Вроде все.

А что за ошибка?

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

25 строка

Dimych70
Offline
Зарегистрирован: 03.02.2022

ua6em пишет:

25 строка

А что не так? Я вот с чарами никак до конца не разберусь. Но при компиляции ошибку не выдает.

Если вы о том, что может быть больше 4 символов, ну так это ясно, просто больше полутора тысяч пока не насчитывает и поэтому виснет. В конце концов то там просто время будет из 4 знаков.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Dimych70 пишет:

А что за ошибка?

А Вы мой пост читали?

ЕвгенийП пишет:

Та, что я сразу вижу - буфер line слишком маленький, он должен быть как минимум 6 символов, а у Вас только 5.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Куда заливаете скетч ?

Dimych70
Offline
Зарегистрирован: 03.02.2022

ЕвгенийП пишет:

А Вы мой пост читали?

Ой! То что ошибка увидел, а какая - нет. Я думал, что надо размер массива ставить сколько символов максимально плю 1, т.е. максимально 4 символа +1 ставим 5. Хорошо, сейчас 6 поставлю. Но не из-за этого ведь виснет?

Dimych70
Offline
Зарегистрирован: 03.02.2022

Komandir пишет:

Куда заливаете скетч ?

Пока Arduino UNO использую. Как все отработаю буду под Attiny передлывать.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

А что с подтяжкой ? На схеме вроде есть, а на деле ?

Dimych70
Offline
Зарегистрирован: 03.02.2022

Komandir пишет:

А что с подтяжкой ? На схеме вроде есть, а на деле ?

На деле тоже есть. Только не 10кОм, а 4,7кОм. Это я после мучений с датчиками AHT10 решил поставить. Хотя раньше всегда 10 ставил.

Dimych70
Offline
Зарегистрирован: 03.02.2022

На плату распаял вчера, не виснут. но часы не работают. Похоже DS1307 сдохла. 7 нога, которая в принципе никуда не идет на землю звонится на коротко. Сегодня вечером другую микруху впаяю и посмотрю.

Dimych70
Offline
Зарегистрирован: 03.02.2022

Народ, прошу помощи. Часы запустить не удалось. Микросхему перепаял, сопротивление резисторов проверил, цепи вроде тоже все проверил. Да их там немного. Только кварц пока не трогал, но что ему будет? Само устройство Wire видит, но часы не ходют, показывают время 165:165. При этом i2c я так понимаю работает, т.к. индикатор работает и картинка на него передается правильная. Куда можно покопать?

b707
Offline
Зарегистрирован: 26.05.2017

Dimych70 пишет:

часы не ходют, показывают время 165:165.

выложите последний код после всех правок

Dimych70
Offline
Зарегистрирован: 03.02.2022

Основной модуль

 #include <Wire.h>
#include <TM1650.h>

#define OUTR 7 //Выход на реле UNO

TM1650 d;

unsigned long timer1 = 0;
bool dot_state = false;
int cmin, chour, cday, cmon, cyear;


void setup() {
  pinMode(OUTR, OUTPUT);
  Serial.begin(115200);
  Wire_init();
  RTC_init();
  d.init();
  d.displayOff();
  d.setBrightness(TM1650_MIN_BRIGHT);
  d.displayOn();
}

void loop() {
  if (millis() - timer1 >= 1000){
    uint8_t sec, min, hour, day, month;
    uint16_t year;
    get_RTC(&sec, &min, &hour, &day, &month, &year);
    timer1 = millis();
    d.displayString("1234");
    dot_state = !dot_state;
    d.setDot(1, dot_state);
    Serial.print(hour);
    Serial.print(":");
    Serial.println(min);
  }
}

void GetTime() {
  uint8_t sec, min, hour, day, month;
  uint16_t year;
  get_RTC(&sec, &min, &hour, &day, &month, &year);
  cmin = min;
  chour = hour;
  cday = day;
  cmon = month;
  cyear = year;
}

Модуль Wire

void Wire_init() {
  Wire.begin();
  Wire.setClock(400000);
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknow error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }   
  }
  if (nDevices == 0){Serial.println("No I2C devices found\n");}
  else {Serial.println("done\n");}
}

Модуль RTC

#define I2C_ADDR 0x68

void RTC_init() {
  uint8_t sec;
  
  //get second and CH bit
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDR, 1);
  sec = Wire.read();
  Wire.read();

  //set second and clear CH bit
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.write(sec & 0x7F);
  Wire.endTransmission();
}

void get_RTC(uint8_t *sec, uint8_t *min, uint8_t *hour, uint8_t *day, uint8_t *month, uint16_t *year) {
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDR, 7);
  *sec   = bcd2bin(Wire.read() & 0x7F);
  *min   = bcd2bin(Wire.read());
  *hour  = bcd2bin(Wire.read());
           bcd2bin(Wire.read()); //day of week
  *day   = bcd2bin(Wire.read());
  *month = bcd2bin(Wire.read());
  *year  = bcd2bin(Wire.read()) + 2000;

  return;
}

void set_RTC(uint8_t sec, uint8_t min, uint8_t hour, uint8_t day, uint8_t month, uint16_t year)
{
  uint8_t ch, d;

  if(year >= 2000)
  {
    year -= 2000;
  }

  //get CH bit
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDR, 1);
  ch = Wire.read();
  d  = Wire.read();
  
  if(ch & 0x80) //CH set?
  {
    ch = 0x80;
  }
  else
  {
    ch = 0x00;
  }

  //set time and date
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(byte(0x00));
  Wire.write(bin2bcd(sec) | ch);
  Wire.write(bin2bcd(min));
  Wire.write(bin2bcd(hour));
  Wire.write(bin2bcd(0));
  Wire.write(bin2bcd(day));
  Wire.write(bin2bcd(month));
  Wire.write(bin2bcd(year));
  Wire.endTransmission();

  return;
}

void set_RTC(int sec, int min, int hour, int day, int month, int year)
{
  return set_RTC((uint8_t)sec, (uint8_t)min, (uint8_t)hour, (uint8_t)day, (uint8_t)month, (uint16_t)year);
}

uint8_t bin2bcd(uint8_t val) {
  return val + 6 * (val / 10);
}

uint8_t bcd2bin(uint8_t val) {
  return val - 6 * (val >> 4);
}

 

nik182
Offline
Зарегистрирован: 04.05.2015

У меня есть 1307, которая стоит с момента покупки.

Dimych70
Offline
Зарегистрирован: 03.02.2022

nik182 пишет:
У меня есть 1307, которая стоит с момента покупки.

У меня тоже есть. В 2 устройствах работает. А тут почему-то не пашет.

Dimych70
Offline
Зарегистрирован: 03.02.2022

У меня сейчас два устройства в разработке. Метеостанция из соседней темы и этот включатель\выключатель. Сверил сигналы осцилографом на ногах DS1307. Одинаковые. Но одна не работает, а другая работает. Схемы копировал в EasyEDA, там же платы разводил. Делал платы у JLCPCB. Т.е. в схеме все один в один. В скетчах к стати тоже одинаковые блоки для Wire и RTC

b707
Offline
Зарегистрирован: 26.05.2017

Dimych70 пишет:

Основной модуль

 

Модуль Wire


Модуль RTC


не вижу, где вы эти модули подключаете в основном коде. Как называются файлы?

Dimych70
Offline
Зарегистрирован: 03.02.2022

Строки 16 и 17 основного кода. Это вызов инициализирующих процедур. Модули в виде файлов ino лежат в одной папке с основным файлом.

b707
Offline
Зарегистрирован: 26.05.2017

Dimych70 пишет:

Модули в виде файлов ino лежат в одной папке с основным файлом.

а нормально, через .h файлы -  сделать не судьба?

Dimych70
Offline
Зарегистрирован: 03.02.2022

b707 пишет:

Dimych70 пишет:

Модули в виде файлов ino лежат в одной папке с основным файлом.

а нормально, через .h файлы -  сделать не судьба?

На самом деле все основные настройки и подключение библиотек в set.h файле, а в основном сверху стоит #include set.h

А по большому счету какая разница .ino или .h? Те что .ino лежат в одной папке прописывать нигде не надо. Ну и с другой стороны из-за этого ведь не может не работать время?

Dimych70
Offline
Зарегистрирован: 03.02.2022

Может чего подскажет. Попробовал поменять местами SCL и SDA. Индикатор работать перестал. Часы так же показывают 165:165. Да, пока подключено к UNO SDA-A4, SCL-A5.

Запитал не от компьютерного USB, а от БП 2А для моего смартфона Huawei. Ситуация не изменилась.

b707
Offline
Зарегистрирован: 26.05.2017

Dimych70 пишет:

Часы так же показывают 165:165.

вас это не удивляет? Или на двух других аналогичных проектах у вас тоже часы 165 минут показывали?

Очевидно, что проблема не в том. что "один из DS1307 не работает, а другой работает", а в кривом коде. Даже если у вас модуль RTC нерабочий и отдает неверное время или не отдает никакого - программа не должна показывать очевидную чушь на экране.

Dimych70
Offline
Зарегистрирован: 03.02.2022

Это понятно. Я так понимаю, что для этого вы и попросили меня код выложить. Собственно я с этого и начал, спросил что не так в моем коде.

И все-таки код в устройстве где часы работают и где не работают - один. Ну код в файлах Wire.ino и RTC.ino. Я их просто копирую из проекта в проект.

И еще вопрос. Стока #define I2C_ADDR 0x68 задает адрес 0х68 для RTC? Просто если я его меняю на другой, он либо не меняется, либо Wire не видит его.

b707
Offline
Зарегистрирован: 26.05.2017

Dimych70 пишет:

Стока #define I2C_ADDR 0x68 задает адрес 0х68 для RTC?

нет, это адрес, куда вы посылаете запросы. С адресом RTC он может и не совпадать.

Кстати, посмотрел внимательнее код - у вас вывода на дисплей нет вообще. Вы где свои 165:165 видите - в Сериал?

И еще - в вашем модуле Wire у вас. кроме Wire.begin() - целиком встроен i2c сканер. Это что. у вас и в готовых проектах так же - при каждом запуске шина будет сканироваться?

Dimych70
Offline
Зарегистрирован: 03.02.2022

b707 пишет:

Кстати, посмотрел внимательнее код - у вас вывода на дисплей нет вообще. Вы где свои 165:165 видите - в Сериал?

Да, время на дисплей не выводится. Смотрю в Serial.

b707 пишет:

И еще - в вашем модуле Wire у вас. кроме Wire.begin() - целиком встроен i2c сканер. Это что. у вас и в готовых проектах так же - при каждом запуске шина будет сканироваться?

Нет. Это только во время отладки.

И да. Какая-то ошибка в коде. Нашел скетч, которым когда-то начинал разбираться с RTC. добавил туда свой индикатор и все заработало!

#include <Wire.h>
#include <iarduino_RTC.h>
#include <TM1650.h>
iarduino_RTC watch(RTC_DS1307);
TM1650 d;
//  Определяем системное время:                           // Время загрузки скетча.
const char* strM="JanFebMarAprMayJunJulAugSepOctNovDec";  // Определяем массив всех вариантов текстового представления текущего месяца.
const char* sysT=__TIME__;                                // Получаем время компиляции скетча в формате "SS:MM:HH".
const char* sysD=__DATE__;                                // Получаем дату  компиляции скетча в формате "MMM:DD:YYYY", где МММ - текстовое представление текущего месяца, например: Jul.
//  Парсим полученные значения sysT и sysD в массив i:    // Определяем массив «i» из 6 элементов типа int, содержащий следующие значения: секунды, минуты, часы, день, месяц и год компиляции скетча.
const int i[6] {(sysT[6]-48)*10+(sysT[7]-48), (sysT[3]-48)*10+(sysT[4]-48), (sysT[0]-48)*10+(sysT[1]-48), (sysD[4]-48)*10+(sysD[5]-48), ((int)memmem(strM,36,sysD,3)+3-(int)&strM[0])/3, (sysD[9]-48)*10+(sysD[10]-48)};
unsigned long timer1 = 0;
bool dot_state = false;

void setup() {
    Serial.begin(115200);  
    watch.begin();                         // инициируем RTC модуль
    watch.settime(i[0],i[1],i[2],i[3],i[4],i[5]);
    watch.blinktime(2);
    d.init();
    d.displayOff();
    d.setBrightness(TM1650_MIN_BRIGHT);
    d.displayOn();
}

void loop(){
 if (millis() - timer1 >= 1000){  
    timer1 = millis(); 
    d.displayString(watch.gettime("Hi"));
    dot_state = !dot_state;
    d.setDot(1, dot_state);
    Serial.println(watch.gettime("H:i:s"));
    Serial.println(watch.gettime("d-m-Y   D"));
 }
}

Но теперь еще больше непонятно где ошибка? Ведь эти файлы я действительно не трогаю, а просто копирую в новый проект.

b707
Offline
Зарегистрирован: 26.05.2017

Dimych70 пишет:

Но теперь еще больше непонятно где ошибка? Ведь эти файлы я действительно не трогаю, а просто копирую в новый проект.

не утверждаю, что проблема в этом - но создание кода из нескольких ino файлов лично я считаю кривым колхозом. Основная проблема в том, что вы никогда не знаете, в каком порядке Ардуино ИДЕ склеит эти файлы в один и где поместит обьявления функций.

b707
Offline
Зарегистрирован: 26.05.2017

кстати. а вот эти функции вы откуда взяли?

uint8_t bin2bcd(uint8_t val) {
  return val + 6 * (val / 10);
}

uint8_t bcd2bin(uint8_t val) {
  return val - 6 * (val >> 4);
}

я еще сразу обратил на них внимание - они совершенно нелогичные. Почему верхний разряд домножаем на шесть? 

Сейчас глянул у вас по ссылке либу iarduino_RTC.h - и там преобразование другое, множитель 10, как и должно быть.

Dimych70
Offline
Зарегистрирован: 03.02.2022

Я вас понял. Тогда вытекающий из этого вопрос. Я правильно понял, что .h файлы надо обязательно объявлять перед Setup?

И сейчас подробнее посмотрел и... оказывается я соврал. Рабочий вариант RTC немного другой. там время из интернета берется. Собственно я эти функции и вырезал. Сейчас попробую поподробнее посмотреть, может чего лишнее вырезал.

Dimych70
Offline
Зарегистрирован: 03.02.2022

b707 пишет:

кстати. а вот эти функции вы откуда взяли?

uint8_t bin2bcd(uint8_t val) {
  return val + 6 * (val / 10);
}

uint8_t bcd2bin(uint8_t val) {
  return val - 6 * (val >> 4);
}

я еще сразу обратил на них внимание - они совершенно нелогичные. Почему верхний разряд домножаем на шесть? 

Сейчас глянул у вас по ссылке либу iarduino_RTC.h - и там преобразование другое, множитель 10, как и должно быть.

Из какой-то библиотеки по RTC. Давно было, больше года назад. Сейчас уже не вспомню из какой. 

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

Может к стати в этом проблема и в другом моем скетче из другой темы?

b707
Offline
Зарегистрирован: 26.05.2017

кстати, на мой взгляд в верхней функции


uint8_t bin2bcd(uint8_t val) {
  return val + 6 * (val / 10);
}

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

должно быть как-то так:

uint8_t bin2bcd(uint8_t val) {
  return val%10 +  ((val / 10)<<4);
}

 

Dimych70
Offline
Зарегистрирован: 03.02.2022

Нашел из какой библиотеки я свою обработку RTC взял.

RTClib-1.4.1

/**************************************************************************/
/*!
    @brief  Convert a binary coded decimal value to binary. RTC stores time/date values as BCD.
    @param val BCD value
    @return Binary value
*/
/**************************************************************************/
static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }

/**************************************************************************/
/*!
    @brief  Convert a binary value to BCD format for the RTC registers
    @param val Binary value
    @return BCD value
*/
/**************************************************************************/
static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }



/**************************************************************************/

 

b707
Offline
Зарегистрирован: 26.05.2017

смотрите iarduino_RTC.h - там другие формулы.

Не берусь сказать, какой из вариантов более правильный, но судя по тому. что тестовый скетч от iarduino_RTC.h работает - я бы пользовался ей.

Dimych70
Offline
Зарегистрирован: 03.02.2022

Да, я тоже так думаю. И в другом скетче метеостанции, тоже попробую заменить. МОжет он виснуть перестанет.

sadman41
Offline
Зарегистрирован: 19.10.2016

Тут надо собирать на стороне макет и в отладку погружаться. Слишком странная плавающая ошибка.

Dimych70
Offline
Зарегистрирован: 03.02.2022

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

Снова я проигрываю войну переменной типа char. Ну никак не победю ее. И вот сейчас. В этой библиотеке есть типа функция мигания тем разрядом, который ты менячешь. Но как это не работало год назад, так и не работает, хоть и вышла новая версия библиотеки. А где написать разработчику, так я и не нашел.

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

      case 5:
        if (dot_state) d.displayString(watch.gettime("Hi"));
        else {
          char* hr = watch.gettime("H");
          strcat(hr, "  ");
          d.displayString(hr);
        }
        dot_state = !dot_state;
        d.setDot(1, dot_state);
        break;

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

      case 6:
        if (dot_state) d.displayString(watch.gettime("Hi"));
        else {
          char* mn = "  "
          char* mn1 = watch.gettime("i");
          strcat(mn, mn1);
          d.displayString(mn);
        }
        dot_state = !dot_state;
        d.setDot(1, dot_state);
        break;

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

Тогда я попробовал так:

      case 6:
        if (dot_state) d.displayString(watch.gettime("Hi"));
        else {
          char mn[5];
          mn[0] = (char)0;
          mn[5] = "  ";
          strcat(mn, watch.gettime("i"));
          d.displayString(mn);
          Serial.println(mn);
        }
        dot_state = !dot_state;
        d.setDot(1, dot_state);
        break;

Но тут другая печаль. В итоге на экран должгно выдаваться "  35". В Serial так и выдается, а вот на экран выходит только минуты. Т.е. текущее время 1535, на экране мигает то 1535, то 3535. т.е. 2 первых пробела пропадают!

Пол дня уже бьюсь! Никак не понимаю.

b707
Offline
Зарегистрирован: 26.05.2017

Что вот это

char* mn = "  "
char* mn1 = watch.gettime("i");

что это

mn[0] = (char)0;
mn[5] = "  ";

и это

char* hr = watch.gettime("H");
strcat(hr, "  ");

какая-то редкостная чушь...

откуда вы эту траву берете....

Dimych70
Offline
Зарегистрирован: 03.02.2022

В первом случае надо к двум пробелам добавить значение минут. Делаю это потом с помощью strcat(mn, mn1).

Во втором случае я где-то на просторах инета нашел, что так очищается char переменная. mn[0] = (char)0;

b707
Offline
Зарегистрирован: 26.05.2017

Сначала поймите простую вешь - строка в формате char* - это просто массив байт с нулем на конце. там нет никакого шаманства, этот массив ничем не отличается от какого-нить такого

byte dd[] = {3,4,6,8);

ваше время 15:35 в массиве выглядит так

char mn[] = {'1','5',':','3','5',0};

а чтобы выключить часы. нужно сделать так

char mn[] = {' ',' ',':','3','5',0};

То есть надо ЗАМЕНЯТЬ символы, а не добавлять! Команда strcat - добавляет

Dimych70
Offline
Зарегистрирован: 03.02.2022

Т.е. 

mn[] = {'1','5',':','3','5',0};
mn[0]=' ';
mn[1]=' ';

И выводить mn на дисплей? Сейчас попробую!

Dimych70
Offline
Зарегистрирован: 03.02.2022

Точнее mn[0] = 20 и mn[1] = 20

b707
Offline
Зарегистрирован: 26.05.2017

Dimych70 пишет:

Точнее mn[0] = 20 и mn[1] = 20

тогда уж не mn[0] = 20, а mn[0] = 0х20 или mn[0] = 32

Но лучше пишите mn[0] = '  ' - не ошибетесь

Dimych70
Offline
Зарегистрирован: 03.02.2022

b707 пишет:

Dimych70 пишет:

Точнее mn[0] = 20 и mn[1] = 20

тогда уж не mn[0] = 20, а mn[0] = 0х20 или mn[0] = 32

Но лучше пишите mn[0] = '  ' - не ошибетесь

Я почему начал коды подбирать? Потому что написал mn[0] = " " и получил не пробел, а | скорее всего или 1. Оказывается есть разница в каких кавычках писать, потому что mn[0] = ' ' действительно дало пробел!

Огромное спасибо!

Но война не закончена. теперь мне предстоит преобразовывать char в int и обратно, чтобы настраивать часы, т.е. прибавлять или отнимать минуты, часы, дни, месяцы при установке часов!

nik182
Offline
Зарегистрирован: 04.05.2015

Зачем? Всё должно быть в интах, чары нужны только для вывода на экран.

Dimych70
Offline
Зарегистрирован: 03.02.2022

nik182 пишет:

Зачем? Всё должно быть в интах, чары нужны только для вывода на экран.

Да, там вроде в библиотеке есть обращение к минутам, часам как к int. Ща почитаю.

Dimych70
Offline
Зарегистрирован: 03.02.2022

Народ, подскажите, вроде со всем разобрался. Есть у меня две установки, которые хранятся в eeprom. Но собственно не важно где они хранятся. В общем есть одна переменная час включения и одна переменная минуты включения. Скажем 7 часов 0 минут. Две byte переменные 7 и 0. Мне надо вывести на экран соответственно 0700. Вот последнее мое изыскание, но не работает:

        char out_on[5] = "1234";
        char out_on0[2] = "";
        char out_on1[2] = "";
        char out_on2[2] = "";
        char out_on3[2] = "";
        itoa(VAR_ON_HOUR/10, out_on0, DEC);
        itoa(VAR_ON_HOUR%10, out_on1, DEC);
        itoa(VAR_ON_MIN/10, out_on2, DEC);
        itoa(VAR_ON_MIN%10, out_on3, DEC);
        out_on[0] = out_on0;
        out_on[1] = out_on1;
        out_on[2] = out_on2;
        out_on[3] = out_on3;
        d.displayString(out_on);

Выводит чушь на экран. Вот не складывается у меня с символьными массивами! Сегодня весь день в перерывах работы читал про работу с char. Видно не начитал.