Ограничение диапазона переменной

Maka
Offline
Зарегистрирован: 24.10.2015

Добрый день, с праздником!

В моем скетче существует большое количество переменных для отображения/изменения/записи в eeprom часов и минут. 

Возможно ли создание своего типа данных hour с диапазоном 0-23 и min от 0 до 59?. Это избавило бы меня от многочисленных 

if (led1_start_h > 23) led1_start_h = 0;

if (led1_start_m > 59) led1_start_m = 0;

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

Конечно, возможно. Это же С++! Откройте любое руководство по С++, там всё написано. Создаёте тип, определяеете для него арифметику и собственно всё.

Остался правда вопрос, что делать с перееносом разряда. Например, при сложении переменной типа "минуты", равной 55 и числа 10, результат - 5, но 1 должна быть перенесена в часы. Если бы у Вас был один тип "время", Вы бы решили эту проблему локально, а если у Вас отдельно тип "часы" и тип "минуты", то с переносами придётся всё равно руками бороться.

uni
uni аватар
Offline
Зарегистрирован: 24.09.2015

Можно хранить всего одну переменную типа time_t, как в UNIX, и все операции выполнять с ним. Эта переменная хранит количество секунд от эпохи unix. Код для перевода туда и обратно можно найти в сети.

Maka
Offline
Зарегистрирован: 24.10.2015

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

Конечно, возможно. Это же С++! Откройте любое руководство по С++, там всё написано. Создаёте тип, определяеете для него арифметику и собственно всё.

Остался правда вопрос, что делать с перееносом разряда. Например, при сложении переменной типа "минуты", равной 55 и числа 10, результат - 5, но 1 должна быть перенесена в часы. Если бы у Вас был один тип "время", Вы бы решили эту проблему локально, а если у Вас отдельно тип "часы" и тип "минуты", то с переносами придётся всё равно руками бороться.

Евгений, а можно поподробней? Про что  читать? Читал про пользовательские типы данных - структуры, битовые поля, перечисления, но не подходит вроде. Как создать что-то вроде byte, только не 0-255, а 0-59 и 0-23?

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

uni
uni аватар
Offline
Зарегистрирован: 24.09.2015

С time_t все ограничения получаются автоматически, они просто не нужны. Зачем нужен велосипед в таком тонком деле как работа со временем?

Maka
Offline
Зарегистрирован: 24.10.2015

uni пишет:

С time_t все ограничения получаются автоматически, они просто не нужны. Зачем нужен велосипед в таком тонком деле как работа со временем?

Может я и не прав, но мне показалось проще в еепроме хранить отдельно часы и минуты для каждого канала, и на монитор выводить для контроля/изменения тоже удобней. Ведь если в еепром будет записан long часы+минуты*секунды, то чтобы отобразить его на lcd в понятном виде... , хотя надо подумать. В еепроме лонг, я его считываю, кнопками плюсую - минусую, потом пересчитываю в вид hh:mm для lcd, и пишу в память новый лонг. Как то так?

uni
uni аватар
Offline
Зарегистрирован: 24.09.2015

Кто же знал, что у вас ещё каналы есть, а вообще, вот тут можно посмотреть код для работы с time_t, правда в нём есть одна досадная ошибка, которую мне лень исправить (плюс на минус поменять).

В том коде используется 32-битовая переменная для хранения секунд (CSystemTime::Counter). Начало отсчёта можно в принципе выбрать любое, но в коде оно принято равным 1 января 1970 (эпоха unix). Далее можно этот код использовать по-разному. Можно как конвертор, можно как программный календарь (Software RTC).

Арифметика со временем поддерживается самим типом данных.

uni
uni аватар
Offline
Зарегистрирован: 24.09.2015

А время отображается так с этим кодом (не Arduino проект):

void TFormRTC::ShowDateTime(){

    SYSTEMTIME Time = { 0, 0, 0, 0, 0, 0, 0, 0 };

    CSystemTime::GetTimeAsSystemTime( & Time );

    CLCD::PutChar( Time.wHour / 10 + '0', 0, 7 );
    CLCD::PutChar( Time.wHour % 10 + '0' );
    
    CLCD::PutChar( ':' );
    
    CLCD::PutChar( Time.wMinute / 10 + '0' );
    CLCD::PutChar( Time.wMinute % 10 + '0' );
    
    CLCD::PutChar( ':' );
    
    CLCD::PutChar( Time.wSecond / 10 + '0' );
    CLCD::PutChar( Time.wSecond % 10 + '0' );

    CLCD::PutChar( Time.wDay / 10 + '0', 1, 6 );
    CLCD::PutChar( Time.wDay % 10 + '0' );
    
    CLCD::PutChar( '-' );
    
    CLCD::PutChar( Time.wMonth / 10 + '0' );
    CLCD::PutChar( Time.wMonth % 10 + '0' );
    
    CLCD::PutChar( '-' );
    
    uint16_t tmp = Time.wYear;

    CLCD::PutChar( ( uint8_t ) ( tmp / 1000U ) + '0' );
    tmp %= 1000U;

    CLCD::PutChar( ( uint8_t ) ( tmp / 100 ) + '0' );
    tmp %= 100;

    CLCD::PutChar( ( uint8_t ) ( tmp / 10 ) + '0' );

    CLCD::PutChar( ( uint8_t ) ( tmp % 10 ) + '0' );

};

 

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

Maka пишет:

Евгений, а можно поподробней? Про что  читать? 

Про классы и определение операци (тимпа +, - и т.п.). Создаёте класс, определяете для него операции сложения, вычитания и чего там Вам ещё надо, а потом работаете с ними как с любыми интами.

Maka
Offline
Зарегистрирован: 24.10.2015

Спасибо всем, буду думать...