Часы на max7219 + DS1307 + DS18B20 + BMP180

vlad1946
Ефрейтор
Ефрейтор
Аватара
vlad1946
Ефрейтор
Ефрейтор
Сообщения: 15
Зарегистрирован: 6 июля 2020
С нами: 3 года 8 месяцев

#51 vlad1946 » 10 сентября 2020, 18:55

Здравствуйте уважаемый! Подскажите плиз как изменить шаг регулировки по яркости матрицы вместо 15 шагов сделать 5-7?


Дим M
Автор темы, Администратор
Администратор
Аватара
Дим M
Автор темы, Администратор
Администратор
Сообщения: 1608
Зарегистрирован: 5 апреля 2013
С нами: 10 лет 11 месяцев

#52 Дим » 12 сентября 2020, 10:29

Не очень понятен вопрос.
[center]i love you [s]mxIni[/s] Mysql[/center]

vlad1946
Ефрейтор
Ефрейтор
Аватара
vlad1946
Ефрейтор
Ефрейтор
Сообщения: 15
Зарегистрирован: 6 июля 2020
С нами: 3 года 8 месяцев

#53 vlad1946 » 24 сентября 2020, 7:54

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

Дим M
Автор темы, Администратор
Администратор
Аватара
Дим M
Автор темы, Администратор
Администратор
Сообщения: 1608
Зарегистрирован: 5 апреля 2013
С нами: 10 лет 11 месяцев

#54 Дим » 17 ноября 2020, 19:00

Второй экземпляр ни как не хочет запускаться. Использую пока другой код. Что бы не потерялся - оставлю тут.

Код: Выделить всё

//include libraries:
#include "LedControl.h"
#include <FontLEDClock.h>                // Font library
#include <Wire.h>                        // DS1307 clock
 #include "RTClib.h"                      // DS1307 clock
#include <Button.h>                      // Button library by Alexander Brevig


// Setup LED Matrix

// DIN   pin 11 is connected to the DataIn on the display DIN
// CLK   pin 13 is connected to the CLK on the display    
// CS    pin 10 is connected to LOAD on the display        CS
LedControl lc LedControl(1113104); //sets the 3 pins as 12, 11 & 10 and then sets 4 displays (max is 8 displays)

//global variables
byte intensity 0;                      // Интенсивность / яркость по умолчанию (0-15)
byte clock_mode 0;                     // Режим часов по умолчанию. По умолчанию = 0  (basic_mode)
bool random_mode 0;                    // Определить случайный режим - меняет тип отображения каждые несколько часов. По умолчанию = 0 (выкл.)
byte old_mode clock_mode;              // Сохраняет предыдущий режим часов, поэтому, если мы перейдем к дате или чему-то еще, мы знаем, в какой режим вернуться после.
bool ampm 0;                           // Задайте время в 12 или 24 часа. 0 = 24 часа. 1 = 12 часов
byte change_mode_time 0;               // Удерживает час, когда режим часов в следующий раз изменится, если в случайном режиме.
unsigned long delaytime 500;           // Мы всегда немного выжидаем между обновлениями дисплея
int rtc[7];                              // Вывод часов реального времени



char days[7][4] = {
  
"Sun""Mon""Tue""Wed""Thu""Fri""Sat"
}; //дневной массив - используется в режимах слайда, basic_mode и jumble (DS1307 выводит 1-7 значений для дня недели)
char daysfull[7][9] = {
  
"Sunday""Monday""Tuesday""Wed""Thursday""Friday""Saturday"
};
char suffix[4][3] = {
  
"st""nd""rd""th"
};  //Массив суффиксов даты, используемый в режимах слайда, basic_mode и jumble. 1-й 2-й ...
//определить константы
#define NUM_DISPLAY_MODES 3              // Режимы отображения чисел (первый режим - ноль)
#define NUM_SETTINGS_MODES 4             // Количество режимов настройки = 6 (в качестве первого режима остается ноль)
#define SLIDE_DELAY 20                   // Время в миллисекундах для эффекта слайда на символ в режиме слайда. Сделайте это выше для более медленного эффекта
#define cls          clear_display       // Четкий дисплей

RTC_DS1307 ds1307;                              // Создать объект RTC

Button buttonA Button(3BUTTON_PULLUP);      // Кнопка настройки A (с использованием библиотеки кнопок)
Button buttonB Button(4BUTTON_PULLUP);      // Кнопка настройки B (с использованием библиотеки кнопок)

void setup() {

  
digitalWrite(2HIGH);                 // включить подтягивающий резистор для кнопки на контакте 2
  
digitalWrite(3HIGH);                 // включить подтягивающий резистор для кнопки на контакте 3
  
digitalWrite(4HIGH);                 // включить подтягивающий резистор для кнопки на контакте 4
  
  
Serial.begin(9600); //start serial

  //инициализировать 4 панели матрицы
  //мы уже установили количество устройств при создании LedControl
  
int devices lc.getDeviceCount();
  
//мы должны запустить все устройства в цикле
  
for (int address 0address devicesaddress++) {
    
/*MAX72XX находится в режиме энергосбережения при запуске*/
    
lc.shutdown(3-addressfalse);
    
/* Установите яркость на средние значения */
    
lc.setIntensity(3-addressintensity);
    
/* и очистить дисплей */
    
lc.clearDisplay(3-address);
  }

  
//Настройка DS1307 RTC
#ifdef AVR
  
Wire.begin();
#else
  
Wire1.begin(); // Контакты Shield I2C подключаются к альтернативной шине I2C на Arduino
#endif
  
ds1307.begin(); //запустить часы RTC

  
if (! ds1307.isrunning()) {
    
Serial.println("RTC is NOT running!");
    
ds1307.adjust(DateTime(__DATE____TIME__));  // устанавливает RTC на дату и время компиляции этого скетча
  
}
  
//Показать версию программного обеспечения и приветственное сообщение
  
printver();
  
  
//включить красный светодиод
  
digitalWrite(13HIGH);
}

void loop() {
  
  
//запускать часы с любым режимом, установленным clock_mode - по умолчанию устанавливается в верхней части кода.
  
switch (clock_mode){
        
  case 
0
    
basic_mode();
    break; 
  case 
1
   
small_mode(); 
    break;
  case 
2
    
slide(); 
    break;
  case 
3
    
word_clock(); 
    break;
  case 
4
    
setup_menu(); 
    break;
  }
}


//нанести точку на дисплей
void plot (byte xbyte ybyte val) {

  
//выбрать какую матрицу в зависимости от координаты x
  
byte address;
  if (
>= && <= 7)   {
    
address 3;
  }
  if (
>= && <= 15)  {
    
address 2;
    
8;
  }
  if (
>= 16 && <= 23) {
    
address 1;
    
16;
  }
  if (
>= 24 && <= 31) {
    
address 0;
    
24;
  }

  if (
val == 1) {
    
lc.setLed(addressyxtrue);
  } else {
    
lc.setLed(addressyxfalse);
  }
}


//очисти экран
void clear_display() {
  for (
byte address 0address 4address++) {
    
lc.clearDisplay(address);
  }
}

//исчезать экран вниз
void fade_down() {

  
//fade from global intensity to 1
  
for (byte i intensity0i--) {
    for (
byte address 0address 4address++) {
      
lc.setIntensity(addressi);
    }
    
delay(30); //измените это, чтобы изменить скорость затухания
  
}

  
clear_display(); //полностью очистить дисплей (выкл.)

  //сбросить намерение до глобального значения
  
for (byte address 0address 4address++) {
    
lc.setIntensity(addressintensity);
  }
}



//включите питание светодиодного индикатора и проверьте номер версии программного обеспечения
void printver() {

  
byte i 0;
  
char ver_a[8] = "MADE";
  
char ver_b[8] = "IN";
  
char ver_c[8] = "RUSSIA";
  
  
// проверить все светодиоды.
  
for (byte x 0<= 32x++) {
    for (
byte y 0<= 7y++) {
      
plot(xy1);
    }
  }
  
delay(300);
  
fade_down();

  while (
ver_a[i]) {
    
puttinychar((4), 1ver_a[i]);
    
delay(35);
    
i++;
  }
  
delay(500);
  
fade_down();
  
0;
  while (
ver_b[i]) {
    
puttinychar((4), 1ver_b[i]);
    
delay(35);
    
i++;
  }
  
delay(500);
  
fade_down();
  
0;
  while (
ver_c[i]) {
    
puttinychar((4), 1ver_c[i]);
    
delay(35);
    
i++;
  }
  
delay(500);
  
fade_down();
}


// puttinychar
// Копируем глиф(glyph) 3x5 символов из структуры данных myfont для отображения памяти с его левым верхним углом в заданной координате
// Это не оптимизировано и просто использует plot () для рисования каждой точки.
void puttinychar(byte xbyte ychar c)
{
  
byte dots;
  if (
>= 'A' && <= 'Z' || (>= 'a' && <= 'z') ) {
    
&= 0x1F;   // A-Z maps to 1-26
  
}
  else if (
>= '0' && <= '9') {
    
= ('0') + 32;
  }
  else if (
== ' ') {
    
0// Космос
  
}
  else if (
== '.') {
    
27// полная остановка
  
}
  else if (
== ':') {
    
28// двоеточие
  
}
  else if (
== '\'') {
    
29// одинарная кавычка
  
}
  else if (
== '!') {
    
30// одинарная кавычка
  
}
  else if (
== '?') {
    
31// одинарная кавычка
  
}

  for (
byte col 0col 3col++) {
    
dots pgm_read_byte_near(&mytinyfont[c][col]);
    for (
char row 0row 5row++) {
      if (
dots & (16 >> row))
        
plot(colrow1);
      else
        
plot(colrow0);
    }
  }
}



void putnormalchar(byte xbyte ychar c)
{

  
byte dots;
  
//  if (c >= 'A' && c <= 'Z' || (c >= 'a' && c <= 'z') ) {
  //    c &= 0x1F;   // A-Z maps to 1-26
  //  }
  
if (>= 'A' && <= 'Z' ) {
    
&= 0x1F;   // A-Z соответствует 1-26
  
}
  else if (
>= 'a' && <= 'z') {
    
= ('a') + 41;   // A-Z соответствует  41-67
  
}
  else if (
>= '0' && <= '9') {
    
= ('0') + 31;
  }
  else if (
== ' ') {
    
0// Космос
  
}
  else if (
== '.') {
    
27// полная остановка
  
}
  else if (
== '\'') {
    
28// одинарная кавычка
  
}
  else if (
== ':') {
    
29// стрелка переключателя clock_mode
  
}
  else if (
== '>') {
    
30// стрелка переключателя clock_mode
  
}
  else if (
>= -80 && <= -67) {
    
*= -1;
  }

  for (
char col 0col 5col++) {
    
dots pgm_read_byte_near(&myfont[c][col]);
    for (
char row 0row 7row++) {
      
//проверьте координаты на экране, прежде чем пытаться построить
      //if ((x >= 0) && (x <= 31) && (y >= 0) && (y <= 7)){

      
if (dots & (64 >> row)) {   // всего 7 рядов.
        
plot(colrow1);
      } else {
        
plot(colrow0);
      }
      
//}
    
}
  }
}

//small_mode
//показываем время маленькими символами 3x5 с отображением секунд

void small_mode() {

  
char textchar[8]; // the 16 characters on the display
  
byte mins 100//mins
  
byte secs rtc[0]; //seconds
  
byte old_secs secs//holds old seconds value - from last time seconds were updated o display - used to check if seconds have changed
  
  
cls();

  
//run clock main loop as long as run_mode returns true
  
while (run_mode()) {

    
get_time();
  
    
//check for button press
    
if (buttonA.uniquePress()) {
      
switch_mode();
      return;
    }
    if (
buttonB.uniquePress()) {
      
display_date();
      return;
    }
    
    
//if secs changed then update them on the display
    
secs rtc[0];
    if (
secs != old_secs) {

      
//secs
      
char buffer[3];
      
itoa(secsbuffer10);

      
//fix - as otherwise if num has leading zero, e.g. "03" secs, itoa coverts this to chars with space "3 ".
      
if (secs 10) {
        
buffer[1] = buffer[0];
        
buffer[0] = '0';
      }

      
puttinychar201':'); //seconds colon
      
puttinychar241buffer[0]); //seconds
      
puttinychar281buffer[1]); //seconds
      
old_secs secs;
    }

    
//if minute changes change time
    
if (mins != rtc[1]) {

      
//reset these for comparison next time
      
mins rtc[1];
      
byte hours rtc[2];
      if (
hours 12) {
        
hours hours ampm 12;
      }
      if (
hours 1) {
        
hours hours ampm 12;
      }


      
//byte dow  = rtc[3]; // the DS1307 outputs 0 - 6 where 0 = Sunday0 - 6 where 0 = Sunday.
      //byte date = rtc[4];

      //set characters
      
char buffer[3];
      
itoa(hoursbuffer10);

      
//fix - as otherwise if num has leading zero, e.g. "03" hours, itoa coverts this to chars with space "3 ".
      
if (hours 10) {
        
buffer[1] = buffer[0];
        
//if we are in 12 hour mode blank the leading zero.
        
if (ampm) {
          
buffer[0] = ' ';
        }
        else {
          
buffer[0] = '0';
        }
      }
      
//set hours chars
      
textchar[0] = buffer[0];
      
textchar[1] = buffer[1];
      
textchar[2] = ':';

      
itoa (minsbuffer10);
      if (
mins 10) {
        
buffer[1] = buffer[0];
        
buffer[0] = '0';
      }
      
//set mins characters
      
textchar[3] = buffer[0];
      
textchar[4] = buffer[1];

      
//do seconds
      
textchar[5] = ':';
      
buffer[3];
      
secs rtc[0];
      
itoa(secsbuffer10);

      
//fix - as otherwise if num has leading zero, e.g. "03" secs, itoa coverts this to chars with space "3 ".
      
if (secs 10) {
        
buffer[1] = buffer[0];
        
buffer[0] = '0';
      }
      
//set seconds
      
textchar[6] = buffer[0];
      
textchar[7] = buffer[1];

      
byte x 0;
      
byte y 0;

      
//print each char
      
for (byte x 0x++) {
        
puttinychar41textchar[x]);
      }
    }
    
delay(50);
  }
  
fade_down();
}


// basic_mode()
// show the time in 5x7 characters
void basic_mode()
{
  
cls();

  
char buffer[3];   //for int to char conversion to turn rtc values into chars we can print on screen
  
byte offset 0;  //used to offset the x postition of the digits and centre the display when we are in 12 hour mode and the clock shows only 3 digits. e.g. 3:21
  
byte xy;        //used to draw a clear box over the left hand "1" of the display when we roll from 12:59 -> 1:00am in 12 hour mode.

  //do 12/24 hour conversion if ampm set to 1
  
byte hours rtc[2];

  if (
hours 12) {
    
hours hours ampm 12;
  }
  if (
hours 1) {
    
hours hours ampm 12;
  }

  
//do offset conversion
  
if (ampm && hours 10) {
    
offset 2;
  }
  
  
//set the next minute we show the date at
  //set_next_date();
  
  // initially set mins to value 100 - so it wll never equal rtc[1] on the first loop of the clock, meaning we draw the clock display when we enter the function
  
byte secs 100;
  
byte mins 100;
  
int count 0;
  
  
//run clock main loop as long as run_mode returns true
  
while (run_mode()) {

    
//get the time from the clock chip
    
get_time();
    
    
//check for button press
    
if (buttonA.uniquePress()) {
      
switch_mode();
      return;
    }
    if (
buttonB.uniquePress()) {
      
display_date();
      return;
    }

    
//check whether it's time to automatically display the date
    //check_show_date();

    //draw the flashing : as on if the secs have changed.
    
if (secs != rtc[0]) {

      
//update secs with new value
      
secs rtc[0];

      
//draw :
      
plot (15 offset21); //top point
      
plot (15 offset51); //bottom point
      
count 400;
    }

    
//if count has run out, turn off the :
    
if (count == 0) {
      
plot (15 offset20); //top point
      
plot (15 offset50); //bottom point
    
}
    else {
      
count--;
    }

    
//re draw the display if button pressed or if mins != rtc[1] i.e. if the time has changed from what we had stored in mins, (also trigggered on first entering function when mins is 100)
    
if (mins != rtc[1]) {

      
//update mins and hours with the new values
      
mins rtc[1];
      
hours rtc[2];

      
//adjust hours of ampm set to 12 hour mode
      
if (hours 12) {
        
hours hours ampm 12;
      }
      if (
hours 1) {
        
hours hours ampm 12;
      }

      
itoa(hoursbuffer10);

      
//if hours < 10 the num e.g. "3" hours, itoa coverts this to chars with space "3 " which we dont want
      
if (hours 10) {
        
buffer[1] = buffer[0];
        
buffer[0] = '0';
      }

      
//print hours
      //if we in 12 hour mode and hours < 10, then don't print the leading zero, and set the offset so we centre the display with 3 digits.
      
if (ampm && hours 10) {
        
offset 2;

        
//if the time is 1:00am clear the entire display as the offset changes at this time and we need to blank out the old 12:59
        
if ((hours == && mins == 0) ) {
          
cls();
        }
      }
      else {
        
//else no offset and print hours tens digit
        
offset 0;

        
//if the time is 10:00am clear the entire display as the offset changes at this time and we need to blank out the old 9:59
        
if (hours == 10 && mins == 0) {
          
cls();
        }


        
putnormalchar(1,  0buffer[0]);
      }
      
//print hours ones digit
      
putnormalchar(offset0buffer[1]);


      
//print mins
      //add leading zero if mins < 10
      
itoa (minsbuffer10);
      if (
mins 10) {
        
buffer[1] = buffer[0];
        
buffer[0] = '0';
      }
      
//print mins tens and ones digits
      
putnormalchar(19 offset0buffer[0]);
      
putnormalchar(25 offset0buffer[1]);
    }
  }
  
fade_down();
}


//like basic_mode but with slide effect
void slide() {

  
byte digits_old[4] = {99999999}; //old values  we store time in. Set to somthing that will never match the time initially so all digits get drawn wnen the mode starts
  
byte digits_new[4]; //new digits time will slide to reveal
  
byte digits_x_pos[4] = {251971}; //x pos for which to draw each digit at

  
char old_char[2]; //used when we use itoa to transpose the current digit (type byte) into a char to pass to the animation function
  
char new_char[2]; //used when we use itoa to transpose the new digit (type byte) into a char to pass to the animation function

  //old_chars - stores the 5 day and date suffix chars on the display. e.g. "mon" and "st". We feed these into the slide animation as the current char when these chars are updated.
  //We sent them as A initially, which are used when the clocl enters the mode and no last chars are stored.
  //char old_chars[6] = "AAAAA";

  //plot the clock colon on the display
  
cls();
  
putnormalchar130':');

  
byte old_secs rtc[0]; //store seconds in old_secs. We compare secs and old secs. WHen they are different we redraw the display

  //run clock main loop as long as run_mode returns true
  
while (run_mode()) {

    
get_time();
    
    
//check for button press
    
if (buttonA.uniquePress()) {
      
switch_mode();
      return;
    }
      if (
buttonB.uniquePress()) {
      
display_date();
      return;
    }

    
//if secs have changed then update the display
    
if (rtc[0] != old_secs) {
      
old_secs rtc[0];

      
//do 12/24 hour conversion if ampm set to 1
      
byte hours rtc[2];
      if (
hours 12) {
        
hours hours ampm 12;
      }
      if (
hours 1) {
        
hours hours ampm 12;
      }

      
//split all date and time into individual digits - stick in digits_new array

      //rtc[0] = secs                        //array pos and digit stored
      //digits_new[0] = (rtc[0]%10);           //0 - secs ones
      //digits_new[1] = ((rtc[0]/10)%10);      //1 - secs tens
      //rtc[1] = mins
      
digits_new[0] = (rtc[1] % 10);         //2 - mins ones
      
digits_new[1] = ((rtc[1] / 10) % 10);  //3 - mins tens
      //rtc[2] = hours
      
digits_new[2] = (hours 10);         //4 - hour ones
      
digits_new[3] = ((hours 10) % 10);  //5 - hour tens
      //rtc[4] = date
      //digits_new[6] = (rtc[4]%10);           //6 - date ones
      //digits_new[7] = ((rtc[4]/10)%10);      //7 - date tens

      //draw initial screen of all chars. After this we just draw the changes.

      //compare digits 0 to 3 (mins and hours)
      
for (byte i 0<= 3i++) {
        
//see if digit has changed...
        
if (digits_old[i] != digits_new[i]) {

          
//run 9 step animation sequence for each in turn
          
for (byte seq 0seq <= seq++) {

            
//convert digit to string
            
itoa(digits_old[i], old_char10);
            
itoa(digits_new[i], new_char10);

            
//if set to 12 hour mode and we're on digit 2 (hours tens mode) then check to see if this is a zero. If it is, blank it instead so we get 2.00pm not 02.00pm
            
if (ampm && == 3) {
              if (
digits_new[3] == 0) {
                
new_char[0] = ' ';
              }
              if (
digits_old[3] == 0) {
                
old_char[0] = ' ';
              }
            }
            
//draw the animation frame for each digit
            
slideanim(digits_x_pos[i], 0seqold_char[0], new_char[0]);
            
delay(SLIDE_DELAY);
          }
        }
      }

      
/*
      //compare date digit 6 (ones) and (7) tens - if either of these change we need to update the date line. We compare date tens as say from Jan 31 -> Feb 01 then ones digit doesn't change
      if ((digits_old[6] != digits_new[6]) || (digits_old[7] != digits_new[7])) {
        //change the day shown. Loop below goes through each of the 3 chars in turn e.g. "MON"
        for (byte day_char = 0; day_char <=2 ; day_char++){
          //run the anim sequence for each char
          for (byte seq = 0; seq <=8 ; seq++){
            //the day (0 - 6) Read this number into the days char array. the seconds number in the array 0-2 gets the 3 chars of the day name, e.g. m o n
            slideanim(6*day_char,8,seq,old_chars[day_char],days[rtc[3]][day_char]); //6 x day_char gives us the x pos for the char
            delay(SLIDE_DELAY);
          }
          //save the old day chars into the old_chars array at array pos 0-2. We use this next time we change the day and feed it to the animation as the current char. The updated char is fed in as the new char.
          old_chars[day_char] = days[rtc[3]][day_char];
        }

        //change the date tens digit (if needed) and ones digit. (the date ones digit wil alwaus change, but putting this in the 'if' loop makes it a bit neater code wise.)
        for (byte i = 7; i >= 6; i--){
          if (digits_old[i] != digits_new[i]) {
            for (byte seq = 0; seq <=8 ; seq++){
              itoa(digits_old[i],old_char,10);
              itoa(digits_new[i],new_char,10);
              slideanim(digits_x_pos[i],8,seq,old_char[0],new_char[0]);
              delay(SLIDE_DELAY);
            }
          }
        }

        //print the day suffix "nd" "rd" "th" etc. First work out date 2 letter suffix - eg st, nd, rd, th
        byte s = 3; //the pos to read our suffix array from.
        byte date = rtc[4];
        if(date == 1 || date == 21 || date == 31) {
          s = 0;
        }
        else if (date == 2 || date == 22) {
          s = 1;
        }
        else if (date == 3 || date == 23) {
          s = 2;
        }

        for (byte suffix_char = 0; suffix_char <=1 ; suffix_char++){
          for (byte seq = 0; seq <=8 ; seq++){
            slideanim((suffix_char*6)+36,8,seq,old_chars[suffix_char+3],suffix[s][suffix_char]); // we pass in the old_char array char as the current char and the suffix array as the new char
            delay(SLIDE_DELAY);
          }
          //save the suffic char in the old chars array at array pos 3 and 5.  We use these chars next time we change the suffix and feed it to the animation as the current char. The updated char is fed in as the new char.
          old_chars[suffix_char+3] = suffix[s][suffix_char];
        }
      }//end do date line
      */


      //save digita array tol old for comparison next loop
      
for (byte i 0<= 3i++) {
        
digits_old[i] =  digits_new[i];
      }
    }
//secs/oldsecs
  
}//while loop
  
fade_down();
}


//called by slide
//this draws the animation of one char sliding on and the other sliding off. There are 8 steps in the animation, we call the function to draw one of the steps from 0-7
//inputs are are char x and y, animation frame sequence (0-7) and the current and new chars being drawn.
void slideanim(byte xbyte ybyte sequencechar current_cchar new_c) {

  
//  To slide one char off and another on we need 9 steps or frames in sequence...

  //  seq# 0123456 <-rows of the display
  //   |   |||||||
  //  seq0 0123456  START - all rows of the display 0-6 show the current characters rows 0-6
  //  seq1  012345  current char moves down one row on the display. We only see it's rows 0-5. There are at display positions 1-6 There is a blank row inserted at the top
  //  seq2 6 01234  current char moves down 2 rows. we now only see rows 0-4 at display rows 2-6 on the display. Row 1 of the display is blank. Row 0 shows row 6 of the new char
  //  seq3 56 0123
  //  seq4 456 012  half old / half new char
  //  seq5 3456 01
  //  seq6 23456 0
  //  seq7 123456
  //  seq8 0123456  END - all rows show the new char

  //from above we can see...
  //currentchar runs 0-6 then 0-5 then 0-4 all the way to 0. starting Y position increases by 1 row each time.
  //new char runs 6 then 5-6 then 4-6 then 3-6. starting Y position increases by 1 row each time.

  //if sequence number is below 7, we need to draw the current char
  
if (sequence 7) {
    
byte dots;
    
// if (current_c >= 'A' &&  || (current_c >= 'a' && current_c <= 'z') ) {
    //   current_c &= 0x1F;   // A-Z maps to 1-26
    // }
    
if (current_c >= 'A' && current_c <= 'Z' ) {
      
current_c &= 0x1F;   // A-Z maps to 1-26
    
}
    else if (
current_c >= 'a' && current_c <= 'z') {
      
current_c = (current_c 'a') + 41;   // A-Z maps to 41-67
    
}
    else if (
current_c >= '0' && current_c <= '9') {
      
current_c = (current_c '0') + 31;
    }
    else if (
current_c == ' ') {
      
current_c 0// space
    
}
    else if (
current_c == '.') {
      
current_c 27// full stop
    
}
    else if (
current_c == '\'') {
      
current_c 28// single quote mark
    
}
    else if (
current_c == ':') {
      
current_c 29//colon
    
}
    else if (
current_c == '>') {
      
current_c 30// clock_mode selector arrow
    
}

    
byte curr_char_row_max sequence//the maximum number of rows to draw is 6 - sequence number
    
byte start_y sequence//y position to start at - is same as sequence number. We inc this each loop

    //plot each row up to row maximum (calculated from sequence number)
    
for (byte curr_char_row 0curr_char_row <= curr_char_row_maxcurr_char_row++) {
      for (
byte col 0col 5col++) {
        
dots pgm_read_byte_near(&myfont[current_c][col]);
        if (
dots & (64 >> curr_char_row))
          
plot(colstart_y1); //plot led on
        
else
          
plot(colstart_y0); //else plot led off
      
}
      
start_y++;//add one to y so we draw next row one down
    
}
  }

  
//draw a blank line between the characters if sequence is between 1 and 7. If we don't do this we get the remnants of the current chars last position left on the display
  
if (sequence >= && sequence <= 8) {
    for (
byte col 0col 5col++) {
      
plot(col+ (sequence 1), 0); //the y position to draw the line is equivalent to the sequence number - 1
    
}
  }



  
//if sequence is above 2, we also need to start drawing the new char
  
if (sequence >= 2) {

    
//work out char
    
byte dots;
    
//if (new_c >= 'A' && new_c <= 'Z' || (new_c >= 'a' && new_c <= 'z') ) {
    //  new_c &= 0x1F;   // A-Z maps to 1-26
    //}
    
if (new_c >= 'A' && new_c <= 'Z' ) {
      
new_c &= 0x1F;   // A-Z maps to 1-26
    
}
    else if (
new_c >= 'a' && new_c <= 'z') {
      
new_c = (new_c 'a') + 41;   // A-Z maps to 41-67
    
}
    else if (
new_c >= '0' && new_c <= '9') {
      
new_c = (new_c '0') + 31;
    }
    else if (
new_c == ' ') {
      
new_c 0// space
    
}
    else if (
new_c == '.') {
      
new_c 27// full stop
    
}
    else if (
new_c == '\'') {
      
new_c 28// single quote mark
    
}
    else if (
new_c == ':') {
      
new_c 29// clock_mode selector arrow
    
}
    else if (
new_c == '>') {
      
new_c 30// clock_mode selector arrow
    
}

    
byte newcharrowmin - (sequence 2); //minimumm row num to draw for new char - this generates an output of 6 to 0 when fed sequence numbers 2-8. This is the minimum row to draw for the new char
    
byte start_y 0//y position to start at - is same as sequence number. we inc it each row

    //plot each row up from row minimum (calculated by sequence number) up to 6
    
for (byte newcharrow newcharrowminnewcharrow <= 6newcharrow++) {
      for (
byte col 0col 5col++) {
        
dots pgm_read_byte_near(&myfont[new_c][col]);
        if (
dots & (64 >> newcharrow))
          
plot(colstart_y1); //plot led on
        
else
          
plot(colstart_y0); //else plot led off
      
}
      
start_y++;//add one to y so we draw next row one down
    
}
  }
}



//print a clock using words rather than numbers
void word_clock() {

  
cls();

  
char numbers[19][10]   = {
    
"one""two""three""four""five""six""seven""eight""nine""ten",
    
"eleven""twelve""thirteen""fourteen""fifteen""sixteen""seventeen""eighteen""nineteen"
  
};
  
char numberstens[5][7] = {
    
"ten""twenty""thirty""forty""fifty"
  
};
  
  
//potentially 3 lines to display
  
char str_a[8];
  
char str_b[8];
  
char str_c[8];

  
//byte hours_y, mins_y; //hours and mins and positions for hours and mins lines

  
byte hours rtc[2];
  if (
hours 12) {
    
hours hours ampm 12;
  }
  if (
hours 1) {
    
hours hours ampm 12;
  }

  
get_time(); //get the time from the clock chip
  
byte old_mins 100//store mins in old_mins. We compare mins and old mins & when they are different we redraw the display. Set this to 100 initially so display is drawn when mode starts.
  
byte mins;

  
//run clock main loop as long as run_mode returns true
  
while (run_mode()) {
    
    
//check for button press
    
if (buttonA.uniquePress()) {
      
switch_mode();
      return;
    }
    if (
buttonB.uniquePress()) {
      
display_date();
    }

    
get_time(); //get the time from the clock chip
    
mins rtc[1];  //get mins


    //if mins is different from old_mins - redraw display
    
if (mins != old_mins) {

      
//update old_mins with current mins value
      
old_mins mins;

      
//reset these for comparison next time
      
mins rtc[1];
      
hours rtc[2];

      
//make hours into 12 hour format
      
if (hours 12) {
        
hours hours 12;
      }
      if (
hours == 0) {
        
hours 12;
      }

      
//split mins value up into two separate digits
      
int minsdigit rtc[1] % 10;
      
byte minsdigitten = (rtc[1] / 10) % 10;

      
//if mins <= 10 , then top line has to read "minsdigti past" and bottom line reads hours
      
if (mins 10) {
        
strcpy (str_anumbers[minsdigit 1]);
        
strcpy (str_b"PAST");
        
strcpy (str_cnumbers[hours 1]);
      }

      
//if mins = 10, cant use minsdigit as above, so soecial case to print 10 past /n hour.
      
if (mins == 10) {
        
strcpy (str_anumbers[9]);
        
strcpy (str_b" PAST");
        
strcpy (str_cnumbers[hours 1]);
      }

      
//if time is not on the hour - i.e. both mins digits are not zero,
      //then make first line read "hours" and 2 & 3rd lines read "minstens"  "mins" e.g. "three /n twenty /n one"
      
else if (minsdigitten != && minsdigit != 0  ) {

        
strcpy (str_anumbers[hours 1]);

        
//if mins is in the teens, use teens from the numbers array for the 2nd line, e.g. "fifteen"
        //if (mins >= 11 && mins <= 19) {
        
if (mins <= 19) {
          
strcpy (str_bnumbers[mins 1]);
        }
        else {
          
strcpy (str_bnumberstens[minsdigitten 1]);

          
strcpy (str_cnumbers[minsdigit 1]);
        }
      }
      
// if mins digit is zero, don't print it. read read "hours" "minstens" e.g. "three /n twenty"
      
else if (minsdigitten != && minsdigit == 0  ) {
        
strcpy (str_anumbers[hours 1]);
        
strcpy (str_bnumberstens[minsdigitten 1]);
        
strcpy (str_c"");
      }

      
//if both mins are zero, i.e. it is on the hour, the top line reads "hours" and bottom line reads "o'clock"
      
else if (minsdigitten == && minsdigit == 0  ) {
        
strcpy (str_anumbers[hours 1]);
        
strcpy (str_b"O'CLOCK");
        
strcpy (str_c"");
      }

    }
//end worknig out time

    //run in a loop
    //print line a "twelve"
    
byte len 0;
    while (
str_a[len]) {
      
len++;
    }; 
//get length of message
    
byte offset_top = (31 - ((len 1) * 4)) / 2//

    //plot hours line
    
byte i 0;
    while (
str_a[i]) {
      
puttinychar((4) + offset_top1str_a[i]);
      
i++;
    }
    
    
//hold display but check for button presses
    
int counter 1000;
    while (
counter 0){
      
//check for button press
      
if (buttonA.uniquePress()) {
        
switch_mode();
        return;
      }
      if (
buttonB.uniquePress()) {
        
display_date();
      }
    
delay(1);
    
counter--;
    }
    
fade_down();

    
//print line b
    
len 0;
    while (
str_b[len]) {
      
len++;
    }; 
//get length of message
    
offset_top = (31 - ((len 1) * 4)) / 2

    
0;
    while (
str_b[i]) {
      
puttinychar((4) + offset_top1str_b[i]);
      
i++;
    }

    
//hold display but check for button presses
    
counter 1000;
    while (
counter 0){
      if (
buttonA.uniquePress()) {
        
switch_mode();
        return;
      }
      if (
buttonB.uniquePress()) {
        
display_date();
      }
      
delay(1);
      
counter--;
    }
    
fade_down();

    
//print line c if there.
    
len 0;
    while (
str_c[len]) {
      
len++;
    }; 
//get length of message
    
offset_top = (31 - ((len 1) * 4)) / 2

    
0;
    while (
str_c[i]) {
      
puttinychar((4) + offset_top1str_c[i]);
      
i++;
    }
    
counter 1000;
    while (
counter 0){
      
//check for button press
      
if (buttonA.uniquePress()) {
        
switch_mode();
        return;
      }
      if (
buttonB.uniquePress()) {
        
display_date();
      }  
      
delay(1);
      
counter--;
    }
    
fade_down();
    
    
    
//hold display blank but check for button presses before starting again.
    
counter 1000;
    while (
counter 0){
       
//check for button press
      
if (buttonA.uniquePress()) {
        
switch_mode();
        return;
      }
      if (
buttonB.uniquePress()) {
        
display_date();
      }  
      
delay(1);
      
counter--;
    }
  }
  
fade_down();
}



/// scroll message - not used at present - too slow.
void scroll() {

  
char message[] = {"Hello There "};

  
cls();
  
byte p 6;      //current pos in string
  
byte chara[] = {012345}; //chars from string
  
int x[] = {0612182430}; //xpos for each char
  
byte y 0;                   //y pos

  // clear_buffer();

  
while (message[p] != '\0') {

    
//draw all 6 chars
    
for (byte c 06c++) {

      
putnormalchar(x[c],y,messagechara[c] ]);
      

      
//draw a line of pixels turned off after each char,otherwise the gaps between the chars have pixels left in them from the previous char
      
for (byte yy yy 8yy ++) {
        
plot(x[c] + 5yy0);
      }

      
//take one off each chars position
      
x[c] = x[c] - 1;
    }

    
//reset a char if it's gone off screen
    
for (byte i 0<= 5i++) {
      if (
x[i] < -) {
        
x[i] = 31;
        
chara[i] = p;
        
p++;
      }
    }
  }
}

//display_date - print the day of week, date and month with a flashing cursor effect
void display_date()
{

  
cls();
  
//read the date from the DS1307

  
byte dow rtc[3]; // day of week 0 = Sunday
  
byte date rtc[4];
  
byte month rtc[5] - 1;

  
//array of month names to print on the display. Some are shortened as we only have 8 characters across to play with
  
char monthnames[12][9] = {
    
"January""February""March""April""May""June""July""August""Sept""October""November""December"
  
};

  
//print the day name
  
  //get length of text in pixels, that way we can centre it on the display by divindin the remaining pixels b2 and using that as an offset
  
byte len 0;
  while(
daysfull[dow][len]) { 
    
len++; 
  }; 
  
byte offset = (31 - ((len-1)*4)) / 2//our offset to centre up the text
      
  //print the name     
  
int i 0;
  while(
daysfull[dow][i])
  {
    
puttinychar((i*4) + offset 1daysfull[dow][i]); 
    
i++;
  }
  
delay(1000);
  
fade_down();
  
cls();
  
  
// print date numerals
  
char buffer[3];
  
itoa(date,buffer,10);
  
offset 10//offset to centre text if 3 chars - e.g. 3rd
  
  // first work out date 2 letter suffix - eg st, nd, rd, th etc
  // char suffix[4][3]={"st", "nd", "rd", "th"  }; is defined at top of code
  
byte s 3
  if(
date == || date == 21 || date == 31) {
    
0;
  } 
  else if (
date == || date == 22) {
    
1;
  } 
  else if (
date == || date == 23) {
    
2;
  } 

  
//print the 1st date number
  
puttinychar(0+offset1buffer[0]);

  
//if date is under 10 - then we only have 1 digit so set positions of sufix etc one character nearer
  
byte suffixposx 4;

  
//if date over 9 then print second number and set xpos of suffix to be 1 char further away
  
if (date 9){
    
suffixposx 8;
    
puttinychar(4+offset1buffer[1]);
    
offset 8//offset to centre text if 4 chars
  
}

  
//print the 2 suffix characters
  
puttinychar(suffixposx+offset1suffix[s][0]); 
  
puttinychar(suffixposx+4+offset1suffix[s][1]); 
 
  
delay(1000);
  
fade_down();
  
  
//print the month name 
  
  //get length of text in pixels, that way we can centre it on the display by divindin the remaining pixels b2 and using that as an offset
  
len 0;
  while(
monthnames[month][len]) { 
    
len++; 
  }; 
  
offset = (31 - ((len-1)*4)) / 2//our offset to centre up the text
  
0;
  while(
monthnames[month][i])
  {  
    
puttinychar((i*4) +offset1monthnames[month][i]); 
    
i++; 
  }
  
  
delay(1000);
  
fade_down();
}


//dislpay menu to change the clock mode
void switch_mode() {

  
//remember mode we are in. We use this value if we go into settings mode, so we can change back from settings mode (6) to whatever mode we were in.
  
old_mode clock_mode;

  
charmodes[] = {
    
"Basic""Small""Slide""Words""Setup"
  
};

  
byte next_clock_mode;
  
byte firstrun 1;

  
//loop waiting for button (timeout after 35 loops to return to mode X)
  
for (int count 0count 35 count++) {

    
//if user hits button, change the clock_mode
    
if (buttonA.uniquePress() || firstrun == 1) {

      
count 0;
      
cls();

      if (
firstrun == 0) {
        
clock_mode++;
      }
      if (
clock_mode NUM_DISPLAY_MODES ) {
        
clock_mode 0;
      }

      
//print arrown and current clock_mode name on line one and print next clock_mode name on line two
      
char str_top[9];

      
//strcpy (str_top, "-");
      
strcpy (str_topmodes[clock_mode]);

      
next_clock_mode clock_mode 1;
      if (
next_clock_mode >  NUM_DISPLAY_MODES ) {
        
next_clock_mode 0;
      }

      
byte i 0;
      while (
str_top[i]) {
        
putnormalchar(60str_top[i]);
        
i++;
      }
      
firstrun 0;
    }
    
delay(50);
  }
}


//run clock main loop as long as run_mode returns true
byte run_mode() {

  
//if random mode is on... check the hour when we change mode.
  
if (random_mode) {
    
//if hour value in change mode time = hours. then reurn false = i.e. exit mode.
    
if (change_mode_time == rtc[2]) {
      
//set the next random clock mode and time to change it
      
set_next_random();
      
//exit the current mode.
      
return 0;
    }
  }
  
//else return 1 - keep running in this mode
  
return 1;
}


//set the next hour the clock will change mode when random mode is on
void set_next_random() {

  
//set the next hour the clock mode will change - current time plus 1 - 4 hours
  
get_time();
  
change_mode_time rtc[2] + random (15);

  
//if change_mode_time now happens to be over 23, then set it to between 1 and 3am
  
if (change_mode_time 23) {
    
change_mode_time random (14);
  }
 
  
//set the new clock mode
  
clock_mode random(0NUM_DISPLAY_MODES 1);  //pick new random clock mode
}


//меню dislpay для изменения настроек часов
void setup_menu() {

  
charset_modes[] = {
     
"Rndom""24 Hr","Set""Brght""Exit"}; 
  if (
ampm == 0) { 
    
set_modes[1] = ("12 Hr"); 
  }

  
byte setting_mode 0;
  
byte next_setting_mode;
  
byte firstrun 1;

  
//цикл ожидания кнопки (таймаут после 35 циклов для возврата в режим X)
  
for(int count=0count 35 count++) {

    
//если пользователь нажимает кнопку, измените clock_mode
    
if(buttonA.uniquePress() || firstrun == 1){

      
count 0;
      
cls();

      if (
firstrun == 0) { 
        
setting_mode++; 
      } 
      if (
setting_mode NUM_SETTINGS_MODES) { 
        
setting_mode 0
      }

      
//вывести стрелку и текущее имя clock_mode в первой строке и напечатать следующее имя clock_mode во второй строке
      
char str_top[9];
    
      
strcpy (str_topset_modes[setting_mode]);

      
next_setting_mode setting_mode 1;
      if (
next_setting_mode NUM_SETTINGS_MODES) { 
        
next_setting_mode 0
      }
      
      
byte i 0;
      while(
str_top[i]) {
        
putnormalchar(i*60str_top[i]); 
        
i++;
      }

      
firstrun 0;
    }
    
delay(50); 
  }
  
  
//выберите режим 
  
switch(setting_mode){
    case 
0
      
set_random(); 
      break;
    case 
1
       
set_ampm(); 
      break;
    case 
2
      
set_time(); 
      break;
    case 
3
       
set_intensity(); 
      break;
    case 
4
      
//exit menu
      
break;
  }
    
  
//изменить часы из режима 6 (настройки) обратно на тот, в котором они были раньше
  
clock_mode=old_mode;
}


//переключить случайный режим - выбирать другой режим часов каждые несколько часов
void set_random(){
  
cls();

  
char text_a[9] = "Off";
  
char text_b[9] = "On";
  
byte i 0;

  
//if random mode is on, turn it off
  
if (random_mode){

    
//turn random mode off
    
random_mode 0;

    
//print a message on the display
    
while(text_a[i]) {
      
putnormalchar((i*6), 0text_a[i]);
      
i++;
    }
  } else {
    
//turn randome mode on. 
    
random_mode 1;
    
    
//set hour mode will change
    
set_next_random();
  
    
//print a message on the display
    
while(text_b[i]) {
      
putnormalchar((i*6), 0text_b[i]);
      
i++;
    }  
  } 
  
delay(1500); //leave the message up for a second or so
}



//set 12 or 24 hour clock
void set_ampm() {

  
// AM/PM or 24 hour clock mode - flip the bit (makes 0 into 1, or 1 into 0 for ampm mode)
  
ampm = (ampm 1);
  
cls();
}


//change screen intensityintensity
void set_intensity() {

  
cls();
  
  
byte i 0;
  
char text[7] = "Bright";
  while(
text[i]) {
    
puttinychar((i*4)+40text[i]);
    
i++;
  }

  
//wait for button input
  
while (!buttonA.uniquePress()) {

    
levelbar (0,6,(intensity*2)+2,2);    //display the intensity level as a bar
    
while (buttonB.isPressed()) {

      if(
intensity == 15) { 
        
intensity 0;
        
cls (); 
      } 
      else {
        
intensity++; 
      }
      
//print the new value 
      
0;
      while(
text[i]) {
        
puttinychar((i*4)+40text[i]);
        
i++;
      }
      
      
//display the intensity level as a bar
      
levelbar (0,6,(intensity*2)+2,2);    
      
      
//change the brightness setting on the displays
      
for (byte address 0address 4address++) {
        
lc.setIntensity(addressintensity);
      }
      
delay(150);
    }
  }
}


// display a horizontal bar on the screen at offset xposr by ypos with height and width of xbar, ybar
void levelbar (byte xposbyte yposbyte xbarbyte ybar) {
  for (
byte x 0xbarx++) {
    for (
byte y 0<= ybary++) {
      
plot(x+xposy+ypos1);
    }
  }
}


//установить время и дату
void set_time() {

  
cls();

  
//заполнить настройки текущими значениями часов, считанными с часов
  
get_time();
  
byte set_min   rtc[1];
  
byte set_hr    rtc[2];
  
byte set_date  rtc[4];
  
byte set_mnth  rtc[5];
  
int  set_yr    rtc[6]; 

  
//Функция установки - мы передаем: какое сообщение "установить" для отображения вверху, текущее значение, значение сброса и ограничение на пролистывание.
  
set_date set_value(2set_date131);
  
set_mnth set_value(3set_mnth112);
  
set_yr   set_value(4set_yr20132099);
  
set_hr   set_value(1set_hr023);
  
set_min  set_value(0set_min059);

  
ds1307.adjust(DateTime(set_yrset_mnthset_dateset_hrset_min));
  
  
cls();
}

// используется для установки значений min, hr, date, month, year. проходят
// message = какое сообщение 'установить' для печати,
// current value = текущее значение свойства, которое мы устанавливаем
// reset_value = к чему сбрасывать значение, если переворачивается. Например. минут от 60 до 0, месяцев от 12 до 1
// rollover limit = при переходе значения

int set_value(byte messageint current_valueint reset_valueint rollover_limit){

  
cls();
  
char messages[6][17]   = {
    
"Set Mins""Set Hour""Set Day""Set Mnth""Set Year"};

  
//Print "set xyz" top line
  
byte i 0;
  while(
messages[message][i])
  {
    
puttinychar(i*1messages[message][i]); 
    
i++;
  }

  
delay(2000);
  
cls();

  
//печатать цифры в нижней строке
  
char buffer[5] = "    ";
  
itoa(current_value,buffer,10);
  
puttinychar(1buffer[0]); 
  
puttinychar(1buffer[1]); 
  
puttinychar(1buffer[2]); 
  
puttinychar(121buffer[3]); 

  
delay(300);
  
//ждать нажатия кнопки
  
while (!buttonA.uniquePress()) {

    while (
buttonB.isPressed()){

      if(
current_value rollover_limit) { 
        
current_value++;
      } 
      else {
        
current_value reset_value;
      }
      
//print the new value
      
itoa(current_valuebuffer ,10);
      
puttinychar(1buffer[0]); 
      
puttinychar(1buffer[1]); 
      
puttinychar(1buffer[2]); 
      
puttinychar(121buffer[3]);    
      
delay(150);
    }
  }
  return 
current_value;
}





void get_time()
{
  
//получить время
  
DateTime now ds1307.now();
  
//сэкономить время на массиве
  
rtc[6] = now.year();
  
rtc[5] = now.month();
  
rtc[4] = now.day();
  
rtc[3] = now.dayOfWeek(); //возвращает 0-6, где 0 = воскресенье
  
rtc[2] = now.hour();
  
rtc[1] = now.minute();
  
rtc[0] = now.second();

  
//flash arduino led on pin 13 every second
  //if ( (rtc[0] % 2) == 0) {
  //  digitalWrite(13, HIGH);
  //}
  //else {
  //  digitalWrite(13, LOW);
  //}

  //print the time to the serial port - useful for debuging RTC issues
  /*
  Serial.print(rtc[2]);
  Serial.print(":");
  Serial.print(rtc[1]);
  Serial.print(":");
  Serial.println(rtc[0]);
  */
[center]i love you [s]mxIni[/s] Mysql[/center]

vlad1946
Ефрейтор
Ефрейтор
Аватара
vlad1946
Ефрейтор
Ефрейтор
Сообщения: 15
Зарегистрирован: 6 июля 2020
С нами: 3 года 8 месяцев

#55 vlad1946 » 3 декабря 2020, 11:41

Здравствуйте. Позвольте поинтересоваться у вас что это за проект?

Дим M
Автор темы, Администратор
Администратор
Аватара
Дим M
Автор темы, Администратор
Администратор
Сообщения: 1608
Зарегистрирован: 5 апреля 2013
С нами: 10 лет 11 месяцев

#56 Дим » 3 декабря 2020, 16:35

vlad1946 писал(а):что это за проект?
Если про код что я оставил выше - то вот примерно такое.
phpBB [media]
[center]i love you [s]mxIni[/s] Mysql[/center]

vlad1946
Ефрейтор
Ефрейтор
Аватара
vlad1946
Ефрейтор
Ефрейтор
Сообщения: 15
Зарегистрирован: 6 июля 2020
С нами: 3 года 8 месяцев

#57 vlad1946 » 4 декабря 2020, 12:04

Здравствуйте уважаемый! Круто,мне понравилось.В прошлых версиях у вас 0 был без черты ,здесь бы тоже так нужно.А русский шрифт возможен? Буду повторять.По ходу все возникающие вопросы буду писать.Да и цифры занимали по высоте всю матрицу.

Дим M
Автор темы, Администратор
Администратор
Аватара
Дим M
Автор темы, Администратор
Администратор
Сообщения: 1608
Зарегистрирован: 5 апреля 2013
С нами: 10 лет 11 месяцев

#58 Дим » 4 декабря 2020, 15:29

Я не сильно вникал в код (он не мой), так как не понравились эти часики.
[center]i love you [s]mxIni[/s] Mysql[/center]

Дим M
Автор темы, Администратор
Администратор
Аватара
Дим M
Автор темы, Администратор
Администратор
Сообщения: 1608
Зарегистрирован: 5 апреля 2013
С нами: 10 лет 11 месяцев

#59 Дим » 27 декабря 2020, 18:34

Пришла посылка с BMP180. Вторую версию сделал как первую.

Код: Выделить всё

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>
#include "IRremote.h"
IRrecv irrecv(12);                            // указываем вывод, к которому подключен ИК приемник
decode_results results;
uint32_t Key1 0x2FD50AF;                    // Определяем код кнопки ПДУ OK
uint32_t Key2 0x2FD52AD;                    // Определяем код кнопки ПДУ лево
uint32_t Key3 0x2FDB24D;                    // Определяем код кнопки ПДУ право
#include <iarduino_RTC.h>                     // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);                // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP085 bmp;
// ============================== кнопки
const uint8_t PIN_button_SET  4;            // указываем номер вывода arduino, к которому подключена кнопка SET
const uint8_t PIN_button_UP   3;            // указываем номер вывода arduino, к которому подключена кнопка UP
//const uint8_t PIN_button_DOWN = 5;            // указываем номер вывода arduino, к которому подключена кнопка DOWN
bool     button_state1      false;          // статус кнопки 1
bool     button_state2      false;          // статус кнопки 2
bool     button_long_state  false;          // удержание кнопки (код выполнится один раз)
uint32_t ms_button         0;
uint32_t ms_auto_click     0;

uint8_t corrClock 0;                        // корректировали время или нет
uint8_t updCnt 0;
uint8_t dots 0;
long dotTime 0;
long clkTime 0;

const 
uint8_t DS18B20 8;                    // Указываем, к какому выводу подключена DQ (уличн темп)

uint8_t wibor 0;                            // После того как длительно нажали на кнопку SET можно будет нажимать коротко
uint8_t mig 0;
uint8_t migSet 0;
uint8_t migTime 0;
long previousMillis 0;
uint8_t val=0

uint8_t wait 50;                            // скорость бегущей строки
uint8_t spacer 2;
uint8_t width spacer;                   // Регулируем расстояние между символами
uint8_t refresh=0;
const 
uint8_t  pinCS 10;                    // Подключение пина CS
uint8_t numberOfHorizontalDisplays 4;       // Количество светодиодных матриц по Горизонтали
uint8_t numberOfVerticalDisplays 1;         // Количество светодиодных матриц по Вертикали
String weatherString;                         // бегущая строка
String clocks;                                // время

Max72xxPanel matrix Max72xxPanel(pinCSnumberOfHorizontalDisplaysnumberOfVerticalDisplays);
OneWire oneWire(DS18B20);                   
DallasTemperature sensors(&oneWire);
byte brightness 0;                         // Яркость матрицы от 0 до 15
// ===================================================================================================================================
void setup(void) {
  
Serial.begin9600 );                       // Инициируем передачу данных в монитор последовательного порта
  
irrecv.enableIRIn();                        // запускаем прием ИК приемника
  
if (!bmp.begin())                           //для температуры улицы
  
{
    while (
1) {}
  } 
  
time.begin();                               // Инициируем работу с модулем.
  //time.settime(0,27,21,03,01,18,3);         // Записываем время в модуль: 0 сек, 27 мин, 21 час, 3, января, 2018 года, среда. time.settime(0,27,21,03,01,18,3);
  
matrix.setIntensity(brightness);            // Яркость матрицы от 0 до 15
  
matrix.setRotation(matrix.getRotation()+2); // 1 - 90  2 - 180   3 - 270 угол поворота
                                   // начальные координаты матриц 8*8
  
matrix.setRotation(01);        // 1 матрица
  
matrix.setRotation(11);        // 2 матрица
  
matrix.setRotation(21);        // 3 матрица
  
matrix.setRotation(31);        // 4 матрица                                  
  
pinMode(PIN_button_SETINPUT_PULLUP);      // кнопки
  
pinMode(PIN_button_UPINPUT_PULLUP);
//  pinMode(PIN_button_DOWN, INPUT_PULLUP);
//   digitalWrite(PIN_button_SET ,HIGH);
}
// =======================================================================
void loop(void
{   
  if(
updCnt<=0
  {                                                               
// каждые 10 циклов получаем данные времени и погоды
    
updCnt 1;
    
getWeatherData();
    
clkTime millis();
  }
//  if((millis()-clkTime > 600000 && dots && mig == 0) || (mig == 3))// Через 10 минут/600000 мили/сек и не переводим часы (mig == 0) (или нажата кнопа UP) запускаем бегущую строку
  
if(((time.minutes == || time.minutes == 19 || time.minutes == 29 || time.minutes == 39 || time.minutes == 49 || time.minutes == 59) && time.seconds == 59 && mig == 0) || (mig == 3)) 
  {                                                               
// каждые (9,19,29,39,49,59) минут и 59 секунд и не переводим часы (mig == 0)(или нажата кнопа UP) запускаем бегущую строку
    //ScrollText(utf8rus("sampawno.ru!"));                        // текст строки
    
ScrollText(utf8rus(weatherString));                           // текст температуры и давления
    
updCnt--;
    
clkTime millis();
    
mig 0;                                                      // переменная mig не 3, для кнопки вызова бегущей строки, что бы не циклило её
  
}
  
DisplayTime();
  
time.blinktime(migSet);                                         // мигаем устанавливаемым параметром (migSet больше 0) при установке времени
  
if(millis()-dotTime 500
  {
    
dotTime millis();
    
dots = !dots;
  }
  
Func_buttons_control();
  if ( 
irrecv.decode( &results )) 
  {                              
// если данные с ПДУ пришли  
    
if (results.value == Key1)                                     // если нажата кнопка 1
      
{mig 3;}                                                   // запускаем бегущую строку
      
    
if (results.value == Key2)                                     // если нажата кнопка 2
      
{brightness --;}                                             // убавляем переменную яркости матрицы
      
if (brightness == 255brightness 15;                      // если вылезли за границы присваеваем 15 
      
{matrix.setIntensity(brightness);}                           // устанавливаем яркость матрицы     
      
    
if (results.value == Key3)                                      // если нажата кнопка 3
      
{brightness ++;}                                             // прибавляем переменную яркости матрицы
      
if (brightness 15brightness 0;                         // если вылезли за границы присваеваем 0
      
{matrix.setIntensity(brightness);}                           // устанавливаем яркость матрицы   
      
    
irrecv.resume();   // принимаем следующую команду
  
}
}
void Func_buttons_control()
{
   
uint32_t ms    millis();
   
bool pin_state1 digitalRead(PIN_button_SET); // кнопка SET
   
bool pin_state2 digitalRead(PIN_button_UP);  // 2 кнопка
//=========================================================================== кнопка SET
// Фиксируем нажатие кнопки  SET
  
if( pin_state1  == LOW && !button_state1 && ( ms ms_button ) > 50 ){
      
button_state1     true;
      
button_long_state false;
      
ms_button         ms;
      if(
wibor == 1)
        switch (
mig
        {
          case 
1:         // кнопка SET выбор мин
            
migSet 2;
            
mig 2;
            break;
          case 
2:         // кнопка SET сброс сек на 00
            
migSet 0;                                   // НЕмигают минуты и часы
            
mig 0;
            
time.settime(0, -1, -1);                      // Сбросит секунды на 0, а часы, минуты и дату, оставит без изменений.
            
wibor 0;
            break;
        }  
  }
// После 2000 мс нажатия кнопки SET единоразово выполним код
  
if( pin_state1  == LOW && !button_long_state && ( ms ms_button ) > 2000 // кнопка SET выбор час
  
{
    
migSet 3;
    
mig 1;  
    
wibor 1;                                     // длительно нажали
  
}
// Фиксируем отпускание кнопки SET 
   
if( pin_state1 == HIGH && button_state1 && ( ms ms_button ) > 50  ){
      
button_state1     false;   
      
ms_button         ms;
      
Serial.println("No Press 2"); //действие после отпуска длительного нажатия
   
}   
  
//===========================================  Кнопка UP (Установка часов)
  
if(mig == && pin_state2  == LOW && !button_state2 && ( ms ms_button ) > 50 )
  { 
    
button_state2     true;
    
ms_button         ms;
    
migSet 0;
    
time.Hours ++;                            // прибавляем единицу к часам
    
if (time.Hours 23time.Hours 0;      // если вылезли за границы присваеваем 0
    
time.settime(-1, -1time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  
}
  if(
mig == && pin_state2  == LOW && ( ms ms_button ) > 1000 && ( ms ms_auto_click )>300 // После 1000 мс нажатия кнопки каждые 400 мс фиксируем событие нажатия  
  
{
    
ms_auto_click     ms;
    
migSet 0;
    
time.Hours ++;                            // прибавляем единицу к часам
    
if (time.Hours 23time.Hours 0;      // если вылезли за границы присваеваем 0
    
time.settime(-1, -1time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  
}
  
//===========================================  Кнопка UP (Установка минут)
  
if(mig == && pin_state2  == LOW && !button_state2 && ( ms ms_button ) > 50 )
  { 
    
button_state2     true;
    
ms_button         ms;
    
migSet 0;
    
time.minutes ++;                          // прибавляем единицу к минутам
    
if (time.minutes 59time.minutes 0;  // если вылезли за границы присваеваем 0
    
time.settime(-1time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  
}
  if(
mig == && pin_state2  == LOW && ( ms ms_button ) > 1000 && ( ms ms_auto_click )>300 // После 1000 мс нажатия кнопки каждые 400 мс фиксируем событие нажатия  
  
{
    
ms_auto_click     ms;
    
migSet 0;
    
time.minutes ++;                          // прибавляем единицу к минутам
    
if (time.minutes 59time.minutes 0;  // если вылезли за границы присваеваем 0
    
time.settime(-1time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  
}
  
//===========================================  Кнопка UP (Установка минут) вызов бегущей строки  
  
if(mig == && pin_state2  == LOW && !button_state2 && ( ms ms_button ) > 50 )
  { 
    
mig 3;
  } 
//==============================================================================  Кнопка UP ( Фиксируем отпускание кнопки установки часов/минут  )
  
if(pin_state2 == HIGH && button_state2 && ( ms ms_button ) > 50  )
  {
    
button_state2     false;   
    
ms_button         ms;
    if(
mig == 1){migSet 3;}
    if(
mig == 2){migSet 2;}
  }
}
void DisplayTime()
{
  
sensors.requestTemperatures();             // Считываем показания температуры 
  
clocks String(time.gettime("His"))+" ";  // Время
  
if(time.Hours == 23 && time.minutes == 30 && time.seconds == 45 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:45 и не переводили часы (corrClock == 0)
  
time.settime(9, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 36 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 9. Было 23:30:45 стало 23:30:09 - на 36 сек меньше.
  
corrClock 1;                             // перевели время (что бы в 23:30:45 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 
corrClock 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:45 опять перевелись часы   
}
 
  
matrix.fillScreen(LOW);
  
int y = (matrix.height() - 8) / 2;         // Центрируем текст по Вертикали
  // if(clocks[5] & 1){matrix.drawChar(14, y-1, (String(":"))[0], HIGH, LOW, 1);} //каждую четную секунду печатаем двоеточие по центру (чтобы мигало)
//  else{matrix.drawChar(14, y, (String(" "))[0], HIGH, LOW, 1);}               //каждую НЕЧЕТНУЮ секунду НЕ ПЕЧАТАЕМ двоеточие по центру (чтобы мигало)
  
if(clocks[5] & 1){matrix.drawChar(14, -1, (String(":"))[0], HIGHLOW1);}    //каждую четную секунду печатаем двоеточие по центру (чтобы бегало)
  
else{matrix.drawChar(14, -2, (String(":"))[0], HIGHLOW1);}                //каждую НЕЧЕТНУЮ секунду печатаем двоеточие ВЫШЕ на 1 (чтобы бегало)
  
  
int xh 2;
  
int xm 19;
  
matrix.drawChar(xhyclocks[0], HIGHLOW1);
  
matrix.drawChar(xh+6yclocks[1], HIGHLOW1);
  
matrix.drawChar(xmyclocks[2], HIGHLOW1);
  
matrix.drawChar(xm+6yclocks[3], HIGHLOW1); 
  
matrix.write();                                     // Вывод на дисплей
}
void ScrollText (String text)
{
    for ( 
int i width text.length() + matrix.width() - spaceri++ ) {
    if (
refresh==1i=0;
    
refresh=0;
    
matrix.fillScreen(LOW);
    
int letter width;
    
int x = (matrix.width() - 1) - width;
    
int y = (matrix.height() - 8) / 2;  // Центрируем текст по Вертикали
    
while ( width spacer >= && letter >= 
    {
      if ( 
letter text.length() ) 
      {
        
matrix.drawChar(xytext[letter], HIGHLOW1);
      }
      
letter--;
      
-= width;
    }
    
matrix.write();                    // Вывод на дисплей
    
delay(wait);
  }
}
//float tempOffset = 1.5;               //поправка уличного датчика
float tempOffset 1.0;               //поправка уличного датчика
void getWeatherData()
{
  
weatherString " t.д: " String(bmp.readTemperature(),1)+" ";
  
weatherString += " ул: " String(sensors.getTempCByIndex(0) - tempOffset1)+" ";
  
weatherString += " дв: " String(bmp.readSealevelPressure()/133.3) + " мм ";       //131.42 поправка реального(из инета)
}
String utf8rus(String source)
{
  
int i,k;
  
String target;
  
unsigned char n;
  
char m[2] = { '0''\0' };
  
source.length(); 0;
  while (
k) {
    
source[i]; i++;
    if (
>= 0xC0) {
      switch (
n) {
        case 
0xD0: {
          
source[i]; i++;
          if (
== 0x81) { 0xA8; break; }
          if (
>= 0x90 && <= 0xBF0x30-1;
          break;
        }
        case 
0xD1: {
          
source[i]; i++;
          if (
== 0x91) { 0xB8; break; }
          if (
>= 0x80 && <= 0x8F0x70-1;
          break;
        }
      }
    }
    
m[0] = ntarget target String(m);
  }
return 
target;
[center]i love you [s]mxIni[/s] Mysql[/center]

S_Sergey_G
Ст. сержант
Ст. сержант
Аватара
S_Sergey_G
Ст. сержант
Ст. сержант
Сообщения: 92
Зарегистрирован: 28 января 2021
С нами: 3 года 2 месяца

#60 S_Sergey_G » 9 апреля 2021, 12:58

Пытаюсь параллельно теме "Часы термометр" собрать Ваш проект, в начале этой теме пост #6 (viewtopic.php?p=14182#p14182). Но после успешной загрузки кода всё висит. На экране мишура. При чём беру любой код из этой темы такая же ерунда. Пробовал на разных ардуино нано. Что не так не пойму? Менял в коде только пины подключения кнопок и датчика DS18B20, правда датчик давления и IR приемник не подключен.


  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Программирование»

Кто сейчас на форуме (по активности за 5 минут)

Сейчас этот раздел просматривают: 5 гостей
Боты: Google [Bot]