• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 - значит значение не прочитано и у нас проблемы в коммуникации с модулем.
 
Сверху Снизу