Arduino барометр - барограф
- Войдите на сайт для отправки комментариев
Представляю на суд общественности проект «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, но лучше, наверное, обсуждать на форуме. Возможно это будет кому-то интересно и полезно. А я ожидаю от сочувствующих предложений по оптимизации кода.
Всего доброго.
Удачи всем, у кого руки растут из головы.
здоровская штука получилась, я бы добавил установку высоты над уровнем моря, т.к. давление с высотой сильно меняется, нужно ввести переменную для этой корректировки, чтобы давление (на высоте где установлено устройство) соответсвовало давлению местной метеостанции, ну или давлению на гисметео.ру и перенеся девайс на другой этаж (высоту) можно было б скорректировать эти изменения высоты/давления
Жалко что точек на дисплее только 71, а не 701. А то бы действительно крутая программа получилась. :)
В строчках 449...519 мапятся 70 переменных v в 70 переменных y. А дальше, в 522...525, все эти переменные y копируются в массив arrayDraw.
Что мешает мапить сразу в arrayDraw, и выбросить из кода все эти y ? :)
И вообще, что мешает перенести вызов функции map в цикл отрисовки, и выбросить arrayDraw тоже?
Ну и не только это, конечно - найдётся и ещё что пооптимизить.
Вам нужно if заменить на switch и потом их еще и объединить и вынести одинаковые действия в отдельные функции.
Зачем Вам переменные v* как long?
это просто какая-то аццкая жесть ))
cтроки 088-098 - быдлокод, таких объявлений не должно быть в принципе, только через массив
094-098 - сильно сомневаюсь, что в этой программе вообще нужен тип long хоть где нибудь. unsigned int должно быть вполне достаточно. в крайнем случае можно сделать одну переменную типа long в котору получаем с датчика текущее значение давления, если оно не влезает в unsigned int, затем вычитаем из него константу. константу подбираем так, чтобы гарантированно хватило вместить результат в инт. хотя я уверен, что диапазон возможных значений атмосферного давления в хабаровске вполне влезает в unsigned int . а уж для отображения графика на экране в 84x48 точек даже типа int многовато...
177-229 - строки, выводимые на экран неизменными, можно сохранять в flash или EEPROM для экономии памяти (читаем про PROGMEM)
449-519 - быдлокод
522-525 - быдлокод. изучайте активнее что такое индекс переменной массива и для чего он нужен.
@Maverik
Это Вы со зла. ТС написал что он хочет оптимизировать, а Вы сразу - "быдлокод".
Человек понимает что сделал не правильно и просит совета, а Вы его носом в тапки.
"Сразу хочу пояснить. Основная цель публикации - получение замечаний и предложений. Особенно буду благодарен за предложения по оптимизации кода."
Вот если бы он написал "смотрите какой у меня чистый и правильный скетчик получился" - я бы одним из первых поржал, а так, по моему, не над чем.
Ту ТС: Если Вы будете следовать уже данным советам, то сократите Ваш код процентов на 70.
совсем не со зла )) "быдлокод" - это такое специальное слово для кода, который написан может и правильно, но некрасиво, вовсе не ругательство, и совсем не значит, что тс- быдло. ))) программисты иногда так про свой код и пишут - "вот кусок программы, на быдлокод внимания не обращайте" - например, когда вставлен кусок другого кода, нужно его привязать к своему и по быстрому потестировать. как временное явление в этом ничего страшного нет, но приучаться к этому как норме не нужно.
человек хотел получить замечания и предложения, особенно по части оптимизации кода. он именно это и получил. )))
кстати, строки 28-400 можно сократить до десяти строк, если напр использовать свич и в каждом варианте писать не функции, а только переменные, которые меняются. эти строки всё-равно занимают память, а ведь их можно тоже запихнуть в флеш или еепром. а уже после присваивания переменных в зависимости от условий, ОДИН раз написть эти функции отображения данных.
про свтич я написал сразу ;)
быдлокод - это например:
Или по "культурному" индусский. а него просто не оптимизированный, от слова совсем.
А В Вашем примере - это говнокод :)
про свтич я написал сразу ;)
быдлокод - это например:
Это не код, это заклятие какое-то...
На счет быдлокода или говнокода скажу так, это все зависит от "школы" если у вас изначально был хороший преподаватель в вузе и вым привили хорошие манеры и любовь к лаконичному оптимизированному коду, это уже не отнять.
Но если постигаете язык сами, то уже стоит вопрос чтоб просто работало!
а, где у нас личка? - или эта тема форвардится с другого форума?
а, где у нас личка? - или эта тема форвардится с другого форума?
Я написал тебе в личку где смотреть личку.
Я написал тебе в личку где смотреть личку.
от тебя я ничего другого и не ожидал.
Sergey_Ch загляни на почту.
Личка - не у всех включается: Вы ее - не видите, а кто-то - видит.
Не мешайте людям жить в своих иллюзиях, и они не будут вытаскивать Вас из ваших.(с)
> А на счет быдлокода или говнокода скажу так, это все зависит от "школы" если у вас изначально был хороший преподаватель в
> вузе и вым привили хорошие манеры и любовь к лаконичному оптимизированному коду, это уже не отнять.
> Но если постигаете язык сами, то уже стоит вопрос чтоб просто работало!
не соглашусь, я вообще языки программирования осваивал сам, и при этом быдлокод я просто органически не перевариваю и сам не пишу, комменты ручки сами тоже автоматически расписывают, специально редактор подбирал для корректного форматирования кода. этому не учат, это врожденное. Хотя, конечно, зависит от знания языка программирования. Напр. я очень плохо знаю язык бд MySQL и то, что я на нём пишу, можно вполне назвать быдлокодом. Но поскольку мне он нужен раз в год, не чаще, на это мне пофиг, и собсно если кто-то скажет что мои вставки на mysql - быдлокод, я уж точно не буду обижаться )))
Алё, гараж. Обороты сбавляем потихоньку))) Во-первых я специально предупредил, что слово "быдлокод" ничего уничижительного по отношению к личности самого автора не подразумевает, и что естественно это не означает, что он "быдло". Но вы,видимо, не читатель а писатель)) Во-вторых, если внимательно изучить код, а потом посмотреть на мои советы, то можно понять, что я ему дал ОЧЕНЬ ценные советы в т.ч. по части оптимизации кода. Ценность этих советов в том, что если афтар ими воспользуется, он не только оптимизирует представленный код, а вообще намного улучшит свой стиль программирования. Например, хорошо видно, что автор знает, что такое массив, но не знает, зачем нужна индексация элементов массива, и, соответственно, удобства от пользования массивами он не получает. То же самое относится к многократной записи функций тогда как достаточно просто изменить в зависимости от условий их аргументы. Это позволит сделать код НА ПОРЯДОК более компактным. Ну и разумеется, использование флеш/еепром для экономии памяти при программировании микроконтроллеров тоже очень важно, о чем я афтару тоже сказал.
Но вы, видимо, опять не читатель и предоставленный кода смотрели невнимательно.
короче говоря, молодежь, нужно быть проще, и люди к вам потянутся )) смотрите больше старых фильмов про обучение боевым искусствам, там вообще в процессе обучения учеников бамбуковой палкой лупят и ничо, все довольны )))
Maverik ну вопервых - не"предупредил" а оправдался.....
я тоже не знаю что такое "индексация элементов массива" и "зависимости от условий их аргументы". Ну нет этого в букварях!!!! Осваиваем .... ищем описания .... почему бы не повесить ссылки ...... Я конечно понимаю - проще кинуть термин и "крутись как хочешь....." . Забью эти термины - буду искать . Пока не попадались ..... Просто ни где эти термины не попадались!!! Тяжело ткнуть носом?... Да проще написать "быдлокод"...... А помоему просто некорректно так относиться к чужому труду ..... Про своё - пожалуста ! Кстати ВЫ упомянули что программисты так говоря про СВОИ коды. Вот код..... Быдлокод..... говнокод..... Прошу прощения у автора темы ..... Но что то полезное (я надеюсь) есть в коде и для него (вроде задачи одни ... только вместо грфика - архив). Писался и доводился больше двух недель. Я - дуб в програмировании. Всё осваиваю по мере возникновения проблем. Массивы, EEPROM, работа с TFT. Всё это две недели назад было темным лесом...... Читаем "букварь" - пишем...... Пршу ВАС - ВАШи предложения ! Желательно с сылками - где и что искать для улучшения кода.
Да . Кстати . Я "читатель". Поэтому болезнено воспринимаю огрехи русского языка при изложении мыслей (камушек в ВАШ огород).
Фото изделия было выше.
Код
Можете выложить TimeHelpers?
Уважаемые участники форума, благодарю Вас за отзывчивость. Особенно участника Maverik. Не обижайте его, пожалуйста. Именно Maverik проанализировал весь код проекта и дал свои замечания и предложения. Пусть несколько не в той манере, которая всем нравится, зато по теме. Только хотелось бы более подробнее и конструктивнее.
Пишите мне s-chuprin@mail.ru или на форум.
С увжением, Sergey_Ch
Заглянул. Пусто.
Пойду загляну в холодильник.
s-chuprin@mail.ru
Не удобно как-то чужими трудами хвалиться.
Я в статье написал по библиотеку работы со временем
Большое спасибо участнику форума Leshak за представленную библиотеку работы с функцией времениhttp://alxarduino.blogspot.ru/2013/08/delay.html.
Там все есть и ссылки для скачивания его библиотеки TimeHelpers от автора Leshak.
Продублировал .....
И ещё кое что добавил про "баюшки - баю"
Тогда скажем так ..... - поищи (поройся) ....(не в холодильнике - там "мыла" нет)....
Эх, давно искал "хороший" пример постоения графика логиования температуры\давления\влажности. :) Хотел поиграться но под свой tft дисплейчик на ili , но несдьба чтото..... Почему то ругается на строчку:
- дескать я кобы _SEC_ неопределена... но этож неправда, в строчках:
всё прописано автором....
Offtop недумал что ХАБАРОВСК настолько ниже БРЯНСКА (я на 252 метрах а автор на 90 всего :) )
У Вас используется куча (все) компоненты, которые хотят работь от 3.3V и стабилизатор на 5V. Зачем? может сразу стабилизатор на 3.3V и тогда потербление должно несколько упасть, глядишь, срок жизни в пару раз может увеличиться.
Так же я бы посоветовал повесить барометр на пину, где есть аппаратный I2C (A4 и A5), правда, видимо придется другую библиотеку использовать. Тоже и с дисплеем. Так же в силу того, что у Вас дисплей и ардуина оба работают на 3.3V, то резисторы между ними не обязательны.
У Вас используется куча (все) компоненты, которые хотят работать от 3.3V и стабилизатор на 5V. Зачем?
+++++
Благодарю Вас за комментарий.
Согласен с Вами полностью, просто не было под рукой стабилизатора на 3.3 в, повышающего напряжение Li-Pol аккумулятора. А сопротивления между Ардуиной и дисплеем остались от первой версии проекта, когда использовалась 5-ти вольтовая Arduino ProMicro 16 мгц. Она потребляла около 60 ма. Заменил на ProMini 8 мгц, потребление составило 15 ма.
Ответ участнику Thorn:
А Вы установили на IDE библиотеку TimeHelpers от автора Leshak ?
Ссылку я публиковал : http://alxarduino.blogspot.ru/2013/08/delay.html.
Точно ... затупил, показалось что такая либа наверное уже была скачана с GitHub`а и лежит в папочке. Теперь всё пучком.... утро радует...
Согласен с Вами полностью, просто не было под рукой стабилизатора на 3.3 в, повышающего напряжение Li-Pol аккумулятора.
Не нашел, какое минимальное напряжение у Li-Pol аккумулятора, но мне кажется, что можно поставить обычный линейный стабилизатор с низким падением напряжения и не париться. Напряжение на аккумуляторе будет больше, чем 3.3V большую часть времени (когда меньше - он уже близок к разряду, как я помню), а для всего кроме дисплея, думаю, можно и вообще без стабилизатора
3.0 -4.2 Вольт норма для ЛиПо. если на 8 МГц или ниже перейдёте- ничего делать не надо.
Ниже трёх- может вздуться. Выше 4.2 - греться.
А так специальный повышающий с ЛиПо на 5 Вольт ставьте .
Есть варианты с 5-ти Вольтовым выходом, клеммами под аккумулятор и входом дла зарядки.
С контролем этой зарядки-разрядки.
3.0 -4.2 Вольт норма для ЛиПо. если на 8 МГц или ниже перейдёте- ничего делать не надо.
Дак уже, если верить первому сообщению. Я про это и говорил, что повышающий не нужен, все и так должно работать замечательно.
Sergey_Ch Пока было время свободное на работе ....... Ну как то так получилось.... Ток замерять пока бестолку (NANO работает). Но экономия АКБ должна быть. Приедет "micro" ......(когда нибуть то приедет....)
Буду рад если чем то вам поможет. В выходные продолжу.
Немогу понять что в первом что в крайнем скетче отображение на дисплее функции: 090 display.display();
как она преобразуется для tft - все перепробовал - невыходит каменный цветок :(
Для TFT такой функции нет(для ST7735 вывод идёт сразу по tft.print(); )
А в PCD8544 по display.display(); выводятся на экран все display.print(); которые выше в {......}.
Я пытался, .... чесно :)) однако в итоге в библиотеке теперь затык: Adafruit_ILI9341.cpp: In member function 'void
вобщем несудьба/
Из-за "отсутствия наличия" соотв. оборудования ничего хорошего по Adafruit_ILI9341 посоветовать не могу. Это "будет одно горе а не советы".....
Но что то с выводом на дисплей вы перехимичили......
Уважаемые Форумчане,
Принимая во внимание замечания и предложения, а особенно констуктивизм сансэя Maverik, немного оптимизировал код.
Правда не дошел еще до использования EEPROM, что-то меня все равно останавливает. Использовать Flash-память не хочу категорически. Подобные проекты с Flash на иноязычных сайтах видел, не вдохновили. Андрей, Вам огромное спасибо, я еще разбираюсь с режимами сна и бодорствования. Хочется не просто скопировать решение, а плотно поместить его в голову. Код писал под тренировочную Arduino UNO3 и другую модель Nokia5110 (синюю). Так что код немного отличается по подключениям. Благодаря совместным усилиям и помощи участников форума удалось уменьшить размер кода - 25112 байт из 32256. Прилагаю новую промежуточную версию кода и жду новых комментариев и предложений по его оптимизации. Кстати, схема проверена на макетке, все работает.
Добрый день Сергей.
Вроде вник в ваш код. Maverik кругом прав(правда грубовато….. и не конкретно). Попробую конкретизировать …… (только ,прошу прощения, без синтаксиса…. )
Строки 088-098 – объявляем массив из 72 элементов , если нужна полоска присваиваем по всем индексам(читай адресам)массива одно и тоже число (47)(Прокрутим один цикл). Кстати от второй переменной я бы отказался (ниже будет ясно почему).
Строки 275-282 - я бы не стал перезаписывать все ячейки . Считаем периоды измерений и пишем последовательно в ваш массив меняя индекс от 0 до 71(индексом будет номер измерения).
Ручная установка режимов просмотра?
Сомневаюсь что за всё время построения графика давление (в мм) может измениться больше чем на вертикальный размер графика (в пикселях).
Читаем текущее давление и автоматически ставим плюс - минус 5-10мм.(крайние значения рисуем на графике).
Преобразование каждого измеренного и записанного в массив (или в память) давления в высоту линий(столбцов) ……….. стр450 и дальше……
После получения данных о давлении (стр 291 ) сразу преобразовываем абсолютную величину давления (ну не нужна она больше!!!!) в высоту столбца ……. Я просто отнимал текущее давление от какой то величины и получал сразу высоту столбца . Если сделать наоборот (что то отнимать от давления) то график перевернётся (при повышении давления столбец будет меньше).Есть, правда, вариант изменять координаты линий при выводе на дисплей.
И уже его пишите в ваш (единственный) массив….. Надобность во второй переменной(упоминал выше) отпадает.
При выводе графика на экран цикл стартует с текущего индекса массива в обратном направлении . При переходе через ноль возвращаемся к конечному индексу массива.(Это вместо перезаписи со сдвигом)
Вроде – всё.
Не пытайтесь изменить всё и сразу .
Посмотрите этот скетч. Что то может быть и понравится(особенно 12.192 байта). Реализовано автоматическое переключение режимов. Считка в обратном порядке с текущего адреса ……
Уважаемый Андрей,
благодарю Вас за присланные материалы. Код компилируется, обязательно учту Ваши рекомендации. Грядут Выходные дни, займусь делом. О результате доложу. Еще раз спасибо.
на всякий случай поясню - синяя модель дисплея 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вольт и земля.
Доброго времени суток. Андрей1963 А как в вашем скетче устанавливать поправку на высоту?
Доброго времени суток. Андрей1963 А как в вашем скетче устанавливать поправку на высоту?
Я в setup добавил строчку dps.init(MODE_ULTRA_HIGHRES, 12000, true);
где 12000 это 120 метров.
Ещё добавил вольтметр.
Доброго времени суток. Пробовал добавить в скетч, не компилируется.
Да посмотрел действительно много чего изменил.
Вотчто получилось
Изменил диапазон с (730-770) на (740-780)
Вывод (А0) ардуины использовал как вход вольтметра (подключен на аккамулятор)
Добавил дясятичную часть в давлении.
В строке 25 проставьте свои выводы ардуины на индикатор.
Доброго времени суток. Огромное спасибо soznik. Всё компилируется и работает. Остаётся температуру вывести, датчик встроенный в BMP085 достаточно точный.
С уважением Алекс
В каком месте дисплея разместить показания температуры?
Доброго дня. Так надпись 24 часа в принцепе не нужна. Можно вместо неё. Сейчас плату делаю под барометр. Чисто микроконтроллер, кварц, и конденсаторы. На 3,3 вольта сделаю. Запитаю от литиевого аккумулятора 3,7 в. Думаю пока без стабилизатора.
С уважением Алекс.
Тогда вот-так
У меня питается от литеевого аккумулятора через step-up преобразователь.
т.е. не зависимо от напряжния на аккамуляторе на ардуине 5V.
если вольтметр не нужен закометировать строки 133,134. И в строке 129 можно вписать "Температура"
должно влезть в строку.
Спасибо большое сегодня вечером займусь сборкой. На UNO работает.
С уважение Алексей.