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

soznik
Offline
Зарегистрирован: 20.09.2015
unsigned long time = 0;
unsigned long loopTime = 0;

void setup(){
  Serial.begin(9600);
  time = millis();
  delay (100);
}
void loop(){  
  time = millis();
  if(time >= (loopTime + 3000))
   { Serial.println("BARO" ) ;
    loopTime = time; 
    }

   else
  {  Serial.println("BATT" ) ; }    
    
  // delay (1000);  
}

 

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

"if(time >= (loopTime + 3000))"    это ни когда не выполнится потому что следом идёт    "loopTime = time;"

 

Здесь вроде всё написано

http://arduino.ru/tutorials/BlinkWithoutDelay

 

Проверил - моргает....

И ваш код тоже заморгал

unsigned long time = 0;
unsigned long loopTime = 0;
long interval = 1000;      // интервал моргания 
int State = 0;             // статус "чо у нас светиться"  1 - BARO ; 0 - BATT
void setup(){
  Serial.begin(9600);
  time = millis();
  delay (100);
}
void loop(){  
  time = millis();
  if(time - loopTime > 1000)  // отсчитали 
   { 
    loopTime = time;          //выравняли (можно и позже лишь бы в этих  { }
    if (State == 0)           // если у нас горит BATT 
    {State = 1;               // зажгём  BARO
   Serial.println("BARO" ) ; 
    }
                              //  и наоборот
   else
  { State = 0 ; 
  Serial.println("BATT" ) ; }    
      
}
}

И самое главное - ЭТО ни хрена не тормозит программу ............

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

Получилось пришлось ввести ещё одну переменную.

int n =0 ;
unsigned long time ;
unsigned long loopTime;

void setup(){
  Serial.begin(9600);

  delay (100);
}
void loop(){  
  time = millis();
  if(time >= (loopTime + 3000))
   {
    if (n == 0)
      n = 1;
    else
      n = 0;

   loopTime = time;   
     
    }
  if ( n== 0)
  {Serial.println("BARO") ;}
  else 
   {Serial.println("BATT") ;}
}

 

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

А без неё - ни как....

А если ещё одну ввести ( вместо  3000) то можно сделать - в одних условиях медленно моргает , в других - быстро (например когда нет совсем аккумулятора)....

 08    delay (100);  помоему вааще ненужна

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

В примерах всё хорошо в реальном мире не всё гладко.

Там стоит еще один if 

 if ( outputVolt >3.8) 

На каком цикле произошло изменеие то и висит на дисплее .

При введении еще одного значения n вообще всё плохо.

  if ( outputVolt >3.8) 
 {..............
 ..............
 ..............}
 eise
   n=2
if ( n== 0)
  { u8g.drawStr(93,11," "); } 
  else if ( n== 1 )
    { u8g.drawStr(93,11,"BATT"); }
   else if ( n== 2 )
    { u8g.drawStr(93,11,"BARO"); } 

Вечером буду разбиратся.

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

Всё у ВАС прекрасно. 

Насчёт  n=2   это вы зря .....(коментарии в  102 посте упустили ....) Я имел ввиду  что нибуть типа  "interval"  вместо ваших фиксированных 3000.  И задавать значение в зависимости от напряжения .  Типа при   <1     interval = 500  (моргает быстро) ;  при    1< V <= 3.8    -  2000 (моргает медленно). 

И ещё ......  "long time"  и   "long loopTime"  не могут использоваться одновременно в различных функциях (моргалка и измерение давления). Или объявлять их внутри каждой функции , или использовать разные имена в функциях (объявив их в начале кода (по мне - так проще).   millis()  -  одна для всего .  time  =  millis()  -  начало отсчёта какогото интервала .А ВАМ надо отсчитать время для моргалки и время для снятия показаний и постройки графика . Получается билиберда .......   

Всё относящееся к контролю батареи (можно и отдельной функцией) ставте сразу после  void loop()  (включая прорисовку на дисплее). А потом всё остальное.   

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

С переменными  типа "long time"  и   "long loopTime" всё нормально.

Одна общая с барографом а вторая отдельная для вольтметра.

А вот с функцией if  сейчас буду разбиратся. if из под if  неработает. Надо использовать else if.

  if ( outputVolt >3.8) 
   { u8g.drawStr(93,11,"BARO"); 
   Serial.println("BARO" ) ;} 
   else 
   {
   if(tim >= (BatTime + 1000))
    {
    if (n == 0)
    {  n = 1;
    u8g.drawStr(93,11,"____");
    Serial.println("_____" );
     BatTime = tim;  
  }
    else 
     {   n = 0;
    
       u8g.drawStr(93,11,"BATT"); 
     Serial.println("BATT" );} 
    }
    } 

"BARO" выводится нормально , а "_____" и "BATT" одновременно и получается бяка.

 

 

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

Нашел http://arduino.ru/forum/programmirovanie/vopros-po-dop-funktsiyam

Надо if ( условие 1 && условие 2 ) 

Но сначала ужин вчера просидел до 2-х ночи и остался без ужина.

 

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

Ну ВОТ!!!    Если долго мучиться - что нибуть получится !!!

Успеха.

А я наверное остановлюсь на таком варианте --

/* Размеры дисплея позволяют вывести 30мм изменения давления  (  735-765мм  ) при большом шрифте текущего давления ( эт шоб усекать без стёклышков на зенках) 
  По результатам работы(если не хватит 30мм(пикселей высоты) - уберу надпись 48часов или переделаю всё изображение. Рисуем линией без автодиапазона , измерения каждые полчаса , график 48 часов , логотип "BARO" (вместо него будет или  температура или что нибуть ещё) , регулировка яркости подсветки в зависимости от освещения */
Подсветку обкатал - результатом доволен (ночью светиться только чтобы было видно изображение ,  раньше лучше ночника освещало всю комнату).
 
/* Размеры дисплея позволяют вывести 30мм изменения давления 
  По результатам работы(если не хватит 30мм(пикселей высоты) - уберу надпись 48часов или переделаю всё изображение
  рисуем линией без автодиаапазона , измерения каждые полчаса , график 48 часов , логотип "BARO" (вместо него будет или
  температура или что нибуть ещё) , регулировка яркости подсветки в зависимости от освещения */
  
  
////////////////  библиотеки   ///////////////////
   #include <U8glib.h>
   #include <Adafruit_BMP085.h>
   #include <Wire.h>
   #include <EEPROM.h>
   /////////// активизируем дисплей ////////////
   U8GLIB_ST7920_128X64_4X u8g(10, 11, 12);
   /////////// активизируем датчик давления ////////////
   Adafruit_BMP085 bmp;
   ///////////////////переменные/////////////////////
   unsigned long time = 0;        //    текущее время
   unsigned long loopTime = 0;    //    время измерения
   int Press  = 0   ;      //  переменная  давление
   byte PressEP     ;      //  высота столбца в памяти
   byte addressP = 0;      //  адрес записи высоты столбца 
   int adresP = 95  ;      //  адрес считывания высоты столбца 
   byte cycle = 0   ;      //  колличество столбцов в графике
   int adrP = 95    ;      //  место столбца графика   
   int analogPin = 0;      //  вход    фоторезистор на корпус
   int ledPin = 6;         //  выход подсветка

void setup()
{     
   Wire.begin();
   bmp.begin(); 
   digitalWrite(A0,HIGH);   //  включаем внутренний резистор подтяжки к "+"
   pinMode(ledPin, OUTPUT); //  6 пин - выход   

   grafik();                  //    что то изобразить до первого измерения
}

void loop()
{
   int val = analogRead(0);         //  читаем аналоговый вход пишем в переменную  val 
   val = map(val, 25, 1024, 90, 0); //  приводим значения в обратной пропорции к выходу  ШИМа и ограничиваем выходное напряжение
                                    //  25 - min значение на 0 пине,  90 - значение ШИМа при котором достигается желаемый максимум яркости
                                                                   //  может достигать значения 255
   analogWrite(6, val);             //  устанавливаем напряжение на 6 пине в соотв. с освещённостью 
                                    //  при 3,3V подсветка потребляла 14 мА    Выход держит 40мА нагрузки  
                                    //  поэтому не стал ставить ни каких транзисторов   
                                    //  BLA подключен непосредственно к  6 пину
   
 time = millis();
 if(time >= (loopTime + 1800000))          //  если уже "пора"  то   
   {  
  /////////////  пишем высоту столбца в EEPROM /////////////////////////////
   
   EEPROM.write(addressP,(799 - Press));  // от константы отнимаем текущее давление 
   grafik();                                //  рисуем график  
   addressP = addressP + 1;                 //  устанавливаем следующий адрес  
   if (addressP >= 96)                      //  адреса 0 - 95
   {addressP = 0;}
   loopTime = time;   
 }
}

/////////////////  рисуем график  ////////////////////////
void grafik()
  { Press = bmp.readPressure()/133.3;
        u8g.firstPage();                    //   открываем страницу
  do {

    u8g.setFont(u8g_font_timR24);           //  выбираем шрифт
    u8g.setPrintPos(5, 23);                 //  устанавливаем позицию
    u8g.print(Press,1);                     //  рисуем текущее давление
    u8g.setFont(u8g_font_timR08);           //  шрифт поменьше
    u8g.print(" MM");
    u8g.drawRFrame(89,2,35,20,3);
    u8g.setPrintPos(93, 15);
    u8g.print("BARO");
    u8g.setPrintPos(2, 33);
    u8g.print("< ------ 48 chas ------ >");  
    u8g.setPrintPos(1,35);
    u8g.print(".");
    u8g.setPrintPos(94,35);
    u8g.print(".");
    u8g.setPrintPos(1, 37);
    u8g.print("................................ .. ");   
    u8g.setPrintPos(99,49);
    u8g.print("..");
  u8g.setPrintPos(109,42);
    u8g.print("765");
    u8g.setPrintPos(1,64);
    u8g.print("................................ ..  ");
    u8g.print("735");
    adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle <96; cycle ++)   //  96 циклов вывода линий на дисплей
    stolb();                               //  рисуем график отдельными столбцами (96 шт.)
    } while( u8g.nextPage() );             //  закрываем страницу   
  }

 void stolb()
 { 
   PressEP = EEPROM.read(adresP);    //  читаем из памяти высоту столбца
   //u8g.drawLine (adrP, PressEP, adrP ,64);            // рисуем столбец 
   u8g.drawPixel( adrP, PressEP);                   // линия                     (спасибо soznik)
   //u8g.drawLine (adrP, PressEP, adrP ,PressEP+1);   // линия толщиной 2 пикселя  (спасибо soznik)
   adrP = adrP - 1;                                   // устанавливаем место следующего столбца
   if (adrP < 0)                                      // следим за местом
   {adrP = 95 ; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = 95 ;}   
 }

 

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

 Заморгало после пляски с бубнами.

 u8g.drawRFrame(89,0,35,15,3);
    if ( outputVolt >3.8) 
   { u8g.drawStr(93,11,"BARO");} 
 
   else  if
   (outputVolt <3.8 &&  tim >= (BatTime + 2000)  ) 
   {    u8g.drawStr(93,11,"BATT");  
   if
   (tim >=(BatTime + 3000))
    { BatTime = tim; }      }

Всё оказалось очень просто.

Ваш вариант посмотрю завтра . У нас уже полночь.

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

 if из под if-а работает.

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

А у меня пошло без "else" в  5 строке ..........  

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

У меyя тоже пошло без "else". Предидущие варианты возможно то-же были рабочие.

В примерах я проставлял время 3 сек. , а в барограф 1 сек. . Но дисплей не успевал прорисовывать изменения 

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

 Сегодня попробую вариант без переключения диапазона , пока на макетной UNO с синим LED 12864.

Если выводить температуру надо подключать DS18B20  и выводить его за корпус устройства.

С датчика давления показания температуры сильно завышаются.

 

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

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

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

Потому-что дипломный проект ни кто не читает.

P.S  А что-бы конструкция была легче заклепки сделаем из дерева  (по той-же причине ).

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

Нормально!

Я пока завязываю(загрузил последний вариант из поста  109 и поставил на полку). Сутки отработал, график нарисовал - ясно отчего башка трещит..... Последний прикол - хотел запитать от адаптера радиотелефона(он рядом стоит) ...... зараза - АС-АС оказался....(трансформатор с вилкой) Емкеость на Vin  уже давно висела (с предыдущей конструкции) ,как и разъём стандартный (типа как на ноуте). Не стал выёживаться - прямо на провода повесил КЦ407 маленькую шестиногую .....(в термоусадку)  9,1В на Vin-е .... С яркостью подсветки вроде угадал.... Ночью не фигачит как прожектор.... Днём..... наверное надо малость резистором подстроечным контрастность убавить.... Со светом у нас вроде стабильно (тьфу, тьфу, тьфу) - с АКБ заморачиваться не стал ( если читали всю ветку - делал чисто батарейный вариант(функционировал нормально , надобность отпала....). Посмотрим что будет с верхним пределом ..... Может придётся шрифт текущего давления чуть меньше сделать (чтобы весь диапазон изменения давления уместился ....). Пока вроде всё нормально.... Пусть работает. Заполнит полностью график - выложу фотки. Насчт температуры - ВАШа правда (тоже нарвался). У окна уже 2 года висит китайский батарейный ЖКИ с тридцатым семисигментным шрифтом и с выносным датчиком .... (пока нет нужды дублировать его).

Удачи.

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

Поддержу ......(не анекдот.....)

На участке монтажников (человек 60-70 за столами вплотную) две подруги лет сорока - сорока пяти паяют себе цветомузыки из наборов....(продавались в былые времена). С двуногими деталями (включая электролиты и диоды) разобрались . А на транзисторах застопорились. Я (рядом оказался) набил одной  транзисторы в плату и собрался идти на своё рабочее место. Вторая во весь голос - "Андрюх обожди обожди ..... покажи как ты им ноги раздвигал и впихивал......."    Гоголь ....   "отдыхает".

 

soznik  ВЫ где ?

Разница уж больно большая во времени с Тамбовом (привет от волков ("Ссссспасибо .... ты заходи ...., если чо....."))

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

Так в темноте 

 

 

А так при лампочке ...... Вообще то он синий ...... фиг его знает почему на фото такой оттенок.... Телефон мля .....

Приживётся - подумаем о корпусе....

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

Я тоже остановился на последнем варианте и поставил на подоконник. Привыкаю.

Корпус пока делать не буду , есть еще дисплей TFT 2.4" он хоть и меньше но контрастность гораздо лучше.

Метеостанцию собрал в корпус , а сейчас она совсем не интересна без графика.

Смотрю только на показания скорости ветра. Показания влажности с датчиков 

DHT11 (дома) и DHT22 (улица) так-же относительны как и название параметра (относительная влажность).

Теперь о барографе. Оба дисплея (зеленый и синий) у меня с отрицательным углом обзора

т.е наилучшая контрастность под углом 45 градусов от центра к низу.

Прорисовка надписей на синем ещё медленее чем на зелёном.

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

К стати 

 u8g.setPrintPos(93, 15);
    u8g.print("BARO");

и

 {u8g.drawStr(93,11,"BARO");}

одно и тоже только в первом варианте информация хранится в ОЗУ , а во втором во флеше.

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

 

Пока всё.

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

Андрей1963 

Ваш последний вариант не хочет прорисовывать график.

Почему не могу понять кроме мелочи ничего не нашел

Встроках 89 и 101 вместо 64 надо поставить 63 т.к 64 строки с нулевой и в строке 103 тогда   PressEP-1

А почему не тикает не нашел

для проверки я прописал в строке 50  if(time >= (loopTime + 8000)) 

В память данные записываются при сбросе график появляется.

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

Вообще то странно ..... Я забыл флешку с кодом на работе. Пришлось дома скачать код из 109 поста и залить в дуинку. Получилось то что ВЫ видете на фото..... 101-ю и 103-ю строку я не использую..... В 89-й стояло 63 (ну не совсем я дурак то) ......  Один пиксель внизу был не прописан......  Не понял почему .....  Наверное всё таки дурак    :(   (или дисплей бракованый.  :)   )

 Насчёт графика - не знаю ...... У меня вообще зависал .....  Вывел EEPROM в Serial.println (между 54 и 55стр.) и обалдел ....... одна цифра соов.  799 - Press . , дальше - "255" и ступор .......(даже в Serial.println). При 2000  в 50-й всё было нормально....... (в смысле "255"  Serial.println  писал несколько раз но не стопорился ). Разбираться что откуда взялось не стал ... (чистить EEPROM спецпрогой  - тоже). Прогнал с 2000 весь график до конца (перезаписал весь используемый EEPROM) и востановил свои 1800000.  Заработало. Может у ВАС тоже самое ..... 

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

Переделал то-же без переключения диапазона, но 1 пиксель на мм давления маловато делать 2 пикселя займет как раз весь экран. Можно на длинных выходных развернуть экран на 90 градусов или на ардуине МЕГА прицепить 2 дисплея  (на одном график на втором информация температура , влажность, скорость ветра итд.) на уно наверно памяти  не хватит.

  Попробовал подключить по паралельной шине. Изменения скорости вывода информации не заметил.          

Ну вот что получилось благодаря огромной помощи участника форума  Андрей1963  .  

   #include <U8glib.h>
   #include <BMP085.h> 
   #include <Wire.h>
   #include <EEPROM.h>
   
   //Для параллельной шины включения(8 bits)
   //(d0, d1, d2, d3, d4, d5, d6, d7, en, di(RS), r/w, reset)
   //U8GLIB_ST7920_128X64_1X u8g(6, 7, 8, 9, 10, 11, 12, 13, 2, 4, 3, 5);
   //Для последовательной шины включения  
   U8GLIB_ST7920_128X64 u8g(6, 5, 4, U8G_PIN_NONE);
   // SCK(6)-E(6), MOSI(5)-R/W(5),CS(4)-RS(4),

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

   float Press  = 0 ;        //  переменная  давление
   byte PressEP    ;       //  высота столбца в памяти
   byte addressP = 0;      //  адрес записи высоты столбца 
   int adresP      ;       //  адрес считывания высоты столбца 
   byte cycle = 0  ;       //  колличество столбцов в графике
   int adrP = 99 ;         //  место столбца графика
   int cons = 0 ;          //  константа высоты столбца
   const int analogInPin = A0;  // Вход вольтметра
   int n =0 ;  
   float outputVolt = 0; 
   const int analogInPin1 = A1;  // Вход фоторезистора
   unsigned long tim ;
   unsigned long loopTime; 
   unsigned long BatTime;
   float outputfoto = 0;    
   long  temp = 0, Pressure = 0; // переменная для получения данных с датчика давления

  void setup()
{
   analogWrite(9, 133); // шим яркость LCD 9 pin  при паралельном закоментировать   
   tim = millis();
   Wire.begin();            //  
   dps.init(MODE_ULTRA_HIGHRES, 0, true); 
   u8g.begin();        //  старт дисплея
   Serial.begin(9600); 
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
 }
  void loop()
  {
   int val = analogRead(analogInPin1);   
   val= constrain(val,33 ,888);      
   outputfoto = val/4;
   
   analogWrite(9, outputfoto);  //    шим яркость LCD 9 pin  при паралельном закоментировать   
   outputVolt = float(analogRead(analogInPin))/204,6; // 1023 аналог / 5V =204,6
 
   dps.getPressure(&Pressure); // получаем данные о давлении
   dps.getTemperature(&temp);  //получаем данные о температуре
   Press = Pressure/133.3;
   // Press = Pressure/133.3-1.3;  // здесь вводим корректировку датчика BMP085
                                   // если есть метеостанция рядом.
   delay(500);
    /////////////  Включаем таймер /////////////////////////////
   tim = millis();
   if(tim >= (loopTime + 864000)) //  864 сек. для 100 столбцов в сутки
   {
   loopTime = tim;  
 
  /////////////  пишем высоту столбца в EEPROM /////////////////////////////
   
   EEPROM.write(addressP,(793 - Press));  // от константы отнимаем текущее давление , 
                                            
   addressP = addressP + 1;                 //  устанавливаем следующий адрес  
   if (addressP >= 100)                      //  адреса 0 - 100
   {addressP = 0;}
 }
 /////////////////  выводим всё на дисплей  ////////////////////////
  u8g.firstPage();
  do {

   grafik();  // в  void grafik() уже прописаны Pressing(); и stolb();

  } while( u8g.nextPage() );
  }
                    //////  ФУНКЦИИ  //////

/////////////////  рисуем график  ////////////////////////
  void grafik()
  { 
    Pressing();                            //  рисуем текущее давление и все надписи
    adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle <100; cycle ++)   //  100 циклов вывода линий на дисплей
    { 
    stolb();
    }  
  }
//////////////  текущее давление и все надписи на дисплей //////////////
  void Pressing()
 {  
    u8g.setFont(u8g_font_timR14);
    u8g.setPrintPos(0, 13);
    u8g.print(Press,1);
    u8g.setFont(u8g_font_timR08);
    u8g.drawStr( 46, 13, "MM");
    u8g.drawStr(1,23,"<------24 HOUR------>");
    
    u8g.drawRFrame(89,0,35,15,3);
  if ( outputVolt >3.8) 
    { u8g.drawStr(93,11,"BARO");} 
 
  if
    (outputVolt <3.8 &&  tim >= (BatTime + 2000)  ) 
  {  // u8g.setPrintPos(93,11);
     // u8g.print(outputVolt);  
     u8g.drawStr(93,11,"BATT");}
  if
   (tim >=(BatTime + 3000))
   { BatTime = tim; }        
   
   //u8g.drawStr( 70, 9, "t="); // нужна температура если 
   //u8g.setPrintPos(93,11);
   //u8g.print((float)temp/10,1);
   //u8g.drawStr(121,9,"C"); 
   ////////////  пределы отображения давления  ////////////
   u8g.setFont(u8g_font_timR10); // можно мельче (u8g_font_timR08)
   {u8g.drawStr(100,21,"_");}
   //if (cons == 776)
   {u8g.drawStr(104,35," 770");} 
   {u8g.drawStr(0,43,". . . . . . . . . . . . . .");}  
   {u8g.drawStr(104,48," 750");}
   {u8g.drawStr(100,61,"_730");}
  }
 //////////////// прорисовка одного столбца  ///////
 void stolb()
 { 
   PressEP = EEPROM.read(adresP);                     //  читаем из памяти высоту столбца
   u8g.drawPixel( adrP, PressEP);                 // линия 
   //u8g.drawLine (adrP, PressEP, adrP ,64);            // столбец 
   //u8g.drawLine (adrP, PressEP, adrP ,PressEP+1);   // линия толщиной 2 пикселя
   adrP = adrP - 1;                                   // устанавливаем место следующего столбца
   if (adrP < 0)                                      // следим за местом
   {adrP = 99 ; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = 99 ;}   
 }

         и Фото оконной коллекции гаджетов.

  датчик на одном устройстве из другой партии показания завышены относительно остальных.

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

КЛАСССС!!!!!

Если у ВАС зрение хорошее можно попробывать всю информацию на один дисплей вместе с графиком вывести....

Программа в коде много места не занимает. Шрифты .... Вот беда .... Но! Нам нужны только цифры , точка (или запятая) и небольшой набор букв (желательно русских)..... Встречал коды с применением самодельных шрифтов (сейчас искать некогда). Экономят очень много.....  Попозже займусь этим вопросом.

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

И в этой библиотеке есть русский шрифт  с проблемкой, но при желании можно надписи сделать

#include <U8glib.h>
U8GLIB_ST7920_128X64 u8g(6, 5, 4, U8G_PIN_NONE);
// SCK(13)-E(6), MOSI(11)-R/W(5),CS(12)-RS(4),
void setup() {

}

void loop() {
   u8g.firstPage();
do {

u8g.setFont(u8g_font_unifont_0_8);
u8g.setPrintPos(0, 30);  // позиция  
u8g.print("АБВГДЕЖЗИКЛ"); 
u8g.setPrintPos(0,45);  
u8g.print("МНОПРСТУФХ"); 
u8g.setPrintPos(0,61);  
u8g.print("ЦЧШЩЪЫЬЭЮЯ"); 
//абвгдежзийклмноп  рстуфхцчшщъыьэюя
//АБВГДЕЖЗИКЛ МНОПРСТУФХ ЦЧШЩЪЫЬЭЮЯ
draw ();
} while( u8g.nextPage() );

}
void draw(void) {

u8g.setFont(u8g_font_timR10);
u8g.drawStr( 0, 13, "Soznik Andrey proba");



}

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

При желании можно что угодно сотворить ......  В этом шрифте таблица русских символов смещена на одну строку (вычитал где то в обсуждении библиотеки). Методом "научного тыка" можно и надпись сотворить.

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

А как такой вариант

Пока две страницы.

1. общая информация.

2. график на весь экран, но вместо шкалы давления плавающее по высоте текущее показание.

3. пока в плане  поочереди первая и вторая.

Переключение страниц кнопка D8 на корпус.

   #include <U8glib.h>
   #include <BMP085.h> 
   #include <Wire.h>
   #include <EEPROM.h>
   
   //Для параллельной шины включения(8 bits)
   //(d0, d1, d2, d3, d4, d5, d6, d7, en, di(RS), r/w, reset)
   //U8GLIB_ST7920_128X64_1X u8g(6, 7, 8, 9, 10, 11, 12, 13, 2, 4, 3, 5);
   //Для последовательной шины включения  
   U8GLIB_ST7920_128X64 u8g(6, 5, 4, U8G_PIN_NONE);
   // SCK(6)-E(6), MOSI(5)-R/W(5),CS(4)-RS(4),

   /////////// активизируем датчик давления ////////////
   BMP085 dps = BMP085();     // Модель Digital Pressure Sensor - BMP085

   float Press  = 0 ;        //  переменная  давление
   byte PressEP    ;       //  высота столбца в памяти
   byte addressP = 0;      //  адрес записи высоты столбца 
   int adresP      ;       //  адрес считывания высоты столбца 
   byte cycle = 0  ;       //  колличество столбцов в графике
   int adrP = 99 ;         //  место столбца графика
   int cons = 0 ;          //  константа высоты столбца
   const int analogInPin = A0;  // Вход вольтметра
   int n =0 ;  
   float outputVolt = 0; 
   const int analogInPin1 = A1;  // Вход фоторезистора
   unsigned long tim ;
   unsigned long loopTime; 
   unsigned long BatTime;
   float outputfoto = 0;    
   long  temp = 0, Pressure = 0; // переменная для получения данных с датчика давления
   int regim=1;
   int flag=0;
   
  void setup()
{
   digitalWrite(8,HIGH);//включаем внутренний резистор
   analogWrite(9, 133); // шим яркость LCD 9 pin  при паралельном закоментировать   
   tim = millis();
   Wire.begin();            //  
   dps.init(MODE_ULTRA_HIGHRES, 0, true); 
   u8g.begin();        //  старт дисплея
   Serial.begin(9600); 
   u8g.setRot180(); 
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
 }
  void loop()
  {
    if(digitalRead(8)==LOW&&flag==0)//если кнопка нажата   
     // и перемення flag равна 0 , то ... 
     { 
       regim++;   
        if(regim>2)//ограничим количество режимов 
        { 
          regim=1;//так как мы используем только одну кнопку, 
                    // то переключать режимы будем циклично 
        } 
     }
   int val = analogRead(analogInPin1);   
   val= constrain(val,33 ,888);      
   outputfoto = val/4;
   
   analogWrite(9, outputfoto);  //    шим яркость LCD 9 pin  при паралельном закоментировать   
   outputVolt = float(analogRead(analogInPin))/204,6; // 1023 аналог / 5V =204,6
 
   dps.getPressure(&Pressure); // получаем данные о давлении
   dps.getTemperature(&temp);  //получаем данные о температуре
   //Press = Pressure/133.3;
    Press = Pressure/133.3-1.2;  // здесь вводим корректировку датчика BMP085
                                   // если есть метеостанция рядом.
   delay(500);
    /////////////  Включаем таймер /////////////////////////////
   tim = millis();
   if(tim >= (loopTime + 864000)) //  864 сек. для 100 столбцов в сутки
   {
   loopTime = tim;  
 
  /////////////  пишем высоту столбца в EEPROM /////////////////////////////
   
   EEPROM.write(addressP,((767 - Press)*2));  // от константы отнимаем текущее давление и *2 пикселя на мм, 
                                            
   addressP = addressP + 1;                 //  устанавливаем следующий адрес  
   if (addressP >= 100)                      //  адреса 0 - 100
   {addressP = 0;}
 }
 /////////////////  выводим всё на дисплей  ////////////////////////
 if(regim==1)//первый режим
 {
  u8g.firstPage();
  do {

   Pressing();  // в  void grafik() уже прописаны Pressing(); и stolb();

  } while( u8g.nextPage() );
  }
   if(regim==2)//второй режим 
    { 
       u8g.firstPage();
  do {

   grafik();  // в  void grafik() уже прописан  stolb();

  } while( u8g.nextPage() );
  }
  }
                    //////  ФУНКЦИИ  //////

/////////////////  рисуем график  ////////////////////////
  void grafik()
  {
    u8g.drawStr(1,7,"<------24 HOUR------>");
    u8g.setPrintPos(103, (PressEP+3));
    u8g.print(Press,1);
   //{u8g.drawStr(100,3,"_");}
   //{u8g.drawStr(108,13," 765");} 
   //{u8g.drawStr(108,38," 750");}
   //{u8g.drawStr(104,61,"_735");}
   { u8g.drawStr(0,35,". . . . . . . . . . . . . . . . . . . . ."); }                           //  рисуем текущее давление и все надписи
    adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle <100; cycle ++)   //  100 циклов вывода линий на дисплей
    { 
    stolb();
    }  
  }
//////////////  текущее давление и все надписи на дисплей //////////////
  void Pressing()
 {  
    u8g.setFont(u8g_font_timR14);
    u8g.setPrintPos(0, 13);
    u8g.print(Press,1);
    u8g.setFont(u8g_font_timR08);
    u8g.drawStr( 46, 13, "MM");
    
    
    u8g.drawRFrame(89,0,35,15,3);
  if ( outputVolt >3.8) 
    { u8g.drawStr(93,11,"BARO");} 
 
  if
    (outputVolt <3.8 &&  tim >= (BatTime + 2000)  ) 
  {  // u8g.setPrintPos(93,11);
     // u8g.print(outputVolt);  
     u8g.drawStr(93,11,"BATT");}
  if
   (tim >=(BatTime + 3000))
   { BatTime = tim; }        
   
   //u8g.drawStr( 70, 9, "t="); // нужна температура если 
   //u8g.setPrintPos(93,11);
   //u8g.print((float)temp/10,1);
   //u8g.drawStr(121,9,"C"); 
   ////////////  пределы отображения давления  ////////////
   u8g.setFont(u8g_font_timR08); // можно мельче (u8g_font_timR08)
   
  }
 //////////////// прорисовка одного столбца  ///////
 void stolb()
 { 
   PressEP = EEPROM.read(adresP);                     //  читаем из памяти высоту столбца
   u8g.drawPixel( adrP, PressEP);                 // линия 
   //u8g.drawLine (adrP, PressEP, adrP ,63);            // рисуем столбец 
   //u8g.drawLine (adrP, PressEP, adrP ,PressEP+1);   // линия толщиной 2 пикселя
   adrP = adrP - 1;                                   // устанавливаем место следующего столбца
   if (adrP < 0)                                      // следим за местом
   {adrP = 99 ; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = 99 ;}   
 }

Да ещё перевернул экран (180 гр.) т.к. у меня дисплеи с отрицательным углом обзора.

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

Если честно, то уже неохота вникать(голова забита другим проектом).....  Пост 58 (фото) 61(код)  Делалось осваивая EEPROM . Графика нет . Информации много. В памяти 4 страницы . Выводятся по кнопке по моему по 4сек(не помню) и опять основной экран. Оптиматизировать код на основе освоенного позже не стал..... Конструкция законченая и обкатанная - лезть не хочется... (как и в пост 117). Надо дождаться когда или надоедят или заглючат :)   ........ Вспомнил Буриданова осла и решил всё таки переключиться на другую тему (а то так можно до конца дней перебирать варианты и улучшать ....улучшать ....улучшать ....).

Удачи!

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

Согласен.

R2PM
Offline
Зарегистрирован: 28.12.2015

Всем с Новым годом!!!!

Есть спаянное устройство по схеме первой страницы, но нужны библиотеки  и рабочий скетч для дисплея нокия 5110.

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

С уважением Виктор R2PM

ValSerg
Offline
Зарегистрирован: 22.11.2015

Есть спаянное устройство по схеме первой страницы, но нужны библиотеки  и рабочий скетч для дисплея нокия 5110.

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

С уважением Виктор R2PM

пришлите адрес почты, отправлю то, что просите...

ValSerg
Offline
Зарегистрирован: 22.11.2015

если конечно Автор не против, ранее он сам мне прислал все рабочие библиотеки..

 

R2PM
Offline
Зарегистрирован: 28.12.2015

 С рождеством!!!

Спасибо за ответ!. мой адрес: rd3pq@rambler.ru

Виктор

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

Доброго времени суток. Не идёт код , а точнее десятые градусов. Код ниже.



    #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 секунд от работы до работы (180)
   int count1 = 0 ;          //  переменная для счётчика циклов по 8 сек
   volatile boolean wdt_tripped=1;
   ////////////  активизируем дисплей  //////////////////
   Adafruit_PCD8544 display = Adafruit_PCD8544(4, 10, 9, 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, 1400, true); 
   display.begin();        //  старт дисплея
   delay(500); 
   display.setContrast(55);
   display.clearDisplay();
   Serial.begin(9600); 
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
}

void loop()
{
  sensorValue = analogRead(analogInPin);            
  outputValue = float(analogRead(analogInPin))/310;
  // 1023 аналог / 3,3V =310
  // просыпаемся смотрим сколько циклов по 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((float)temp/10,1);
   //display.PrintPos(99, 9); 
   //display.print("бат=");
   display.print("*C ");
   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();                          // Здесь устройство перейдет в режим сна!!!
}

Мега 328 с минимальным обвесом. Питание 3,3 вольта, дисплей nokia3110. Всё работает кроме десятых температуры.  И ещё вопрос, можно расширить диапозон от 790до 730. В этом году давление разгулялось. Код поста № 49.

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

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

Доброго времени всем 

Я уже писал что в версии с поста № 49 у меня ошибка (в десятых долях градусов постоянно висит 0 ).

Вчера только приехал из Китая отдохну до завтра исправлю и выложу. Только напишите может лучше подвесить датчик DS18B20 с датчика давления из за разогрева идут завышенные показания.

 

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

Расширить диапазон наверное так:

Строка 58 – константа величины высоты столбца в зависимости от текущего давления Высота столбца = константа –(минус) текущее давление . Добовляйте по аналогии нужное в последующие строки .

Перед  63 будет например

If (Press <790)

{cons = 804;)

После 70 – сообразите….

Соотв. добавить перед 129 , после 136 , перед 140 ,  после 148

Вроде должно получится

Насчёт температуры – сильно не вникал , но переменная "temp"  объявена  "long" …  а это целые числа ….. Наверное надо изменить "long"  на  "float"  (это 27 строка) (код лучше сворачивать (скрывать)- крутить колесо на мышке долго - при вставке кода "дополнительно" нажмите...)

Soznik  извините - опередил…..  Поправте если ошибся.

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

Всё правильно у меня где-то есть уже исправленый код, если не найду перепишу этот.

Но датчик лучше выносить за корпус.

 

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

Посмотрел строка 118 надо закомментировать, а 119 раскомментировать и будет счастье.

тогда строки 16 и 61 ненужны. Тип переменной менять не надо с датчика данные идут в десятых градуса.

А с диапазоном как написал Андрей 1963.

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

Сам не пойму почему так получается переменные Press и temp1 прописаны одинаково везде, а десятые в градусах не идут.

если применить строку 119 то всё нормально.

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

Выполняется строка 27 потом строка 61 - десятых нет. В строке 119 переменная объявляется внутри функции - всё пошло . Испавлять 27

А вообще то строки 60,61,118 и переменная temp1 неужны . Одной  119 помоему будет достаточно.....

Всё просто когда нарисованны функции когда и что выполняется (и что выполняется внутри каждой функции) ......

Алексей . После отладки закоментируйте все строки относящиеся к Serial (вместе с delay тормозящим программу)(больше он вам не нужен будет - зачем грузить программу).

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

 Спасибо большое, буду эксперементировать. Да датчик прийдётся вынести, завышается температура градуса на 2.

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

Андрей давай смотреть переменные Press & temp1 стоят везде вместе  стр. 16 и17 , 27 , 61 и 62 , 113 и118

Однако давление с десятыми  нормально , а темп. в/10   висит 0. А с одной 119 нормально.

60 строка нужна. опрос датчика.

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

стр 62  Press получается делением на дробное число ......  

А   temp1 = temp/10  .  Скорее всего при делении целых чисел получаем целое число(с округлением) . Можно попробывать поставить 10.0 . Попробуйте .....

А в 119 стр  temp проходит в пределах функции как float - дробное число......

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

Верно поставил 10,0 всё заработало. Надо запомнить на будующее.

С 119 строкой лучше это я после узнал что после принта можно арифметику ставить.

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

Вы получаете с датчиков целые числа (стр27) . Только при последующем делении получаются десятые доли(в принципе погрешность получается в пределах +-0.1 единицы)

В 119  точнее т.к. сразу получаем дробь....

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

А я из первого барографа на нокии сделал термограф уличный на далласе. Плюсовая темп. столбики рисуются вверх, а отрицательная вниз.

 

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

Нормально. Меня интересовало только изменение давления в предыдующие сутки-двое . Механический бытовой барометр показывает текущее давление после хорошего пинка . Стрелку-указатель забываешь когда поставил на текущее давление.... Достало... А тут - голова загудела (вроде не употреблял) глянул - ясно почему (нечего свою температуру и своё давление мерять..... и глотать таблетки). И маманя уже привыкла(у ней тоже самое , только острее - возраст). Плюс - не надо очки на зенки вешать что бы стрелку и деления разглядывать, особенно вечером.

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

Термограф не ради прибора , а для общего развития (почему-бы и нет). 

А на LCD12864 стоит работает уже привык пора в корпус вставлять.

Я остановился на версии с тремя страницами и тремя кнопками выбора страницы.

1. Общая информация.

2. График с переключением диапазона.

3.График во весь экран с плавающеми по высоте показаниями текущего давления.

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

Памяти хватило для кода?

А что три кнопки? Одной нельзя листать по очереди?

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

Память 90% один размер шрифта убрал.

Пробовал с одной кнопкой очень сложно выйти из режима с переключением диапазона. Наверно слишком много IF-ов тормозят программу. На первой странице BARO  и BATT моргают отлично , а на странице с переключением диапазона пришлось отказатся (тормозится ) вместо рамки нарисовал батарейку и внутри вольтметр. Кнопки подключил на аналоговый вход делителем напряжения (Просто была планка с тремя кнопками от DVD уже с делителем).

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

Сложного вроде нет ничего , особенно если не использовать спящий режим. Не видя ваш вариант кода трудно что то предполагать . У вас ещё не пропало желание перебирать варианты  и улучшать эту конструкцию ?    :)   Я конечно понимаю - совершенству нет предела...... 

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

Вот код с датчиком влажности использовано 93% памяти.

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

  #include <U8glib.h>
   #include <BMP085.h> 
   #include <Wire.h>
   #include <EEPROM.h>
   #include "DHT.h"
   //Для параллельной шины включения(8 bits) в скорости вывода информации разницы не заметил
   //(d0, d1, d2, d3, d4, d5, d6, d7, en, di(RS), r/w, reset)
   //U8GLIB_ST7920_128X64_1X u8g(6, 7, 8, 9, 10, 11, 12, 13, 2, 4, 3, 5);
   //Для последовательной шины включения  
   U8GLIB_ST7920_128X64 u8g(6, 5, 4, U8G_PIN_NONE);
   // SCK(6)-E(6), MOSI(5)-R/W(5),CS(4)-RS(4),

   /////////// активизируем датчик давления ////////////
   BMP085 dps = BMP085();     // Модель Digital Pressure Sensor - BMP085
   DHT dht(7, DHT11);
   float Press  = 0 ;        //  переменная  давление
   byte PressEP    ;       //  высота столбца в памяти
   byte PressEP1    ;
   byte addressP = 0;      //  адрес записи высоты столбца 
   byte addressP1 = 100;      //  адрес записи высоты столбца 
   int adresP      ;       //  адрес считывания высоты столбца 
   int adresP1      ;
   byte cycle = 0  ;       //  колличество столбцов в графике
   byte cycle1 = 0  ;  
   int adrP = 99 ;         //  место столбца графика
   int adrP1 = 199 ;         //  место столбца графика
   int cons = 0 ;          //  константа высоты столбца
   const int analogInPin = A0;  // Вход вольтметра
   int n =0 ;  
   float outputVolt = 0; 
   float h ; 
   float t ; 
   const int analogInPin1 = A1;  // Вход фоторезистора
   unsigned long tim ;
   unsigned long loopTime; 
   unsigned long BatTime;
   float outputfoto = 0;    
   long  temp = 0, Pressure = 0; // переменная для получения данных с датчика давления
   int regim=1;
   int flag=0;
   unsigned long DispTime;
   int analog=0;

  void setup()
{
   //digitalWrite(8,HIGH);//включаем внутренний резистор (была одна кнопка) 
   analogWrite(9, 133); // шим яркость LCD 9 pin  при паралельном закоментировать   
   tim = millis();
   Wire.begin();            //  
   dps.init(MODE_ULTRA_HIGHRES, 0, true); 
   dht.begin();        // старт датчика влажности
   u8g.begin();        //  старт дисплея
   Serial.begin(9600); 
   u8g.setRot180();   //  переворачиваем дисплей если надо
   adresP = addressP ;     //  начальный адрес чтения - текущий адрес записи
   adresP1 = addressP1 ;     //  начальный адрес чтения - текущий адрес записи
 }
  void loop()
  {
    analog=analogRead(16);//считываем сигнал с пина АЦП  кнопки
    // Serial.println(analog);
    if(analog<100)//если кнопка 1 нажата   
     { 
       regim=1; 
                }
    if(analog>700&&analog<800)//если кнопка 2 нажата   
     { 
       regim=2; 
                }
    if(analog>800&&analog<900)//если кнопка 3 нажата   
     { 
       regim=3; 
                }


   int val = analogRead(analogInPin1);   
   val= constrain(val,33 ,888);      
   outputfoto = val/4;
   
   analogWrite(9, outputfoto);  //    шим яркость LCD 9 pin  при паралельном закоментировать   
   outputVolt = float(analogRead(analogInPin))/204,6; // 1023 аналог / 5V =204,6
   h = dht.readHumidity();       // получаем данные
   t = dht.readTemperature();   //  с DHT 11
   dps.getPressure(&Pressure); // получаем данные о давлении
   dps.getTemperature(&temp);  //получаем данные о температуре
   //Press = Pressure/133.3;
    Press = Pressure/133.3-0.2;  // здесь вводим корректировку датчика BMP085
                                   // если есть метеостанция рядом.
    /////////////  устанавливаем константу величины столбца в зависимости от текущего давления /////////////////
  //  794(770 - 780);784(760 - 770); 774(750 - 760); 764(740 - 750); 
 
  if ( Press < 770)
  {cons = 776;}
  if ( Press < 760)
  {cons = 766;}
  if (Press < 750)
  {cons = 756;}
  if (Press < 740)
  {cons = 746;}
    /////////////  Включаем таймер /////////////////////////////
   tim = millis();
   if(tim >= (loopTime + 864000)) //  864 сек. для 100 столбцов в сутки
   {
   loopTime = tim;  
 
  /////////////  пишем высоту столбца в EEPROM /////////////////////////////
   
   EEPROM.write(addressP,((767 - Press)*2));  // от константы отнимаем текущее давление и *2 пикселя на мм, 
                                            
   addressP = addressP + 1;                 //  устанавливаем следующий адрес  
   if (addressP >= 99)                      //  адреса 0 - 100
   {addressP = 0;}
    EEPROM.write(addressP1,(cons - Press)*4);  // от константы отнимаем текущее давление , 
                                            
   addressP1 = addressP1 + 1;                 //  устанавливаем следующий адрес  
   if (addressP1 >= 199)                      //  адреса 0 - 100
   {addressP1 = 100;}
 }
 /////////////////  выводим всё на дисплей  ////////////////////////
  if(regim==1)//первый режим
   {
    u8g.firstPage();
  do {
    u8g.drawStr(0,63,"1");
    Pressing();  // в  void grafik() уже прописаны Pressing(); и stolb();

  } while( u8g.nextPage() );
  }
   if(regim==2)//второй режим график на всю высоту дисплея без переключения диапазона
    { 
       u8g.firstPage();
  do {
   u8g.drawStr(0,63,"2");
   grafik();  // в  void grafik() уже прописан  stolb();

  } while( u8g.nextPage() );
  }
  
   if(regim==3)// четвертый режим график  с переключением диапазона измерения
    {  
       u8g.firstPage();
  do {
    u8g.setFont(u8g_font_timR08);
   {u8g.drawStr(0,63,"3");}
    grafik1(); 
   }while( u8g.nextPage() );
   }
  }
             //////  ФУНКЦИИ  //////

/////////////////  рисуем графики  ////////////////////////
  void grafik()     // на всю высоту дисплея без переключения диапазона
  {
    u8g.setFont(u8g_font_timR08); 
    u8g.drawStr(1,7,"<------24 HOUR------>"); 
    u8g.setPrintPos(103, ((767 - Press)*2)+3); // устанавливаем позицию показания давления
    u8g.print(Press,1);
   //{u8g.drawStr(100,3,"_");}
   //{u8g.drawStr(108,13," 765");} 
   //{u8g.drawStr(108,38," 750");}
   //{u8g.drawStr(104,61,"_735");}
   { u8g.drawStr(0,35,". . . . . . . . . . . . . . . . . . . . ."); }   //  рисуем осевую 750 mm/Hg
       adresP = addressP ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle = 0; cycle <100; cycle ++)   //  100 циклов вывода линий на дисплей
    { 
    stolb();
    }  
  }
   void grafik1()   //  рисуем  всё с переключением диапазона
  { 
     
    u8g.setFont(u8g_font_timR14);  
    u8g.setPrintPos(0, 13);
    u8g.print(Press,1);
    u8g.setFont(u8g_font_timR08);
    u8g.drawStr( 46, 13, "MM");
    u8g.drawStr(1,23,"<------24 HOUR------>");
    
    u8g.drawRFrame(89,0,35,15,3);
  
    u8g.setPrintPos(93,11);
       u8g.print(outputVolt,1);  
    u8g.drawStr( 111, 11, "V");
    u8g.drawBox(124, 5, 2, 5);
   
    //u8g.drawStr( 70, 9, "temp=");
    //u8g.setPrintPos(99, 9);
    //u8g.print((float)temp/10,1);
    //u8g.drawStr(121,9,"C"); 
   ////////////  пределы отображения давления  ////////////
   u8g.setFont(u8g_font_timR10);
   {u8g.drawStr(100,21,"_");}
   if (cons == 776)
   {u8g.drawStr(104,35," 770");}        
   if (cons == 766)
   {u8g.drawStr(104,35," 760");}
   if (cons == 756)
   {u8g.drawStr(104,35," 750");}
   if (cons == 746)
   {u8g.drawStr(104,35," 740");}
   //display.setCursor(63,34);
   //display.println("-");
   
   if (cons == 776)
   {u8g.drawStr(100,61,"_760");}
   if (cons == 766)
   {u8g.drawStr(100,61,"_750");}
   if (cons == 756)
   {u8g.drawStr(100,61,"_740");}
   if (cons == 746)
   {u8g.drawStr(100,61,"_730");}              
     adresP1 = addressP1 ;                    //  начальный адрес чтения - текущий адрес записи
    for (cycle1 = 0; cycle1 <100; cycle1 ++)   //  100 циклов вывода линий на дисплей
    {
     stolb1();
    } 
    }  

 
  void Pressing()    //  рисуем текущее давление и все надписи
 {  
    u8g.setFont(u8g_font_timR14);
    u8g.setPrintPos(0, 13);
    u8g.print(Press,1);
    u8g.setFont(u8g_font_timR08);
    u8g.drawStr( 46, 13, "MM/Hg");
    
    
    u8g.drawRFrame(88,0,35,15,3);
  if ( outputVolt >3.8) 
    { u8g.drawStr(93,11,"BARO");} 
 
  if
    (outputVolt <3.8 &&  tim >= (BatTime + 2000)  ) 
  {  // u8g.setPrintPos(93,11);
     // u8g.print(outputVolt);  
     u8g.drawStr(93,11,"BATT");}
  if
   (tim >=(BatTime + 3000))
   { BatTime = tim; }        
   u8g.setFont(u8g_font_timR14);
   u8g.drawStr( 0, 31, "t="); 
   u8g.setPrintPos(23,31);
   u8g.print((float)temp/10,1);
   u8g.drawRFrame(58,18,4,4,1);  // значок градуса
   u8g.drawStr(66,31,"C"); 
   u8g.drawStr( 0, 51, "H=");
   u8g.setPrintPos(35,51);
   
   u8g.print((float) h-0,0);   //  h-0  можно ввести корректировку датчика или привыкнуть к текущим
   u8g.drawStr(66, 51, "%");
   u8g.setFont(u8g_font_timR08);
  }
 //////////////// прорисовка одного столбца  ///////
 void stolb()                // на всю высоту дисплея
 { 
   PressEP = EEPROM.read(adresP);                     //  читаем из памяти высоту столбца
   u8g.drawPixel( adrP, PressEP);                 // линия 
   //u8g.drawLine (adrP, PressEP, adrP ,63);            // рисуем столбец 
   //u8g.drawLine (adrP, PressEP, adrP ,PressEP+1);   // линия толщиной 2 пикселя
   adrP = adrP - 1;                                   // устанавливаем место следующего столбца
   if (adrP < 0)                                      // следим за местом
   {adrP = 99 ; }                                     // при переходе через начало ставим в конец
   adresP = adresP - 1 ;                              // устанавливаем следующий адрес памяти
   if (adresP < 0)                                    //  следим за адресом
   {adresP = 99 ;}   
 }
   void stolb1()      // с переключением диапазона измерения
 { 
   PressEP1 = EEPROM.read(adresP1);                     //  читаем из памяти высоту столбца
   u8g.drawLine (adrP1-100, PressEP1, adrP1-100 ,63);            // рисуем столбец 

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

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

По подключению датчиков и кнопок спрашивайте отвечу всем.