Arduino барометр - барограф

Sergey_Ch
Offline
Зарегистрирован: 15.01.2015

Представляю на суд общественности проект «Arduino барограф».

Сразу хочу пояснить. Основная цель публикации - получение замечаний и предложений. Особенно буду благодарен за предложения по оптимизации кода. Так как написанный мною код уже занял, практически, всю память контроллера. Хотелось бы добавить еще несколько функций (в частности визуальный контроль заряда АКБ), но не куда.

Конструкция потребляет около 10мА, ели не включать подсветку дисплея. Li-Pol аккумулятора, емкостью 1200 мА/ч хватает, примерно на 5 дней. Если есть возможность оптимизировать энергопотребление – буду признателен за советы и предложенные решения. Задача – мобильность данного устройства, возможность максимально длительной эксплуатации в полевых условиях без подзарядки. (Воздержитесь от советов по использованию АКБ от КАМАЗа).

Большое спасибо участнику форума Leshak за представленную библиотеку работы с функцией времени http://alxarduino.blogspot.ru/2013/08/delay.html.

Отдельная благодарность Валентину Олеговичу за очень грамотную и очень полезную статью по теме работы с кнопками http://linuxmd.net/avr/332-dejstviya-posle-nazhatiya-knopki-arduino-uno-atmega-328-p.

Очень надеюсь, что «Леший в мире Ардуино» и Валентин Олегович отзовутся на мою статью.

Компоненты:

Arduino Pro Mini 3.3V ATMega328 8 МГц;

дисплей Nokia 5110;

датчик давления BMP085;

модуль зарядки Li-Pol аккумулятора EM4056;

DC-DC стабилизатор Pololu 5V, 1A Step-Down Voltage Regulator D24V10F5;

Аккумулятор LP633040-PCM (Li-POL 3,7V 920mAh, с платой защиты).

Все компоненты, кроме батареи и повышающего модуля приобретались в интернет-магазине http://dvrobot.ru/. Доставка по Хабаровску в течение 1-2 дня, все исправно. Дороже, конечно, чем в Китае, зато быстро. Каждый имеет право на выбор.

Аккумулятор и стабилизатор Pololu 5V прислали по почте из интернет-магазина «Dessy» http://www.dessy.ru/. Обычно там все нормально, но на этот раз исполняли заказ почти 3 месяца (из них 10 дней на доставку от Москвы до Хабаровска). Предоплату приняли с удовольствием и больше инициативы в общении не проявляли, проснулись только после ряда гневных писем. По сравнению с Китайским AliExpress, Dessy получился в два раза медленнее по срокам и в два раза дороже по цене.

Конструкция собрана пока на макетной плате. После полной отладки поместим в корпус.

Что умеет предлагаемая конструкция барографа.

 

При подаче питания на экране отображается меню установок «SETUP MENU»

Третья строка – пределы режимы измерения давления

Нижняя строка – значение текущего давления в мм рт.ст.

Нажатием кнопки «Select» в режиме «SETUP MENU» выбираем пределы измерений давления для построения на графике.

Нажатием кнопки «Start» выходим из режима «SETUP MENU» и переходим к режиму построения графика давления.

 

В режиме построения графика, нажав кнопку «Select» можем снова перейти в режим «SETUP MENU» и нажимая дальше «Select» изменить пределы измерений. Нажав «Start» снова переходим к построению графика, при этом ранее полученные данные о давлении не теряются, а приобретают значение в соответствии с выбранным режимом измерений.

 

Экран графика давления.

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

На экране дисплея отображается 71 линия, высота каждой соответствует измеренному давлению. После заполнения экрана 71-м значением (экран заполнен), новое значение давления выводится на позиции 71 экрана, на позицию 0 «сдвигается» значение 1, на его место 2 и так далее. Так что на экране мы видим значения последних 71 измерений давления.

Периодичность измерений устанавливается заданием значения переменной

#define Diagram_interval _SEC_(608)
// периодичность вывода данных на дисплей (608 cекунд)
// полное заполнение 71 позиции графика = 12 часов)

В моем варианте установлено 1 измерение в 608 секунд, при этом на экране отображаются значения давления за последние 12 часов.

Для наглядной демонстрации работы устройства, значение этой переменной можно установить 2 сек (закомментированная строка ниже). Тогда экран будет заполняться данными за 142 сек.

// #define Diagram_interval _SEC_(2)
// периодичность вывода данных на дисплей=2 cек (Исп. для настройки)

Схема барографа 

 

Программный код

Я постарался как можно подробнее комментировать программный код.

/*********************************
Проект "Барограф"
При включении питания, при перезагрузке Arduino путем нажатия на Reset, или при нажтии кнопки Select
на экране отображается меню установок SETUP MENU. В этом режиме, нажимая на кнопку Select выбираем
предел измерений атмосферного давления. Нажав на кнопку Start, выходим из меню настроек и начинает работать
основная программа. 

mmHg    Pa
730    97309
735    97976
740    98642
745    99309
750    99975
755   100642
760   101308
765   101975
770   102641
                         Pmin  Pmax
РЕЖИМ 0:(730-770 ммHg = 97309 -102641 Pa)
РЕЖИМ 1:(730-740 ммHg = 97309 - 98642 Pa)
РЕЖИМ 2:(735-745 ммHg = 97976 - 99309 Pa)
РЕЖИМ 3:(740-750 ммHg = 98642 - 99975 Pa)
РЕЖИМ 4:(745-755 ммHg = 99309 -100642 Pa)
РЕЖИМ 5:(750-760 ммHg = 99975 -101308 Pa)
РЕЖИМ 6:(755-765 ммHg = 100642-101975 Pa)
РЕЖИМ 7:(760-770 ммHg = 101308-102641 Pa)

************* Подключение дисплея Nokia 5110 к Arduino ProMicro **************
// 1 - VCC---------------------------------------- +3.3v от понижающего модуля
// 2 - GND------------------------------------------------------- к общему GND
// 3 - SCE (LCD chip select (CS)-------- через R=10 kOm pin 7 Arduino ProMicro
// 4 - RST--------------------------------------------- pin 8 Arduino ProMicro
// 5 - D/C (Data/Command select)-------- через R=10 kOm pin 6 Arduino ProMicro 
// 6 - DN<MOSI> (Serial data out (DIN)-- через R=10 kOm pin 5 Arduino ProMicro
// 7 - SCLK (Serial clock out (SCLK)---- через R=10 kOm pin 4 Arduino ProMicro
// 8 - LED--------------------------------------------VCC +5v Arduino ProMicro

************** Подключение датчика BMP085 к Arduino ProMicro *****************
// 1 - VCC----- VCC +5v Arduino ProMicro
// 2 - SDA--- SDA pin 2 Arduino ProMicro
// 3 - SCL--- SCL pin 3 Arduino ProMicro
// 4 - XCLR------------- не используется
// 5 - EDC-------------- не используется 
// 6 - GND----------------- к общему GND
**********************************/

#include <Wire.h>              // библиотека шины получения и передачи данных
#include <BMP085.h>            // библиотека для работы с датчиком давления BMP085
#include <Adafruit_GFX.h>      // библиотека для работы дисплея Nokia5110
#include <Adafruit_PCD8544.h>
#include <TimeHelpers.h>       // библиотека для работы с периодами времени

//Инициализируем дисплей на указанных пинах Arduino ProMicro
Adafruit_PCD8544 display = Adafruit_PCD8544(4, 5, 6, 7, 8);

BMP085 dps = BMP085();     // Модель Digital Pressure Sensor - BMP085

long Pressure = 0; // переменная для получения данных с датчика давления

long Pmax = 0; // переменная для установки максимального значения давления
long Pmin = 0; // переменная для установки минимального значения давления

int But_Select = 9; // На pin 9 Arduino подключаем кнопку Select - выбора режима (диапазона измерений). Pin 9 через R=10 kOm подтянут к GND
int But_Start = 10; // На pin 10 Arduino подключаем кнопку Start - запуска программы построения и отображения графика
                    // Pin 10 через R=10 kOm подтянут к GND

int flag = 0;   // переменная /флаг/ для работы кнопки Select
int regim = 0;  // переменная - номер режима (диапазона измерений)

boolean Status = false; // переменная статус изначально принимает значение false.
                        // Применяется для выхода из меню установок SETUP MENU (цикла "while (Status == false)")

int cycle = 0; // Значение переменной - циклы изменения при выполнении цикла for (рисование линий графика)
int x = 70;    // Значение переменной Х - х координата дисплея
int y = 0;     // Значение переменной Y – y координата дисплея
int z = 47;    // координата z – 48-я строка дисплея(нижняя) по оси y для
               // привязки линии от значения температуры к нулевому уровню


/*-------------- Настройка времени работы циклов измерения давления --------------------------*/

#define Diagram_interval _SEC_(608)  // переодичность вывода данных на дисплей (608 cекунд)
                                     // полное заполнение 71 позиции графика = 12 часов)
// #define Diagram_interval _SEC_(2) // переодичность вывода данных на дисплей=2 cек (Исп. для настройки)

// объявляем переменные у0 - у70 и присваиваем им значение 47.
// При первом цикле получения данных горизонтальная линия на 47 позиции в виде 70 точек
int y0=47, y1=47, y2=47, y3=47, y4=47, y5=47, y6=47, y7=47, y8=47, y9=47, y10=47, y11=47, y12=47, y13=47, y14=47, y15=47, 
y16=47, y17=47, y18=47, y19=47, y20=47, y21=47, y22=47, y23=47, y24=47, y25=47, y26=47, y27=47, y28=47, y29=47, y30=47, y31=47,
y32=47, y33=47, y34=47, y35=47, y36=47, y37=47, y38=47, y39=47, y40=47, y41=47, y42=47, y43=47, y44=47, y45=47, y46=47, y47=47,
y48=47, y49=47, y50=47, y51=47, y52=47, y53=47, y54=47, y55=47, y56=47, y57=47, y58=47, y59=47, y60=47, y61=47, y62=47, y63=47,
y64=47, y65=47, y66=47, y67=47, y68=47, y69=47, y70=47; 

long v0=47, v1=47, v2=47, v3=47, v4=47, v5=47, v6=47, v7=47, v8=47, v9=47, v10=47, v11=47, v12=47, v13=47, v14=47, v15=47, 
v16=47, v17=47, v18=47, v19=47, v20=47, v21=47, v22=47, v23=47, v24=47, v25=47, v26=47, v27=47, v28=47, v29=47, v30=47, v31=47,
v32=47, v33=47, v34=47, v35=47, v36=47, v37=47, v38=47, v39=47, v40=47, v41=47, v42=47, v43=47, v44=47, v45=47, v46=47, v47=47,
v48=47, v49=47, v50=47, v51=47, v52=47, v53=47, v54=47, v55=47, v56=47, v57=47, v58=47, v59=47, v60=47, v61=47, v62=47, v63=47,
v64=47, v65=47, v66=47, v67=47, v68=47, v69=47, v70=47; 


void setup ()
{
  Wire.begin();       // старт шины данных
  display.begin();    // старт дисплея
  delay(500);         // время на инициализацию датчика и дисплея
 
  dps.init(MODE_ULTRA_HIGHRES, 9000, true); 
  /*
  значение 9000 см = 90 метров - истинная высота Хабаровска над уровнем моря,
  давление будет рассчитываться на основе этой величины.
  */
    
  display.setContrast(60);  // регулировка контраста изображения
  display.clearDisplay();   // Очистка экрана и буфера дисплея
}


void loop()
{
 // усли не нажата кнопка Select и изначально установленное значение 
 // переменной Status = false,- при каждом запуске (Reset)
 // выполняем подпрограмму установок меню
 if((digitalRead(But_Select) == LOW) && (Status == false))
  {
   SetupMenu();
  }
// при нажатии кнопки Select изменяем значение Status на false,
// тем самым даем команду на вход в цикл SetupMenu while (Status == false)
  if (digitalRead(But_Select) == HIGH)
   {
    Status = false;
    return; // игнорируем оставшуюся часть кода
   }

Diagram(); // Выполняем подпрограмму построения графика давления

// выполняем подпрограмму периодичного измерения давления Meterage()
// с переодичностью, установленной в коде для переменной Diagram_interval (сек).
DO_EVERY(Diagram_interval,
  {Meterage();});
 
} // завершаем цикл void loop

//==============================================================//
//----------------- ПОДПРОГРАММА УСТАНОВОК МЕНЮ ----------------//
//==============================================================//
void SetupMenu()
{
 while (Status == false) // крутим цикл, пока условие(false) на станет ложным
     {              
       /********** Устанавливаем режим работы кнопки Select *************/
       // при нажатии кнопки Select значение regim увеличиваем на 1
       if(digitalRead(But_Select) == HIGH && flag == 0) 
        { 
         regim ++;
         flag = 1;

         if(regim > 7) // Если номер режима превышает требуемый
          {
           // то отсчет начинается с нуля
           regim = 0;
          }
       }

      if(digitalRead(But_Select) == LOW && flag == 1)
       {
        flag = 0;
       } 
     /***************************************************/

  dps.getPressure(&Pressure); // получаем данные о давлении
  delay (50); 
  
  /************** Оформляем экран "SETUP MENU" *************/ 
       
     display.setTextSize(1);
     display.setTextColor(BLACK);
     display.setCursor(11,0);
     display.println("SETUP MENU");
     display.setCursor(3,10);
     display.println("BORDER VALUES");
          
display.setCursor(0,20);
//РЕЖИМ 0:
if(regim == 0)
{
display.println("730 - 770 mmHg");
}
// РЕЖИМ 1:
if(regim == 1)
{
display.println("730 - 740 mmHg"); 
}
// РЕЖИМ 2:
if(regim == 2)
{
display.println("735 - 745 mmHg"); 
}
// РЕЖИМ 3:
if(regim == 3)
{
display.println("740 - 750 mmHg"); 
}
// РЕЖИМ 4:
if(regim == 4)
{
display.println("745 - 755 mmHg"); 
}
// РЕЖИМ 5:
if(regim == 5)
{
display.println("750 - 760 mmHg"); 
}
// РЕЖИМ 6:
if(regim == 6)
{
display.println("755 - 765 mmHg"); 
}
// РЕЖИМ 7:
if(regim == 7)
{
display.println("760 - 770 mmHg"); 
}

    display.setCursor(3,30);
    display.println("CURRENT PRESS");
    display.setCursor(17,40);
    display.print (Pressure/133.3); // выводим текущее атм. давление в ммРтСт.
    display.println ("Hg");

    display.display(); // все нарисованное выводим на экран дисплея
    display.clearDisplay(); // очищаем экран и буфер дисплея

// при нажатии кнопки Start изменяем значение Status на true,
// тем самым даем команду на выход из цикла while (Status == false)
              if (digitalRead(But_Start) == HIGH)
               {
                Status = true;
                Diagram(); // начинаем выполнение подпрограммы построения графика давления
               }
  } // закрываем цикл while (Status == false) 
} // закрываем void SetupMenu()
/**************************************************************/


//==============================================================//
//------- ПОДПРОГРАММА ПЕРИОДИЧНОСТИ ИЗМЕРЕНИЙ ДАВЛЕНИЯ --------//
//==============================================================//
void Meterage ()
{
dps.getPressure(&Pressure); // получаем данные о давлении
delay (50);

// последовательно изменяем значение давления « v » на предыдущее при каждом цикле замера
v70 = v69; v69 = v68; v68 = v67; v67 = v66; v66 = v65; v65 = v64; v64 = v63; v63 = v62; v62 = v61; v61 = v60;
v60 = v59; v59 = v58; v58 = v57; v57 = v56; v56 = v55; v55 = v54; v54 = v53; v53 = v52; v52 = v51; v51 = v50;
v50 = v49; v49 = v48; v48 = v47; v47 = v46; v46 = v45; v45 = v44; v44 = v43; v43 = v42; v42 = v41; v41 = v40;
v40 = v39; v39 = v38; v38 = v37; v37 = v36; v36 = v35; v35 = v34; v34 = v33; v33 = v32; v32 = v31; v31 = v30;
v30 = v29; v29 = v28; v28 = v27; v27 = v26; v26 = v25; v25 = v24; v24 = v23; v23 = v22; v22 = v21; v21 = v20; 
v20 = v19; v19= v18; v18 = v17; v17 = v16; v16 = v15; v15 = v14; v14 = v13; v13 = v12; v12 = v11; v11 = v10; 
v10 = v9; v9 = v8; v8 = v7; v7 = v6; v6 = v5; v5 = v4; v4 = v3; v3 = v2; v2 = v1; v1 = v0; v0 = Pressure;

} // закрываем void meterage ()


//==============================================================//
//--------------- ПОДПРИГРАММА ПОСТРОЕНИЯ ГРАФИКА --------------//
//==============================================================//
void Diagram()
{
  dps.getPressure(&Pressure); // получаем данные о давлении
  delay (50);
  
 /********* Оформляем экран ***********/
    display.setTextSize(1);
    display.setTextColor(BLACK);

// В зависимости от выбранного режима пределов границ измерений
// рисуем отметки значений давления
//РЕЖИМ 0:
if(regim == 0)
{
    display.setCursor(66,0);
    display.println("770");
    display.setCursor(72,10);
    display.println("60");
    display.setCursor(72,21);
    display.println("50");
    display.setCursor(72,32);
    display.println("40");
    display.setCursor(72,41);
    display.println("30");
}

// РЕЖИМ 1:
if(regim == 1)
{
    display.setCursor(66,0);
    display.println("740");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("35");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("30");
}

// РЕЖИМ 2:
if(regim == 2)
{
    display.setCursor(66,0);
    display.println("745");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("40");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("35");  
}

// РЕЖИМ 3:
if(regim == 3)
{
    display.setCursor(66,0);
    display.println("750");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("45");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("40");
}

// РЕЖИМ 4:
if(regim == 4)
{
    display.setCursor(66,0);
    display.println("755");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("50");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("45");
}

// РЕЖИМ 5:
if(regim == 5)
{
    display.setCursor(66,0);
    display.println("760");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("55");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("50");
}

// РЕЖИМ 6:
if(regim == 6)
{
    display.setCursor(66,0);
    display.println("765");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("60");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("55");
}

// РЕЖИМ 7:
if(regim == 7)
{
    display.setCursor(66,0);
    display.println("770");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("65");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("60");
}

 /*************** Рисуем значение текущего давления ********************/  
    display.setCursor(0,0);
    display.print (Pressure/133.3); // выводим текущее атм. давление переведя его в мм Рт.Ст.
    display.print ("Hg");
    
/**************** Рисуем график ********************/
//В соответствии с выбранным режимом измерений, устанавливаем значение мин и мах давление отображаемое на графике
//РЕЖИМ 0:(730-770 ммHg = 97309-102641 Pa)
if(regim == 0)
{
Pmin = 97309; Pmax = 102641; 
}
// РЕЖИМ 1:(730-740 ммHg = 97309-98642 Pa)
if(regim == 1)
{
Pmin = 97309; Pmax = 98642; 
}
// РЕЖИМ 2:(735-745 ммHg = 97976-99309 Pa)
if(regim == 2)
{
Pmin = 97976; Pmax = 99309; 
}
// РЕЖИМ 3:(740-750 ммHg = 98642-99975 Pa)
if(regim == 3)
{
Pmin = 98642; Pmax = 99975;
}
// РЕЖИМ 4:(745-755 ммHg = 99309-100642 Pa)
if(regim == 4)
{
Pmin = 99309; Pmax = 100642;
}
// РЕЖИМ 5:(750-760 ммHg = 99975-101308 Pa)
if(regim == 5)
{
Pmin = 99975; Pmax = 101308;
}
// РЕЖИМ 6:(755-765 ммHg = 100642-101975 Pa)
if(regim == 6)
{
Pmin = 100642; Pmax = 101975;
}
// РЕЖИМ 7:(760-770 ммHg = 101308-102641 Pa)
if(regim == 7)
{
Pmin = 101308; Pmax = 102641;
}

//Значение всех Y от 0 до 70 (высоту линий графика 0-47) приводим пропорционально к параметрам измеряемого давления
y0 = map(v0, Pmin, Pmax, 47, 1); 
y1 = map(v1, Pmin, Pmax, 47, 1); 
y2 = map(v2, Pmin, Pmax, 47, 1); 
y3 = map(v3, Pmin, Pmax, 47, 1); 
y4 = map(v4, Pmin, Pmax, 47, 1); 
y5 = map(v5, Pmin, Pmax, 47, 1); 
y6 = map(v6, Pmin, Pmax, 47, 1); 
y7 = map(v7, Pmin, Pmax, 47, 1); 
y8 = map(v8, Pmin, Pmax, 47, 1); 
y9 = map(v9, Pmin, Pmax, 47, 1); 
y10 = map(v10, Pmin, Pmax, 47, 1); 
y11 = map(v11, Pmin, Pmax, 47, 1); 
y12 = map(v12, Pmin, Pmax, 47, 1); 
y13 = map(v13, Pmin, Pmax, 47, 1); 
y14 = map(v14, Pmin, Pmax, 47, 1); 
y15 = map(v15, Pmin, Pmax, 47, 1); 
y16 = map(v16, Pmin, Pmax, 47, 1); 
y17 = map(v17, Pmin, Pmax, 47, 1); 
y18 = map(v18, Pmin, Pmax, 47, 1); 
y19 = map(v19, Pmin, Pmax, 47, 1); 
y20 = map(v20, Pmin, Pmax, 47, 1);
y21 = map(v21, Pmin, Pmax, 47, 1); 
y22 = map(v22, Pmin, Pmax, 47, 1); 
y23 = map(v23, Pmin, Pmax, 47, 1); 
y24 = map(v24, Pmin, Pmax, 47, 1); 
y25 = map(v25, Pmin, Pmax, 47, 1); 
y26 = map(v26, Pmin, Pmax, 47, 1); 
y27 = map(v27, Pmin, Pmax, 47, 1); 
y28 = map(v28, Pmin, Pmax, 47, 1); 
y29 = map(v29, Pmin, Pmax, 47, 1); 
y30 = map(v30, Pmin, Pmax, 47, 1);
y31 = map(v31, Pmin, Pmax, 47, 1);
y32 = map(v32, Pmin, Pmax, 47, 1);
y33 = map(v33, Pmin, Pmax, 47, 1);
y34 = map(v34, Pmin, Pmax, 47, 1);
y35 = map(v35, Pmin, Pmax, 47, 1);
y36 = map(v36, Pmin, Pmax, 47, 1);
y37 = map(v37, Pmin, Pmax, 47, 1);
y38 = map(v38, Pmin, Pmax, 47, 1);
y39 = map(v39, Pmin, Pmax, 47, 1);
y40 = map(v40, Pmin, Pmax, 47, 1);
y41 = map(v41, Pmin, Pmax, 47, 1);
y42 = map(v42, Pmin, Pmax, 47, 1);
y43 = map(v43, Pmin, Pmax, 47, 1);
y44 = map(v44, Pmin, Pmax, 47, 1);
y45 = map(v45, Pmin, Pmax, 47, 1);
y46 = map(v46, Pmin, Pmax, 47, 1);
y47 = map(v47, Pmin, Pmax, 47, 1);
y48 = map(v48, Pmin, Pmax, 47, 1);
y49 = map(v49, Pmin, Pmax, 47, 1);
y50 = map(v50, Pmin, Pmax, 47, 1);
y51 = map(v51, Pmin, Pmax, 47, 1);
y52 = map(v52, Pmin, Pmax, 47, 1);
y53 = map(v53, Pmin, Pmax, 47, 1);
y54 = map(v54, Pmin, Pmax, 47, 1);
y55 = map(v55, Pmin, Pmax, 47, 1);
y56 = map(v56, Pmin, Pmax, 47, 1);
y57 = map(v57, Pmin, Pmax, 47, 1);
y58 = map(v58, Pmin, Pmax, 47, 1);
y59 = map(v59, Pmin, Pmax, 47, 1);
y60 = map(v60, Pmin, Pmax, 47, 1);
y61 = map(v61, Pmin, Pmax, 47, 1);
y62 = map(v62, Pmin, Pmax, 47, 1);
y63 = map(v63, Pmin, Pmax, 47, 1);
y64 = map(v64, Pmin, Pmax, 47, 1);
y65 = map(v65, Pmin, Pmax, 47, 1);
y66 = map(v66, Pmin, Pmax, 47, 1);
y67 = map(v67, Pmin, Pmax, 47, 1);
y68 = map(v68, Pmin, Pmax, 47, 1);
y69 = map(v69, Pmin, Pmax, 47, 1);
y70 = map(v70, Pmin, Pmax, 47, 1);

// формируем массив из 71-го значения данных, которые будут выводиться на дисплей
int arrayDraw [71] =
{ y0,y1,y2,y3,y4,y5,y6,y7,y8,y9,y10,y11,y12,y13,y14,y15,y16,y17,y18,y19,y20,y21,y22,y23,y24,
y25,y26,y27,y28,y29,y30,y31,y32,y33,y34,y35,y36,y37,y38,y39,y40,y41,y42,y43,y44,y45,y46,y47,y48,y49,
y50,y51,y52,y53,y54,y55,y56,y57,y58,y59,y60,y61,y62,y63,y64,y65,y66,y67,y68,y69,y70 };

for (cycle = 0; cycle <71; cycle ++) // 71 цикл вывода 71-ой линии на дисплей
   {
    // рисуем линии на позициях от х=70 до х=0 справа налево с значениями, полученными из массива
    // с номерами согласно циклу от 0 до 71, значениями, равными от=у0 до у=70)
    display.drawLine (70-cycle, arrayDraw [cycle], 70-cycle, z, BLACK);    
    } 

display.display(); // все нарисованное выводим на экран дисплея

if (cycle >70)  // Если значение циклов cycle достигло значения больше 70 (экран дисплея заполнен)
  {
   cycle = 0;
/* номер цикла приобретает значение = 0, начинаем убирать значение с позиции по х=0
на его месте размещаем значение с поз.1, на его - с поз.2 и так далее.
Самое свежее значение выводится на позиции 70, остальные сдвигаются на 1 влево. Самое старое
значение, полученное 71 цикл назад, удаляется безвозвратно. */
  }

display.clearDisplay(); // очищаем дисплей

} // завершаем подпрограмму void Diagram()
/*********************************************************/

 

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

 

Можно писать мне на почту s-chuprin@mail.ru, но лучше, наверное, обсуждать на форуме. Возможно это будет кому-то интересно и полезно. А я ожидаю от сочувствующих предложений по оптимизации кода.

 

Всего доброго.

Удачи всем, у кого руки растут из головы.

 

 

 

 

msng
Offline
Зарегистрирован: 07.06.2012

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

Datak
Онлайн
Зарегистрирован: 09.10.2014

Жалко что точек на дисплее только 71,  а не 701. А то бы действительно крутая программа получилась. :)

В строчках 449...519 мапятся 70 переменных  v  в 70 переменных  y. А дальше, в 522...525, все эти переменные  y  копируются в массив  arrayDraw.
Что мешает мапить сразу в  arrayDraw, и выбросить из кода все эти  y ? :)
И вообще, что мешает перенести вызов функции  map  в цикл отрисовки, и выбросить  arrayDraw  тоже?

Ну и не только это, конечно - найдётся и ещё что пооптимизить.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Вам нужно if заменить на switch и потом их еще и объединить и вынести одинаковые действия в отдельные функции.

Зачем Вам переменные v* как long?

Maverik
Offline
Зарегистрирован: 12.09.2012

это просто какая-то аццкая жесть ))

cтроки 088-098 - быдлокод, таких объявлений не должно быть в принципе, только через массив

094-098 - сильно сомневаюсь, что в этой программе вообще нужен тип long хоть где нибудь.  unsigned int должно быть вполне достаточно. в крайнем случае можно сделать одну переменную типа long в котору получаем с датчика текущее значение давления, если оно не влезает в unsigned int, затем вычитаем из него константу. константу подбираем так, чтобы гарантированно хватило вместить результат в инт. хотя я уверен, что диапазон возможных значений атмосферного давления в хабаровске вполне влезает в unsigned int . а уж для отображения графика на экране в 84x48 точек даже типа int многовато...

177-229 - строки, выводимые на экран неизменными, можно сохранять в flash или EEPROM для экономии памяти (читаем про PROGMEM)

449-519 - быдлокод

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

 

 

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

@Maverik

Это Вы со зла. ТС написал что он хочет оптимизировать, а Вы сразу - "быдлокод".

Человек понимает что сделал не правильно и просит совета, а Вы его носом в тапки.

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

Вот если бы он написал "смотрите какой у меня чистый и правильный скетчик получился" - я бы одним из первых поржал, а так, по моему, не над чем.

Ту ТС: Если Вы будете следовать уже данным советам, то сократите Ваш код процентов на 70.

Maverik
Offline
Зарегистрирован: 12.09.2012

совсем не со зла ))  "быдлокод" - это такое специальное слово для кода, который написан может и правильно, но некрасиво, вовсе не ругательство, и совсем не значит, что тс- быдло. ))) программисты иногда так про свой код и пишут - "вот кусок программы, на быдлокод внимания не обращайте" - например, когда вставлен кусок другого кода, нужно его привязать к своему и по быстрому потестировать.  как временное явление в этом ничего страшного нет, но приучаться к этому как норме не нужно.

человек хотел получить замечания и предложения, особенно по части оптимизации кода. он именно это и получил.  )))

кстати, строки 28-400 можно сократить до десяти строк, если напр использовать свич и в каждом варианте писать не функции, а только переменные, которые меняются.  эти строки всё-равно занимают память, а ведь их можно тоже запихнуть в флеш или еепром. а уже после присваивания переменных в зависимости от условий, ОДИН раз написть эти функции отображения данных.

 

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

про свтич я написал сразу ;)

быдлокод - это например:

if(true) {
    int a = 0;
    int b = a + 1;
} else {
    int a = 0;
    int b = 1 + a;
}

Или по "культурному" индусский. а него просто не оптимизированный, от слова совсем.

А В Вашем примере - это говнокод :)

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

JollyBiber пишет:

про свтич я написал сразу ;)

быдлокод - это например:

if(true) {
    int a = 0;
    int b = a + 1;
} else {
    int a = 0;
    int b = 1 + a;
}

Это не код, это заклятие какое-то...

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015
Добрый день.
В код пока вникнуть некогда (да и рановато мне коментировать, сам ещё не во всём разбираюсь).
Проект понравился . Перекликается с моей конструкцией .
Я делал для родителей (хотя и сам уже - погодозависимый). Поэтому - всего одна кнопка(и без графика). Архив суточный 4-х страничный(на фото одна из страниц) EEPROM - ский. Код пока не окончательный (пока половина памяти свободна). TFT - на фото , UNO , BMP180 , DS3231 .
Корпус - коробка из под ангийских булавок(иголок с ушком). Фото - экспромт на мобильник (не пинайте -  я на работе). Если кого то заинтересует - будет тема с кодом и фотками в субботу - воскресенье.
Прошу прощения у автора темы.
 
     
bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

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

Но если постигаете язык сами, то уже стоит вопрос чтоб просто работало!

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015
bodriy2014     ВО ВО!
Maverik в ВАШем посте читаем - код написало быдло, которому надо читать то-то и то -то . 
Сами же пишите- "человек хотел получить замечания и предложения, особенно по части оптимизации кода." . А что человек (далеко не програмист сведущий в терминах и жаргоне) получил ?  "Хамскую"(не зная жаргона) критику и совет "активнее" изучать букварь програмиста........  А ведь можно было бы написать "... вместо этого я бы написал -так ..." , " ...а вот это проще сделать так ......"
Хотел своё для всех выложить ......  Может какому то первокласнику вроде меня и пригодилось бы ....  Да боюсь Maverik-ов......  Если всё таки решусь , то очень ВАС прошу - не надо меня коментировать в таком духе.... 
 
Sergey_Ch  . Сегодня - завтра в личку скину код изделия на фото и свои предложения 
 
Ещё раз прошу прощения.
Клапауций 999
Offline
Зарегистрирован: 06.06.2015

Андрей1963 пишет:

завтра в личку скину...

а, где у нас личка? - или эта тема форвардится с другого форума?

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Клапауций 999 пишет:

Андрей1963 пишет:

завтра в личку скину...

а, где у нас личка? - или эта тема форвардится с другого форума?

Я написал тебе в личку где смотреть личку.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

JollyBiber пишет:

Я написал тебе в личку где смотреть личку.

от тебя я ничего другого и не ожидал.

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Sergey_Ch    загляни на почту.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Клапауций 999 пишет:
а, где у нас личка?

Личка - не у всех включается: Вы ее - не видите, а кто-то - видит.

Не мешайте людям жить в своих иллюзиях, и они не будут вытаскивать Вас из ваших.(с)

Maverik
Offline
Зарегистрирован: 12.09.2012

> А на счет быдлокода или говнокода скажу так, это все зависит от "школы" если у вас изначально был хороший преподаватель в

> вузе и вым привили хорошие манеры и любовь к лаконичному оптимизированному коду, это уже не отнять.

> Но если постигаете язык сами, то уже стоит вопрос чтоб просто работало!

не соглашусь, я вообще языки программирования осваивал сам, и при этом быдлокод я просто органически не перевариваю и сам не пишу, комменты ручки сами тоже автоматически расписывают,  специально редактор подбирал для корректного форматирования кода.  этому не учат, это врожденное.  Хотя, конечно, зависит от знания языка программирования. Напр. я очень плохо знаю язык бд MySQL и то, что я на нём пишу, можно вполне назвать быдлокодом. Но поскольку мне он нужен раз в год, не чаще, на это мне пофиг, и собсно если кто-то скажет что мои вставки на mysql - быдлокод, я уж точно не буду обижаться )))

> Maverik в ВАШем посте читаем - код написало быдло, которому надо читать то-то и то -то . 
> Сами же пишите- "человек хотел получить замечания и предложения, особенно по части оптимизации кода." . А что человек
> (далеко не програмист сведущий в терминах и жаргоне) получил ?  "Хамскую"(не зная жаргона) 

Алё, гараж. Обороты сбавляем потихоньку)))  Во-первых я специально предупредил, что слово "быдлокод" ничего уничижительного по отношению к личности самого автора не подразумевает, и что естественно это не означает, что он "быдло".  Но вы,видимо, не читатель а писатель))  Во-вторых, если внимательно изучить код, а потом посмотреть на мои советы, то можно понять, что я ему дал ОЧЕНЬ ценные советы в т.ч. по части оптимизации кода.  Ценность этих советов в том, что если афтар ими воспользуется, он не только оптимизирует представленный код, а вообще намного улучшит свой стиль программирования.  Например, хорошо видно, что автор знает, что такое массив, но не знает, зачем нужна индексация элементов массива, и, соответственно,  удобства от пользования массивами он не получает. То же самое относится к многократной записи функций тогда как достаточно просто изменить в зависимости от условий их аргументы. Это позволит сделать код НА ПОРЯДОК более компактным. Ну и разумеется, использование флеш/еепром для экономии памяти при программировании микроконтроллеров тоже очень важно, о чем я афтару тоже сказал.

Но вы, видимо, опять не читатель и предоставленный кода смотрели невнимательно.

короче говоря, молодежь, нужно быть проще, и люди к вам потянутся )) смотрите больше старых фильмов про обучение боевым искусствам, там вообще в процессе обучения учеников бамбуковой палкой лупят и ничо, все довольны )))

 

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Maverik    ну вопервых - не"предупредил" а оправдался..... 

я тоже не знаю что такое "индексация элементов массива" и "зависимости от условий их аргументы". Ну нет этого в букварях!!!! Осваиваем .... ищем описания .... почему бы не повесить ссылки ......  Я конечно понимаю - проще кинуть термин и "крутись как хочешь....." . Забью эти термины - буду искать . Пока не попадались ..... Просто ни где эти термины не попадались!!!  Тяжело ткнуть носом?... Да проще написать "быдлокод"......  А помоему просто некорректно так относиться к чужому труду .....  Про своё  - пожалуста !  Кстати ВЫ упомянули что программисты так говоря про СВОИ коды. Вот код..... Быдлокод..... говнокод.....  Прошу прощения у автора темы ..... Но что то полезное (я надеюсь) есть в коде и для него (вроде задачи одни ... только вместо грфика - архив).  Писался и доводился больше двух недель. Я - дуб в програмировании. Всё осваиваю по мере возникновения проблем. Массивы, EEPROM, работа с TFT. Всё  это две недели назад было темным лесом...... Читаем "букварь" - пишем...... Пршу ВАС - ВАШи предложения !  Желательно с сылками - где и что искать для улучшения кода. 

Да . Кстати . Я "читатель". Поэтому болезнено воспринимаю огрехи русского языка при изложении мыслей (камушек в ВАШ огород).

Фото изделия было выше.

Код




   
   //////////// БИБЛИОТЕКИ //////////
   #include <Adafruit_GFX.h>    
   #include <Adafruit_ST7735.h> 
   #include <Adafruit_BMP085.h>
   #include <SPI.h>
   #include <Wire.h>
   #include <EEPROM.h>
   #include "DS3231.h"
   
   //////////// активизируем дисплей /////////
   #define TFT_CS     9
   #define TFT_RST    8     
   #define TFT_DC     10
   Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);
   ///////////// пробывал и так - не понравилось ///////////
   //#define TFT_SCLK 13   // set these to be whatever pins you like!
   //#define TFT_MOSI 11   // set these to be whatever pins you like!
   //Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
   
   /////////// активизируем датчик давления ////////////
   Adafruit_BMP085 bmp;
   
   /////////// активизируем часы ///////////
   DS3231 Clock;
   bool Century=false;
   
   //////////   ПЕРЕМЕННЫЕ   /////////////////
   // "byte" - вписываются в 0 - 255 , остальные "int" //
   /////////// часов ///////////
   byte year, month, date, DoW, hour, minute, second;
   byte Lsecond = 0;
   
    int analogPin = 0;      //  пин входа фоторезистора с "+" , на "-" резистор ....
    int ledPin   = 6 ;      //  пин регулировки яркости  " BL "
    int Temp   = 0 ;        //  температура
    int Press  = 0 ;        //  давление
 
    byte knop = 0    ;         //  кнопка
    byte ChassEP     ;         //  часы из памяти
    byte PressEP    ;          //  давление из памяти 
    int TempEP     ;           //  температура из памяти
    byte addressP = 30;        //  адрес чтения давления 
    byte addressT = 60;        //  адрес чтения температуры  
    int addressCH = 0;         //  адрес чтения часов
    byte chas = 0   ;          //  переменная отсчитываем 1 час         
    int minut = 0   ;          //  переменная отсчитываем 5 мин
    int minutX = 0  ;
    int prevPress = 0;         // тут будем хранить, какое давление было при выводе на дисплей
    int prevTemp=0;            // тут будем хранить, температуру 
    
        
    /////////////////    массивы календаря  ////////
    char* months [] = {" января"," февраля","  марта"," апреля","   мая","  июня","  июля", " августа"," сентября"," октября"," ноября"," декабря"};
    char* DoWs [] = {"Понедельник","  Вторник","   Среда","  Четверг","  Пятница","  Суббота","Воскресенье"};

    
void setup(void) {
   //Serial.begin(9600);
   Wire.begin();
   bmp.begin();
   tft.initR(INITR_BLACKTAB); 
   tft.fillScreen(ST7735_BLACK);    //  дисплей цвет фона 
   tft.setRotation(1);              //  повернуть по горизонту
   pinMode(2,INPUT);                //  кнопка на  пин2
   digitalWrite(2,HIGH);            //  подтягиваем к +
  
  ///////////////////////////////////////////////////
 
}

void loop() {
  /////////    стереть память  //////////
/*
   EEPROM.write(addressP, 0);
   EEPROM.write(addressT, 0);
   EEPROM.write(addressCH, 0);
   addressP = addressP + 1;          //  устанавливаем следующие адреса
   addressT = addressT + 1;
   addressCH = addressCH + 1;
   if (addressP == 54)  
   addressP =30  ;
   if (addressT  == 84) 
   addressT  = 60 ;
   if (addressCH  == 24)
   addressCH = 0 ;
*/

/////////  при смене даты очищаем экран ////////

   byte static prevdate=0;             // тут будем хранить дату
   if(date  !=  prevdate)              // если поменялась чистим экран
   {tft.fillScreen(ST7735_BLACK);      // таким же образом будем стирать предыдущие записи
  
   kalendar ();    // пишем новые данные

   prevdate = date ;
}
   
/////////  регулируем яркость (что бы ночью не светил как прожектор)  //////

   int val = analogRead(analogPin);    // Создаем переменную val для чтения analogRead
   val= constrain(val,50 ,799);        // устанавливаем нужные(посмотрим в Serial.print) границы переменной
   val /= 4 ;                          // 1024 преобразуем в 255
   analogWrite(ledPin,val);            // установим яркость в соотв.с освещением
      
   Clock.getTime(year, month, date, DoW, hour, minute, second);  // читаем часы
   Temp = bmp.readTemperature();       //читаем датчик
   Press = bmp.readPressure()/133.3;
   
   knop = digitalRead(2);              //  читаем кнопку
 
   if (knop == HIGH)                    //  если не нажата  то  
      
  //////////////////    ПОЕХАЛИ ....  /////////////////
 { 
 ///////////////  часы ////////////////////////
  
   tft.setTextSize(4);         //  размер
   byte static prevhour=0;     // тут будем хранить, сколько часов было при выводе
   if(hour!=prevhour)          //  если часы поменялись - стираем старые
   {
   tft.setCursor(20, 35);      //  курсор
   tft.setTextColor(ST7735_BLACK);
   if(hour<10)              
   {   tft.println("0");  }    //  если был , стираем  "0"
   tft.println(prevhour);
   }
  /////////////  и пишем новые  //////////////
   tft.setCursor(20, 35);           //  курсор
   tft.setTextColor(ST7735_CYAN);   //  цвет
   if(hour<10)
   { tft.println("0");   }          //  если нужен, пишем "0"
   tft.println(hour);
   prevhour = hour ;
  
     /////////////////////  моргаем индикатором секунд ////////////////////////////
     
    byte static prevSecond=0;   // тут будем хранить, сколько секунд было при выводе
    if(second!=prevSecond)      //  если секунды поменялись
 { 
    tft.setTextSize(3);
    tft.setCursor(70, 40);      //  курсор
    if (Lsecond == 0)           // и индикатор не светится 
    ///////////  зажигаем его ////////////
  {
    tft.setTextColor(ST7735_CYAN);
    tft.println(":");
    Lsecond = 1 ;
  }
    else  //////  если светится - гасим 
  {
    tft.setTextColor(ST7735_BLACK);
    tft.println(":");
    Lsecond = 0 ;
  }
 }
    prevSecond=second; // запомнили когда мы "отчитались"
 
       ////////  минуты //////////////
  
   tft.setTextSize(4);              //шрифт
  
   byte static prevminute=0;       // тут будем хранить, сколько минут было при выводе 
   if(minute!=prevminute)          // если минуты поменялись стираем предыдущие
  {  
   tft.setCursor(90, 35);          //  курсор
   tft.setTextColor(ST7735_BLACK); 
   if(prevminute<10)
   { tft.print("0");   }            //  если был , стираем  "0"
   tft.print(prevminute);
  }
     //////////  пишем новые  //////////
     tft.setCursor(90, 35);
     tft.setTextColor(ST7735_CYAN);   //  цвет
     if(minute<10)
     {  tft.print("0");   }           //  если нужен, пишем "0"
     tft.print(minute);
     prevminute = minute  ;           //  Запоминаем что записали

////////////////   выводим давление и температуру  1 раз в 5 мин (300000 мсек) ////////////////////
  
///////////////  Давление /////////////////////////

    minut = millis() - minutX ;   //  отсчитываем 5 мин 
    if (minut >= 5000)            //  5 мин - 300000 а это для настройки
{
    if(Press!=prevPress)          //  если давление поменялось стираем предыдущее 
  {
    tft.setCursor(20, 100);
    tft.setTextSize(2);
    tft.setTextColor(ST7735_BLACK);
    tft.print(prevPress);
  
 ///////////// и пишем настоящее /////////////
 
    tft.setCursor(20, 100);
    tft.setTextColor(ST7735_YELLOW);
    tft.print(Press);
    tft.println("mm");
    prevPress  = Press ;                 // Запоминаем что записали
    }
 
 ///////////////  температура  /////////////////////

    if(Temp!=prevTemp) //  если температура поменялась стираем предыдущую 
  {
    tft.setCursor(100, 100);
    tft.setTextSize(2);
    tft.setTextColor(ST7735_BLACK);
    tft.print(prevTemp);
  
 ///////////// и пишем настоящую /////////////
 
    tft.setCursor(100, 100);
    tft.setTextColor(ST7735_YELLOW);
    tft.print(Temp);
    tft.println("*C");
    prevTemp  = Temp ;      // Запоминаем что записали
    }
    minut = 0 ;
    minutX = millis() ;
}  
//////// запись в EEPROM давления и тепературы каждый час //////////////////
{
    byte static chas=0; // тут будем хранить, сколько часов было при прошлом отчете

    if(hour  != chas) // если часы поменялись
  
    EEPROM.write(hour, hour);
    EEPROM.write(hour + 30, Press - 600);  // т.к. EEPROM хранит 0 - 255 здесь отнимим 600 а 
    EEPROM.write(hour + 60, Temp);                               // при считывании добавим 
    chas = hour ;
  }       
    ///////////////  ПРИЕХАЛИ  //////////
   
 } 
   else         //  если кнопка нажата  //
   /////////////  ПОЛЕТЕЛИ /////////////////////
   
   //////////////  ЧИТАЕМ EEPROM /////////////////
   {
   addressCH  = hour   ;             //
   addressP  = hour+30 ;             //  начальные адреса чтения из памяти
   addressT  = hour+60 ;             //
   
   ////////////  выводим постранично по 5 сек //////////////
   
   stranica () ;
   stranica () ;
   stranica () ;
   stranica () ;
   tft.fillScreen(ST7735_BLACK);     //  стираем экран
   
  /////////////  всстанавливаем данные на экране  ///////////
   
   kalendar ();
   tft.setCursor(20, 100);
   tft.setTextColor(ST7735_YELLOW);
   tft.print(prevPress);
   tft.println("mm");
   tft.setCursor(100, 100);
   tft.setTextColor(ST7735_YELLOW);
   tft.print(prevTemp);
   tft.println("*C");
   
   }
 }
 //////////////  ДАЛЕЕ ВСЕ ФУНКЦИИ  //////////////////
 
 //////////////  чтение строки памяти //////////
 
  void stroka ()
 {
   ChassEP = EEPROM.read(addressCH); //  читаем из памяти последний час
   PressEP = EEPROM.read(addressP);  //  читаем из памяти последнее давление 
   TempEP  = EEPROM.read(addressT);  //  читаем из памяти последнюю температуру
   
   tft.setTextSize(2);               //  устанавливаем размер текста
   tft.setTextColor(ST7735_RED);
   if (ChassEP < 10)
   tft.println("0");
   tft.println(ChassEP);             //  выводим значения
   tft.setTextSize(1);
   tft.println("00 ");
   tft.setTextSize(2);
   tft.setTextColor(ST7735_YELLOW);
   tft.println(PressEP + 600);       //  добавляем 600 отобранных при записи 
   tft.println("mm ");
   tft.setTextColor(ST7735_GREEN);
   tft.println(TempEP);
   tft.println("C");  
   }
 //////////  изменение адресов чтения /////////////////
 
   void adres()
   {
   addressP = addressP - 1;          //  устанавливаем следующие адреса
   addressT = addressT - 1;
   addressCH = addressCH -1;
   
   if (addressCH < 0)
   addressCH = 23 ;
   if (addressP < 30)                // следим за адресами 
   addressP = 53 ;                   // при переходе через начальные 
   if (addressT < 60)                // устанавливаем конечные
   addressT = 83 ;
   
   }
   //////////// вывод страницы /////////////////////////
   
   void stranica ()
   {
   tft.fillScreen(ST7735_BLACK); //  стираем экран
   
   tft.setCursor(5, 5);          //  устанавливаем курсор
   stroka ();
   adres () ;                    //  устанавливаем следующие адреса
   
   tft.setCursor(5, 25);         //  устанавливаем курсор
   stroka ();
   adres () ;                    //  устанавливаем следующие адреса

   tft.setCursor(5, 45);         //  устанавливаем курсор
   stroka ();
   adres () ;                    //  устанавливаем следующие адреса

   tft.setCursor(5, 65);         //  устанавливаем курсор
   stroka ();
   adres () ;                    //  устанавливаем следующие адреса
   
   tft.setCursor(5, 85);         //  устанавливаем курсор
   stroka ();
   adres () ;                    //  устанавливаем следующие адреса
   
   tft.setCursor(5, 105);        //  устанавливаем курсор
   stroka ();
   adres () ;                    //  устанавливаем следующие адреса

   
   delay(5000);                  //  ждём 5 секунд

   }
   
   ///////////////////  календарь ///////////////////////
   
 void kalendar ()
 {
    ////////////////  дата  /////////////////////

   tft.setCursor(25, 10);              //  курсор
   tft.setTextColor(ST7735_MAGENTA);   //  цвет
   tft.setTextSize(2);                 //  размер
   tft.println(date);
   tft.println(months[month-1]);       //  месяц

     ////////  день недели  ////////
  
   tft.setTextColor(ST7735_RED);       //  цвет
   tft.setTextSize(2);                 //  размер
   tft.setCursor(15, 75);
   tft.println(DoWs[DoW-1]);
 }
DimaD
Offline
Зарегистрирован: 26.03.2015

Можете выложить TimeHelpers?

Sergey_Ch
Offline
Зарегистрирован: 15.01.2015

Уважаемые участники форума, благодарю Вас за отзывчивость. Особенно участника Maverik. Не обижайте его, пожалуйста. Именно Maverik проанализировал весь код проекта и дал свои замечания и предложения. Пусть несколько не в той манере, которая всем нравится, зато по теме. Только хотелось бы более подробнее и конструктивнее.

Пишите мне s-chuprin@mail.ru или на форум.

С увжением, Sergey_Ch 

Sergey_Ch
Offline
Зарегистрирован: 15.01.2015

Заглянул. Пусто.

Пойду загляну в холодильник.

s-chuprin@mail.ru

Sergey_Ch
Offline
Зарегистрирован: 15.01.2015

Не удобно как-то чужими трудами хвалиться.

Я в статье написал по библиотеку работы со временем

Большое спасибо участнику форума Leshak за представленную библиотеку работы с функцией времениhttp://alxarduino.blogspot.ru/2013/08/delay.html.

Там все есть и ссылки для скачивания его библиотеки TimeHelpers от автора Leshak.

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Продублировал .....

И ещё кое что добавил про "баюшки - баю"

Тогда скажем так .....   - поищи (поройся) ....(не в холодильнике - там  "мыла" нет)....

Thorn
Offline
Зарегистрирован: 07.11.2014

Эх, давно искал "хороший" пример постоения графика логиования температуры\давления\влажности.  :) Хотел поиграться но под свой tft дисплейчик на ili , но несдьба чтото..... Почему то ругается на строчку:

139	DO_EVERY(Diagram_interval,
140	  {Meterage();});

- дескать я кобы _SEC_ неопределена... но этож неправда, в строчках:

082	#define Diagram_interval _SEC_(608)  // переодичность вывода данных на дисплей (608 cекунд)
083	                                     // полное заполнение 71 позиции графика = 12 часов)
084	// #define Diagram_interval _SEC_(2) // переодичность вывода данных на дисплей=2 cек (Исп. для настройки)

всё прописано автором.... 

Offtop недумал что ХАБАРОВСК настолько ниже БРЯНСКА (я на 252 метрах а автор на 90 всего :) )

SunX
SunX аватар
Offline
Зарегистрирован: 04.10.2014

У Вас используется куча (все) компоненты, которые хотят работь от 3.3V и стабилизатор на 5V. Зачем? может сразу стабилизатор на 3.3V и тогда потербление должно несколько упасть, глядишь, срок жизни в пару раз может увеличиться.

Так же я бы посоветовал повесить барометр на пину, где есть аппаратный I2C (A4 и A5), правда, видимо придется другую библиотеку использовать. Тоже и с дисплеем. Так же в силу того, что у Вас дисплей и ардуина оба работают на 3.3V, то резисторы между ними не обязательны.

Sergey_Ch
Offline
Зарегистрирован: 15.01.2015

У Вас используется куча (все) компоненты, которые хотят работать от 3.3V и стабилизатор на 5V. Зачем? 

+++++

Благодарю Вас за комментарий.

Согласен с Вами полностью, просто не было под рукой стабилизатора на 3.3 в, повышающего напряжение Li-Pol аккумулятора. А сопротивления между Ардуиной и дисплеем остались от первой версии проекта, когда использовалась 5-ти вольтовая Arduino ProMicro 16 мгц. Она потребляла около 60 ма. Заменил на ProMini 8 мгц, потребление составило 15 ма.

 

Sergey_Ch
Offline
Зарегистрирован: 15.01.2015

Ответ участнику Thorn:

А Вы установили на IDE библиотеку TimeHelpers от автора Leshak ?

Ссылку я публиковал : http://alxarduino.blogspot.ru/2013/08/delay.html.

 

Thorn
Offline
Зарегистрирован: 07.11.2014

Точно ... затупил, показалось что такая либа наверное уже была скачана с GitHub`а и лежит в папочке. Теперь всё пучком.... утро радует...

SunX
SunX аватар
Offline
Зарегистрирован: 04.10.2014

Sergey_Ch пишет:

Согласен с Вами полностью, просто не было под рукой стабилизатора на 3.3 в, повышающего напряжение Li-Pol аккумулятора.

Не нашел, какое минимальное напряжение у Li-Pol аккумулятора, но мне кажется, что можно поставить обычный линейный стабилизатор с низким падением напряжения и не париться. Напряжение на аккумуляторе будет больше, чем 3.3V большую часть времени (когда меньше - он уже близок к разряду, как я помню), а для всего кроме дисплея, думаю, можно и вообще без стабилизатора

trembo
trembo аватар
Онлайн
Зарегистрирован: 08.04.2011

3.0 -4.2 Вольт  норма для ЛиПо. если на 8 МГц или ниже перейдёте- ничего делать не надо.
Ниже трёх- может вздуться. Выше 4.2 - греться.
А так специальный повышающий с ЛиПо на 5 Вольт ставьте .
Есть варианты с 5-ти Вольтовым выходом, клеммами под аккумулятор и входом дла зарядки.
С контролем этой зарядки-разрядки.

SunX
SunX аватар
Offline
Зарегистрирован: 04.10.2014

trembo пишет:

3.0 -4.2 Вольт  норма для ЛиПо. если на 8 МГц или ниже перейдёте- ничего делать не надо.

Дак уже, если верить первому сообщению. Я про это и говорил, что повышающий не нужен, все и так должно работать замечательно.

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015


/* Вариант не окончательный
   Исправить начальный адрес чтения из памяти.
   Ввести переменную при записи(сейчас 790) в зависимости от текущего 
   давления при записи в память для того чтобы растянуть 
   график по вертикали до 10мм давления на всю вертикаль
   (те же "режимы" только в автомате) и прорисовать на графике "min" и "max".
   Время цикла и колличество циклов установлены для настройки.
   (Цикл - 8сек. Кол-во - 450 (изменения - 1раз в час). График - трое суток.)
   Почистить .... Убрать всё лишнее.... Получше прокоментировать.... 
   
 */


   #include <Adafruit_GFX.h>
   #include <Adafruit_PCD8544.h>
   #include <Adafruit_BMP085.h>
   #include <Wire.h>
   #include <avr/sleep.h>
   #include <avr/wdt.h>
   #include <EEPROM.h>
   #define CNT 2             //  количество циклов по 8 секунд от работы до работы
   int count1 = 0 ;          //  переменная для счётчика циклов по 8 сек
   volatile boolean wdt_tripped=1;
   ////////////  активизируем дисплей  //////////////////
   Adafruit_PCD8544 display = Adafruit_PCD8544(4, 5, 6, 7, 8);
   /////////// активизируем датчик давления ////////////
   Adafruit_BMP085 bmp;
   int Press  = 0 ;        //  переменная  давление
   byte PressEP    ;       //  давление в памяти
   byte addressP = 0;      //  адрес записи давления 
   int adresP      ;       //  адрес считывания давления 
   byte cycle = 0  ;       //  колличество столбцов в графике
   int adrP = 71 ;         //  место столбца графика

void setup()
{
   wdt_disable();          //  активация пробуждения 
   wdt_reset();            //  по сторожевому таймеру
   wdt_enable(WDTO_2S);    //  каждые 8 сек (меньше - для настройки)             
   Wire.begin();
   bmp.begin(); 
   
   display.begin();        //  старт дисплея
   delay(500); 
   display.setContrast(55);
   display.clearDisplay();
   Serial.begin(9600); 
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
}

void loop()
{
  // просыпаемся смотрим сколько циклов по 8 сек. спали
   wdt_interrupt_mode(); 
   if (wdt_tripped ==1) 
 {
   count1++;
   wdt_tripped = 0; 
   if (count1 == CNT)                   //  если уже "пора" 
   {  
    
  /////////////  пишем давление в EEPROM /////////////////////////////
   
   EEPROM.write(addressP,790 - Press);  // т.к. EEPROM хранит 0 - 255 здесь отнимим 600 а 
                                         // при считывании если надо добавим 
   addressP = addressP + 1;              // устанавливаем следующий адрес  
   if (addressP >= 72)                   // адреса 0 - 71
   {addressP = 0;}
   count1 = 0;
      //////////  рисуем график //////////////   
   grafik(); 
 }
 }
    //   и снова "баюшки"
    sleepNow();
}
                     //////  ФУНКЦИИ  //////

/////////////////  рисуем график  ////////////////////////
  void grafik()
  { 
    display.clearDisplay();                //  очищаем дисплей
    Pressing();                            //  рисуем текущее давление 
    display.setTextColor(BLACK);
    adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle <72; cycle ++)   // 72 цикла вывода линий на дисплей
    {  
    stolb();
    }
    display.display();
    delay(100);
  }
//////////////  текущее давление на дисплей //////////////
  void Pressing()
 { 
   Press = bmp.readPressure()/133.3; 
   display.clearDisplay();
   display.setTextSize(2);
   display.setTextColor(BLACK);
   display.setCursor(0,0);
   display.println(Press);
   display.println("mm");
   display.display();
 }
 //////////////// прорисовка одного столбца  ///////
 void stolb()
 { 
   PressEP = EEPROM.read(adresP);                     //  читаем из памяти давление
 
   display.drawLine (adrP, PressEP, adrP, 48, BLACK); // рисуем столбец
   adrP = adrP - 1;                                   // устанавливаем место следующего столбца
   if (adrP < 0)                                      // следим за местом
   {adrP = 71 ; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = 71 ;}   
 }

 ///////////  здесь мы просто просыпаемся
   void wdt_interrupt_mode() 
   {
   wdt_reset();
   WDTCSR |= _BV(WDIE);                 // Restore WDT interrupt mode
   }
   ISR(WDT_vect) 
   {
   wdt_tripped=1;                       // set global volatile variable
   }

/////////////  а здесь засыпаем 
   void sleepNow()   
{
   _SFR_BYTE(ADCSRA) &= ~_BV(ADEN);
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // Здесь устанавливается режим сна
   sleep_enable();                        // Включаем sleep-бит в регистре mcucr. Теперь возможен слип 
   _SFR_BYTE(ADCSRA) |= _BV(ADEN);
   sleep_mode();                          // Здесь устройство перейдет в режим сна!!!
}

Sergey_Ch   Пока было время свободное на работе ....... Ну как то так получилось.... Ток замерять пока бестолку (NANO работает). Но экономия АКБ должна быть. Приедет "micro" ......(когда нибуть то приедет....)

Буду рад если чем то вам поможет. В выходные продолжу.

 

 

Thorn
Offline
Зарегистрирован: 07.11.2014

Немогу понять что в первом что в крайнем скетче отображение на дисплее функции: 090     display.display();

как она преобразуется для tft - все перепробовал - невыходит каменный цветок :(

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Для TFT такой функции нет(для ST7735 вывод идёт сразу по tft.print(); )

А в PCD8544 по display.display(); выводятся на экран все  display.print(); которые выше в {......}.

 

Thorn
Offline
Зарегистрирован: 07.11.2014

Я пытался, .... чесно :)) однако в итоге в библиотеке теперь затык: Adafruit_ILI9341.cpp: In member function 'void

вобщем несудьба/

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Из-за "отсутствия наличия" соотв. оборудования ничего хорошего по  Adafruit_ILI9341  посоветовать не могу. Это "будет одно горе а не советы".....  

Но что то с выводом на дисплей вы перехимичили......

Sergey_Ch
Offline
Зарегистрирован: 15.01.2015

Уважаемые Форумчане,

Принимая во внимание замечания и предложения, а особенно констуктивизм сансэя Maverik, немного оптимизировал код.

Правда не дошел еще до использования EEPROM, что-то меня все равно останавливает. Использовать Flash-память не хочу категорически. Подобные проекты с Flash на иноязычных сайтах видел, не вдохновили. Андрей, Вам огромное спасибо, я еще разбираюсь с режимами сна и бодорствования. Хочется не просто скопировать решение, а плотно поместить его в голову. Код писал под тренировочную Arduino UNO3 и другую модель Nokia5110 (синюю). Так что код немного отличается по подключениям. Благодаря совместным усилиям и помощи участников форума удалось уменьшить размер кода - 25112 байт из 32256. Прилагаю новую промежуточную версию кода и жду новых комментариев и предложений по его оптимизации. Кстати, схема проверена на макетке, все работает.

/*********************************
Проект "Барограф"
При включении питания, при перезагрузке Arduino путем нажатия на Reset, или при нажтии кнопки Select
на экране отображается меню установок SETUP MENU. В этом режиме, нажимая на кнопку Select выбираем
предел измерений атмосферного давления. Нажав на кнопку Start, выходим из меню настроек и начинает работать
основная программа. 

mmHg    Pa
730    97309
735    97976
740    98642
745    99309
750    99975
755   100642
760   101308
765   101975
770   102641
                         Pmin  Pmax
РЕЖИМ 0:(730-770 ммHg = 97309 -102641 Pa)
РЕЖИМ 1:(730-740 ммHg = 97309 - 98642 Pa)
РЕЖИМ 2:(735-745 ммHg = 97976 - 99309 Pa)
РЕЖИМ 3:(740-750 ммHg = 98642 - 99975 Pa)
РЕЖИМ 4:(745-755 ммHg = 99309 -100642 Pa)
РЕЖИМ 5:(750-760 ммHg = 99975 -101308 Pa)
РЕЖИМ 6:(755-765 ммHg = 100642-101975 Pa)
РЕЖИМ 7:(760-770 ммHg = 101308-102641 Pa)

************* Подключение дисплея Nokia 5110 к Arduino UNO **************
// VCC ---------------------------------------- +3.3v
// BL ----------------------------------------- +3.3v через кнопку подсветки
// GND------------------------------------------------------- к общему GND
// RST--------------------------------------------- pin 7 Arduin UNO
// SE (LCD chip select (CS)-------- через R=10 kOm pin 6 Arduino UNO
// DC (Data/Command select)-------- через R=10 kOm pin 5 Arduino UNO 
// Din (Serial data out (DIN)-- через R=10 kOm pin 4 Arduino UNO
// Clk (Serial clock out (SCLK)---- через R=10 kOm pin 3 Arduino UNO

************** Подключение датчика BMP085 к Arduino ProMicro *****************
// VCC----- VCC +3,3v ArduinoUNO
// SDA---  pin SDA ArduinoUNO
// SCL---  pin SCL ArduinoUNO
// XCLR------------- не используется
// EDC-------------- не используется 
// GND----------------- к общему GND
************** Подключение кнопок ********************************************
// Кнопка Select ------------------  pin 9 ArduinoUNO (выбора режима). Pin 9 через R=10 kOm подтянут к GND
// Кнопка Start -------------------  pin 10 ArduinoUNO(построение графика). Pin 10 через R=10 kOm подтянут к GND
**********************************/

#include <Wire.h>              // библиотека шины получения и передачи данных
#include <BMP085.h>            // библиотека для работы с датчиком давления BMP085
#include <Adafruit_GFX.h>      // библиотека для работы дисплея Nokia5110
#include <Adafruit_PCD8544.h>
#include <TimeHelpers.h>       // библиотека для работы с периодами времени

//Инициализируем дисплей на указанных пинах ArduinoUNO
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 6, 7);

BMP085 dps = BMP085();     // Модель Digital Pressure Sensor - BMP085

long Pressure = 0; // переменная для получения данных с датчика давления

long Pmax = 0; // переменная для установки максимального значения давления
long Pmin = 0; // переменная для установки минимального значения давления

int But_Select = 9; // На pin 9 Arduino подключаем кнопку Select (выбора режима). Pin 9 через R=10 kOm подтянут к GND
int But_Start = 10; // На pin 10 Arduino подключаем кнопку Start (построение графика). Pin 10 через R=10 kOm подтянут к GND

int flag = 0;   // переменная /флаг/ для работы кнопки Select
int regim = 0;  // переменная - номер режима работы

boolean Status = false; // переменная статусизначально принимает значение false. Применяется для выхода из цикла "while (Status == false)"

int cycle = 0; // Значение переменной - шаг изменения при выполнении цикла for
int x = 70;    // Значение переменной Х - х координата дисплея
int y = 0;     // Значение переменной Y – y координата дисплея
int z = 47;    // координата z – 48-я строка дисплея(нижняя) по оси y для
               // привязки линии от значения температуры к нулевому уровню


/*-------------- Настройка времени работы циклов измерения давления --------------------------*/

//#define Diagram_interval _SEC_(608)  // переодичность вывода данных на дисплей (608 cекунд)
#define Diagram_interval _SEC_(2)  // переодичность вывода данных на дисплей (60 cек.)

// объявляем переменные у0 - у70 и присваиваем им значение 47.
// При первом цикле получения данных горизонтальная линия на 47 позиции в виде 70 точек
int y0=47, y1=47, y2=47, y3=47, y4=47, y5=47, y6=47, y7=47, y8=47, y9=47, y10=47, y11=47, y12=47, y13=47, y14=47, y15=47, 
y16=47, y17=47, y18=47, y19=47, y20=47, y21=47, y22=47, y23=47, y24=47, y25=47, y26=47, y27=47, y28=47, y29=47, y30=47, y31=47,
y32=47, y33=47, y34=47, y35=47, y36=47, y37=47, y38=47, y39=47, y40=47, y41=47, y42=47, y43=47, y44=47, y45=47, y46=47, y47=47,
y48=47, y49=47, y50=47, y51=47, y52=47, y53=47, y54=47, y55=47, y56=47, y57=47, y58=47, y59=47, y60=47, y61=47, y62=47, y63=47,
y64=47, y65=47, y66=47, y67=47, y68=47, y69=47, y70=47; 

long v0=47, v1=47, v2=47, v3=47, v4=47, v5=47, v6=47, v7=47, v8=47, v9=47, v10=47, v11=47, v12=47, v13=47, v14=47, v15=47, 
v16=47, v17=47, v18=47, v19=47, v20=47, v21=47, v22=47, v23=47, v24=47, v25=47, v26=47, v27=47, v28=47, v29=47, v30=47, v31=47,
v32=47, v33=47, v34=47, v35=47, v36=47, v37=47, v38=47, v39=47, v40=47, v41=47, v42=47, v43=47, v44=47, v45=47, v46=47, v47=47,
v48=47, v49=47, v50=47, v51=47, v52=47, v53=47, v54=47, v55=47, v56=47, v57=47, v58=47, v59=47, v60=47, v61=47, v62=47, v63=47,
v64=47, v65=47, v66=47, v67=47, v68=47, v69=47, v70=47; 


void setup ()
{
  Wire.begin();       // старт шины данных
  display.begin();    // старт дисплея
  delay(500);         // время на инициализацию датчика и дисплея
 
  dps.init(MODE_ULTRA_HIGHRES, 9000, true); 
  /*
  значение 9000 см = 90 метров - истинная высота Хабаровска над уровнем моря,
  давление будет рассчитываться на основе этой величины.
  Примечание: используйте функцию zeroCal после инициализации датчика.
  dps.zeroCal (101800, 0); // Установить нулевую точку
  */
    
  display.setContrast(60);  // регулировка контраста изображения
  display.clearDisplay();   // Очистка экрана и буфера дисплея
}


void loop()
{
 // усли не нажата кнопка Select и изначально установленное значение 
 // переменной Status = false,- при каждом запуске (Reset)
 // выполняем подпрограмму установок меню
 if((digitalRead(But_Select) == LOW) && (Status == false))
  {
   SetupMenu();
  }
// при нажатии кнопки Select изменяем значение Status на false,
// тем самым даем команду на вход в цикл SetupMenu while (Status == false)
  if (digitalRead(But_Select) == HIGH)
   {
    Status = false;
    return; // игнорируем оставшуюся часть кода
   }

Diagram(); // Выполняем подпрограмму построения графика давления

// выполняем подпрограмму периодичного измерения давления Meterage()
// с переодичностью, установленной в коде для переменной Diagram_interval (сек).
DO_EVERY(Diagram_interval,
  {
   Meterage();
  }
  );
 
} // завершаем цикл void loop



//==============================================================//
//----------------- ПОДПРОГРАММА УСТАНОВОК МЕНЮ ----------------//
//==============================================================//
void SetupMenu()
{
 while (Status == false) // крутим цикл, пока условие(false) на станет ложным
     {              
       /********** Устанавливаем режим работы кнопки Select *************/
       // при нажатии кнопки Select значение regim увеличиваем на 1
       if(digitalRead(But_Select) == HIGH && flag == 0) 
        { 
         regim ++;
         flag = 1;

         if(regim > 7) // Если номер режима превышает требуемый
          {
           // то отсчет начинается с нуля
           regim = 0;
          }
       }

      if(digitalRead(But_Select) == LOW && flag == 1)
       {
        flag = 0;
       } 
     /***************************************************/

  dps.getPressure(&Pressure); // получаем данные о давлении
  delay (50); 
  
  /************** Оформляем экран "SETUP MENU" *************/ 
       
     display.setTextSize(1);
     display.setTextColor(BLACK);
     display.setCursor(11,0);
     display.println("SETUP MENU");
     display.setCursor(3,10);
     display.println("BORDER VALUES");
          
display.setCursor(0,20);

switch (regim)
{
//РЕЖИМ 0:
case 0:
{
display.println("730 - 770 mmHg");
break;
}
// РЕЖИМ 1:
case 1:
{
display.println("730 - 740 mmHg");
break; 
}
// РЕЖИМ 2:
case 2:
{
display.println("735 - 745 mmHg"); 
break;
}
// РЕЖИМ 3:
case 3:
{
display.println("740 - 750 mmHg"); 
break;
}
// РЕЖИМ 4:
case 4:
{
display.println("745 - 755 mmHg"); 
break;
}
// РЕЖИМ 5:
case 5:
{
display.println("750 - 760 mmHg"); 
break;
}
// РЕЖИМ 6:
case 6:
{
display.println("755 - 765 mmHg"); 
break;
}
// РЕЖИМ 7:
case 7:
{
display.println("760 - 770 mmHg"); 
break;
}
} // закрываем switch (regim)


    display.setCursor(3,30);
    display.println("CURRENT PRESS");
    display.setCursor(17,40);
    display.print (Pressure/133.3); // выводим текущее атм. давление в ммРтСт.
    display.println ("Hg");

    display.display(); // все нарисованное выводим на экран дисплея
    display.clearDisplay(); // очищаем экран и буфер дисплея

// при нажатии кнопки Start изменяем значение Status на true,
// тем самым даем команду на выход из цикла while (Status == false)
              if (digitalRead(But_Start) == HIGH)
               {
                Status = true;
                Diagram(); // начинаем выполнение подпрограммы построения графика давления
               }
  } // закрываем цикл while (Status == false) 
} // закрываем void SetupMenu()
/**************************************************************/


//==============================================================//
//------- ПОДПРИГРАММА ПЕРИОДИЧНОСТИ ИЗМЕРЕНИЙ ДАВЛЕНИЯ --------//
//==============================================================//
void Meterage ()
{
dps.getPressure(&Pressure); // получаем данные о давлении
delay (50);

// последовательно изменяем значение давления « v » на предыдущее при каждом цикле замера
v70 = v69; v69 = v68; v68 = v67; v67 = v66; v66 = v65; v65 = v64; v64 = v63; v63 = v62; v62 = v61; v61 = v60;
v60 = v59; v59 = v58; v58 = v57; v57 = v56; v56 = v55; v55 = v54; v54 = v53; v53 = v52; v52 = v51; v51 = v50;
v50 = v49; v49 = v48; v48 = v47; v47 = v46; v46 = v45; v45 = v44; v44 = v43; v43 = v42; v42 = v41; v41 = v40;
v40 = v39; v39 = v38; v38 = v37; v37 = v36; v36 = v35; v35 = v34; v34 = v33; v33 = v32; v32 = v31; v31 = v30;
v30 = v29; v29 = v28; v28 = v27; v27 = v26; v26 = v25; v25 = v24; v24 = v23; v23 = v22; v22 = v21; v21 = v20; 
v20 = v19; v19= v18; v18 = v17; v17 = v16; v16 = v15; v15 = v14; v14 = v13; v13 = v12; v12 = v11; v11 = v10; 
v10 = v9; v9 = v8; v8 = v7; v7 = v6; v6 = v5; v5 = v4; v4 = v3; v3 = v2; v2 = v1; v1 = v0; v0 = Pressure;

} // закрываем void meterage ()


//==============================================================//
//--------------- ПОДПРОГРАММА ПОСТРОЕНИЯ ГРАФИКА --------------//
//==============================================================//
void Diagram()
{
  dps.getPressure(&Pressure); // получаем данные о давлении
  delay (50);
  
 /********* Оформляем экран ***********/
    display.setTextSize(1);
    display.setTextColor(BLACK);
    
// В соответствии с выбранным режимом измерений, устанавливаем значение мин и мах давление отображаемое на графике
// В зависимости от выбранных пределлов границ измерений рисуем отметки значений давления
switch (regim)
{

//РЕЖИМ 0:
case 0:
{
  Pmin = 97309; Pmax = 102641; 
    display.setCursor(66,0);
    display.println("770");
    display.setCursor(72,10);
    display.println("60");
    display.setCursor(72,21);
    display.println("50");
    display.setCursor(72,32);
    display.println("40");
    display.setCursor(72,41);
    display.println("30");
    break;
}

// РЕЖИМ 1:
case 1:
{
  Pmin = 97309; Pmax = 98642; 
    display.setCursor(66,0);
    display.println("740");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("35");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("30");
    break;
}

// РЕЖИМ 2:
case 2:
{
  Pmin = 97976; Pmax = 99309; 
    display.setCursor(66,0);
    display.println("745");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("40");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("35"); 
    break; 
}

// РЕЖИМ 3:
case 3:
{
  Pmin = 98642; Pmax = 99975;
    display.setCursor(66,0);
    display.println("750");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("45");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("40");
    break;
}

// РЕЖИМ 4:
case 4:
{
  Pmin = 99309; Pmax = 100642;
    display.setCursor(66,0);
    display.println("755");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("50");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("45");
    break;
}

// РЕЖИМ 5:
case 5:
{
  Pmin = 99975; Pmax = 101308;
    display.setCursor(66,0);
    display.println("760");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("55");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("50");
    break;
}

// РЕЖИМ 6:
case 6:
{
  Pmin = 100642; Pmax = 101975;
    display.setCursor(66,0);
    display.println("765");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("60");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("55");
    break;
}

// РЕЖИМ 7:
case 7:
{
  Pmin = 101308; Pmax = 102641;
    display.setCursor(66,0);
    display.println("770");
    display.setCursor(72,10);
    display.println("<=");
    display.setCursor(72,21);
    display.println("65");
    display.setCursor(72,32);
    display.println("<=");
    display.setCursor(72,41);
    display.println("60");
    break;
}
} // закрываем switch (regim)

 /*************** Рисуем значение текущего давления ********************/  
    display.setCursor(0,0);
    display.print (Pressure/133.3); // выводим текущее атм. давление переведя его в мм Рт.Ст.
    display.print ("Hg");
    
/**************** Готовим данные для вывода на график ********************/

//Значение Y (высоту линий графика 0-47) приводим пропорционально к параметрам измеряемого давления
// формируем массив из 71-го значения данных, которые будут выводиться на дисплей
int arrayDraw [71] =
{ 
y0 = map(v0, Pmin, Pmax, 47, 1),
y1 = map(v1, Pmin, Pmax, 47, 1), 
y2 = map(v2, Pmin, Pmax, 47, 1), 
y3 = map(v3, Pmin, Pmax, 47, 1),
y4 = map(v4, Pmin, Pmax, 47, 1), 
y5 = map(v5, Pmin, Pmax, 47, 1), 
y6 = map(v6, Pmin, Pmax, 47, 1), 
y7 = map(v7, Pmin, Pmax, 47, 1), 
y8 = map(v8, Pmin, Pmax, 47, 1), 
y9 = map(v9, Pmin, Pmax, 47, 1), 
y10 = map(v10, Pmin, Pmax, 47, 1), 
y11 = map(v11, Pmin, Pmax, 47, 1), 
y12 = map(v12, Pmin, Pmax, 47, 1), 
y13 = map(v13, Pmin, Pmax, 47, 1), 
y14 = map(v14, Pmin, Pmax, 47, 1), 
y15 = map(v15, Pmin, Pmax, 47, 1), 
y16 = map(v16, Pmin, Pmax, 47, 1), 
y17 = map(v17, Pmin, Pmax, 47, 1), 
y18 = map(v18, Pmin, Pmax, 47, 1), 
y19 = map(v19, Pmin, Pmax, 47, 1), 
y20 = map(v20, Pmin, Pmax, 47, 1),
y21 = map(v21, Pmin, Pmax, 47, 1), 
y22 = map(v22, Pmin, Pmax, 47, 1), 
y23 = map(v23, Pmin, Pmax, 47, 1), 
y24 = map(v24, Pmin, Pmax, 47, 1), 
y25 = map(v25, Pmin, Pmax, 47, 1), 
y26 = map(v26, Pmin, Pmax, 47, 1), 
y27 = map(v27, Pmin, Pmax, 47, 1), 
y28 = map(v28, Pmin, Pmax, 47, 1), 
y29 = map(v29, Pmin, Pmax, 47, 1), 
y30 = map(v30, Pmin, Pmax, 47, 1),
y31 = map(v31, Pmin, Pmax, 47, 1),
y32 = map(v32, Pmin, Pmax, 47, 1),
y33 = map(v33, Pmin, Pmax, 47, 1),
y34 = map(v34, Pmin, Pmax, 47, 1),
y35 = map(v35, Pmin, Pmax, 47, 1),
y36 = map(v36, Pmin, Pmax, 47, 1),
y37 = map(v37, Pmin, Pmax, 47, 1),
y38 = map(v38, Pmin, Pmax, 47, 1),
y39 = map(v39, Pmin, Pmax, 47, 1),
y40 = map(v40, Pmin, Pmax, 47, 1),
y41 = map(v41, Pmin, Pmax, 47, 1),
y42 = map(v42, Pmin, Pmax, 47, 1),
y43 = map(v43, Pmin, Pmax, 47, 1),
y44 = map(v44, Pmin, Pmax, 47, 1),
y45 = map(v45, Pmin, Pmax, 47, 1),
y46 = map(v46, Pmin, Pmax, 47, 1),
y47 = map(v47, Pmin, Pmax, 47, 1),
y48 = map(v48, Pmin, Pmax, 47, 1),
y49 = map(v49, Pmin, Pmax, 47, 1),
y50 = map(v50, Pmin, Pmax, 47, 1),
y51 = map(v51, Pmin, Pmax, 47, 1),
y52 = map(v52, Pmin, Pmax, 47, 1),
y53 = map(v53, Pmin, Pmax, 47, 1),
y54 = map(v54, Pmin, Pmax, 47, 1),
y55 = map(v55, Pmin, Pmax, 47, 1),
y56 = map(v56, Pmin, Pmax, 47, 1),
y57 = map(v57, Pmin, Pmax, 47, 1),
y58 = map(v58, Pmin, Pmax, 47, 1),
y59 = map(v59, Pmin, Pmax, 47, 1),
y60 = map(v60, Pmin, Pmax, 47, 1),
y61 = map(v61, Pmin, Pmax, 47, 1),
y62 = map(v62, Pmin, Pmax, 47, 1),
y63 = map(v63, Pmin, Pmax, 47, 1),
y64 = map(v64, Pmin, Pmax, 47, 1),
y65 = map(v65, Pmin, Pmax, 47, 1),
y66 = map(v66, Pmin, Pmax, 47, 1),
y67 = map(v67, Pmin, Pmax, 47, 1),
y68 = map(v68, Pmin, Pmax, 47, 1),
y69 = map(v69, Pmin, Pmax, 47, 1),
y70 = map(v70, Pmin, Pmax, 47, 1)};

/**************** Рисуем график ********************/
for (cycle = 0; cycle <71; cycle ++) // 71 цикл вывода 71-ой линии на дисплей
   {
    // рисуем линии на позициях от х=70 до х=0 справа налево с значениями, полученными из массива
    // с номерами согласно циклу от 0 до 71, значениями, равными от=у0 до у=70)
    display.drawLine (70-cycle, arrayDraw [cycle], 70-cycle, z, BLACK);    
    } 

display.display(); // все нарисованное выводим на экран дисплея

if (cycle >70)  // Если значение циклов cycle достигло значения больше 70 (экран дисплея заполнен)
  {
   cycle = 0;
/* номер цикла приобретает значение = 0, начинаем убирать значение с позиции по х=0
на его месте размещаем значение с поз.1, на его - с поз.2 и так далее.
Самое свежее значение выводится на позиции 70, остальные сдвигаются на 1 влево. Самое старое
значение, полученное 71 цикл назад, удаляется безвозвратно. */
  }

display.clearDisplay(); // очищаем дисплей

} // завершаем подпрограмму void Diagram()
/*********************************************************/

 

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Добрый день Сергей.

Вроде вник в ваш код. Maverik кругом прав(правда грубовато….. и не конкретно). Попробую конкретизировать …… (только ,прошу прощения, без синтаксиса…. )

Строки 088-098 – объявляем массив из 72 элементов , если нужна полоска присваиваем по всем индексам(читай адресам)массива одно и тоже число (47)(Прокрутим один цикл). Кстати от второй переменной я бы отказался (ниже будет ясно почему).

Строки 275-282  - я бы не стал перезаписывать все ячейки . Считаем периоды измерений и пишем последовательно в ваш массив меняя индекс от 0 до 71(индексом будет номер измерения).

Ручная установка режимов просмотра?

Сомневаюсь что за всё время построения графика давление (в мм) может измениться больше чем на вертикальный размер графика (в пикселях).

Читаем текущее давление и автоматически ставим плюс - минус 5-10мм.(крайние значения рисуем на графике).

Преобразование каждого измеренного и записанного в массив (или в память) давления в высоту линий(столбцов) ……….. стр450 и дальше……

После получения данных о давлении  (стр 291 ) сразу преобразовываем абсолютную величину давления (ну не нужна она больше!!!!) в высоту столбца ……. Я просто отнимал текущее давление от какой то величины и получал сразу высоту столбца . Если сделать наоборот (что то отнимать от давления) то график перевернётся (при повышении давления столбец будет меньше).Есть, правда, вариант изменять координаты линий при выводе на дисплей.

 И уже его пишите в ваш (единственный) массив…..   Надобность во второй переменной(упоминал выше) отпадает.

При выводе графика на экран цикл стартует с текущего индекса массива в обратном направлении . При переходе через ноль возвращаемся к конечному индексу массива.(Это вместо перезаписи со сдвигом)

 

Вроде – всё.

Не пытайтесь изменить всё и сразу .

Посмотрите этот скетч. Что то может быть и понравится(особенно 12.192 байта). Реализовано автоматическое переключение режимов. Считка в обратном порядке с текущего адреса ……

/* Вариант не окончательный
   Введена переменная при записи в зависимости от текущего 
   давления при записи в память для того чтобы растянуть 
   график по вертикали до 10мм давления на всю вертикаль
   (те же "режимы" только в автомате) и прорисованы на графике "min" и "max".
   Время цикла и колличество циклов установлены для настройки.
   (Цикл - 8сек. Кол-во - 450 (изменения - 1раз в час). График 72 столбца - трое суток.)
   (540 циклов - 60столбцов - трое суток - на дисплее пределы отображения графика) 
   Почистить .... Убрать всё лишнее.... Получше прокоментировать.... 
   
 */


   #include <Adafruit_GFX.h>
   #include <Adafruit_PCD8544.h>
   #include <Adafruit_BMP085.h>
   #include <Wire.h>
   #include <avr/sleep.h>
   #include <avr/wdt.h>
   #include <EEPROM.h>
   #define CNT 2             //  количество циклов по 8 секунд от работы до работы
   int count1 = 0 ;          //  переменная для счётчика циклов по 8 сек
   volatile boolean wdt_tripped=1;
   ////////////  активизируем дисплей  //////////////////
   Adafruit_PCD8544 display = Adafruit_PCD8544(4, 5, 6, 7, 8);
   /////////// активизируем датчик давления ////////////
   Adafruit_BMP085 bmp;
   int Press  = 0 ;        //  переменная  давление
   byte PressEP    ;       //  высота столбца в памяти
   byte addressP = 0;      //  адрес записи высоты столбца 
   int adresP      ;       //  адрес считывания высоты столбца 
   byte cycle = 0  ;       //  колличество столбцов в графике
   int adrP = 59 ;         //  место столбца графика
   int cons = 0 ;          //  константа высоты столбца

void setup()
{
   wdt_disable();          //  активация пробуждения 
   wdt_reset();            //  по сторожевому таймеру
   wdt_enable(WDTO_2S);    //  каждые 8 сек (меньше - для настройки)             
   Wire.begin();
   bmp.begin();            //  
   
   display.begin();        //  старт дисплея
   delay(500); 
   display.setContrast(55);
   display.clearDisplay();
   Serial.begin(9600); 
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
}

void loop()
{
  // просыпаемся смотрим сколько циклов по 8 сек. спали
   wdt_interrupt_mode(); 
   if (wdt_tripped ==1) 
 {
   count1++;
   wdt_tripped = 0; 
   if (count1 == CNT)                   //  если уже "пора" 
   {  
  /////////////  устанавливаем константу величины столбца в зависимости от текущего давления /////////////////
  //  784(760 - 770); 774(750 - 760); 764(740 - 750); 754(730 - 740)
  
  Press = bmp.readPressure()/133.3;
  if ( Press < 770)
  {cons = 784;}
  if ( Press < 760)
  {cons = 774;}
  if (Press < 750)
  {cons = 764;}
  if (Press < 740)
  {cons = 754;}
  //Serial.println(cons);
  //delay(100);
  
  /////////////  пишем высоту столбца в EEPROM /////////////////////////////
   
   EEPROM.write(addressP,(cons - Press)*2);  // от константы отнимаем текущее давление , вписываем 10мм давления  в (48 - 28) величину столбца, 1мм давления-2пикселя
                                            
   grafik();                                //  рисуем график       
   addressP = addressP + 1;                 //  устанавливаем следующий адрес  
   if (addressP >= 60)                      //  адреса 0 - 60
   {addressP = 0;}
   count1 = 0;      
 }
 }
    //   и снова "баюшки"
    sleepNow();
}
                     //////  ФУНКЦИИ  //////

/////////////////  рисуем график  ////////////////////////
  void grafik()
  { 
    display.clearDisplay();                //  очищаем дисплей
    Pressing();                            //  рисуем текущее давление и все надписи
    display.setTextColor(BLACK);
    adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle <60; cycle ++)   //  60 циклов вывода линий на дисплей
    { 
    stolb();
    }
    display.display();
    delay(100);
  }
//////////////  текущее давление и все надписи на дисплей //////////////
  void Pressing()
 {  
   display.clearDisplay();
   display.setTextSize(2);             // покрупнее
   display.setTextColor(BLACK);
   display.setCursor(0,0);
   display.println(Press);             // давление 
   display.println("мм");
   display.setTextSize(1);
   display.setCursor(1,17);
   display.println("<-72часа->");
   display.setCursor(60,21);
   display.println("_");   
   ////////////  пределы отображения давления  ////////////
   display.setCursor(66,27);
   if (cons == 784)
   {display.println("770");}        
   if (cons == 774)
   {display.println("760");}
   if (cons == 764)
   {display.println("750");}
   if (cons == 754)
   {display.println("740");}
   //display.setCursor(63,34);
   //display.println("-");
   display.setCursor(60,41);
   if (cons == 784)
   {display.println("_760");}
   if (cons == 774)
   {display.println("_750");}
   if (cons == 764)
   {display.println("_740");}
   if (cons == 754)
   {display.println("_730");}
 
   display.display();
 }
 //////////////// прорисовка одного столбца  ///////
 void stolb()
 { 
   PressEP = EEPROM.read(adresP);                     //  читаем из памяти высоту столбца
   display.drawLine (adrP, PressEP, adrP,48, BLACK);  // рисуем столбец (PressEP вместо 48 - получим одну линию)

   adrP = adrP - 1;                                   // устанавливаем место следующего столбца
   if (adrP < 0)                                      // следим за местом
   {adrP = 59 ; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = 59 ;}   
 }

 ///////////  здесь мы просто просыпаемся
   void wdt_interrupt_mode() 
   {
   wdt_reset();
   WDTCSR |= _BV(WDIE);                 // Restore WDT interrupt mode
   }
   ISR(WDT_vect) 
   {
   wdt_tripped=1;                       // set global volatile variable
   }

/////////////  а здесь засыпаем 
   void sleepNow()   
{
   _SFR_BYTE(ADCSRA) &= ~_BV(ADEN);
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // Здесь устанавливается режим сна
   sleep_enable();                        // Включаем sleep-бит в регистре mcucr. Теперь возможен слип 
   _SFR_BYTE(ADCSRA) |= _BV(ADEN);
   sleep_mode();                          // Здесь устройство перейдет в режим сна!!!
}
//////////  НО ЧИСТИТЬ ВСЁ РАВНО НАДО!!!!!   /////////

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015
И ещё ......
Читаем - "Li-Pol аккумулятор maxU-4.2V  , minU-3.0V при норме 3.6 - 3.7V"
"Arduino Pro Mini  Входное напряжение  3.35-12 В (модель 3.3 В)".
Выкидываем повышающий стабилизатор. АКБ напрямик к RAW(вход стабилизатора. см.схему Arduino Pro Mini)  Подсветку напрямик к АКБ. SunX и trembo это имели ввиду.
Светодиод на х... с платы (или резистор идущий на него). При желании АКБ на один из аналоговых входов(через делитель), пять строчек  кода и на дисплее уровень зарядки АКБ ....... Это даже желательно потому что стабилизатор на дуинке сам может оказаться повышающим (Перекопал все стабилизаторы в таком корпусе... TPS71533DCKR  "Входное напряжение 2.5...24 В"........; LP2985-33DBVR  Входное напряжение  МИН.+ 2.2 V  ...... ну и т.д. ) Хотя -  "Arduino Pro Mini  Входное напряжение  3.35-12 В (модель 3.3 В)" .... Чёрт их знает что они поставили......
Sergey_Ch
Offline
Зарегистрирован: 15.01.2015

Уважаемый Андрей,

благодарю Вас за присланные материалы. Код компилируется, обязательно учту Ваши рекомендации. Грядут Выходные дни, займусь делом. О результате доложу. Еще раз спасибо.

Maverik
Offline
Зарегистрирован: 12.09.2012
другую модель Nokia5110 (синюю).

на всякий случай поясню - синяя модель дисплея NOKIA 5110 это та же красная, только чуть по другому расположены и названы пины.

ну и печатная плата чуть по другому разведена. вот различия в пинах:

а вот соответствие разных версий названий пинов.

99% проблем с этим дисплеем - это то, что народ путается в названиях пинов, а производители маркируют их как бог на душу положит.

SCK=CLK = SCK = SCLK = пин тактовой частоты

MOSI=DN = SDIN = DIN = serial data in = пин входящих данных 

CS=CE = SCE = chip select  = выбор чипа шины SPI

A0=DC = D/C  = data/command selector = переключатель данные/комманды

Reset = RST = сброс

LED = BLK = backlight = подсветка

VCC = питание  (3.3 вольта !)

подключать нужно все кроме  LED.  LED можно не подключать, просто не будет подсветки.

т.е. для подключения этого дисплея нужно 5 цифровых пинов, питание 3.3вольт и земля.

aleksrulevoi
Offline
Зарегистрирован: 25.05.2015

Доброго времени суток. Андрей1963  А как в вашем скетче устанавливать поправку на высоту?

soznik
Offline
Зарегистрирован: 20.09.2015

aleksrulevoi пишет:

Доброго времени суток. Андрей1963  А как в вашем скетче устанавливать поправку на высоту?

Я в setup добавил строчку  dps.init(MODE_ULTRA_HIGHRES, 12000, true);

где 12000 это 120 метров.

Ещё добавил вольтметр.

aleksrulevoi
Offline
Зарегистрирован: 25.05.2015

Доброго времени суток. Пробовал добавить в скетч, не компилируется. 

barometr.ino: In function 'void setup()':
barometr:44: error: 'dps' was not declared in this scope
barometr:44: error: 'MODE_ULTRA_HIGHRES' was not declared in this scope
Multiple libraries were found for "EEPROM.h"
 Used: C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM
 Not used: C:\Program Files (x86)\Arduino\libraries\AT24C32_TEST
'dps' was not declared in this scope
Ошибка такая. Скетч от поста 38.
 
soznik
Offline
Зарегистрирован: 20.09.2015

Да посмотрел действительно много чего изменил.

/* Вариант не окончательный
   Введена переменная при записи в зависимости от текущего 
   давления при записи в память для того чтобы растянуть 
   график по вертикали до 10мм давления на всю вертикаль
   (те же "режимы" только в автомате) и прорисованы на графике "min" и "max".
   Время цикла и колличество циклов установлены для настройки.
   (Цикл - 8сек. Кол-во - 450 (изменения - 1раз в час). График 72 столбца - трое суток.)
   (540 циклов - 60столбцов - трое суток - на дисплее пределы отображения графика) 
   Почистить .... Убрать всё лишнее.... Получше прокоментировать.... 
   
 */

    #include <SPI.h>
   #include <Adafruit_GFX.h>
   #include <Adafruit_PCD8544.h>
   #include <BMP085.h> 
   #include <Wire.h>
   #include <avr/sleep.h>
   #include <avr/wdt.h>
   #include <EEPROM.h>
   #define CNT 180             //  количество циклов по 8 секунд от работы до работы
   int count1 = 0 ;          //  переменная для счётчика циклов по 8 сек
   volatile boolean wdt_tripped=1;
   ////////////  активизируем дисплей  //////////////////
   Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 2, 8);
   /////////// активизируем датчик давления ////////////
   BMP085 dps = BMP085();     // Модель Digital Pressure Sensor - BMP085
   float Press  = 0 ;        //  переменная  давление
   byte PressEP    ;       //  высота столбца в памяти
   byte addressP = 0;      //  адрес записи высоты столбца 
   int adresP      ;       //  адрес считывания высоты столбца 
   byte cycle = 0  ;       //  колличество столбцов в графике
   int adrP = 59 ;         //  место столбца графика
   int cons = 0 ;          //  константа высоты столбца
   const int analogInPin = A0;  // Analog input pin 
   float sensorValue = 0;        
   float outputValue = 0;        
   long  temp3 = 0, Pressure = 0; // переменная для получения данных с датчика давления
void setup()
{
   wdt_disable();          //  активация пробуждения 
   wdt_reset();            //  по сторожевому таймеру
   wdt_enable(WDTO_8S);    //  каждые 8 сек (меньше - для настройки)             
   Wire.begin();
  Wire.begin();            //  
    dps.init(MODE_ULTRA_HIGHRES, 12000, true); 
   display.begin();        //  старт дисплея
   delay(500); 
   display.setContrast(55);
   display.clearDisplay();
   Serial.begin(9600); 
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
}

void loop()
{
  sensorValue = analogRead(analogInPin);            
  outputValue = float(analogRead(analogInPin))/204,6;
  // 1023 аналог / 5V =204,6
  // просыпаемся смотрим сколько циклов по 8 сек. спали
   wdt_interrupt_mode(); 
   if (wdt_tripped ==1) 
 {
   count1++;
   wdt_tripped = 0; 
   if (count1 == CNT)                   //  если уже "пора" 
   {  
  /////////////  устанавливаем константу величины столбца в зависимости от текущего давления /////////////////
  //  794(770 - 780);784(760 - 770); 774(750 - 760); 764(740 - 750); 
    dps.getPressure(&Pressure); // получаем данные о давлении
 
  Press = Pressure/133.3;
  if ( Press < 780)
  {cons = 794;}
  if ( Press < 770)
  {cons = 784;}
  if (Press < 760)
  {cons = 774;}
  if (Press < 750)
  {cons = 764;}
 
  Serial.print ("pressure:");
  Serial.println(Press);
  delay(100);
  
  /////////////  пишем высоту столбца в EEPROM /////////////////////////////
   
   EEPROM.write(addressP,(cons - Press)*2);  // от константы отнимаем текущее давление , вписываем 10мм давления  в (48 - 28) величину столбца, 1мм давления-2пикселя
                                            
   grafik();                                //  рисуем график       
   addressP = addressP + 1;                 //  устанавливаем следующий адрес  
   if (addressP >= 60)                      //  адреса 0 - 60
   {addressP = 0;}
   count1 = 0;      
 }
 }
    //   и снова "баюшки"
    sleepNow();
}
                     //////  ФУНКЦИИ  //////

/////////////////  рисуем график  ////////////////////////
  void grafik()
  { 
    display.clearDisplay();                //  очищаем дисплей
    Pressing();                            //  рисуем текущее давление и все надписи
    display.setTextColor(BLACK);
    adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle <60; cycle ++)   //  60 циклов вывода линий на дисплей
    { 
    stolb();
    }
    display.display();
    delay(100);
  }
//////////////  текущее давление и все надписи на дисплей //////////////
  void Pressing()
 {  
   display.clearDisplay();
   display.setTextSize(2);             // покрупнее
   display.setTextColor(BLACK);
   display.setCursor(0,0);
   display.print(Press,1);             // давление 
   display.println("мм");
   display.setTextSize(1);
   display.setCursor(1,17);
   display.print("<-24часа->");
   display.println(outputValue,1);
 
   display.setCursor(60,21);
   display.println("_");   
   ////////////  пределы отображения давления  ////////////
   display.setCursor(66,27);
   if (cons == 794)
   {display.println("780");}        
   if (cons == 784)
   {display.println("770");}
   if (cons == 774)
   {display.println("760");}
   if (cons == 764)
   {display.println("750");}
   //display.setCursor(63,34);
   //display.println("-");
   display.setCursor(60,41);
   if (cons == 794)
   {display.println("_770");}
   if (cons == 784)
   {display.println("_760");}
   if (cons == 774)
   {display.println("_750");}
   if (cons == 764)
   {display.println("_740");}
 
   display.display();
 }
 //////////////// прорисовка одного столбца  ///////
 void stolb()
 { 
   PressEP = EEPROM.read(adresP);                     //  читаем из памяти высоту столбца
   display.drawLine (adrP, PressEP, adrP,48, BLACK);  // рисуем столбец (PressEP вместо 48 - получим одну линию)

   adrP = adrP - 1;                                   // устанавливаем место следующего столбца
   if (adrP < 0)                                      // следим за местом
   {adrP = 59 ; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = 59 ;}   
 }

 ///////////  здесь мы просто просыпаемся
   void wdt_interrupt_mode() 
   {
   wdt_reset();
   WDTCSR |= _BV(WDIE);                 // Restore WDT interrupt mode
   }
   ISR(WDT_vect) 
   {
   wdt_tripped=1;                       // set global volatile variable
   }

/////////////  а здесь засыпаем 
   void sleepNow()   
{
   _SFR_BYTE(ADCSRA) &= ~_BV(ADEN);
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // Здесь устанавливается режим сна
   sleep_enable();                        // Включаем sleep-бит в регистре mcucr. Теперь возможен слип 
   _SFR_BYTE(ADCSRA) |= _BV(ADEN);
   sleep_mode();                          // Здесь устройство перейдет в режим сна!!!
}
//////////  НО ЧИСТИТЬ ВСЁ РАВНО НАДО!!!!!   /////////

Вотчто получилось

Изменил диапазон с (730-770) на (740-780)

Вывод (А0) ардуины использовал как вход вольтметра (подключен на аккамулятор)

Добавил дясятичную часть в давлении.

В строке 25 проставьте свои выводы ардуины на индикатор.

aleksrulevoi
Offline
Зарегистрирован: 25.05.2015

Доброго времени суток. Огромное спасибо soznik. Всё компилируется и работает. Остаётся температуру вывести, датчик встроенный в BMP085 достаточно точный.

С уважением Алекс

soznik
Offline
Зарегистрирован: 20.09.2015

В каком месте дисплея разместить показания температуры?

 

aleksrulevoi
Offline
Зарегистрирован: 25.05.2015

  Доброго дня. Так надпись 24 часа в принцепе не нужна. Можно вместо неё. Сейчас плату делаю под барометр. Чисто микроконтроллер, кварц, и конденсаторы. На 3,3 вольта сделаю. Запитаю от литиевого аккумулятора 3,7 в. Думаю пока без стабилизатора.

С уважением Алекс.

soznik
Offline
Зарегистрирован: 20.09.2015

Тогда вот-так

/* Вариант не окончательный
   Введена переменная при записи в зависимости от текущего 
   давления при записи в память для того чтобы растянуть 
   график по вертикали до 10мм давления на всю вертикаль
   (те же "режимы" только в автомате) и прорисованы на графике "min" и "max".
   Время цикла и колличество циклов установлены для настройки.
   (Цикл - 8сек. Кол-во - 450 (изменения - 1раз в час). График 72 столбца - трое суток.)
   (540 циклов - 60столбцов - трое суток - на дисплее пределы отображения графика) 
   Почистить .... Убрать всё лишнее.... Получше прокоментировать.... 
   
 */

    #include <SPI.h>
   #include <Adafruit_GFX.h>
   #include <Adafruit_PCD8544.h>
   #include <BMP085.h> 
   #include <Wire.h>
   #include <avr/sleep.h>
   #include <avr/wdt.h>
   #include <EEPROM.h>
   #define CNT 180             //  количество циклов по 8 секунд от работы до работы
   int count1 = 0 ;          //  переменная для счётчика циклов по 8 сек
   volatile boolean wdt_tripped=1;
   ////////////  активизируем дисплей  //////////////////
   Adafruit_PCD8544 display = Adafruit_PCD8544(4, 5, 6, 7, 8);
   /////////// активизируем датчик давления ////////////
   BMP085 dps = BMP085();     // Модель Digital Pressure Sensor - BMP085
   float temp1 = 0 ;
   float Press  = 0 ;        //  переменная  давление
   byte PressEP    ;       //  высота столбца в памяти
   byte addressP = 0;      //  адрес записи высоты столбца 
   int adresP      ;       //  адрес считывания высоты столбца 
   byte cycle = 0  ;       //  колличество столбцов в графике
   int adrP = 59 ;         //  место столбца графика
   int cons = 0 ;          //  константа высоты столбца
   const int analogInPin = A0;  // Analog input pin 
   float sensorValue = 0;        
   float outputValue = 0;        
   long  temp = 0, Pressure = 0; // переменная для получения данных с датчика давления
void setup()
{
   wdt_disable();          //  активация пробуждения 
   wdt_reset();            //  по сторожевому таймеру
   wdt_enable(WDTO_8S);    //  каждые 8 сек (меньше - для настройки)             
   Wire.begin();
  Wire.begin();            //  
    dps.init(MODE_ULTRA_HIGHRES, 12000, true); 
   display.begin();        //  старт дисплея
   delay(500); 
   display.setContrast(55);
   display.clearDisplay();
   Serial.begin(9600); 
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
}

void loop()
{
  sensorValue = analogRead(analogInPin);            
  outputValue = float(analogRead(analogInPin))/204,6;
  // 1023 аналог / 5V =204,6
  // просыпаемся смотрим сколько циклов по 8 сек. спали
   wdt_interrupt_mode(); 
   if (wdt_tripped ==1) 
 {
   count1++;
   wdt_tripped = 0; 
   if (count1 == CNT)                   //  если уже "пора" 
   {  
  /////////////  устанавливаем константу величины столбца в зависимости от текущего давления /////////////////
  //  794(770 - 780);784(760 - 770); 774(750 - 760); 764(740 - 750); 
    dps.getPressure(&Pressure); // получаем данные о давлении
  dps.getTemperature(&temp);  //получаем данные о температуре
  temp1 = temp/10;
  Press = Pressure/133.3;
  if ( Press < 780)
  {cons = 794;}
  if ( Press < 770)
  {cons = 784;}
  if (Press < 760)
  {cons = 774;}
  if (Press < 750)
  {cons = 764;}
 
  Serial.print ("pressure:");
  Serial.println(Press);
  delay(100);
  
  /////////////  пишем высоту столбца в EEPROM /////////////////////////////
   
   EEPROM.write(addressP,(cons - Press)*2);  // от константы отнимаем текущее давление , вписываем 10мм давления  в (48 - 28) величину столбца, 1мм давления-2пикселя
                                            
   grafik();                                //  рисуем график       
   addressP = addressP + 1;                 //  устанавливаем следующий адрес  
   if (addressP >= 60)                      //  адреса 0 - 60
   {addressP = 0;}
   count1 = 0;      
 }
 }
    //   и снова "баюшки"
    sleepNow();
}
                     //////  ФУНКЦИИ  //////

/////////////////  рисуем график  ////////////////////////
  void grafik()
  { 
    display.clearDisplay();                //  очищаем дисплей
    Pressing();                            //  рисуем текущее давление и все надписи
    display.setTextColor(BLACK);
    adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle <60; cycle ++)   //  60 циклов вывода линий на дисплей
    { 
    stolb();
    }
    display.display();
    delay(100);
  }
//////////////  текущее давление и все надписи на дисплей //////////////
  void Pressing()
 {  
   display.clearDisplay();
   display.setTextSize(2);             // покрупнее
   display.setTextColor(BLACK);
   display.setCursor(0,0);
   display.print(Press,1);             // давление 
   display.println("мм");
   display.setTextSize(1);
   display.setCursor(0,17);
   display.print("t=");
   display.print(temp1,1);
   display.print("*C ");
   //display.print("бат=");
   display.print(outputValue,1);
   display.println("V");
   display.setCursor(60,21);
   display.println("_");   
   ////////////  пределы отображения давления  ////////////
   display.setCursor(66,27);
   if (cons == 794)
   {display.println("780");}        
   if (cons == 784)
   {display.println("770");}
   if (cons == 774)
   {display.println("760");}
   if (cons == 764)
   {display.println("750");}
   //display.setCursor(63,34);
   //display.println("-");
   display.setCursor(60,41);
   if (cons == 794)
   {display.println("_770");}
   if (cons == 784)
   {display.println("_760");}
   if (cons == 774)
   {display.println("_750");}
   if (cons == 764)
   {display.println("_740");}
 
   display.display();
 }
 //////////////// прорисовка одного столбца  ///////
 void stolb()
 { 
   PressEP = EEPROM.read(adresP);                     //  читаем из памяти высоту столбца
   display.drawLine (adrP, PressEP, adrP,48, BLACK);  // рисуем столбец (PressEP вместо 48 - получим одну линию)

   adrP = adrP - 1;                                   // устанавливаем место следующего столбца
   if (adrP < 0)                                      // следим за местом
   {adrP = 59 ; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = 59 ;}   
 }

 ///////////  здесь мы просто просыпаемся
   void wdt_interrupt_mode() 
   {
   wdt_reset();
   WDTCSR |= _BV(WDIE);                 // Restore WDT interrupt mode
   }
   ISR(WDT_vect) 
   {
   wdt_tripped=1;                       // set global volatile variable
   }

/////////////  а здесь засыпаем 
   void sleepNow()   
{
   _SFR_BYTE(ADCSRA) &= ~_BV(ADEN);
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // Здесь устанавливается режим сна
   sleep_enable();                        // Включаем sleep-бит в регистре mcucr. Теперь возможен слип 
   _SFR_BYTE(ADCSRA) |= _BV(ADEN);
   sleep_mode();                          // Здесь устройство перейдет в режим сна!!!
}
//////////  НО ЧИСТИТЬ ВСЁ РАВНО НАДО!!!!!   /////////

У меня питается от литеевого аккумулятора через step-up преобразователь.

т.е. не зависимо от напряжния на аккамуляторе на ардуине 5V.

если вольтметр не нужен закометировать строки 133,134. И в строке 129 можно вписать "Температура"

должно влезть в строку.

aleksrulevoi
Offline
Зарегистрирован: 25.05.2015

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

С уважение Алексей.