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 летают ниже высоты перехода / эшелона перехода?