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

Ildar
Аватара
Ildar

#21 Ildar » 22 апреля 2018, 0:26

Ну если у тебя много времени не отнимет то скетч.


Toropyizhka
Аватара
Toropyizhka
Сообщения: 1
Зарегистрирован: 19 октября 2018
С нами: 5 лет 5 месяцев

#22 Toropyizhka » 19 октября 2018, 10:22

Доброго времени суток!
Поигравшись с 7-сегментниками и матрицами собрал несколько вариантов своей погодной станции. Интересным показался и Ваш пример. Не сильно вдаваясь в теорию, на просторах Интернета пересмотрел могучую кучу различных проектов и переработал Ваш скетч на свой лад. Меня устраивает, но пока не всё. И так ...
Светодиодные матрицы MAX7219 8х8 в линейке 8 шт., плата Arduino UNO R3 (в своё время удачно прикупил оригинальную), модуль часов RTC 1307, датчики температуры/влажности DHT22, "пищалка", пара резисторов 10кОм, перемычки и макетка, зарядка от планшета 5V 2A (мне просто удобно питать Ардуинку через USB-кабель от принтера). Ко всему этому голова и руки из нужного места :wink:
Время: отображаются часы, минуты и секунды. Двоеточие постоянно, секунды отсчитываются. При показе времени горит значок часиков. Добавил "пищалку" и теперь каждый час с 07:00 до 22:00 звучит сигнал (5 раз по 0,5 сек.). С "пищалкой" отдельная история. Перепробовал всяко-разно: и компьютерные. и кукольные (Лапочка-дочка любезно "выдрала" пару штук), и из музыкальных открыток. В режиме молчания все они сильно "фонили", резистор на 100Ом фоновый шум снижали. но и снижали громкость. В итоге выпаял "пищалку" из китайского набора для сборки часов, которая оказалась наилучшим вариантом  :dance:
Датчики: подключил пока две штуки DHT22. Уличный висит за балконом, провод телефонный 4-х жильный. Комнатный на макетке (впрочем как и вся конструкция) :roll:
Бегущая строка: их две. Одна выводит показания температуры/влажности на улице и в комнате каждые 5 минут на 42-й секунде. Вместо словесного обозначения вывел значки (солнышко, домик и капелька). Библиотека 5х7 не позволяет сообразить полноценные солнышко и домик, но есть то что есть. Единственное что изменил, коды фигурных скобок { и } заменил на солнышко и капельку соответственно, а символ | заменил на домик. Вторая строка выводит дату каждые 10 минут на 53-й секунде. Символ ещё не придумал :oops:
Кнопки: пока не ставил да и нет такой необходимости. Вся конструкция, как у заправского радиолюбителя, собрана на макетке и может как её предшественницы годами работать в таком виде.
В планах добавить датчик давления, будильники и переписать значки в библиотеке, а лучше всю библиотеку. Шрифт 5х7, конечно, выглядит зрительно приятно, но оставлять незадействованной восьмой (нижний) ряд светодиодов как-то не айс на мой взгляд. Библиотеки хочу оптимизировать непосредственно под готовый продукт, ибо они универсальны и рассчитаны на различные модули и датчики (что есть хорошо), но при этом тоже хорошо "кушают" память контроллера (что ни есть здорово). :mad:
Ну и наконец сам код. Библиотеки все те же...
Спойлер

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

// Библиотеки
   #include <SPI.h>
   #include <Wire.h>
   #include <Adafruit_GFX.h>
   #include <Max72xxPanel.h>
   #include <iarduino_DHT.h>
   #include <iarduino_RTC.h>
// Подключение пьезоэлемента: Black - GND, Red - 5
   int soundPin = 5; 
// Подключение матриц и их количество по вертикали и горизонтали: CLK - 13, DIN - 11, CS - 9
   int pinCS = 9;
   int numberOfHorizontalDisplays = 1;
   int numberOfVerticalDisplays = 8;
   Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);
// Подключение DHT22 на улице и в комнате: PIN1 - +5V, PIN2 - 2(3), PIN4 - GND
   iarduino_DHT sensor1(2);
   iarduino_DHT sensor2(3);
// Объект time для работы с модулем RTC на базе чипа DS1307, аппаратная шина I2C:
   iarduino_RTC time(RTC_DS1307);
// Символ часов
   const byte data[8]={B00111000,B01010100,B10010010,B11110010,B10000010,B01000100,B00111000,B00000000};

   String clocks;
   String weather;
   String calendar;
//==================================================================================
void setup(void)
// Назначение PIN5 режима работы "Выход":
{  pinMode(soundPin, OUTPUT);
// Инициализация модуля RTC DS1307:
   time.begin();
// Яркость матриц (от 0 до 15) и направление текста (1 - 90 гр., 2 - 180 гр., 3 - 270 гр.):
   matrix.setIntensity(1);
   matrix.setRotation(3);
}
   int updCnt = 0;
   int dots = 0;
   long dotTime = 0;
   long clkTime = 0;
   byte del=0;
//==================================================================================
void loop(void)
// Получение данных календаря, времени и погоды (каждые 10 циклов)  :
{  if(updCnt<=0) {updCnt = 1; getData(); clkTime = millis();}
// Звуковое сопровождение каждого часа c 06:00 до 22:00 в течение 5-и секунд:
   if(((time.Hours==|| time.Hours==|| time.Hours==|| time.Hours==|| time.Hours==10 || time.Hours==11 || time.Hours==12 || time.Hours==13 || time.Hours==14 || time.Hours==15 || time.Hours==16 || time.Hours==17 || time.Hours==18 || time.Hours==19 || time.Hours==20 || time.Hours==21 || time.Hours==22) && time.minutes==0) && time.seconds==0) {
   analogWrite(soundPin, 255); delay(500); analogWrite(soundPin, 0); delay(500);
   analogWrite(soundPin, 255); delay(500); analogWrite(soundPin, 0); delay(500);
   analogWrite(soundPin, 255); delay(500); analogWrite(soundPin, 0); delay(500);
   analogWrite(soundPin, 255); delay(500); analogWrite(soundPin, 0); delay(500);
   analogWrite(soundPin, 255); delay(500); analogWrite(soundPin, 0); delay(500);}
// Запуск бегущей строки каждые 5 минут на 42-й секунде и запись показаний температуры/влажности в бегущую строку:
   if((time.minutes==|| time.minutes==|| time.minutes==14 || time.minutes==19 || time.minutes==24 || time.minutes==29 || time.minutes==34 || time.minutes==39 || time.minutes==44 || time.minutes==49 || time.minutes==54 || time.minutes==58) && time.seconds==42)
   {ScrollText(weather); updCnt--; clkTime = millis();}      
// Запуск бегущей строки каждые 10 минут на 53-й секунде и запись календаря в бегущую строку:
   if((time.minutes==|| time.minutes==18 || time.minutes==27 || time.minutes==36 || time.minutes==45 || time.minutes==54) && time.seconds==53)
   {ScrollText(calendar); updCnt--; clkTime = millis();}
   DisplayTime(); if(millis()-dotTime > 500) {dotTime = millis(); dots = !dots;}
}
//==================================================================================
void DisplayTime()
// Чтение показаний датчиков DHT22:
{  switch(sensor1.read()){}
   switch(sensor2.read()){}
// Очистка матрицы   
   matrix.fillScreen(LOW);
// Формирование символа часов и вывод на дисплей:
   for ( int y = 0; y < 8; y++ ) {for ( int x = 0; x < 8; x++ ) {matrix.drawPixel(x, y, data[y] & (1<<x));}}
// Получение и вывод текущего времени:
   clocks = String(time.gettime("His"));
// Положение текущего времени по горизонтали:
   int xh = 18;
   int xi = 35;
   int xs = 52;
// Центровка текущего времени по вертикали:
   int y = (matrix.height() - 8) / 2;
// Отображение двоеточия между часами и минутами, минутами и секундами по центру:
   matrix.drawChar(30, y, (String(":"))[0], HIGH, LOW, 1);
   matrix.drawChar(47, y, (String(":"))[0], HIGH, LOW, 1);
// Формирование показаний текущего времени и вывод на дисплей:
   matrix.drawChar(xh, y, clocks[0], HIGH, LOW, 1);
   matrix.drawChar(xh+6, y, clocks[1], HIGH, LOW, 1);
   matrix.drawChar(xi, y, clocks[2], HIGH, LOW, 1);
   matrix.drawChar(xi+6, y, clocks[3], HIGH, LOW, 1);
   matrix.drawChar(xs, y, clocks[4], HIGH, LOW, 1);
   matrix.drawChar(xs+6, y, clocks[5], HIGH, LOW, 1);
   matrix.write();
}
//==================================================================================
void ScrollText (String text)
  // Скорость бегущей строки:
{  int wait = 50;
// Центровка данных по вертикали:
   int y = (matrix.height() - 8) / 2;
// Расстояние между буквами (в точках) и размер шрифта (прописные буквы, в точках):
   int spacer = 1;
   int width = 5 + spacer;
   int refresh=0;
   for (int i = 0 ; i < width * text.length() + matrix.width() - 1 - spacer; i++)
   {if (refresh==1) i=0; refresh=0;
   matrix.fillScreen(LOW);
   int letter = i / width;
   int x = (matrix.width() - 1) - i % width;
   while (+ width - spacer >= 0 && letter >= 0)
   {if (letter < text.length())
   {matrix.drawChar(x, y, text[letter], HIGH, LOW, 1);}
   letter--; x -= width;}
// Вывод бегущей строки на дисплей:
   matrix.write();
   delay(wait);}
}
//==================================================================================
void getData()
// Формирование показаний календаря в бегущей строке:
{  calendar = ((String)+time.gettime("d.m.Y"));
// Формирование показаний температуры и влажности в бегущей строке:
   weather  = ((String)+"{ "+sensor1.tem+"'C" +"   } "+sensor1.hum+"%"+"   | "+sensor2.tem+"'C" +"   } "+sensor2.hum+"%");
}
Как только разберусь здесь с мультимедиа, закину для обзора фото и видео...

Arduino
Сержант
Сержант
Аватара
Arduino
Сержант
Сержант
Сообщения: 64
Зарегистрирован: 19 апреля 2017
С нами: 6 лет 11 месяцев

#23 Arduino » 18 мая 2019, 19:25

Toropyizhka писал(а):DHT22. Уличный висит за балконом
Это если температура не опускается ниже -40 :grin:

Arduino
Сержант
Сержант
Аватара
Arduino
Сержант
Сержант
Сообщения: 64
Зарегистрирован: 19 апреля 2017
С нами: 6 лет 11 месяцев

#24 Arduino » 24 мая 2019, 21:55

Toropyizhka писал(а):коды фигурных скобок { и } заменил на солнышко и капельку соответственно, а символ | заменил на домик
Каким образом это сделал?

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

#25 Дим » 16 июня 2019, 13:34

Потребовался ещё один экземпляр часов. Но так как барометр BMP280 по I2C почему то не захотел работать, пришлось подключать по SPI и соответственно менять код. Пока оставлю его тут, когда всё доделаю - будет в новой теме.

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

#include <Wire.h>                             // Библиотека протокола 1-Wire
#include <Adafruit_BMP280.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>                // Библиотека для работы с датчиками DS*
#include <iarduino_RTC.h>                     // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);                // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP280 bmp;
#define BMP_SCK 9                             // Пины подключения атчика атмосферного давления BMP280
#define BMP_MISO 7
#define BMP_MOSI 6 
#define BMP_CS 5
Adafruit_BMP280 bme(BMP_CSBMP_MOSIBMP_MISO,  BMP_SCK);
#define ONE_WIRE_BUS 8                        // Шина данных датчика температуры DS18B20 на 8 пине
OneWire oneWire(ONE_WIRE_BUS);                // Создаем экземпляр объекта протокола 1-WIRE - OneWire
DallasTemperature sensors(&oneWire);          // На базе ссылки OneWire создаем экземпляр объекта, работающего с датчиками DS*
// ============================== кнопки
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);                
// ===================================================================================================================================
void setup(void) {
  
Serial.begin9600 );                       // Инициируем передачу данных в монитор последовательного порта
  //nsors.begin();                            // Запускаем поиск всех датчиков DS1307 для температуры улицы
  
if (!bme.begin()) {                         // Датчик атмосферного давления BMP280 
  
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
  while (
1);
  }
  
time.begin();                               // Инициируем работу с модулем часов DS1307
  //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(0);                     // Яркость матрицы от 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);
}
// =======================================================================
void loop(void
{   
  if(
updCnt<=0
  {                                                               
// каждые 10 циклов получаем данные времени и погоды
    
updCnt 1;
    
getWeatherData();
    
clkTime millis();
  }
  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();
}
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();             // Запускаем измерение температуры на всех датчиках DS18B20 (уличн темп)
  
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(10, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 35 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 10. Было 23:30:45 стало 23:30:10 - на 35 сек меньше.
  
corrClock 1;                             // перевели время (что бы в 23:30:45 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 
corrClock 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:55 опять перевелись часы   
}
 
  
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(140, (String(":"))[0], HIGHLOW1);}    //каждую четную секунду печатаем двоеточие по центру (чтобы бегало)
  
else{matrix.drawChar(14, -1, (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.0;               //поправка уличного датчика
void getWeatherData()
{
  
weatherString " t.дом: " String(bme.readTemperature(), 1)+" ";            // .... ,1 ... - еденица делает из сотых десятые после запятой
  
weatherString += " улица: " String(sensors.getTempCByIndex(0) - tempOffset1)+" "// Поскольку датчик всего один, то запрашиваем данные с устройства с индексом 0
  
weatherString += " давл: " String(bme.readPressure()/133.3) + " мм ";       //131.42 поправка реального(из инета)bme.readPressure
}
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;

Так же и новую схему.
Часы на max7219 + DS1307 + DS18B20 + BMP180.png
Часы на max7219 + DS1307 + DS18B20 + BMP180
Часы на max7219 + DS1307 + DS18B20 + BMP180.png (356.42 КБ) 5737 просмотров
[center]i love you [s]mxIni[/s] Mysql[/center]

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

#26 Дим » 9 июля 2019, 23:07

phpBB [media]


Для первой версии часов добавил ИК приёмник. Теперь появилась возможность не вставая с дивана запустить бегущую строку, а так же увеличить или уменьшить яркость дисплея. Надеюсь что это будет последняя моя доработка этой версии. Чуть позже добавлю схему.

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

#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 = 5 + 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(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);
OneWire oneWire(DS18B20);                   
DallasTemperature sensors
(&oneWire);
byte brightness = 0;                         // Яркость матрицы от 0 до 15
// ===================================================================================================================================
void setup(void) {
  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  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(0, 1);        // 1 матрица
  matrix.setRotation(1, 1);        // 2 матрица
  matrix.setRotation(2, 1);        // 3 матрица
  matrix.setRotation(3, 1);        // 4 матрица                                  
  pinMode(PIN_button_SET, INPUT_PULLUP);      // кнопки
  pinMode(PIN_button_UP, INPUT_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 == 9 || 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 == 255) brightness = 15;                      // если вылезли за границы присваеваем 15 
      {matrix.setIntensity(brightness);}                           // устанавливаем яркость матрицы     
      
    if 
(results.value == Key3)                                      // если нажата кнопка 3
      {brightness ++;}                                             // прибавляем переменную яркости матрицы
      if (brightness > 15) brightness = 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 == 1 && pin_state2  == LOW && !button_state2 && ( ms - ms_button ) > 50 )
  { 
    button_state2     
= true;
    ms_button         = ms;
    migSet = 0;
    time.Hours ++;                            // прибавляем единицу к часам
    if (time.Hours > 23) time.Hours = 0;      // если вылезли за границы присваеваем 0
    time.settime(-1, -1, time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  }
  if(mig == 1 && 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 > 23) time.Hours = 0;      // если вылезли за границы присваеваем 0
    time.settime(-1, -1, time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  }
  //===========================================  Кнопка UP (Установка минут)
  if(mig == 2 && pin_state2  == LOW && !button_state2 && ( ms - ms_button ) > 50 )
  { 
    button_state2     
= true;
    ms_button         = ms;
    migSet = 0;
    time.minutes ++;                          // прибавляем единицу к минутам
    if (time.minutes > 59) time.minutes = 0;  // если вылезли за границы присваеваем 0
    time.settime(-1, time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  }
  if(mig == 2 && 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 > 59) time.minutes = 0;  // если вылезли за границы присваеваем 0
    time.settime(-1, time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  }
  //===========================================  Кнопка UP (Установка минут) вызов бегущей строки  
  if(mig == 0 && 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 == 35 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:55 и не переводили часы (corrClock == 0)
  time.settime(10, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 30 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 5. Было 23:30:55 стало 23:30:05 - на 50 сек меньше.
  corrClock = 1;                             // перевели время (что бы в 23:30:55 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 corrClock = 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:55 опять перевелись часы   
}
 
  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, 0, (String(":"))[0], HIGH, LOW, 1);}    //каждую четную секунду печатаем двоеточие по центру (чтобы бегало)
  else{matrix.drawChar(14, -1, (String(":"))[0], HIGH, LOW, 1);}                //каждую НЕЧЕТНУЮ секунду печатаем двоеточие ВЫШЕ на 1 (чтобы бегало)
  
  int xh 
= 2;
  int xm = 19;
  matrix.drawChar(xh, y, clocks[0], HIGH, LOW, 1);
  matrix.drawChar(xh+6, y, clocks[1], HIGH, LOW, 1);
  matrix.drawChar(xm, y, clocks[2], HIGH, LOW, 1);
  matrix.drawChar(xm+6, y, clocks[3], HIGH, LOW, 1); 
  matrix
.write();                                     // Вывод на дисплей
}
void ScrollText (String text)
{
    for ( int i = 0 ; i < width * text.length() + matrix.width() - 1 - spacer; i++ ) {
    if (refresh==1) i=0;
    refresh=0;
    matrix.fillScreen(LOW);
    int letter = i / width;
    int x = (matrix.width() - 1) - i % width;
    int y = (matrix.height() - 8) / 2;  // Центрируем текст по Вертикали
    while ( x + width - spacer >= 0 && letter >= 0 ) 
    
{
      if ( letter < text.length() ) 
      
{
        matrix.drawChar(x, y, text[letter], HIGH, LOW, 1);
      }
      letter--;
      x -= 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) - tempOffset, 1)+" ";
  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' };
  k = source.length(); i = 0;
  while (< k) {
    n = source[i]; i++;
    if (>= 0xC0) {
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (== 0x81) { n = 0xA8; break; }
          if (>= 0x90 && n <= 0xBF) n = n + 0x30-1;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (== 0x91) { n = 0xB8; break; }
          if (>= 0x80 && n <= 0x8F) n = n + 0x70-1;
          break;
        }
      }
    }
    m[0] = n; target = target + String(m);
  }
return target;
}
[center]i love you [s]mxIni[/s] Mysql[/center]

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

#27 Дим » 4 августа 2019, 22:44

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

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

#include <Wire.h>                             // Библиотека протокола 1-Wire
#include <Adafruit_BMP280.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>                // Библиотека для работы с датчиками DS*
#include <iarduino_IR_RX.h>                      // Подключаем библиотеку для работы с ИК-приёмником
iarduino_IR_RX IR(7);                            // Объявляем объект IR, с указанием вывода к которому подключён ИК-приёмник
#include <iarduino_RTC.h>                     // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);                // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP280 bmp;
#define BMP_SCK 5                             // Пины подключения атчика атмосферного давления BMP280
#define BMP_MISO 9                            //SDO
#define BMP_MOSI 6                            //SDA
#define BMP_CS 7
Adafruit_BMP280 bme(BMP_CS, BMP_MOSI, BMP_MISO,  BMP_SCK);
#define ONE_WIRE_BUS 8                        // Шина данных датчика температуры DS18B20 на 8 пине
OneWire oneWire(ONE_WIRE_BUS);                // Создаем экземпляр объекта протокола 1-WIRE - OneWire
DallasTemperature sensors(&oneWire);          // На базе ссылки OneWire создаем экземпляр объекта, работающего с датчиками DS*
// ============================== кнопки
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 = 5 + 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(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);                
// ===================================================================================================================================
void setup(void) {
//  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  IR.begin();                                    // Инициируем работу с ИК-приёмником
  //nsors.begin();                            // Запускаем поиск всех датчиков DS1307 для температуры улицы
  if (!bme.begin()) {                         // Датчик атмосферного давления BMP280 
 // Serial.println("Could not find a valid BMP280 sensor, check wiring!");
  while (1);
  }
  time.begin();                               // Инициируем работу с модулем часов DS1307
  //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(0);                     // Яркость матрицы от 0 до 15
  matrix.setRotation(matrix.getRotation()+2); // 1 - 90  2 - 180   3 - 270 угол поворота
                                   // начальные координаты матриц 8*8
  matrix.setRotation(0, 1);        // 1 матрица
  matrix.setRotation(1, 1);        // 2 матрица
  matrix.setRotation(2, 1);        // 3 матрица
  matrix.setRotation(3, 1);        // 4 матрица                                  
  pinMode(PIN_button_SET, INPUT_PULLUP);      // кнопки
  pinMode(PIN_button_UP, INPUT_PULLUP);
}
// =======================================================================
void loop(void) 
{   
  if
(updCnt<=0) 
  
{                                                               // каждые 10 циклов получаем данные времени и погоды
    updCnt = 1;
    getWeatherData();
    clkTime = millis();
  }
  if(((time.minutes == 9 || 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();
}
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 == 1 && pin_state2  == LOW && !button_state2 && ( ms - ms_button ) > 50 )
  { 
    button_state2     
= true;
    ms_button         = ms;
    migSet = 0;
    time.Hours ++;                            // прибавляем единицу к часам
    if (time.Hours > 23) time.Hours = 0;      // если вылезли за границы присваеваем 0
    time.settime(-1, -1, time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  }
  if(mig == 1 && 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 > 23) time.Hours = 0;      // если вылезли за границы присваеваем 0
    time.settime(-1, -1, time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  }
  //===========================================  Кнопка UP (Установка минут)
  if(mig == 2 && pin_state2  == LOW && !button_state2 && ( ms - ms_button ) > 50 )
  { 
    button_state2     
= true;
    ms_button         = ms;
    migSet = 0;
    time.minutes ++;                          // прибавляем единицу к минутам
    if (time.minutes > 59) time.minutes = 0;  // если вылезли за границы присваеваем 0
    time.settime(-1, time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  }
  if(mig == 2 && 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 > 59) time.minutes = 0;  // если вылезли за границы присваеваем 0
    time.settime(-1, time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  }
  //===========================================  Кнопка UP (Установка минут) вызов бегущей строки  
  if(mig == 0 && 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();             // Запускаем измерение температуры на всех датчиках DS18B20 (уличн темп)
  clocks = String(time.gettime("His"))+" ";  // Время
  if(time.Hours == 23 && time.minutes == 30 && time.seconds == 55 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:55 и не переводили часы (corrClock == 0)
  time.settime(5, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 50 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 5. Было 23:30:55 стало 23:30:05 - на 50 сек меньше.
  corrClock = 1;                             // перевели время (что бы в 23:30:55 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 corrClock = 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:55 опять перевелись часы   
}
 
  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, 0, (String(":"))[0], HIGH, LOW, 1);}    //каждую четную секунду печатаем двоеточие по центру (чтобы бегало)
  else{matrix.drawChar(14, -1, (String(":"))[0], HIGH, LOW, 1);}                //каждую НЕЧЕТНУЮ секунду печатаем двоеточие ВЫШЕ на 1 (чтобы бегало)
  
  int xh 
= 2;
  int xm = 19;
  matrix.drawChar(xh, y, clocks[0], HIGH, LOW, 1);
  matrix.drawChar(xh+6, y, clocks[1], HIGH, LOW, 1);
  matrix.drawChar(xm, y, clocks[2], HIGH, LOW, 1);
  matrix.drawChar(xm+6, y, clocks[3], HIGH, LOW, 1); 
  matrix
.write();                                     // Вывод на дисплей
}
void ScrollText (String text)
{
    for ( int i = 0 ; i < width * text.length() + matrix.width() - 1 - spacer; i++ ) {
    if (refresh==1) i=0;
    refresh=0;
    matrix.fillScreen(LOW);
    int letter = i / width;
    int x = (matrix.width() - 1) - i % width;
    int y = (matrix.height() - 8) / 2;  // Центрируем текст по Вертикали
    while ( x + width - spacer >= 0 && letter >= 0 ) 
    
{
      if ( letter < text.length() ) 
      
{
        matrix.drawChar(x, y, text[letter], HIGH, LOW, 1);
      }
      letter--;
      x -= width;
    }
    matrix.write();                    // Вывод на дисплей
    delay(wait);
  }
}
float tempOffset = 1.0;               //поправка уличного датчика
void getWeatherData()
{
  weatherString = " t.дом: " + String(bme.readTemperature(), 1)+" ";            // .... ,1 ... - еденица делает из сотых десятые после запятой
  weatherString += " улица: " + String(sensors.getTempCByIndex(0) - tempOffset, 1)+" "; // Поскольку датчик всего один, то запрашиваем данные с устройства с индексом 0
  weatherString += " давл: " + String(bme.readPressure()/133.3) + " мм ";       //131.42 поправка реального(из инета)bme.readPressure
}
String utf8rus(String source)
{
  int i,k;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };
  k = source.length(); i = 0;
  while (< k) {
    n = source[i]; i++;
    if (>= 0xC0) {
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (== 0x81) { n = 0xA8; break; }
          if (>= 0x90 && n <= 0xBF) n = n + 0x30-1;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (== 0x91) { n = 0xB8; break; }
          if (>= 0x80 && n <= 0x8F) n = n + 0x70-1;
          break;
        }
      }
    }
    m[0] = n; target = target + String(m);
  }
return target;
}


С ИК приёмником:

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

#include <Wire.h>                             // Библиотека протокола 1-Wire
#include <Adafruit_BMP280.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>                // Библиотека для работы с датчиками DS*
#include "IRremote.h"
IRrecv irrecv(12);                            // указываем вывод, к которому подключен ИК приемник
decode_results results;
uint32_t Key1 0x2FD50AF;                    // Определяем код кнопки ПДУ OK
#include <iarduino_RTC.h>                     // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);                // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP280 bmp;
#define BMP_SCK 5                             // Пины подключения атчика атмосферного давления BMP280
#define BMP_MISO 9                            //SDO
#define BMP_MOSI 6                            //SDA
#define BMP_CS 7
Adafruit_BMP280 bme(BMP_CSBMP_MOSIBMP_MISO,  BMP_SCK);
#define ONE_WIRE_BUS 8                        // Шина данных датчика температуры DS18B20 на 8 пине
OneWire oneWire(ONE_WIRE_BUS);                // Создаем экземпляр объекта протокола 1-WIRE - OneWire
DallasTemperature sensors(&oneWire);          // На базе ссылки OneWire создаем экземпляр объекта, работающего с датчиками DS*
// ============================== кнопки
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);                
// ===================================================================================================================================
void setup(void) {
  
irrecv.enableIRIn();                        // запускаем прием ИК приемника
//  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  //nsors.begin();                            // Запускаем поиск всех датчиков DS1307 для температуры улицы
  
if (!bme.begin()) {                         // Датчик атмосферного давления BMP280 
//  Serial.println("Could not find a valid BMP280 sensor, check wiring!");
  
while (1);
  }
  
time.begin();                               // Инициируем работу с модулем часов DS1307
  //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(0);                     // Яркость матрицы от 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);
}
// =======================================================================
void loop(void
{   
  if(
updCnt<=0
  {                                                               
// каждые 10 циклов получаем данные времени и погоды
    
updCnt 1;
    
getWeatherData();
    
clkTime millis();
  }
  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;}                                                   // запускаем бегущую строку   
    
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();             // Запускаем измерение температуры на всех датчиках DS18B20 (уличн темп)
  
clocks String(time.gettime("His"))+" ";  // Время
  
if(time.Hours == 23 && time.minutes == 30 && time.seconds == 55 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:55 и не переводили часы (corrClock == 0)
  
time.settime(5, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 50 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 5. Было 23:30:55 стало 23:30:05 - на 50 сек меньше.
  
corrClock 1;                             // перевели время (что бы в 23:30:55 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 
corrClock 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:55 опять перевелись часы   
}
 
  
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(140, (String(":"))[0], HIGHLOW1);}    //каждую четную секунду печатаем двоеточие по центру (чтобы бегало)
  
else{matrix.drawChar(14, -1, (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.0;               //поправка уличного датчика
void getWeatherData()
{
  
weatherString " t.дом: " String(bme.readTemperature(), 1)+" ";            // .... ,1 ... - еденица делает из сотых десятые после запятой
  
weatherString += " улица: " String(sensors.getTempCByIndex(0) - tempOffset1)+" "// Поскольку датчик всего один, то запрашиваем данные с устройства с индексом 0
  
weatherString += " давл: " String(bme.readPressure()/133.3) + " мм ";       //131.42 поправка реального(из инета)bme.readPressure
}
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]

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

#28 Дим » 5 августа 2019, 18:30

Убрал (закомментировал) корректировку времени и поменял местами выходы на кнопки.

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

#include <Wire.h>                             // Библиотека протокола 1-Wire
#include <Adafruit_BMP280.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>                // Библиотека для работы с датчиками DS*
#include "IRremote.h"
IRrecv irrecv(12);                            // указываем вывод, к которому подключен ИК приемник
decode_results results;
uint32_t Key1 0x2FD50AF;                    // Определяем код кнопки ПДУ OK
#include <iarduino_RTC.h>                     // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);                // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP280 bmp;
#define BMP_SCK 5                             // Пины подключения атчика атмосферного давления BMP280
#define BMP_MISO 9                            //SDO
#define BMP_MOSI 6                            //SDA
#define BMP_CS 7
Adafruit_BMP280 bme(BMP_CSBMP_MOSIBMP_MISO,  BMP_SCK);
#define ONE_WIRE_BUS 8                        // Шина данных датчика температуры DS18B20 на 8 пине
OneWire oneWire(ONE_WIRE_BUS);                // Создаем экземпляр объекта протокола 1-WIRE - OneWire
DallasTemperature sensors(&oneWire);          // На базе ссылки OneWire создаем экземпляр объекта, работающего с датчиками DS*
// ============================== кнопки
const uint8_t PIN_button_SET  3;            // указываем номер вывода arduino, к которому подключена кнопка SET
const uint8_t PIN_button_UP   4;            // указываем номер вывода 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);                
// ===================================================================================================================================
void setup(void) {
  
irrecv.enableIRIn();                        // запускаем прием ИК приемника
//  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  //nsors.begin();                            // Запускаем поиск всех датчиков DS1307 для температуры улицы
  
if (!bme.begin()) {                         // Датчик атмосферного давления BMP280 
//  Serial.println("Could not find a valid BMP280 sensor, check wiring!");
  
while (1);
  }
  
time.begin();                               // Инициируем работу с модулем часов DS1307
  //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(0);                     // Яркость матрицы от 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);
}
// =======================================================================
void loop(void
{   
  if(
updCnt<=0
  {                                                               
// каждые 10 циклов получаем данные времени и погоды
    
updCnt 1;
    
getWeatherData();
    
clkTime millis();
  }
  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;}                                                   // запускаем бегущую строку   
    
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();             // Запускаем измерение температуры на всех датчиках DS18B20 (уличн темп)
  
clocks String(time.gettime("His"))+" ";  // Время
/*  if(time.Hours == 23 && time.minutes == 30 && time.seconds == 55 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:55 и не переводили часы (corrClock == 0)
  time.settime(5, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 50 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 5. Было 23:30:55 стало 23:30:05 - на 50 сек меньше.
  corrClock = 1;                             // перевели время (что бы в 23:30:55 опять не перевелись часы)
}
if(time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 corrClock = 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:55 опять перевелись часы   
}*/
 
  
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(140, (String(":"))[0], HIGHLOW1);}    //каждую четную секунду печатаем двоеточие по центру (чтобы бегало)
  
else{matrix.drawChar(14, -1, (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.0;               //поправка уличного датчика
void getWeatherData()
{
  
weatherString " t.дом: " String(bme.readTemperature(), 1)+" ";            // .... ,1 ... - еденица делает из сотых десятые после запятой
  
weatherString += " улица: " String(sensors.getTempCByIndex(0) - tempOffset1)+" "// Поскольку датчик всего один, то запрашиваем данные с устройства с индексом 0
  
weatherString += " давл: " String(bme.readPressure()/133.3) + " мм ";       //131.42 поправка реального(из инета)bme.readPressure
}
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]

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

#29 Дим » 8 августа 2019, 17:13

С помощью Image generate v2.004 переделал размер цифр по высоте. Теперь они занимают всю матрицу, а не только семь точек. Для этого в библиотеке Adafruit-GFX в файле glcdfont.c изменяем несколько строк.
Было:
Было
Было.JPG
Было

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

0x3E, 0x41, 0x41, 0x41, 0x3E,  // 48 
0x44, 0x42, 0x7F, 0x40, 0x40,  // 49
0x42, 0x61, 0x51, 0x49, 0x46,  // 50
0x21, 0x41, 0x45, 0x4B, 0x31,  // 51
0x18, 0x14, 0x12, 0x7F, 0x10,  // 52
0x27, 0x45, 0x45, 0x45, 0x39,  // 53
0x3C, 0x4A, 0x49, 0x49, 0x30,  // 54
0x01, 0x71, 0x09, 0x05, 0x03,  // 55
0x36, 0x49, 0x49, 0x49, 0x36,  // 56
0x06, 0x49, 0x49, 0x29, 0x1E,  // 57    

Стало:
Стало
Стало.JPG
Стало

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

0x7E, 0x81, 0x81, 0x81, 0x7E,  // 48 0
0x84, 0x82, 0xFF, 0x80, 0x80,  // 49 1  
0x82, 0xC1, 0xA1, 0x91, 0x8E,  // 50 2
0x42, 0x81, 0x89, 0x89, 0x76,  // 51 3
0x18, 0x14, 0x12, 0xFF, 0x10,  // 52 4
0x4F, 0x89, 0x89, 0x89, 0x71,  // 53 5
0x7C, 0x8A, 0x89, 0x89, 0x70,  // 54 6
0x01, 0xF1, 0x09, 0x05, 0x03,  // 55 7
0x76, 0x89, 0x89, 0x89, 0x76,  // 56 8
0x0E, 0x91, 0x91, 0x51, 0x3E,  // 57 9    

переделал размер цифр по высоте.png
переделал размер цифр по высоте
переделал размер цифр по высоте.png (15.27 КБ) 5421 просмотр
[center]i love you [s]mxIni[/s] Mysql[/center]

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

#30 Дим » 1 февраля 2020, 19:50

Изменил текст и цифры, пришлось в скетче изменить местоположение двоеточия. (...14, -1...)

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

 if(clocks[5] & 1){matrix.drawChar(14, -1, (String(":"))[0], HIGH, LOW, 1);}    //каждую четную секунду печатаем двоеточие по центру (чтобы бегало)
  else{matrix.drawChar(14, -2, (String(":"))[0], HIGH, LOW, 1);}                //каждую НЕЧЕТНУЮ секунду печатаем двоеточие ВЫШЕ на 1 (чтобы бегало)


Весь код для второй версии:

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

#include <Wire.h>                             // Библиотека протокола 1-Wire
#include <Adafruit_BMP280.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>                // Библиотека для работы с датчиками DS*
#include "IRremote.h"
IRrecv irrecv(12);                            // указываем вывод, к которому подключен ИК приемник
decode_results results;
uint32_t Key1 0x2FD50AF;                    // Определяем код кнопки ПДУ OK
#include <iarduino_RTC.h>                     // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);                // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP280 bmp;
#define BMP_SCK 5                             // Пины подключения атчика атмосферного давления BMP280
#define BMP_MISO 9                            //SDO
#define BMP_MOSI 6                            //SDA
#define BMP_CS 7
Adafruit_BMP280 bme(BMP_CSBMP_MOSIBMP_MISO,  BMP_SCK);
#define ONE_WIRE_BUS 8                        // Шина данных датчика температуры DS18B20 на 8 пине
OneWire oneWire(ONE_WIRE_BUS);                // Создаем экземпляр объекта протокола 1-WIRE - OneWire
DallasTemperature sensors(&oneWire);          // На базе ссылки OneWire создаем экземпляр объекта, работающего с датчиками DS*
// ============================== кнопки
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);                
// ===================================================================================================================================
void setup(void) {
  
irrecv.enableIRIn();                        // запускаем прием ИК приемника
//  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  //nsors.begin();                            // Запускаем поиск всех датчиков DS1307 для температуры улицы
  
if (!bme.begin()) {                         // Датчик атмосферного давления BMP280 
//  Serial.println("Could not find a valid BMP280 sensor, check wiring!");
  
while (1);
  }
  
time.begin();                               // Инициируем работу с модулем часов DS1307
  //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(0);                     // Яркость матрицы от 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);
}
// =======================================================================
void loop(void
{   
  if(
updCnt<=0
  {                                                               
// каждые 10 циклов получаем данные времени и погоды
    
updCnt 1;
    
getWeatherData();
    
clkTime millis();
  }
  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;}                                                   // запускаем бегущую строку   
    
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();             // Запускаем измерение температуры на всех датчиках DS18B20 (уличн темп)
  
clocks String(time.gettime("His"))+" ";  // Время
  
if(time.Hours == 23 && time.minutes == 30 && time.seconds == 55 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:55 и не переводили часы (corrClock == 0)
  
time.settime(25, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 30 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 25. Было 23:30:55 стало 23:30:25 - на 30 сек меньше.
  
corrClock 1;                             // перевели время (что бы в 23:30:55 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 
corrClock 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:55 опять перевелись часы   
}
 
  
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.0;               //поправка уличного датчика
void getWeatherData()
{
  
weatherString " t.дом: " String(bme.readTemperature(), 1)+" ";            // .... ,1 ... - еденица делает из сотых десятые после запятой
  
weatherString += " улица: " String(sensors.getTempCByIndex(0) - tempOffset1)+" "// Поскольку датчик всего один, то запрашиваем данные с устройства с индексом 0
  
weatherString += " давл: " String(bme.readPressure()/133.3) + " мм ";       //131.42 поправка реального(из инета)bme.readPressure
}
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;


И файл glcdfont.c (не весь переделанный)

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

#ifndef FONT5X7_H
#define FONT5X7_H

#ifdef __AVR__
 #include <avr/io.h>
 #include <avr/pgmspace.h>
#else
 #define PROGMEM
#endif
 
// Standard ASCII 5x7 font

static const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00,  // 00
0x3E, 0x55, 0x51, 0x55, 0x3E,  // 01 смайл
0x3E, 0x6B, 0x6F, 0x6B, 0x3E,  // 02
0x0C, 0x1E, 0x3C, 0x1E, 0x0C,  // 03
0x08, 0x1C, 0x3E, 0x1C, 0x08,  // 04
0x1C, 0x4A, 0x7F, 0x4A, 0x1C,  // 05
0x18, 0x5C, 0x7F, 0x5C, 0x18,  // 06
0x00, 0x1C, 0x1C, 0x1C, 0x00,  // 07
0x7F, 0x63, 0x63, 0x63, 0x7F,  // 08
0x00, 0x1C, 0x14, 0x1C, 0x00,  // 09
0x7F, 0x63, 0x6B, 0x63, 0x7F,  // 10
0x30, 0x48, 0x4D, 0x33, 0x07,  // 11
0x06, 0x29, 0x79, 0x29, 0x06,  // 12
0x20, 0x50, 0x3F, 0x02, 0x0C,  // 13
0x60, 0x7F, 0x05, 0x35, 0x3F,  // 14
0x2A, 0x1C, 0x77, 0x1C, 0x2A,  // 15
0x00, 0x7F, 0x3E, 0x1C, 0x08,  // 16
0x08, 0x1C, 0x3E, 0x7F, 0x00,  // 17
0x14, 0x22, 0x7F, 0x22, 0x14,  // 18
0x00, 0x5F, 0x00, 0x5F, 0x00,  // 19
0x06, 0x09, 0x7F, 0x01, 0x7F,  // 20 пи
0x4A, 0x55, 0x55, 0x55, 0x29,  // 21
0x60, 0x60, 0x60, 0x60, 0x60,  // 22
0x54, 0x62, 0x7F, 0x62, 0x54,  // 23
0x08, 0x04, 0x7E, 0x04, 0x08,  // 24
0x08, 0x10, 0x3F, 0x10, 0x08,  // 25
0x08, 0x08, 0x2A, 0x1C, 0x08,  // 26
0x08, 0x1C, 0x2A, 0x08, 0x08,  // 27
0x1C, 0x10, 0x10, 0x10, 0x10,  // 28
0x1C, 0x3E, 0x08, 0x3E, 0x1C,  // 29
0x30, 0x3C, 0x3F, 0x3C, 0x30,  // 30
0x06, 0x1E, 0x7E, 0x1E, 0x06,  // 31
0x00, 0x00, 0x00, 0x00, 0x00,  // 32
0x00, 0x00, 0x5F, 0x00, 0x00,  // 33
0x00, 0x07, 0x00, 0x07, 0x00,  // 34
0x14, 0x7F, 0x14, 0x7F, 0x14,  // 35
0x24, 0x2A, 0x7F, 0x2A, 0x12,  // 36
0x23, 0x13, 0x08, 0x64, 0x62,  // 37
0x36, 0x49, 0x56, 0x20, 0x50,  // 38
0x00, 0x00, 0x07, 0x00, 0x00,  // 39
0x00, 0x1C, 0x22, 0x41, 0x00,  // 40
0x00, 0x41, 0x22, 0x1C, 0x00,  // 41
0x14, 0x08, 0x3E, 0x08, 0x14,  // 42
0x08, 0x08, 0x3E, 0x08, 0x08,  // 43
0x00, 0xA0, 0x60, 0x00, 0x00,  // 44
0x08, 0x08, 0x08, 0x08, 0x08,  // 45
0x00, 0xC0, 0xC0, 0x00, 0x00,  // 46 точка
0x20, 0x10, 0x08, 0x04, 0x02,  // 47 слеш слева-направо ('/').
0x7E, 0x81, 0x81, 0x81, 0x7E,  // 48 0
0x84, 0x82, 0xFF, 0x80, 0x80,  // 49 1  
0x82, 0xC1, 0xA1, 0x91, 0x8E,  // 50 2
0x42, 0x81, 0x89, 0x89, 0x76,  // 51 3
0x18, 0x14, 0x12, 0xFF, 0x10,  // 52 4
0x4F, 0x89, 0x89, 0x89, 0x71,  // 53 5
0x7C, 0x8A, 0x89, 0x89, 0x70,  // 54 6
0x01, 0xF1, 0x09, 0x05, 0x03,  // 55 7
0x76, 0x89, 0x89, 0x89, 0x76,  // 56 8
0x0E, 0x91, 0x91, 0x51, 0x3E,  // 57 9 
0x00, 0xD8, 0xD8, 0x00, 0x00,  // 58 двоеточие.
0x00, 0xAC, 0x6C, 0x00, 0x00,  // 59 точка с запятой.
0x08, 0x14, 0x22, 0x41, 0x00,  // 60 меньше
0x14, 0x14, 0x14, 0x14, 0x14,  // 61 равно
0x00, 0x41, 0x22, 0x14, 0x08,  // 62 больше
0x02, 0x01, 0x51, 0x09, 0x06,  // 63 вопросительный знак
0x3E, 0x41, 0x5D, 0x55, 0x5E,  // 64 "собака" ('@').
0x7C, 0x12, 0x11, 0x12, 0x7C,  // 65 A
0x7F, 0x49, 0x49, 0x49, 0x36,  // 66 B
0x3E, 0x41, 0x41, 0x41, 0x22,  // 67 C
0x7F, 0x41, 0x41, 0x22, 0x1C,  // 68 D
0x7F, 0x49, 0x49, 0x49, 0x41,  // 69 E
0x7F, 0x09, 0x09, 0x09, 0x01,  // 70 F
0x3E, 0x41, 0x49, 0x49, 0x7A,  // 71 G
0x7F, 0x08, 0x08, 0x08, 0x7F,  // 72 H
0x00, 0x41, 0x7F, 0x41, 0x00,  // 73 I
0x20, 0x40, 0x41, 0x3F, 0x01,  // 74 J
0x7F, 0x08, 0x14, 0x22, 0x41,  // 75 K
0x7F, 0x40, 0x40, 0x40, 0x60,  // 76 L
0x7F, 0x02, 0x0C, 0x02, 0x7F,  // 77 M
0x7F, 0x04, 0x08, 0x10, 0x7F,  // 78 M
0x3E, 0x41, 0x41, 0x41, 0x3E,  // 79 O
0x7F, 0x09, 0x09, 0x09, 0x06,  // 80 P
0x3E, 0x41, 0x51, 0x21, 0x5E,  // 81 Q
0x7F, 0x09, 0x19, 0x29, 0x46,  // 82 R
0x46, 0x49, 0x49, 0x49, 0x31,  // 83 S
0x03, 0x01, 0x7F, 0x01, 0x03,  // 84 T
0x3F, 0x40, 0x40, 0x40, 0x3F,  // 85 U
0x1F, 0x20, 0x40, 0x20, 0x1F,  // 86 V
0x3F, 0x40, 0x3C, 0x40, 0x3F,  // 87 V
0x63, 0x14, 0x08, 0x14, 0x63,  // 88 X
0x07, 0x08, 0x70, 0x08, 0x07,  // 89 X
0x61, 0x51, 0x49, 0x45, 0x43,  // 90 X
0x00, 0x7F, 0x41, 0x41, 0x00,  // 91 [
0x02, 0x04, 0x08, 0x10, 0x20,  // 92 (\)
0x00, 0x41, 0x41, 0x7F, 0x00,  // 93 ]
0x04, 0x02, 0x01, 0x02, 0x04,  // 94 ^
0x40, 0x40, 0x40, 0x40, 0x40,  // 95 _
0x00, 0x01, 0x02, 0x04, 0x00,  // 96 обратный апостроф.
0x20, 0x54, 0x54, 0x54, 0x78,  // 97 a
0x7F, 0x48, 0x44, 0x44, 0x38,  // 98
0x38, 0x44, 0x44, 0x44, 0x48,  // 99
0x38, 0x44, 0x44, 0x48, 0x7F,  // 100
0x38, 0x54, 0x54, 0x54, 0x18,  // 101
0x08, 0x7E, 0x09, 0x01, 0x02,  // 102
0x08, 0x54, 0x54, 0x58, 0x3C,  // 103
0x7F, 0x08, 0x04, 0x04, 0x78,  // 104
0x00, 0x44, 0x7D, 0x40, 0x00,  // 105
0x20, 0x40, 0x44, 0x3D, 0x00,  // 106
0x7F, 0x10, 0x10, 0x28, 0x44,  // 107
0x00, 0x41, 0x7F, 0x40, 0x00,  // 108
0x7C, 0x04, 0x78, 0x04, 0x78,  // 109
0x7C, 0x08, 0x04, 0x04, 0x78,  // 110
0x38, 0x44, 0x44, 0x44, 0x38,  // 111
0x7C, 0x14, 0x14, 0x14, 0x08,  // 112 p
0x08, 0x14, 0x14, 0x0C, 0x7C,  // 113
0x7C, 0x08, 0x04, 0x04, 0x08,  // 114
0x48, 0x54, 0x54, 0x54, 0x24,  // 115
0x08, 0x7E, 0x88, 0x80, 0x40,  // 116 t 0x04, 0x3F, 0x44, 0x40, 0x20,
0x3C, 0x40, 0x40, 0x20, 0x7C,  // 117
0x1C, 0x20, 0x40, 0x20, 0x1C,  // 118
0x3C, 0x40, 0x38, 0x40, 0x3C,  // 119
0x44, 0x28, 0x10, 0x28, 0x44,  // 120
0x0C, 0x50, 0x50, 0x50, 0x3C,  // 121
0x44, 0x64, 0x54, 0x4C, 0x44,  // 122 x
0x00, 0x08, 0x36, 0x41, 0x00,  // 123 {
0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F,  // 124 (| 0x00, 0x00, 0x7F, 0x00, 0x00) теперь домик
0x00, 0x41,  // 125 } 0x00, 0x41, 0x36, 0x08, 0x00
0x02, 0x01, 0x02, 0x04, 0x02,  // 126 ~
0x70, 0x48, 0x44, 0x48, 0x70,  // 127 домик
0x00, 0x0E, 0x11, 0x0E, 0x00,  // 128
0x00, 0x12, 0x1F, 0x10, 0x00,  // 129
0x00, 0x12, 0x19, 0x16, 0x00,  // 130
0x00, 0x11, 0x15, 0x0B, 0x00,  // 131
0x00, 0x07, 0x04, 0x1F, 0x00,  // 132
0x00, 0x17, 0x15, 0x09, 0x00,  // 133
0x00, 0x0E, 0x15, 0x09, 0x00,  // 134
0x00, 0x01, 0x1D, 0x03, 0x00,  // 135
0x00, 0x0A, 0x15, 0x0A, 0x00,  // 136
0x00, 0x12, 0x15, 0x0E, 0x00,  // 137
0x00, 0x04, 0x04, 0x04, 0x00,  // 138
0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  // 139
0x3E, 0x00, 0x00, 0x00, 0x00,  // 140
0x3E, 0x3E, 0x00, 0x00, 0x00,  // 141
0x3E, 0x3E, 0x00, 0x3E, 0x00,  // 142
0x3E, 0x3E, 0x00, 0x3E, 0x3E,  // 143
0x80, 0x80, 0x80, 0x80, 0x80,  // 144
0xC0, 0xC0, 0xC0, 0xC0, 0xC0,  // 145
0xD0, 0xD0, 0xD0, 0xD0, 0xD0,  // 146
0xD8, 0xD8, 0xD8, 0xD8, 0xD8,  // 147
0xDA, 0xDA, 0xDA, 0xDA, 0xDA,  // 148
0xDB, 0xDB, 0xDB, 0xDB, 0xDB,  // 149
0x40, 0x00, 0x40, 0x00, 0x40,  // 150
0x60, 0x00, 0x40, 0x00, 0x40,  // 151
0x60, 0x00, 0x70, 0x00, 0x40,  // 152
0x60, 0x00, 0x70, 0x00, 0x78,  // 153
0x7C, 0x00, 0x40, 0x00, 0x40,  // 154
0x7C, 0x00, 0x7E, 0x00, 0x40,  // 155
0x7C, 0x00, 0x7E, 0x00, 0x7F,  // 156
0x1C, 0x77, 0x41, 0x41, 0x41,  // 157
0x41, 0x41, 0x41, 0x41, 0x41,  // 158
0x41, 0x41, 0x41, 0x7F, 0x00,  // 159
0x1C, 0x77, 0x41, 0x5D, 0x5D,  // 160
0x41, 0x41, 0x41, 0x5D, 0x5D,  // 161
0x5D, 0x5D, 0x41, 0x5D, 0x5D,  // 162
0x5D, 0x5D, 0x41, 0x7F, 0x00,  // 163
0x22, 0x1C, 0x14, 0x1C, 0x22,  // 164
0x00, 0x08, 0x1C, 0x08, 0x00,  // 165
0x00, 0x00, 0x77, 0x00, 0x00,  // 166
0x46, 0x5D, 0x55, 0x5D, 0x31,  // 167
0x7C, 0x55, 0x54, 0x55, 0x44,  // 168
0x08, 0x08, 0x2A, 0x08, 0x08,  // 169
0x00, 0x14, 0x08, 0x14, 0x00,  // 170
0x08, 0x14, 0x22, 0x08, 0x14,  // 171
0x7F, 0x41, 0x71, 0x31, 0x1F,  // 172
0x03, 0x05, 0x7F, 0x05, 0x03,  // 173
0x22, 0x14, 0x7F, 0x55, 0x22,  // 174
0x02, 0x55, 0x7D, 0x05, 0x02,  // 175
0x06, 0x09, 0x09, 0x06, 0x00,  // 176
0x44, 0x44, 0x5F, 0x44, 0x44,  // 177
0x1C, 0x14, 0x1C, 0x22, 0x7F,  // 178
0x20, 0x3E, 0x61, 0x3E, 0x20,  // 179
0x20, 0x50, 0x3F, 0x02, 0x0C,  // 180
0x80, 0x7C, 0x20, 0x3C, 0x40,  // 181
0x44, 0x3C, 0x04, 0x7C, 0x44,  // 182
0x00, 0x00, 0x08, 0x00, 0x00,  // 183
0x38, 0x55, 0x54, 0x55, 0x18,  // 184
0x7E, 0x08, 0x10, 0x7F, 0x01,  // 185
0x08, 0x10, 0x08, 0x04, 0x02,  // 186
0x14, 0x08, 0x22, 0x14, 0x08,  // 187
0x0E, 0x06, 0x0A, 0x10, 0x20,  // 188
0x20, 0x10, 0x0A, 0x06, 0x0E,  // 189
0x38, 0x30, 0x28, 0x04, 0x02,  // 190
0x02, 0x04, 0x28, 0x30, 0x38,  // 191
0x7E, 0x11, 0x11, 0x11, 0x7E,  // 192
0x7F, 0x49, 0x49, 0x49, 0x31,  // 193
0x7F, 0x49, 0x49, 0x49, 0x36,  // 194
0x7F, 0x01, 0x01, 0x01, 0x03,  // 195
0xC0, 0x7F, 0x41, 0x7F, 0xC0,  // 196
0x7F, 0x49, 0x49, 0x49, 0x41,  // 197
0x77, 0x08, 0x7F, 0x08, 0x77,  // 198
0x41, 0x49, 0x49, 0x49, 0x36,  // 199
0x7F, 0x10, 0x08, 0x04, 0x7F,  // 200
0x7C, 0x21, 0x12, 0x09, 0x7C,  // 201
0x7F, 0x08, 0x14, 0x22, 0x41,  // 202
0x40, 0x3E, 0x01, 0x01, 0x7F,  // 203
0x7F, 0x02, 0x0C, 0x02, 0x7F,  // 204
0x7F, 0x08, 0x08, 0x08, 0x7F,  // 205
0x3E, 0x41, 0x41, 0x41, 0x3E,  // 206
0x7F, 0x01, 0x01, 0x01, 0x7F,  // 207
0x7F, 0x09, 0x09, 0x09, 0x06,  // 208
0x3E, 0x41, 0x41, 0x41, 0x22,  // 209
0x01, 0x01, 0x7F, 0x01, 0x01,  // 210
0x07, 0x48, 0x48, 0x48, 0x3F,  // 211
0x0E, 0x11, 0x7F, 0x11, 0x0E,  // 212
0x63, 0x14, 0x08, 0x14, 0x63,  // 213
0x7F, 0x40, 0x40, 0x7F, 0xC0,  // 214
0x07, 0x08, 0x08, 0x08, 0x7F,  // 215
0x7F, 0x40, 0x7F, 0x40, 0x7F,  // 216
0x7F, 0x40, 0x7F, 0x40, 0xFF,  // 217
0x01, 0x7F, 0x48, 0x48, 0x30,  // 218
0x7F, 0x48, 0x48, 0x30, 0x7F,  // 219
0x7F, 0x48, 0x48, 0x48, 0x30,  // 220
0x22, 0x41, 0x49, 0x49, 0x3E,  // 221
0x7F, 0x08, 0x3E, 0x41, 0x3E,  // 222
0x46, 0x29, 0x19, 0x09, 0x7F,  // 223
0x40, 0xA8, 0xA8, 0xA8, 0xF0,  // 224 а
0x3C, 0x4A, 0x4A, 0x49, 0x31,  // 225 б
0xF8, 0xA8, 0xA8, 0xA8, 0x50,  // 226 в
0x7C, 0x04, 0x04, 0x04, 0x0C,  // 227 г
0x80, 0xF0, 0x88, 0xF8, 0x80,  // 228 д
0x38, 0x54, 0x54, 0x54, 0x18,  // 229 е
0x6C, 0x10, 0x7C, 0x10, 0x6C,  // 230 ж
0x44, 0x54, 0x54, 0x54, 0x28,  // 231 з
0xF8, 0x40, 0x20, 0x10, 0xF8,  // 232 и
0xF8, 0x40, 0x24, 0x10, 0xF8,  // 233 й
0x7C, 0x10, 0x10, 0x28, 0x44,  // 234 к
0x80, 0x70, 0x08, 0x08, 0xF8,  // 235 л
0xF8, 0x10, 0x20, 0x10, 0xF8,  // 236 м
0x7C, 0x10, 0x10, 0x10, 0x7C,  // 237 н
0x70, 0x88, 0x88, 0x70, 0x00,  // 238 о
0x7C, 0x04, 0x04, 0x04, 0x7C,  // 239 п
0x7C, 0x14, 0x14, 0x14, 0x08,  // 240 р
0x38, 0x44, 0x44, 0x44, 0x48,  // 241 с
0x04, 0x04, 0x7C, 0x04, 0x04,  // 242 т
0x18, 0xA0, 0xA0, 0xA0, 0x78,  // 243 у
0x18, 0x24, 0xFC, 0x24, 0x18,  // 244 ф
0x44, 0x28, 0x10, 0x28, 0x44,  // 245 х
0xF8, 0x80, 0x80, 0xF8, 0x80,  // 246 ц
0x0C, 0x10, 0x10, 0x10, 0x7C,  // 247 ч
0x7C, 0x40, 0x7C, 0x40, 0x7C,  // 248 ш
0x7C, 0x40, 0x7C, 0x40, 0xFC,  // 249 щ
0x04, 0x7C, 0x50, 0x50, 0x20,  // 250 ъ
0x7C, 0x50, 0x50, 0x20, 0x7C,  // 251 ы
0x7C, 0x50, 0x50, 0x50, 0x20,  // 252 ь
0x28, 0x44, 0x54, 0x54, 0x38,  // 253 э
0x7C, 0x10, 0x38, 0x44, 0x38,  // 254 ю
0x48, 0x34, 0x14, 0x14, 0x7C   // 255 я
};
#endif // FONT5X7_H
 
[center]i love you [s]mxIni[/s] Mysql[/center]


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

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

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

Сейчас этот раздел просматривают: 2 гостя