• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь Перестает отвечать вебсервер ESP8266-01

lavAzza

New member
Нашел другой скетч. Пока без зависов.
Код:
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <SPI.h>
#include <ArduinoJson.h>

Adafruit_BMP280 bmp; // I2C

// Replace with your network details
const char* ssid = "ssid";
const char* password = "pwd";
float t, p;
char temperatureString[6];
char pressureString[7];

// Web Server on port 80
WiFiServer server(80);

// only runs once on boot
void setup() {
  // Initializing serial port for debugging purposes
  Serial.begin(115200);
  delay(10);
  Wire.begin(0, 2);
  Wire.setClock(100000);
  // Connecting to WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Starting the web server
  server.begin();
  Serial.println("Web server running. Waiting for the ESP IP...");
  delay(10000);
 
  // Printing the ESP IP address
  Serial.println(WiFi.localIP());
  Serial.println(F("BME280 test"));

  if (!bmp.begin()) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

void getWeather() {

    t = bmp.readTemperature();
    p = (bmp.readPressure() * 7.5006e-3);
    dtostrf(t, 5, 1, temperatureString);
    dtostrf(p, 6, 1, pressureString);
    delay(100);
}

// runs over and over again
void loop() {

  // Listenning for new clients 
  WiFiClient client = server.available();
 
  StaticJsonBuffer<300> JSONbuffer;
  JsonObject& JSONencoder = JSONbuffer.createObject();
 
  if (client) {
    Serial.println("New 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();
            JSONencoder["Place"] = "Mub, 7";
            JSONencoder["Number"] = "1";
            JSONencoder["Temp"] = temperatureString;
            JSONencoder["Pres"] = pressureString;
            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></head>");
            client.println("<body>");
            String out;
            JSONencoder.printTo(out);
            client.println(out);
            client.println("</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();
    Serial.println("Client disconnected.");
  }
}
 

lavAzza

New member
код проработал всю ночь, отвечая на запросы каждые две минуты, но утром датчик уже показывает {"Place":"Mub, 7","Number":"1","Temp":"-139.0","Pres":" 882.2"} :)
 

kab

New member
А ХЕЗ :D Я действовал в духе ардуинщиков - накидал код из говна и палок примеров, что идут в ардуине :p
Мне кажется, что вещи типа

WiFiClient client
StaticJsonBuffer<300> JSONbuffer
JsonObject& JSONencoder
boolean blank_line
и т. д.

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

gerkimuyda

New member
В общем, я запустил на сутки следующий код:
Код:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Wire.h>
#include <SSD1306.h>
#include <ArduinoJson.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
extern "C" {
#include "user_interface.h"
}

Adafruit_BMP280 bmp;
SSD1306 display(0x3c, D3, D4);


const char* ssid = "ыышв";
const char* password = "зыц";
unsigned long mytime = 0;

ESP8266WebServer server(80);
float t, p;
char temperatureString[6];
char pressureString[7];

String print_time(void) {
  unsigned long Time = millis() / 1000;
  return
    String(((Time%86400L)/3600)<10?"0":"")+String((Time%86400L)/3600)+":"+
    String(((Time%3600)/60)<10?"0":"")+String((Time%3600)/60)+":"+
    String((Time%60)<10?"0":"")+String(Time%60);
}

void getWeather() {
    t = bmp.readTemperature();
    p = (bmp.readPressure() * 7.5006e-3);
    dtostrf(t, 5, 1, temperatureString);
    dtostrf(p, 6, 1, pressureString);
    delay(100);
}

void handleRoot() {
    StaticJsonBuffer<300> JSONbuffer;
    JsonObject& JSONencoder = JSONbuffer.createObject();
    JSONencoder["Place"] = "Mub, 7";
    JSONencoder["Number"] = "1";
    JSONencoder["Temp"] = temperatureString;
    JSONencoder["Pres"] = pressureString;
    JSONencoder["Memory"] = system_get_free_heap_size();
    JSONencoder["Time"] = print_time();
    String out;
    JSONencoder.printTo(out);
    server.send(200, "text/html", "<!DOCTYPE HTML>\r\n<html>" + out + "</html>");
}

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.print("\r\nConnecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.println("\r\nWiFi connected");
 
  server.on("/", handleRoot);
  server.begin();
  Serial.print("Server started: http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

  Wire.begin(D3, D4); delay(10);
  if (!bmp.begin()) { Serial.println(F("Could not find a valid BMP280 sensor, check wiring!")); }

  display.init();
  display.flipScreenVertically();
  display.setContrast(255);
}
void loop() {

  if( (millis() - mytime) > 1000) { mytime=millis();
    getWeather();
    display.clear();
    display.setFont(ArialMT_Plain_16);
    display.setTextAlignment(TEXT_ALIGN_LEFT);
    display.drawString(0, 0, "Temp: "+ String(temperatureString) );
    display.drawString(0, 16, "Press: " + String(pressureString) );
    display.drawString(0, 32, "Uptime: " + print_time() );
    display.drawString(0, 48, "FreeMem: " + String(system_get_free_heap_size()) );
    display.display();
}

  server.handleClient();

}
Вот фотка:
IMG_2017-12-01_161040.jpg IMG_2017-12-01_162930.jpg

Если у вас через время отваливается BMP280 - поменьше трогайте его, и проверьте питание/наводки/помехи.
 
Последнее редактирование:

gerkimuyda

New member
Проработало 25 часов с http-запросами каждую минуту (т.е. 1500 запросов). Все в порядке и работает. Температуру показывает и давление (обновление при каждом выводе на lcd, т.е. каждую секунду).
В чем проблема?
 

gerkimuyda

New member
Проблема, похоже, в BMP280 - накрылся.) Не прохдит if (!bmp.begin()) ...
Вот вам код скетча, с которым можно запустить модуль вообще без дисплея и датчика, а потом их подключать "на лету" ("на гарячую")
Код:
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Wire.h>
#include <SSD1306.h>
#include <ArduinoJson.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
extern "C" {
#include "user_interface.h"
}

#define LCD_address    0x3c  // I2C address
#define BMP280_address 0x76  // I2C address

Adafruit_BMP280 bmp;
SSD1306 display(LCD_address, D3, D4);


const char* ssid = "ссид";
const char* password = "псв";
unsigned long mytime = 0;

ESP8266WebServer server(80);
float t, p;
char temperatureString[6] = "-- \0\0";
char pressureString[7] = "-- \0\0\0";
boolean display_enable;
boolean bmp280_enable;

boolean find_i2c(uint8_t address) {
  Wire.beginTransmission(address);
  return (Wire.endTransmission () == 0);
}

String print_time(void) {
  unsigned long Time = millis() / 1000;
  return
    String((Time/3600)<10?"0":"")+String(Time/3600)+":"+
    String(((Time%3600)/60)<10?"0":"")+String((Time%3600)/60)+":"+
    String((Time%60)<10?"0":"")+String(Time%60);
}

void getWeather() {
  if( bmp280_enable ) {
    t = bmp.readTemperature(); dtostrf(t, 5, 1, temperatureString);
    p = (bmp.readPressure() * 7.5006e-3); dtostrf(p, 6, 1, pressureString);
    delay(100);
  } else { temperatureString[0] = temperatureString[1] = pressureString[0] = pressureString[1] = 45; temperatureString[2] = pressureString[2]= temperatureString[3] = pressureString[3] = 32; temperatureString[4] = pressureString[4] = 0; }
}

void handleRoot() {
    StaticJsonBuffer<300> JSONbuffer;
    JsonObject& JSONencoder = JSONbuffer.createObject();
    JSONencoder["Place"] = "Mub, 7";
    JSONencoder["Number"] = "1";
    JSONencoder["Temp"] = temperatureString;
    JSONencoder["Pres"] = pressureString;
    JSONencoder["Memory"] = system_get_free_heap_size();
    JSONencoder["Time"] = print_time();
    String out;
    JSONencoder.printTo(out);
    server.send(200, "text/html", "<!DOCTYPE HTML>\r\n<html>" + out + "</html>");
}

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.print("\r\nConnecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  Serial.println("\r\nWiFi connected");
 
  server.on("/", handleRoot);
  server.begin();
  Serial.print("Server started: http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");

  Wire.begin(D3, D4); delay(10);
  if ( bmp280_enable = find_i2c(BMP280_address)) { bmp.begin(BMP280_address); }else{ Serial.println(F("Could not find a valid BMP280 sensor, check wiring!")); }
  if( display_enable = find_i2c(LCD_address) ) { display.init(); display.flipScreenVertically(); display.setContrast(255); }
}
void loop() {
 

  if( (millis() - mytime) > 1000) { mytime=millis();
    if( bmp280_enable ) { bmp280_enable = find_i2c(BMP280_address); getWeather(); }
     else{ if( bmp280_enable = find_i2c(BMP280_address) ) { bmp.begin(BMP280_address); } }
    if( display_enable ) { display_enable = find_i2c(LCD_address);
      display.clear();
      display.setFont(ArialMT_Plain_16);
      display.setTextAlignment(TEXT_ALIGN_LEFT);
      display.drawString(0, 0,  "Temp °C :");
      display.drawString(0, 16, "Pressure:");
      display.drawString(0, 32, "Uptime :");
      display.drawString(0, 48, "FreeMem:");

      display.setTextAlignment(TEXT_ALIGN_RIGHT);
      display.drawString(128, 0,  String(temperatureString) );
      display.drawString(128, 16, String(pressureString) );
      display.drawString(128, 32, print_time() );
      display.drawString(128, 48, String(system_get_free_heap_size()) );
 
      display.display();
    }else{ if( display_enable = find_i2c(LCD_address) ) { display.init(); display.flipScreenVertically(); display.setContrast(255); } }
}

  server.handleClient();
}
(Стоит отметить, что в используемом библиотеке для дисплея надо поправить баг утечки памяти)
Если у вас проблемы с контактами - подергайте их.
 

lavAzza

New member
@gerkimuyda
и опять спасибо.)
чтоб темы не плодить, тут спрошу. вместо, видимо сгоревшего старого завевшегося с пол оборота bmp280 купил bmp280 от robotdyn вот такую Датчик атмосферного давления Bosch BMP280
а она - никак.. даташита в сети не нашел, даже на сайте производителя.. как ее подключить???
 

gerkimuyda

New member
Не знаю. Пробуйте. +3v и GND, SCK и SDO подключить и запустить сканирование I2C для нахождения адреса.

Код:
#include <Wire.h>
#include <Arduino.h>
long speed[] = { 50, 100, 200, 250, 400, 500, 800 };
const int speeds = sizeof(speed)/sizeof(speed[0]);
#define RESTORE_LATENCY  5   
bool delayFlag = false;
bool printAll = true;
bool header = true;
enum states { STOP, ONCE, CONT, HELP };
states state = STOP;
uint32_t startScan;
uint32_t stopScan;

void setup()  {
  Serial.begin(115200);
  Wire.begin();
  displayHelp();
}

void loop() {
  switch (getCommand()) {
    case 's':  state = ONCE; break;
    case 'c':  state = CONT; break;
    case 'd':  delayFlag = !delayFlag; Serial.print(F("<delay=")); Serial.println(delayFlag?F("5>"):F("0>")); break;
    case 'e':  break;
    case 'h':  header = !header; Serial.print(F("<header=")); Serial.println(header?F("yes>"):F("no>")); break;
    case '?':  state = HELP; break;
    case 'p':  printAll = !printAll; Serial.print(F("<print=")); Serial.println(printAll?F("all>"):F("found>")); break;
    case 'q':  state = HELP; break;
     default: break;
   }

  switch(state) {
    case ONCE: I2Cscan(); state = HELP; break;
    case CONT: I2Cscan(); delay(1000); break;   
    case HELP: displayHelp(); state = STOP; break;
    case STOP: break;
      default: break;
   }
}

char getCommand() {
  char c = '\0';
  if (Serial.available()) { c = Serial.read(); }
  return c;
}

void displayHelp() {
  Serial.println(F("\nArduino I2C Scanner - 0.1.03\n"));
  Serial.println(F("\ts = single scan"));
  Serial.println(F("\tc = continuous scan - 1 second delay"));
  Serial.println(F("\tq = quit continuous scan"));
  Serial.println(F("\td = toggle latency delay between successful tests."));
  Serial.println(F("\tp = toggle printAll - printFound."));
  Serial.println(F("\th = toggle header - noHeader."));
  Serial.println(F("\t? = help - this page"));
  Serial.println();
}

void I2Cscan() {
  startScan = millis();
  uint8_t count = 0;
  if (header) { Serial.print(F("TIME\tDEC\tHEX\t"));
    for (uint8_t s = 0; s < speeds; s++) {
      Serial.print(F("\t"));
      Serial.print(speed[s]);
     }
    Serial.println(F("\t[KHz]"));
    for (uint8_t s = 0; s < speeds + 5; s++) { Serial.print(F("--------")); }
    Serial.println();
   }

  for (uint8_t address = 8; address < 120; address++) {
    bool printLine = printAll;
    bool found[speeds];
    bool fnd = false;
    for (uint8_t s = 0; s < speeds ; s++) {
      Wire.beginTransmission (address);
      found[s] = (Wire.endTransmission () == 0);
      fnd |= found[s];
      if (fnd && delayFlag) delay(RESTORE_LATENCY);    // give device 5 millis
     }
    if (fnd) count++;
    printLine |= fnd;
    if (printLine) {
      Serial.print(millis());      Serial.print(F("\t"));
      Serial.print(address, DEC);  Serial.print(F("\t0x"));
      Serial.print(address, HEX);  Serial.print(F("\t"));
      for (uint8_t s = 0; s < speeds ; s++) { Serial.print(F("\t")); Serial.print(found[s]? F("V"):F(".")); }
      Serial.println();
     }
   }

  stopScan = millis();
  if (header) {
    Serial.println();
    Serial.print(count);
    Serial.print(F(" devices found in "));
    Serial.print(stopScan - startScan);
    Serial.println(F(" milliseconds."));
   }
}
 
Последнее редактирование:

lavAzza

New member
@gerkimuyda
отличный сканер!
выдает
7033 118 0x76 . . . . . . .
7036 119 0x77 V V V V V V V
Т.е. устройство таки обнаружено по 0x77?

Поменял в библиотеке адафруит бмп280 адрес i2c на 0x77, все равно
Код:
ME280 test
Could not find a valid BME280 sensor, check wiring!

Soft WDT reset

ctx: cont
sp: 3ffef760 end: 3ffef950 offset: 01b0

>>>stack>>>
3ffef910:  3ffe84c4 3ffee838 3ffef990 4020244c 
3ffef920:  3ffe89e8 7200a8c0 feefeffe feefeffe 
3ffef930:  3fffdad0 00000000 3ffee920 40204990 
3ffef940:  feefeffe feefeffe 3ffee930 40100718 
<<<stack<<<

ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16
tail 8
chksum 0x2d
csum 0x2d
v00000000
~ld
(((
 

gerkimuyda

New member
Да, это адрес, на котором отвечает какое-то устройство (ведь их может быть несколько на одной шине)

Вы как выводы указываете и адрес? Так?
Код:
 Wire.begin(D3, D4); delay(10);
bmp.begin(0x77);
У вас программа падает по WatchDogTimer. Вы какой код проверяете?
 
Последнее редактирование:

kab

New member

gerkimuyda

New member
Судя по логу, потом устройство перезагружается, но в режиме прошивки: Должно же быть 3,7 ? Это тоже что-то "нехорошее"?
kab, :D , учи матчасть: режимы 4,5,6,7 - это разные скорости. А режим прошивки - это bootmode 1, вместо работы bootmode 3
Код:
7 SDIO HighSpeed V2 IO Uart1 Booting
6 SDIO LowSpeed V1 IO Uart1 Booting
5 SDIO HighSpeed V1 IO Uart1 Booting
4 SDIO LowSpeed V2 IO Uart1 Booting
3 FLASH BOOT
2 Jump Boot
1 UART Boot
0 Remapping

Режим 7 и как и режим 6 самые часто встречаемые режимы и зависят от прошивки (их можно менять).
Вот по бутлоадеру можно посмотреть esp8266web/boot_1_2.c at master · pvvx/esp8266web · GitHub
 
Последнее редактирование:

lavAzza

New member
@gerkimuyda
Запускаю вот этот код (в библиотеке адафрут адрес по умолчанию стоит 0x77)
Код:
/*********
  Project: BME Weather Web server using NodeMCU
  Implements Adafruit's sensor libraries.
  Complete project is at: http://embedded-lab.com/blog/making-a-simple-weather-web-server-using-esp8266-and-bme280/
 
  Modified code from Rui Santos' Temperature Weather Server posted on http://randomnerdtutorials.com
*********/

#include <Wire.h>
#include <ESP8266WiFi.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#include <SPI.h>
#include <ArduinoJson.h>

Adafruit_BMP280 bmp; // I2C
//#define BMP280_address 0x77
// Replace with your network details
const char* ssid = "ssid";
const char* password = "pwd";
float t, p;
char temperatureString[6];
char pressureString[7];

StaticJsonBuffer<300> JSONbuffer;
JsonObject& JSONencoder = JSONbuffer.createObject();
// Web Server on port 80
WiFiServer server(80);

// only runs once on boot
void setup() {
  // Initializing serial port for debugging purposes
  Serial.begin(115200);
  delay(10);
  //Wire.begin(5, 4); delay(10);
  Wire.begin(D1, D2); delay(10);
  Wire.setClock(100000);
  // Connecting to WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Starting the web server
  server.begin();
  Serial.println("Web server running. Waiting for the ESP IP...");
  delay(10000);
 
  // Printing the ESP IP address
  Serial.println(WiFi.localIP());
  Serial.println(F("BMP280 test"));

  if (!bmp.begin(0x77)) {
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    while (1);
  }
}

void getWeather() {

    t = bmp.readTemperature();
    p = (bmp.readPressure() * 7.5006e-3);
    dtostrf(t, 5, 1, temperatureString);
    dtostrf(p, 6, 1, pressureString);
    delay(100);

}

// runs over and over again
void loop() {

  // Listenning for new clients
  WiFiClient client = server.available();
 
  //StaticJsonBuffer<300> JSONbuffer;
  //JsonObject& JSONencoder = JSONbuffer.createObject();
 
  if (client) {
    Serial.println("New 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();
            JSONencoder["Place"] = "Mub, 7";
            JSONencoder["Snum"] = "1";
            JSONencoder["Temp"] = temperatureString;
            JSONencoder["Pres"] = pressureString;
            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=\"Content-Type\" content=\"text/html; charset=utf-8\"></head>");
            client.println("<body>");
            String out;
            JSONencoder.printTo(out);
            client.println(out);
            client.println("</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();
    Serial.println("Client disconnected.");
  }
}
Ваш тоже, конечно же, тестировал - тоже не находит датчик.
прочитал один отзыв в алиэкспресса:
Хороший плюс это возможность запитать от 5 вольт. Библиотеку от Adafruit так и не смог запустить. Хорошо заработало с библиотекуой от IARDUINO.
Но iarduino не работает на ESP.
 

gerkimuyda

New member
Крэшися из-за 64 строки в вашем скетче (вечный цикл).

Там в Adafruit_BMP280.h есть еще привязка к чип_ид, и если он не совпадает - тогда функция begin возвращает, что датчик не найден.
Код:
    #define BMP280_ADDRESS                (0x76)
    #define BMP280_CHIPID                 (0x58)
Покопайте в эту сторону. Какой у вас CHIPID (если он считывается правильно)
Вставьте строку
[inline] Serial.print(read8(BMP280_REGISTER_CHIPID));[/inline]
в файл Adafruit_BMP280.cpp
Код:
bool Adafruit_BMP280::begin(uint8_t a, uint8_t chipid) {
  _i2caddr = a;

  if (_cs == -1) {
    // i2c
    Wire.begin();
  } else {
    digitalWrite(_cs, HIGH);
    pinMode(_cs, OUTPUT);

    if (_sck == -1) {
      // hardware SPI
      SPI.begin();
    } else {
      // software SPI
      pinMode(_sck, OUTPUT);
      pinMode(_mosi, OUTPUT);
      pinMode(_miso, INPUT);
    }
  }

  Serial.printf("0x%02X", read8(BMP280_REGISTER_CHIPID)); // <-- вот она
  if (read8(BMP280_REGISTER_CHIPID) != chipid)
    return false;

  readCoefficients();
  write8(BMP280_REGISTER_CONTROL, 0x3F);
  return true;
}
Это выведет значение CHIPID. Если он FF или 00 - значит значение не прочитано и у нас проблемы в коммуникации с модулем.
 
Сверху Снизу