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

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

#1 Дим » 14 января 2018, 18:43

Так как в данной теме всё сумбурно, и переплелись две версии часов, разобью её на две отдельные темы. В принципе они будут одинаковы за исключением схемы подключения барометра BMP280 (по I2C не захотел работать, пришлось подключать по SPI), соответственно и другой код для его функционирования.

Первая тема: Часы на max7219 метеостанция V1

В продолжении разработки часов на max7219, подключил DS1307. Для показаний уличной температуры установлен датчик DS18B20, а для показаний давления и домашней температуры датчик атмосферного давления BMP280. Так же добавил две тактовые кнопки c подтягивающими резисторами на 10 кОм, одна для выбора действия другая для изменения. Если нажать на кнопку выбора будут мигать часы на дисплее, и кнопкой установки устанавливаем время. При повторном нажатии на копку выбора - будут мигать минуты, а если нажать кнопку ещё раз (третий) то мигать ни чего не будет, и в это же время секунды установятся на нули. Мигание двоеточия можно изменить - что бы оно "бегало" вверх - вниз на один пиксель. Для поддержки кириллицы (русские буквы) используются библиотеки Adafruit max 7219 и GFX. Вот что в итоге у меня получилось.

Часы на max7219 + DS1307 + DS18B20 + BMP180.jpg
Часы на max7219 + DS1307 + DS18B20 + BMP180
Часы на max7219 + DS1307 + DS18B20 + BMP180.jpg (303.05 КБ) 12406 просмотров


КОД

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

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>
#include <iarduino_RTC.h>           // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);      // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP085 bmp;
// ============================== кнопки
#define keyHor 4
#define keyMin 2
#define keyBr 8
#define keyPL 3
#define DS18B20 8                   // Указываем, к какому выводу подключена DQ (уличн темп)

int mig = 0;
int migtime = 0;
long previousMillis = 0;
 int val=0; 

int wait 
= 50;                      // скорость бегущей строки
int spacer = 2;
int width = 5 + spacer;             // Регулируем расстояние между символами
int refresh=0;
int pinCS = 10;                     // Подключение пина CS
int numberOfHorizontalDisplays = 4; // Количество светодиодных матриц по Горизонтали
int numberOfVerticalDisplays = 1;   // Количество светодиодных матриц по Вертикали
String weatherString;               //бегущая строка
String clocks;                      // время
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);
OneWire oneWire(DS18B20);                   
DallasTemperature sensors
(&oneWire);
// =======================================================================
void setup(void) {
  Serial.begin( 9600 );    // Инициируем передачу данных в монитор последовательного порта
  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(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(keyHor, INPUT_PULLUP);
  pinMode(keyMin, INPUT_PULLUP);
  pinMode(keyPL, INPUT_PULLUP);
  pinMode(keyBr, INPUT_PULLUP); 
}
// =======================================================================
int updCnt = 0;
int dots = 0;
long dotTime = 0;
long clkTime = 0;
byte del=0;
// =======================================================================
void loop(void) 
{   
  if
(updCnt<=0) 
  
{ // каждые 10 циклов получаем данные времени и погоды
    updCnt = 1;
    getWeatherData();
    clkTime = millis();
  }
  if(millis()-clkTime > 180000 && !del && dots) {          //каждые 3 минуты/180000 сек запускаем бегущую строку
  //ScrollText(utf8rus("sampawno.ru!"));                   //тут текст строки
  ScrollText(utf8rus(weatherString));                      //тут текст температуры и давления
  updCnt--;
  clkTime = millis();
  }
  DisplayTime();
  if(millis()-dotTime > 500) 
  
{
    dotTime = millis();
    dots = !dots;
  }
}
// =======================================================================
void DisplayTime()
{
  sensors.requestTemperatures();             // Считываем показания температуры 
  clocks = String(time.gettime("His"))+" ";  // Время
  matrix.fillScreen(LOW);
  int y = (matrix.height() - 8) / 2;         // Центрируем текст по Вертикали
  // if(clocks[5] & 1){matrix.drawChar(14, y, (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 (чтобы бегало)
  
//============================================ Кнока выбора часов/минут для установки времени
if (!digitalRead(keyPL) && mig==0)
{
  time.blinktime(3);                        // мигают часы для установки времени
  mig = 1;
  delay(700);
}
if (!digitalRead(keyPL) && mig==1)
{
  time.blinktime(2);                        // мигают минуты для установки времени
  mig=2;
  delay(700);
}
if (!digitalRead(keyPL) && mig==2)
{
  time.blinktime(0);                        // НЕмигают минуты и часы
  mig=0;
  time.settime(0, -1, -1);                  // Сбросит секунды на 0, а часы, минуты и дату, оставит без изменений.
  delay(700);
}
//============================================ Установка часов 
if (mig==&& !digitalRead(keyHor))       
{  
  time
.Hours ++;                            // прибавляем единицу к часам
  if (time.Hours > 23) time.Hours = 0;      // если вылезли за границы присваеваем 0
  time.settime(-1, -1, time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  delay(200);
}
//============================================ Установка минут
if (mig==&& !digitalRead(keyHor))          
{   
  time
.minutes ++;                          // прибавляем единицу к минутам
  if (time.minutes > 59) time.minutes = 0;  // если вылезли за границы присваеваем 0
  time.settime(-1, time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  delay(200);
}
  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;               //поправка уличного датчика
void getWeatherData()
{
  weatherString = "t.дом: " + String(bmp.readTemperature(),1)+" ";
  weatherString += " улица: " + String(sensors.getTempCByIndex(0) - tempOffset, 1)+" ";
  weatherString += " давл: " + String(bmp.readSealevelPressure()/131.42) + " мм ";       //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 месяцев

#2 Дим » 16 января 2018, 21:15

Немного доработал код. Конечно не очень красиво получилось - но за то работоспособно. Программно избавился от дребезга кнопок, теперь подтягивающие резисторы не обязательны. При установке времени, цифры не продолжают прибавляться, когда отпускаем кнопку после длительного удержания. Ранее такое присутствовало - порядка на одну - две цифры прыгало вперёд. Схема подключения осталась такая же как в первом сообщении.

КОД

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

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>
#include <iarduino_RTC.h>                     // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);                // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP085 bmp;
// ============================== кнопки
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
uint32_t ms_button         = 0;
uint32_t ms_auto_click     = 0;

uint8_t updCnt = 0;
uint8_t dots = 0;
long dotTime = 0;
long clkTime = 0;
byte del=0;

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

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);
// ===================================================================================================================================
void setup(void) {
  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  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(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);
//  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 > 300000 && !del && dots && mig == 0) {   //каждые 5 минут/300000 мили/сек запускаем бегущую строку
  //ScrollText(utf8rus("sampawno.ru!"));                        // текст строки
  ScrollText(utf8rus(weatherString));                           // текст температуры и давления
  updCnt--;
  clkTime = millis();
  }
  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
  if(pin_state1  == LOW && !button_state1 && ( ms - ms_button ) > 50 )
  { 
    button_state1      
= true;
    ms_button         = ms;
    switch (mig) 
    
{
      case 0:         // кнопка SET выбор час
        migSet = 3;
        mig = 1;
        break;
      case 1:         // кнопка SET выбор мин
        migSet = 2;
        mig = 2;
        break;
     case 2:         // кнопка SET сброс сек на 00
        migSet = 0;                                   // НЕмигают минуты и часы
        mig = 0;
        time.settime(0, -1, -1);                      // Сбросит секунды на 0, а часы, минуты и дату, оставит без изменений.
        break;
    }
  }
  //=========================================================================== кнопка SET (Фиксируем отпускание кнопки SET)  
  if( pin_state1 == HIGH && button_state1 && ( ms - ms_button ) > 50  )
  {
    button_state1      = false;   
    ms_button         
= ms;
  }
  //============================================================================ Кнопка UP (Установка часов)
  if(mig == 1 && pin_state2  == LOW && !button_state2 && ( ms - ms_button ) > 50 )// кнопка SET
  { 
    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 )>400 ) // После 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 )// кнопка SET
  { 
    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 )>400 ) // После 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(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"))+" ";  // Время
  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;               //поправка уличного датчика
void getWeatherData()
{
  weatherString = "t.дом: " + String(bmp.readTemperature(),1)+" ";
  weatherString += " улица: " + String(sensors.getTempCByIndex(0) - tempOffset, 1)+" ";
  weatherString += " давл: " + String(bmp.readSealevelPressure()/131.42) + " мм ";       //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 месяцев

#3 Дим » 25 января 2018, 21:35

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

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

uint8_t corrClock = 0

Что бы знать, корректировали время или нет. Если часы нужно переводить вперёд - то этой переменной и соответственно проверку на corrClock делать не нужно.
И далее в DisplayTime при наступлении определённого времени, я выбрал 23:30:30 будем корректировать время.

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

  if(time.Hours == 23 && time.minutes == 30 && time.seconds == 30 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:30 и не переводили часы (corrClock == 0)
  time.settime(15, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 15 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 15. Было 23:30:30 стало 23:30:15 - на 15 сек меньше.
  corrClock = 1;                             // перевели время (что бы в 23:30:30 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 corrClock = 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:30 опять перевелись часы   


Вот и всё! В коде всё прокомментировано, так что вам не составит труда подправить под свои значения отставания или убегания часов.

Ниже привожу весь код часов полностью.
КОД

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

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>
#include <iarduino_RTC.h>                     // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
iarduino_RTC time(RTC_DS1307);                // Объявляем объект time для работы с RTC модулем на базе чипа DS1307, используется аппаратная шина I2C
Adafruit_BMP085 bmp;
// ============================== кнопки
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
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;
byte del=0;

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

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);
// ===================================================================================================================================
void setup(void) {
  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  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(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);
//  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 > 300000 && !del && dots && mig == 0) {   //каждые 5 минут/300000 мили/сек запускаем бегущую строку
  //ScrollText(utf8rus("sampawno.ru!"));                        // текст строки
  ScrollText(utf8rus(weatherString));                           // текст температуры и давления
  updCnt--;
  clkTime = millis();
  }
  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
  if(pin_state1  == LOW && !button_state1 && ( ms - ms_button ) > 50 )
  { 
    button_state1      
= true;
    ms_button         = ms;
    switch (mig) 
    
{
      case 0:         // кнопка SET выбор час
        migSet = 3;
        mig = 1;
        break;
      case 1:         // кнопка SET выбор мин
        migSet = 2;
        mig = 2;
        break;
     case 2:         // кнопка SET сброс сек на 00
        migSet = 0;                                   // НЕмигают минуты и часы
        mig = 0;
        time.settime(0, -1, -1);                      // Сбросит секунды на 0, а часы, минуты и дату, оставит без изменений.
        break;
    }
  }
  //=========================================================================== кнопка SET (Фиксируем отпускание кнопки SET)  
  if( pin_state1 == HIGH && button_state1 && ( ms - ms_button ) > 50  )
  {
    button_state1      = false;   
    ms_button         
= ms;
  }
  //============================================================================ Кнопка UP (Установка часов)
  if(mig == 1 && pin_state2  == LOW && !button_state2 && ( ms - ms_button ) > 50 )// кнопка SET
  { 
    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 )// кнопка SET
  { 
    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(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 == 30 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:30 и не переводили часы (corrClock == 0)
  time.settime(15, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 15 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 15. Было 23:30:30 стало 23:30:15 - на 15 сек меньше.
  corrClock = 1;                             // перевели время (что бы в 23:30:30 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 corrClock = 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:30 опять перевелись часы   
}
 
  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;               //поправка уличного датчика
void getWeatherData()
{
  weatherString = " t.дом: " + String(bmp.readTemperature(),1)+" ";
  weatherString += " улица: " + String(sensors.getTempCByIndex(0) - tempOffset, 1)+" ";
  weatherString += " давл: " + String(bmp.readSealevelPressure()/131.42) + " мм ";       //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 месяцев

#4 Дим » 27 января 2018, 12:39

Бывает нужно узнать данные датчиков, а ждать когдпа наступит время показа (у меня настроено раз в пять минут) не охота или нет времени. Для того что бы не ждать, решил задействовать кнопку установки часов/минут/секунд, в неактивном состоянии. То есть, если просто нажать кнопку установки - button_state1 (не нажимая до этого на кнопку выбора - button_state1) на экрае появиться бегущая строка. Для реализации этого я решил использовать уже имеющуюся переменную mig, применяя к ней значение 3, при нажатии на кнопку...

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

  if(mig == 0 && pin_state2  == LOW && !button_state2 && ( ms - ms_button ) > 50 )// кнопка SET
  { 
    mig 
= 3;
  


... и сбрасываем на 0 при окончании вывода бегущей строки.

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

  if(millis()-clkTime > 300000 && !del && dots || mig == 3) {   // каждые 5 минут/300000 мили/сек (или нажата кнопа UP) запускаем бегущую строку
  //ScrollText(utf8rus("sampawno.ru!"));                        // текст строки
  ScrollText(utf8rus(weatherString));                           // текст температуры и давления
  updCnt--;
  clkTime = millis();
  mig = 0;                                                      // переменная mig не 3, для кнопки вызова бегущей строки, что бы не циклило её
   

И как обычно весь код часов:
КОД

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

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>
#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
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;
byte del=0;

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

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);
// ===================================================================================================================================
void setup(void) {
  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  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(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);
//  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 > 300000 && !del && dots || mig == 3) 
  
{                                                               // каждые 5 минут/300000 мили/сек (или нажата кнопа 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
  if(pin_state1  == LOW && !button_state1 && ( ms - ms_button ) > 50 )
  { 
    button_state1      
= true;
    ms_button         = ms;
    switch (mig) 
    
{
      case 0:         // кнопка SET выбор час
        migSet = 3;
        mig = 1;
        break;
      case 1:         // кнопка SET выбор мин
        migSet = 2;
        mig = 2;
        break;
     case 2:         // кнопка SET сброс сек на 00
        migSet = 0;                                   // НЕмигают минуты и часы
        mig = 0;
        time.settime(0, -1, -1);                      // Сбросит секунды на 0, а часы, минуты и дату, оставит без изменений.
        break;
    }
  }
  //=========================================================================== кнопка SET (Фиксируем отпускание кнопки SET)  
  if( pin_state1 == HIGH && button_state1 && ( ms - ms_button ) > 50  )
  {
    button_state1      = false;   
    ms_button         
= ms;
  }
  //============================================================================ Кнопка 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 == 30 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:30 и не переводили часы (corrClock == 0)
  time.settime(15, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 15 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 15. Было 23:30:30 стало 23:30:15 - на 15 сек меньше.
  corrClock = 1;                             // перевели время (что бы в 23:30:30 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 corrClock = 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:30 опять перевелись часы   
}
 
  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;               //поправка уличного датчика
void getWeatherData()
{
  weatherString = " t.дом: " + String(bmp.readTemperature(),1)+" ";
  weatherString += " улица: " + String(sensors.getTempCByIndex(0) - tempOffset, 1)+" ";
  weatherString += " давл: " + String(bmp.readSealevelPressure()/131.42) + " мм ";       //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 месяцев

#5 Дим » 27 января 2018, 21:30

Давно мне в библиотеке Adafruit-GFX не нравилось, что в нуле присутствует диагональная черта. И вот сегодня решил исправить это. Для этого в файле glcdfont.c

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

0x3E, 0x51, 0x49, 0x45, 0x3E,  // 48  

нужно заменить на

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

0x3E, 0x41, 0x41, 0x41, 0x3E,  // 48  

Было:
нуль с диагональной чертой.png
нуль с диагональной чертой
нуль с диагональной чертой.png (97.64 КБ) 12339 просмотров

Стало:
нуль без черты.png
нуль без черты
нуль без черты.png (102.7 КБ) 12339 просмотров

При редактировании символа помогла данная статья _http://zlitos.com/publ/ehlektronika/arduino_i_t_p/arduino_i_svetodiodnye_matricy_8kh8_max7219/12-1-0-35
и эти сервис _https://math.semestr.ru/inf/index.php _http://arduino.on.kg/matrix-font
[center]i love you [s]mxIni[/s] Mysql[/center]

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

#6 Дим » 1 февраля 2018, 21:18

Заметил ещё один косяк. При установке времени могла запускаться бегущая строка (если ей пришло время). Исправил это добавив условие - если mig == 0. И удалил !del вместе с byte del=0;.

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

if((millis()-clkTime > 300000 && dots && mig == 0) || (mig == 3)) 

Теперь код выглядит вот так:
КОД

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

#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <DallasTemperature.h>
#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);
// ===================================================================================================================================
void setup(void) {
  Serial.begin( 9600 );                       // Инициируем передачу данных в монитор последовательного порта
  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(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);
//  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 > 300000 && dots && mig == 0) || (mig == 3))
  {                                                               // каждые 5 минут/300000 мили/сек (или нажата кнопа 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();             // Считываем показания температуры 
  clocks = String(time.gettime("His"))+" ";  // Время
  if(time.Hours == 23 && time.minutes == 30 && time.seconds == 30 && corrClock == 0){ // Действия внутри оператора if, будут выполняться если время 23:30:30 и не переводили часы (corrClock == 0)
  time.settime(15, -1, -1);                  // Корректируем - устанавливаем время. Так как у меня убегали на 15 сек. Часы (-1) не трогаем, минуты (-1) не трогаем, а сек ставим 15. Было 23:30:30 стало 23:30:15 - на 15 сек меньше.
  corrClock = 1;                             // перевели время (что бы в 23:30:30 опять не перевелись часы)
}
if(
time.Hours==23 && time.minutes==59 && time.seconds==00){ //в  23:59:00...
 corrClock = 0;                                             // обнуляем переменную corrClock, что перевели время, что бы на следующие сутки в 23:30:30 опять перевелись часы   
}
 
  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;               //поправка уличного датчика
void getWeatherData()
{
  weatherString = " t.дом: " + String(bmp.readTemperature(),1)+" ";
  weatherString += " улица: " + String(sensors.getTempCByIndex(0) - tempOffset, 1)+" ";
  weatherString += " давл: " + String(bmp.readSealevelPressure()/131.42) + " мм ";       //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 месяцев

#7 Дим » 18 марта 2018, 10:54

Ещё немного "модернизировал" код - бегущая строка теперь запускается в определённое время, а именно - каждый час 09, 19, 29, 39, 49, 59 минут и 59 секунд.

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

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) запускаем бегущую строку 

И весь код:
весь код

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

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

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

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

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

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

Max72xxPanel matrix Max72xxPanel(pinCSnumberOfHorizontalDisplaysnumberOfVerticalDisplays);
OneWire oneWire(DS18B20);                   
DallasTemperature sensors(&oneWire);
// ===================================================================================================================================
void setup(void) {
  
Serial.begin9600 );                       // Инициируем передачу данных в монитор последовательного порта
  
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(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);
//  pinMode(PIN_button_DOWN, INPUT_PULLUP);
//   digitalWrite(PIN_button_SET ,HIGH);
}
// =======================================================================
void loop(void
{   
  if(
updCnt<=0
  {                                                               
// каждые 10 циклов получаем данные времени и погоды
    
updCnt 1;
    
getWeatherData();
    
clkTime millis();
  }
//  if((millis()-clkTime > 600000 && dots && mig == 0) || (mig == 3))// Через 10 минут/600000 мили/сек и не переводим часы (mig == 0) (или нажата кнопа UP) запускаем бегущую строку
  
if(((time.minutes == || time.minutes == 19 || time.minutes == 29 || time.minutes == 39 || time.minutes == 49 || time.minutes == 59) && time.seconds == 59 && mig == 0) || (mig == 3)) 
  {                                                               
// каждые (9,19,29,39,49,59) минут и 59 секунд и не переводим часы (mig == 0)(или нажата кнопа UP) запускаем бегущую строку
    //ScrollText(utf8rus("sampawno.ru!"));                        // текст строки
    
ScrollText(utf8rus(weatherString));                           // текст температуры и давления
    
updCnt--;
    
clkTime millis();
    
mig 0;                                                      // переменная mig не 3, для кнопки вызова бегущей строки, что бы не циклило её
  
}
  
DisplayTime();
  
time.blinktime(migSet);                                         // мигаем устанавливаемым параметром (migSet больше 0) при установке времени
  
if(millis()-dotTime 500
  {
    
dotTime millis();
    
dots = !dots;
  }
  
Func_buttons_control();
}
void Func_buttons_control()
{
   
uint32_t ms    millis();
   
bool pin_state1 digitalRead(PIN_button_SET); // кнопка SET
   
bool pin_state2 digitalRead(PIN_button_UP);  // 2 кнопка
//=========================================================================== кнопка SET
// Фиксируем нажатие кнопки  SET
  
if( pin_state1  == LOW && !button_state1 && ( ms ms_button ) > 50 ){
      
button_state1     true;
      
button_long_state false;
      
ms_button         ms;
      if(
wibor == 1)
        switch (
mig
        {
          case 
1:         // кнопка SET выбор мин
            
migSet 2;
            
mig 2;
            break;
          case 
2:         // кнопка SET сброс сек на 00
            
migSet 0;                                   // НЕмигают минуты и часы
            
mig 0;
            
time.settime(0, -1, -1);                      // Сбросит секунды на 0, а часы, минуты и дату, оставит без изменений.
            
wibor 0;
            break;
        }  
  }
// После 2000 мс нажатия кнопки SET единоразово выполним код
  
if( pin_state1  == LOW && !button_long_state && ( ms ms_button ) > 2000 // кнопка SET выбор час
  
{
    
migSet 3;
    
mig 1;  
    
wibor 1;                                     // длительно нажали
  
}
// Фиксируем отпускание кнопки SET 
   
if( pin_state1 == HIGH && button_state1 && ( ms ms_button ) > 50  ){
      
button_state1     false;   
      
ms_button         ms;
      
Serial.println("No Press 2"); //действие после отпуска длительного нажатия
   
}   
  
//===========================================  Кнопка UP (Установка часов)
  
if(mig == && pin_state2  == LOW && !button_state2 && ( ms ms_button ) > 50 )
  { 
    
button_state2     true;
    
ms_button         ms;
    
migSet 0;
    
time.Hours ++;                            // прибавляем единицу к часам
    
if (time.Hours 23time.Hours 0;      // если вылезли за границы присваеваем 0
    
time.settime(-1, -1time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  
}
  if(
mig == && pin_state2  == LOW && ( ms ms_button ) > 1000 && ( ms ms_auto_click )>300 // После 1000 мс нажатия кнопки каждые 400 мс фиксируем событие нажатия  
  
{
    
ms_auto_click     ms;
    
migSet 0;
    
time.Hours ++;                            // прибавляем единицу к часам
    
if (time.Hours 23time.Hours 0;      // если вылезли за границы присваеваем 0
    
time.settime(-1, -1time.Hours);         // установит часы, а секунды, минуты и дату, оставит без изменений.
  
}
  
//===========================================  Кнопка UP (Установка минут)
  
if(mig == && pin_state2  == LOW && !button_state2 && ( ms ms_button ) > 50 )
  { 
    
button_state2     true;
    
ms_button         ms;
    
migSet 0;
    
time.minutes ++;                          // прибавляем единицу к минутам
    
if (time.minutes 59time.minutes 0;  // если вылезли за границы присваеваем 0
    
time.settime(-1time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  
}
  if(
mig == && pin_state2  == LOW && ( ms ms_button ) > 1000 && ( ms ms_auto_click )>300 // После 1000 мс нажатия кнопки каждые 400 мс фиксируем событие нажатия  
  
{
    
ms_auto_click     ms;
    
migSet 0;
    
time.minutes ++;                          // прибавляем единицу к минутам
    
if (time.minutes 59time.minutes 0;  // если вылезли за границы присваеваем 0
    
time.settime(-1time.minutes, -1);       // установит минуты, а секунды, часы и дату, оставит без изменений.
  
}
  
//===========================================  Кнопка UP (Установка минут) вызов бегущей строки  
  
if(mig == && pin_state2  == LOW && !button_state2 && ( ms ms_button ) > 50 )
  { 
    
mig 3;
  } 
//==============================================================================  Кнопка UP ( Фиксируем отпускание кнопки установки часов/минут  )
  
if(pin_state2 == HIGH && button_state2 && ( ms ms_button ) > 50  )
  {
    
button_state2     false;   
    
ms_button         ms;
    if(
mig == 1){migSet 3;}
    if(
mig == 2){migSet 2;}
  }
}
void DisplayTime()
{
  
sensors.requestTemperatures();             // Считываем показания температуры 
  
clocks String(time.gettime("His"))+" ";  // Время
  
if(time.Hours == 23 && time.minutes == 30 && time.seconds == 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.5;               //поправка уличного датчика
float tempOffset 1.0;               //поправка уличного датчика
void getWeatherData()
{
  
weatherString " t.дом: " String(bmp.readTemperature(),1)+" ";
  
weatherString += " улица: " String(sensors.getTempCByIndex(0) - tempOffset1)+" ";
  
weatherString += " давл: " String(bmp.readSealevelPressure()/131.42) + " мм ";       //131.42 поправка реального(из инета)
}
String utf8rus(String source)
{
  
int i,k;
  
String target;
  
unsigned char n;
  
char m[2] = { '0''\0' };
  
source.length(); 0;
  while (
k) {
    
source[i]; i++;
    if (
>= 0xC0) {
      switch (
n) {
        case 
0xD0: {
          
source[i]; i++;
          if (
== 0x81) { 0xA8; break; }
          if (
>= 0x90 && <= 0xBF0x30-1;
          break;
        }
        case 
0xD1: {
          
source[i]; i++;
          if (
== 0x91) { 0xB8; break; }
          if (
>= 0x80 && <= 0x8F0x70-1;
          break;
        }
      }
    }
    
m[0] = ntarget target String(m);
  }
return 
target;
}  
[center]i love you [s]mxIni[/s] Mysql[/center]

bibo
Аватара
bibo
Сообщения: 4
Зарегистрирован: 18 апреля 2018
С нами: 5 лет 11 месяцев

#8 bibo » 18 апреля 2018, 16:52

Привет.
Я взял твой проект за основу, на его примере разбирался в работе некоторых библиотек, в общем более-менее осознал работу с наличными у меня датчиками.
Но вот кнопки не смог одолеть. В моем скетче полностью весь твой код, кроме того, что не использовал встроенные подтягивающие резисторы(input_pullup заменил на input).
Проблема заключается в том, что у меня сами цифры переключаются, как будто кнопка то замыкается, то размыкается(дребезг я так понимаю). Подключил я свои кнопки к цифровым пинам через резисторы 10 кОм. Вот мой скетч(там много закомментированных частей, пока не почистил)

Спойлер

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

#include <iarduino_Pressure_BMP.h>

#include <Wire.h>
#include "DHT.h"  // подключаем библиотеку для работы с датчиком DHT
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
 #include <iarduino_RTC.h>

#define DHTTYPE DHT11   // DHT 11
#define DHTPIN 2    
// #define pin_SW_SDA 4                                    // Назначение любого вывода Arduino для работы в качестве линии SDA программной шины I2C.
//  #define pin_SW_SCL 9
//const int buttonPin = 8;     // the number of the pushbutton pin

iarduino_Pressure_BMP sensor;  
iarduino_RTC time
(RTC_DS1302, 5, 7, 6);   // Объявляем объект time для работы с RTC модулем на базе чипа DS1302, указывая выводы Arduino подключённые к выводам модуля RST, CLK, DAT
DHT dht(DHTPIN, DHTTYPE);

int buttonState; 
int wait 
= 25; // скорость бегущей строки
int spacer = 2;
int width = 5 + spacer; // Регулируем расстояние между символами
int refresh=0;
int pinCS = 10; // Подключение пина CS
int numberOfHorizontalDisplays = 4; // Количество светодиодных матриц по Горизонтали
int numberOfVerticalDisplays = 1; // Количество светодиодных матриц по Вертикали
String weatherString;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);


/*=========================кнопки======================*/



const uint8_t PIN_button_SET  = 8;            // указываем номер вывода 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; 
String clocks
;

//int updCnt = 0;
//int dots = 0;
//long dotTime = 0;
//long clkTime = 0;
byte del=0;
int h,m,s, hum, temp;
float  pres, pres1;
String mesyc = " ";




/*===================================================================================*/
void setup(void) {
  Serial.begin(9600);
    time.begin();
//time.settime(0,42,11,18,4,18,3);//секунды, минуты,часы,число,месяц,год,день недели


/*=========================кнопки======================*/
pinMode(PIN_button_SET, INPUT);      // кнопки
  pinMode(PIN_button_UP, INPUT);

/*=====================================================*/


 dht.begin();//датчик влажности и температуры
  sensor.begin(); //датчик давления
   
  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 матрица
}



/*==================================================================================*/
void loop(void) {

  //Serial.println(time.gettime("H:i")); // выводим время
  
 if
(updCnt<=0) 
  
{ // каждые 10 циклов получаем данные времени и погоды
    updCnt = 1;
   time.gettime();
   sensor.read(2);
   String mesyc = " ";
 hum = dht.readHumidity();
 temp = sensor.temperature;
 pres = sensor.pressure/101325;
 pres1 = pres/1.5;
    clkTime = millis();
 }


 
  if
(millis()-clkTime > 60000 && !del && dots) { // через каждые 60000 мс запускаем бегущую строку
 ScrollText(utf8rus( mesyc + "влаж.  " + hum + " %    темп. " + temp + " `C " + "давл. " + pres1 + " атм "));
  updCnt--;
  clkTime = millis();
  mig = 0;   
  
}

  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;}
  }
}


/*================================функция для работы кнопок заверешена =============================*/










  /*DisplayTime();
  if(millis()-dotTime > 500) {
    dotTime = millis();
    dots = !dots;
  }
//  buttonState = digitalRead(buttonPin);
  
 //if (buttonState == HIGH) {
       // ScrollText(utf8rus( mesyc + "влаж.  " + hum + " %    темп. " + temp + " `C " + "давл. " + pres1 + " атм " ));
        
  } 
  

  
}*/

// =======================================================================
/*+++++++++++++

 void DisplayTime(){
  time.gettime();
    h = time.Hours;
 m = time.minutes;

    matrix.fillScreen(LOW);
    int y = (matrix.height() - 8) / 2; // Центрируем текст по Вертикали

    
 
if(time.seconds&1 ){matrix.drawChar(14, y, (String(":"))[0], HIGH, LOW, 1);}
      else  {matrix.drawChar(14, y, (String(" "))[0], HIGH, LOW, 1);} 

  
 
   String hour1 = String (h/10);
    String hour2 = String (h%10);
    String min1 = String (m/10);
    String min2 = String (m%10);
    String sec1 = String (s/10);
    String sec2 = String (s%10);
    int xh = 2;
    int xm = 19;
//    int xs = 28; //секунды

  

      matrix.drawChar(xh, y, hour1[0], HIGH, LOW, 1);
    matrix.drawChar(xh+6, y, hour2[0], HIGH, LOW, 1);
    matrix.drawChar(xm, y, min1[0], HIGH, LOW, 1);
    matrix.drawChar(xm+6, y, min2[0], HIGH, LOW, 1);
    matrix.write();


    
Serial.print(hour1);
Serial.print(hour2);
Serial.print(":");
Serial.print(min1);
Serial.print(min2);
Serial.print(":");
Serial.println(time.seconds);
//Serial.println(sec2);
Serial.println(sensor.pressure);
delay(1000);
   
}+++++++++++++++++*/



void DisplayTime()
{
 // sensors.requestTemperatures();             // Считываем показания температуры 
  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.5; //поправка уличного датчика
void getWeatherData()
{
 // weatherString = "t.дом: " + String(bmp.readTemperature(),1)+" ";
  weatherString += " темп.: " + String(  dht.readTemperature(), 1)+" `С ";
  weatherString += " влаж.: " + String(mesyc + dht.readHumidity()) + " % ";
}
// =======================================================================
float utcOffset = 18; //поправка часового пояса (при первом включении)
float minOffset = 42; //установка минут (при первом включении)
long localEpoc = 0;
long localMillisAtUpdate = 0;
// =======================================================================r
void updateTime()
{
  long curEpoch = localEpoc + ((millis() - localMillisAtUpdate) / 1000);
  //long epoch = round(curEpoch + 3600 * utcOffset + 86400L) % 86400L;
  long epoch = round(curEpoch + 3600 * utcOffset + 86400L + (minOffset * 60)) % 86400L; //(minOffset * 60) - установка минут
  h = ((epoch  % 86400L) / 3600 ) % 24;
  m = (epoch % 3600) / 60;
  s = epoch % 60;
}*/
// ============================ латиница =================================
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;
}

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

#9 Дим » 19 апреля 2018, 11:13

У меня кнопки подключены без резисторов, как я писал во втором сообщении - избавился от дребезга программно. Делал на основе этого - Обработка кнопок Arduino, работает нормально. Попробуй мой код, не меняя input_pullup на input.
[center]i love you [s]mxIni[/s] Mysql[/center]

bibo
Аватара
bibo
Сообщения: 4
Зарегистрирован: 18 апреля 2018
С нами: 5 лет 11 месяцев

#10 bibo » 19 апреля 2018, 15:47

Без резисторов и с использованием input_pullup ардуина у меня просто напросто виснет(
Кнопки включал и в разрыв плюса, и в разрыв земли к пину. Эффект всегда одинаков.


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

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

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

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