ESP8266 c bme/bmp280 и ds18b20
- Войдите на сайт для отправки комментариев
Народ, не пойму в чем загвоздка. Сначала настроил esp8266 и bme/bmp280. Вывод идет на адресную матрицу (пока она одна 16х16, но будет 4 штуки) бегущей строкой. Пока было это сочетание, все работало. Но вот пришел датчик ds18b20 чтобы мерить температуру на улице и поломалась бегущая строка. Данные все собирает, температуру в комнате, давление, влажность, температуру на улице, но бегущая строка ползет как черепаха. Все Dalay поубирал, проверил. Выяснил что тормозит. Вот эта команда
DS18B20.requestTemperatures();
Если ее убрать, то строка бежит нормально. Но не меряет температуру на улице.
Вот собственно сам скетч. Он из 4 файлов (2 шрифты, их я не буду прикладывать). Вот основной
// -------- ВРЕМЯ ------- #define GMT 3 // смещение (москва 3) #define NTP_ADDRESS "europe.pool.ntp.org" // сервер времени #define NTP_INTERVAL 60 * 1000 // обновление (1 минута) //-------------------Библиотеки------------------- #include <FastLED.h> #include "font12.h" #include "font_sm.h" #include <WiFiManager.h> #include <NTPClient.h> #include <WiFiUdp.h> #include "Adafruit_Sensor.h" #include "Adafruit_BME280.h" #include "Wire.h" #include <DallasTemperature.h> #include <OneWire.h> //-------------------Заданные значения--------------- #define MATRIX_WIDTH 16 //ширина матрицы #define MATRIX_HEIGHT 16 //высота матрицы #define COLOR_ORDER GRB #define NUM_LEDS MATRIX_WIDTH * MATRIX_HEIGHT #define FASTLED_INTERRUPT_RETRY_COUNT 0 #define FASTLED_ALLOW_INTERRUPTS 0 #define FASTLED_ESP8266_RAW_PIN_ORDER #define DATA_PIN 4 //пин матрицы #define LIGHT_PIN A0 //пин матрицы #define ONE_WIRE_BUS D1 //контакт для передачи данных подключен к D1ES8266 12-Е (GPIO5) CRGB leds[NUM_LEDS]; WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, NTP_ADDRESS, GMT * 3600, NTP_INTERVAL); WiFiServer server(80); // создаем экземпляр класса oneWire; с его помощью // можно коммуницировать с любыми девайсами, работающими // через интерфейс 1-Wire, а не только с температурными датчиками // от компании Maxim/Dallas: OneWire oneWire(ONE_WIRE_BUS); // передаем объект oneWire объекту DS18B20: DallasTemperature DS18B20(&oneWire); const float SEA_LEVEL_PRESSURE_HPA = 1013.25; Adafruit_BME280 bme; // ----------------- ПЕРЕМЕННЫЕ ------------------ int symbols[] = {32,37,43,44,45,46,48,49,50,51,52,53,54,55,56,57,58,59,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,194}; int smallnum[] = {32,37,45,46,48,49,50,51,52,53,54,55,56,57,58}; uint8_t curX; uint8_t curY; uint16_t lineStart=0;//с какого столбца строки начинаем вопроизведение текста uint16_t lineFin=0;//каким столбцом строки заканчиваем вопроизведение текста uint8_t startRunLineX=MATRIX_WIDTH-1;//столбец X начала отрисовки бегущей строки byte sl, sn, days, hs, ms, ss, my, dm; String DayOfWeek, MonthOfYear; unsigned long Full_tm, yy, interval, corr; int BRIGHTNESS, RBRIGHTNESS, cc; float h, t, p, pin, dp; char temperatureString[6]; //температура в комнате char dpString[6]; char humidityString[6]; char pressureString[7]; char pressureInchString[6]; char temperatureCString[6]; //температура на улице void setup() { pinMode(DATA_PIN, OUTPUT); pinMode(LIGHT_PIN, INPUT); FastLED.addLeds<WS2812B, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); Serial.begin(9600); interval = 0; WiFiManager wifiManager; wifiManager.autoConnect("Meteo-ST"); sl = sizeof(symbols)/sizeof(symbols[0]); sn = sizeof(smallnum)/sizeof(smallnum[0]); timeClient.begin(); Wire.begin(D6, D5); Wire.setClock(100000); if(!bme.begin()) { Serial.println("Could not find a valid BME280 sensor, check wiring!"); while (1) { yield(); delay(3000); } } //Запускаем WEB сервер server.begin(); DS18B20.begin(); cc = random(255); } void loop() { timeClient.update(); RBRIGHTNESS = analogRead(LIGHT_PIN); RBRIGHTNESS = 1023 - RBRIGHTNESS; BRIGHTNESS = map(RBRIGHTNESS, 0, 1023, 1, 50); FastLED.setBrightness(BRIGHTNESS);//0-255 FastLED.clear(); CHSV color = CHSV(cc,255,255); GetData(); days = timeClient.getDay(); hs = timeClient.getHours(); ms = timeClient.getMinutes(); ss = timeClient.getSeconds(); String frmdt = getDTString(); String OutDT = DayOfWeek + ", " + dm + " " + MonthOfYear + " " + yy + " года"; String OutTm = timeClient.getFormattedTime(); String OutTmp = "Температура в комнате " + String(temperatureString) + "°C"; String OutTmpOut = "Температура на улице " + String(temperatureCString) + "°C"; String OutHum = "Влажность " + String(humidityString) + "%"; String OutPre = "Давление " + String(pressureString) + "мм.рт.ст."; if (millis() - interval < 30000) { if (runText(OutTm, 0, color, 30) == 1){ corr = 30000 - (millis() - interval); interval = interval - corr; } } if ((millis() - interval >= 30000)&&(millis() - interval < 60000)) { if (runText(OutDT, 0, color, 30) == 1){ corr = 60000 - (millis() - interval); interval = interval - corr; } } if ((millis() - interval >= 60000)&&(millis() - interval < 90000)) { if (runText(OutTmp, 0, color, 30) == 1){ corr = 90000 - (millis() - interval); interval = interval - corr; } } if ((millis() - interval >= 90000)&&(millis() - interval < 120000)) { if (runText(OutTmpOut, 0, color, 30) == 1){ corr = 120000 - (millis() - interval); interval = interval - corr; } } if ((millis() - interval >= 120000)&&(millis() - interval < 150000)) { if (runText(OutHum, 0, color, 30) == 1){ corr = 150000 - (millis() - interval); interval = interval - corr; } } if ((millis() - interval >= 150000)&&(millis() - interval < 180000)) { if (runText(OutPre, 0, color, 30) == 1){ corr = 180000 - (millis() - interval); interval = interval - corr; } } if (millis() - interval >= 180000) { interval = millis(); cc = random(255); } FastLED.show(); WiFiClient client = server.available(); if (client) { // bolean to locate when the http request ends boolean blank_line = true; while (client.connected()) { if (client.available()) { char c = client.read(); if (c == '\n' && blank_line) { //getWeather(); client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // your actual web page that displays temperature client.println("<!DOCTYPE HTML>"); client.println("<html>"); //client.println("<head><META HTTP-EQUIV=\"refresh\" CONTENT=\"15; charset=Windows-1251 \"></head>"); client.println("<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />"); client.println("<script>"); client.println("setTimeout(function(){location.reload();}, 15000);"); client.println("</script></head>"); client.println("<body><h1>ESP8266 Weather Web Server</h1>"); client.println("<h1>"+OutDT+"</h1>"); client.println("<table border=\"2\" width=\"456\" cellpadding=\"10\"><tbody><tr><td>"); client.println("<h3>"); client.println(OutTmp); client.println("</h3><h3>"); client.println(OutTmpOut); client.println("</h3><h3>"); client.println(OutHum); client.println("</h3><h3>"); client.println(OutPre); client.println("</h3></td></tr></tbody></table></body></html>"); break; } if (c == '\n') { // when starts reading a new line blank_line = true; } else if (c != '\r') { // when finds a character on the current line blank_line = false; } } } // closing the client connection delay(1); client.stop(); } }
А вот файлик с процедурами.
byte runText(String text, byte startY, CHSV color, int speedText){//вывод бегущей строки int i, n, m; byte fin; bool isRusLetter=false; uint32_t vertPixels; unsigned long tp; fin = 0; curY=startY; curX=startRunLineX; int l=0; for (i=0;i<text.length();i++){ byte sym = (byte)text[i]; if ((sym == 208) || ((sym == 209))) { i++; sym = (byte)text[i]; } if (sym == 194){ i++; } n=getArrayIndex(sym,sl,1); for (byte j=0;j<12;j++){ vertPixels=pgm_read_word(&(font12[n][j])); if ((j==0)||(vertPixels>0)){//только первая колонка и не пустые колонки if ((l>=lineStart)&&(l<=lineFin)){ getPixel12 (vertPixels, startY, color); } l++; } if (j==11){//в конце каждого символа добавляем пробел if ((l>=lineStart)&&(l<=lineFin)){ curX++; } l++; } } } lineFin++; if (lineFin>=MATRIX_WIDTH) { lineStart++; } if (startRunLineX>0){//каждый кадр смещаем начало отрисовки бегущей строки на 1 пиксель влево от правого края матрицы startRunLineX--; } if (lineStart>l){//воспроизводим с начала l=0; lineStart=0; lineFin=0; startRunLineX=MATRIX_WIDTH-1; fin = 1; } tp = millis(); while (millis() - tp != speedText){} return fin; } void setPixel(int X, int Y, CHSV color){ int curLed; if (X%2 == 0){ curLed = MATRIX_HEIGHT*X+Y; } else { curLed = (MATRIX_HEIGHT*(X+1)-1)-Y; } leds[curLed] = color; } byte getPixel12 (uint32_t vertPixels, byte startY, CHSV color) { byte pixel; for (int k = 10; k >=0; k--) {// pixel = ((vertPixels >> k) & 0x01); if (pixel==1){ setPixel (curX, curY, color); } curY++; } curY=startY; curX++; } byte getArrayIndex(byte znach, byte ln, byte an){ for (byte n=0;n<ln;n++) { if (an == 1){ if (symbols[n] == znach){ return n; } } else { if (smallnum[n] == znach){ return n; } } } } String getDTString() { unsigned long rawTime = (timeClient.getEpochTime()) / 86400L; // in days unsigned long days = 0, yr = 1970; uint8_t month; static const uint8_t monthDays[]={31,28,31,30,31,30,31,31,30,31,30,31}; static const String weekDays[]={"Понедельник","Вторник","Среда","Четверг","Пятница","Суббота","Воскресенье"}; static const String monthNames[]={"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}; while((days += (LEAP_YEAR(yr) ? 366 : 365)) <= rawTime) yr++; rawTime -= days - (LEAP_YEAR(yr) ? 366 : 365); // now it is days in this year, starting at 0 days=0; for (month=0; month<12; month++) { uint8_t monthLength; if (month==1) { // february monthLength = LEAP_YEAR(yr) ? 29 : 28; } else { monthLength = monthDays[month]; } if (rawTime < monthLength) break; rawTime -= monthLength; } yy = yr; my = month+1; dm = rawTime+1; DayOfWeek = weekDays[timeClient.getDay()-1]; MonthOfYear = monthNames[my-1]; String monthStr = ++month < 10 ? "0" + String(month) : String(month); // jan is month 1 String dayStr = ++rawTime < 10 ? "0" + String(rawTime) : String(rawTime); // day of month return String(yr) + "-" + monthStr + "-" + dayStr + "T" + timeClient.getFormattedTime(ss ? ss : 0) + "Z"; } void GetData(){ h = bme.readHumidity(); t = bme.readTemperature(); //dp = t-0.36*(100.0-h); float tempC; p = bme.readPressure()/133.3224; pin = 0.02953*p; dtostrf(t, 5, 1, temperatureString); dtostrf(h, 5, 1, humidityString); dtostrf(p, 5, 1, pressureString); DS18B20.requestTemperatures(); tempC = DS18B20.getTempCByIndex(0); dtostrf(tempC, 2, 2, temperatureCString); }
Может кто подскажет в чем проблема. Я вот думаю нельзя ли для измерения температуры датчиком ds18b20 использовать библиотеку wire.h, а не onewire.h? Пока вижу, что bmp280 по двум пинам подключается, а ds18b20 по одному. Активно рою интернет.
Ну вроде ты сам разобрался с проблемой -
requestTemperatures
занимает много времени. Нет, за меньше времени этого не выполнить. Нет, wire.h и onewire.h это не одно и тоже. Может быть тебе не обязательно измерять температуру сто раз в секунду?Много информации можно почерпнуть тут
Ну вроде ты сам разобрался с проблемой -
requestTemperatures
занимает много времени. Нет, за меньше времени этого не выполнить. Нет, wire.h и onewire.h это не одно и тоже. Может быть тебе не обязательно измерять температуру сто раз в секунду?Блин! Ведь собирался раз в минуту измерение сделать! Вот я идиёт!
Спасибо! Все заработало!
Народ, а можно еще вопрос.
При измерении атмосферного давления, есть параметр высоты над уровнем моря. Вот датчик у меня на уровне 10 этажа. Чтобы получить точное значение на земле мне надо указать эту высоту или наоборот, если я укажу высоту, то получу давление именно на этой высоте?
Вам надо указать ту высоту над уровнем моря, на которой расположен датчик.
Народ, а можно еще вопрос.
При измерении атмосферного давления, есть параметр высоты над уровнем моря. Вот датчик у меня на уровне 10 этажа. Чтобы получить точное значение на земле мне надо указать эту высоту или наоборот, если я укажу высоту, то получу давление именно на этой высоте?
почитайте как самолёты берут эшелон, станет всё понятно
почитайте как самолёты берут эшелон, станет всё понятно
Кстати, в РФ уже перешли на QNH или до сих пор по QFE летают ниже высоты перехода / эшелона перехода?