DSM501A на ESP8266 - при питании от компьютера работает, от блока питания - нет. Почему?

Привет от новичка!

Собираю мини-датчик воздуха на ESP8266, в который подключены датчики SGP30, BME280 и DSM501A. Данные считываются через Wi-Fi со встроенного веб-сервера ESP8266.

С датчиком DSM501A странная проблема: при подключении NodeMCU к компьютеру по USB порту он работает и выдаёт нормальные показания, но если подключить плату к зарядке от смартфона - этот датчик не работает, точнее показывает значения вроде -0.01. У меня такое было, когда он был подсоединён +5V пином на +3V вывод, и есть ощущение, что ему не хватает питания. В то же время, пробовал его на хорошей 10-портовой зарядке и на хорошем кабеле, дающими ток более 1А - безрезультатно.

У меня этот датчик подключен похожим образом - сигнальные проводки к D5 и D7 (13 и 14 PIN), а GND - к соседнему с VIN. Вот у него на схеме GND сверху, а у меня - снизу. Замерили напряжение между VIN и GND при питании от USB зарядки - 5.02В.

Не знаю, код нужно или нет, если да - выложу.

Зарядка с USB штекером? Включаете в тот же USB разъем, что и при питании от компа?

То что это хороший зарядник для телефонов не делает это хорошим блоком питания для других устройств. Почитай стандарт на это на досуге.

думаю стандарты читать в данной ситуации это лишнее, а вот хороший фильтр по питанию наверняка поможет, просто ваша “хорошая” зарядка слишком шумит…

А вот лучше бы почитал.

ну ладно, давайте тогда уж конкретно, что именно почитать по стандартам питания, исключая “шум”(амплитуду и частоту пульсаций), о чем я написал выше, если человек там видит прибором 5 вольт?

Подключал через On-line UPS - та же история, так что шумы из сети исключены. Сейчас перепробую все зарядки в доме.

Стандарт. Весь. Чтобы знать, что такое “хорошая зарядка” на самом деле.

вы должны понимать, что подключать шумящий сам по себе зарядник от UPS не включенного в розетку - бесполезно, так ещё и притащит за собой кучу проблем офигенно кривой “синусоиды” которую формирует ваш UPS…

просто попробуйте зацепить на питание датчика электролитический и керамический конденсаторы

штудировать USB 1.0, USB 2.0, USB 3.0, USB 3.1 ?
А USB-C, QC и PD тоже читать?
зачем надувать щёки какими то стандартами когда проблема то элементарна?

Хорошая идея, а какие номиналы подойдут?

ну если по уму, то надо смотреть осциллографом частоту пульсаций как минимум, и тогда уж полноценный фильтр считать, но для начала покатит просто на вскидку электролит например на 50 Мкф и керамику 0.1 Мкф

Зачем молоть языком, когда ты сам точно не знаешь и не можешь знать в чем проблема.
И еще раз, для недоходчивых. Читать нужно для ликбеза, а не для решения конкретно этого вопроса.

Попробовали 3 электролита между VIN и GND с номиналами 16V ёмкостью 22, 100 и 1000 мкФ - толку ноль. С повербанка - то же самое. Может, дело в коде, и он каким-то образом не может часы сбросить?

/*********
  Complete project details at https://randomnerdtutorials.com  
*********/

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include<string.h>
//Подключаем библиотеку для BME280
#include <Adafruit_BME280.h>
// Подключаем библиотеку для SGP30
#include "Adafruit_SGP30.h"
// Подключаем библиотеку Wi-Fi
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
// Подключаем библиотеку Web-сервера
#include <ESP8266WebServer.h>

// ПАРАМЕТРЫ СЕТИ

/* Установите здесь свои SSID и пароль */
const char* ssid = "censored";       // SSID
const char* password = "censored";  // пароль

/* Настройки IP адреса */
IPAddress subnet(255, 255, 255, 0);			            // Subnet Mask
IPAddress gateway(192, 168, 17, 1);			            // Default Gateway
IPAddress local_IP(192, 168, 17, 4);			        // Static IP Address for ESP8266

// Настройки порта Web-сервера
ESP8266WebServer server(80);

// Определяем высоту над уровнем моря (в гектопаскалях)
#define SEALEVELPRESSURE_HPA (990.75) // высота над уровнем моря на 13 этаже - 178 метров по GPS

// Устанавливаем способ подключения датчиков
Adafruit_BME280 bme; // I2C
Adafruit_SGP30 sgp; // I2C

//unsigned long delayTime;


// Параметры для датчика PM2.5

#define PM1PIN 13//DSM501A input D6 on ESP8266
#define PM25PIN 14
byte buff[2];
unsigned long durationPM1;
unsigned long durationPM25;
unsigned long starttime;
unsigned long endtime;
unsigned long sampletime_ms = 30000;
unsigned long lowpulseoccupancyPM1 = 0;
unsigned long lowpulseoccupancyPM25 = 0;

int i=0;


// Формула компенсации датчика TVOC от температуры и влажности

/* return absolute humidity [mg/m^3] with approximation formula
* @param temperature [°C]
* @param humidity [%RH]
*/
uint32_t getAbsoluteHumidity(float temperature, float humidity) {
    // approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
    const float absoluteHumidity = 216.7f * ((humidity / 100.0f) * 6.112f * exp((17.62f * temperature) / (243.12f + temperature)) / (273.15f + temperature)); // [g/m^3]
    const uint32_t absoluteHumidityScaled = static_cast<uint32_t>(1000.0f * absoluteHumidity); // [mg/m^3]
    return absoluteHumidityScaled;
}

float Temperature;
float Humidity;
float Pressure;
float eCO2;
float TVOC;
int Absolutehumidity;
float ConcentrationPM1;
float ConcentrationPM25;
int baseline_eco2;
int baseline_tvoc;

// Первичная настройка системы


void setup() {
  Serial.begin(115200);
  Serial.println(F("BME280 test"));
  Serial.println("Starting please wait 30s");
  pinMode(PM1PIN,INPUT);
  pinMode(PM25PIN,INPUT);
  starttime = millis(); 

  bool status;

// Проверка датчиков
  status = bme.begin(0x76);  
  if (!status) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }

   if (!sgp.begin()) {
    Serial.println("SGP30 not found!");
    while (1);
  }
 
  // calibrate the sensor for indoor air quality
//  sgp.setIAQBaseline(0x8E14, 0x8F2E);

  Serial.println("-- Default Test --");
  Serial.println();



// Configure Wi-Fi
 if (WiFi.config(local_IP, gateway, subnet)) {
    Serial.println("Static IP Configured");
  }
  else {
    Serial.println("Static IP Configuration Failed");
  }
  
  WiFi.begin(ssid, password);

  Serial.print("Connecting...");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi Connected! IP address:");
  Serial.println(WiFi.localIP());

// Start Web-server

  server.on("/", handle_OnConnect);
  server.onNotFound(handle_NotFound);
  server.begin();
  Serial.println("HTTP server started");

}


// Расчёт параметров пыли
float calculateConcentration(long lowpulseInMicroSeconds, long durationinSeconds){
  
  float ratio = (lowpulseInMicroSeconds/1000000.0)/30.0*100.0; //Calculate the ratio
  float concentration = 0.001915 * pow(ratio,2) + 0.09522 * ratio - 0.04884;//Calculate the mg/m3
  Serial.print("lowpulseoccupancy:");
  Serial.print(lowpulseInMicroSeconds);
  Serial.print("    ratio:");
  Serial.print(ratio);
  Serial.print("    Concentration:");
  Serial.println(concentration);
  return concentration;
}


// сброс счётчика для вывода baseline
int counter =0;

// Основной цикл

void loop() { 

    if (!sgp.IAQmeasure()) {
    Serial.println("Measurement failed!");
    return;
  }


// Запуск веб-сервера
 server.handleClient();

/////// ДАТЧИК ПЫЛИ 

  durationPM1 = pulseIn(PM1PIN, LOW);
  durationPM25 = pulseIn(PM25PIN, LOW);
  
  lowpulseoccupancyPM1 += durationPM1;
  lowpulseoccupancyPM25 += durationPM25;
  
  endtime = millis();
  if ((endtime-starttime) > sampletime_ms) //Only after 30s has passed we calcualte the ratio
  {
    
    
    float conPM1 = calculateConcentration(lowpulseoccupancyPM1,30);
    float conPM25 = calculateConcentration(lowpulseoccupancyPM25,30);
    Serial.print("PM1 ");
    Serial.print(conPM1);
    Serial.print("  PM25 ");
    Serial.println(conPM25);
    lowpulseoccupancyPM1 = 0;
    lowpulseoccupancyPM25 = 0;

    ConcentrationPM1 = conPM1;
    ConcentrationPM25 = conPM25;



// Вывод температуры
  printtemperature();
// Вывод TVOC

  printtvoc();

// Вывод калибровки датчика TVOC


   counter++;
    Serial.print("Значения счётчика для Baseline: "); Serial.print(counter);
  if (counter == 3) {
    counter = 0;

    uint16_t TVOC_base, eCO2_base;
    if (! sgp.getIAQBaseline(&eCO2_base, &TVOC_base)) {
      Serial.println("Failed to get baseline readings");
      return;
    }
    Serial.print("****Baseline values: eCO2: 0x"); Serial.print(eCO2_base, HEX);
    Serial.print(" & TVOC: 0x"); Serial.println(TVOC_base, HEX);
    baseline_eco2 = (eCO2_base);
    baseline_tvoc = (TVOC_base);

  }




    starttime = millis();
  } 







 // delay(delayTime);
}

void printtemperature() {
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");
  Temperature = bme.readTemperature(); // Gets the values of the temperature
 

  Serial.print("Pressure = ");
  Serial.print(bme.readPressure() / 133.3F);
  Serial.println("mm. of mercury column");
  Pressure = (bme.readPressure() / 133.3F);

  Serial.print("Approx. Altitude = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");
  Humidity = bme.readHumidity(); // Gets the values of the humidity 
  Serial.println();
}


void printtvoc() {

  // Вывод температурных данных для компенсации
  float temperature = bme.readTemperature(); // [°C]
  float humidity = bme.readHumidity(); // [%RH]
  sgp.setHumidity(getAbsoluteHumidity(temperature, humidity));

  // print the air quality data
  Serial.print("eCO2: ");
  Serial.print(sgp.eCO2);
  Serial.print(" ppm\tTVOC: ");
  Serial.print(sgp.TVOC);
  Serial.println(" ppb");

  eCO2 = sgp.eCO2;
  TVOC = sgp.TVOC;
  Absolutehumidity= getAbsoluteHumidity(temperature,humidity);

 // Serial.print("Absolute Humidity:  ");
 // Serial.print(getAbsoluteHumidity(temperature,humidity));
 // Serial.println("Absolute Humidity");
 // Serial.print(absoluteHumidityScaled);


}

// Описание функции вывода
void handle_OnConnect() {

// Temperature = bme.readTemperature(); // Gets the values of the temperature
//  Humidity = bme.readHumidity(); // Gets the values of the humidity 
  server.send(200, "text/html", SendHTML(Temperature,Humidity,Pressure,eCO2,TVOC,Absolutehumidity,ConcentrationPM1,ConcentrationPM25,baseline_eco2,baseline_tvoc)); 
}

// Описание вывода 404-й ошибки
void handle_NotFound(){
  server.send(404, "text/plain", "Not found");
}

// Описание страницы вывода
String SendHTML(float Temperature,float Humidity, float Pressure, float eCO2, float TVOC, int Absolutehumidity, float ConcentrationPM1, float ConcentrationPM25, int baseline_eco2, int baseline_tvoc){
  String ptr = "<!DOCTYPE html> <html>\n";
  ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
  ptr +="<title>Chemtrail sensor</title>\n";
  ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
  ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
  ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
  ptr +="</style>\n";
  ptr +="</head>\n";
  ptr +="<body>\n";
  ptr +="<div id=\"webpage\">\n";
  ptr +="<h1>Chemtrail sensor</h1>\n";
  ptr +="<h1>BME280</h1>\n";
  
  ptr +="<p>Temperature: ";
  ptr += Temperature;
  ptr +=" C</p>";
  ptr +="<p>Humidity: ";
  ptr += Humidity;
  ptr +="%</p>";
  ptr +="<p>Pressure: ";
  ptr += Pressure;
  ptr +="mm Hg C</p>";

  ptr +="<h1>SGP30</h1>\n";

   ptr +="<p>eCO2: ";
   ptr += eCO2;
   ptr +=" ppm</p>";
   ptr +="<p>TVOC: ";
   ptr += TVOC;
   ptr +=" ppb</p>";
   ptr +="<p>Absolutehumidity: ";
   ptr += Absolutehumidity;
   ptr +=" mm Hg C</p>";
   ptr +="<p>Baseline Values: ";
   ptr += baseline_tvoc;
   ptr +=" - tvoc, ";
   ptr += baseline_eco2;
   ptr +=" - eco2</p>";


   ptr +="<h1>DSM501A</h1>\n";

   ptr +="<p>Concentration PM 1: ";
   ptr += ConcentrationPM1;
   ptr +=" mg/cubemeter</p>";
   ptr +="<p>Concentration PM 2.5: ";
   ptr += ConcentrationPM25;
   ptr +=" mg/cubemeter</p>";

  ptr +="</div>\n";
  ptr +="</body>\n";
  ptr +="</html>\n";
  return ptr;
}


И того, на схеме должны присутствовать:

  1. ESP8266.
  2. SGP30.
  3. BME280.
  4. DSM501A.
  5. Блок питания.

Итого - 5 устройств.
А что мы видим на приведенной наскальной живописи?

При чём тут код, если вы говорите что от USB компа всё работает исправно?

конденсатор желательно вешать на плату датчика!

и да, вам написали выше, рисуйте всю схему целиком! Вы точно когда отключили балалайку от компа только питание подключили или всю схему “оптимизировали” и теперь пытаетесь заставить взлететь?

Схема достаточно проста: есть плата NodeMCU1 ESP8266 с разъёмом Mini-USB и WiFi.
(если смотреть лицом на плату с USB разъёмом снизу)

ESP8266

SGP 30 подключен:

  • SDA - D3
  • SCL - D2
  • GND - GND справа по центру
  • VCC - VIN - 3V справа снизу

BME280 подключен:

  • SDA - D3
  • SCL - D2
  • GND - GND справа снизу
  • VCC - VIN -3V справа снизу

DSM501A подключен:

  • 5 Ground - GND слева снизу
  • 4 PM25 - D5
  • 3 VCC - VIN слева снизу
  • 2 PM1 - D7

Втыкаю в компьютер, подключаю к фронтальному USB на корпусе, закрываю Arduino IDE, захожу на Web-морду - показания DSM501A нормальные, вроде 0.71/0.19. Отключаю от компьютера, подключаю к USB порту зарядок или повербанков тем же или другими USB кабелями - захожу на Web-морду: показания DSM501A в районе 0.01/-0.05, как положительные так и отрицательные, колеблются, по прошествии 15 минут ситуация не меняется, нормальные данные он так и не выдаёт. Снова отключаю от зарядок - подключаю к компу и всё нормально.

Аналогично подключил к старому Macbook - нормально.

К показаниям SGP30 и BME280 вопросов нет, там всё норм.

что-то верится с трудом, вот распиновка nodemcu

#define PIN_WIRE_SDA (4)
#define PIN_WIRE_SCL (5)

static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;

#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif
#define LED_BUILTIN_AUX 16

static const uint8_t D0   = 16;
static const uint8_t D1   = 5;
static const uint8_t D2   = 4;
static const uint8_t D3   = 0;
static const uint8_t D4   = 2;
static const uint8_t D5   = 14;
static const uint8_t D6   = 12;
static const uint8_t D7   = 13;
static const uint8_t D8   = 15;
static const uint8_t D9   = 3;
static const uint8_t D10  = 1;

#include "../generic/common.h"

#endif /* Pins_Arduino_h */

Подключили через блок питания 5V, та же история. Может, там с PWM что-то связано? По какой-то причине от компьютера же он запускается?

Я тебе просто так распиновку вытащил? Где у тебя синхронизация ???