Все великолепно. До минус 16 неделю были морозы. С похолоданием напряжение увеличивается на графиках.как аккум зимой? или у вас не бывает сильных морозов?
#define VccDiode 840//Падение напряжения (мВ) на диоде в питании ESP от литиевого АКБ для коректировки показаний напряжения питания 3,95/3,49
#define maxVCC 4150// Максимальное напряжение питания. При превышении ЕСП не отключается а садит батарею.
Нет, еще одну собираю. Первая, откуда график скинул, работает на лифере на предыдущей прошивке. 5000мАч слишком жирно на самом деле.мне больше интересно что будет за неделю морозов в -35, но это скоро сам уже проверю
посмотрел код, судя по этим строчкам:
отказались от LiFePo4?C++:#define VccDiode 840//Падение напряжения (мВ) на диоде в питании ESP от литиевого АКБ для коректировки показаний напряжения питания 3,95/3,49 #define maxVCC 4150// Максимальное напряжение питания. При превышении ЕСП не отключается а садит батарею.
Да так же, просто солнечная батарея через диод шотки с падением 0,2 В. Один нюанс - ESP подключается к банке литя минуя плату защиты чтоб в определенный момент срабатывания платы защиты все напряжение ХХ солнца не прошло на спящий ESP. С диодом между банкой и есп пока не разобрался, вроде от 4,2В работает но даташит на esp и bmp запрещает.прошивка не нужна, я использую 18б20
вчера купил лифе на 6500 мАч, допилю корпус и выставлю на мороз
вэб морда как по мне для такого устройства вообще лишнее, а вот подключение солнечной панели к литию интересно
#ESPхххххххх
#TEMPC#23.66
#PRESS#99608.85
#VCC#3905
#WORKTIME#0.27
#WM#3
#283bd17997080365#21.00
#WIFI#-74
#LUX#2980#
##
#include <ESP8266WiFi.h>
//Настройки скетча:
#define debug false // Вывод отладочных сообщений в TCP сервер. Замедляет работу. false по умолчанию
#define Host "narodmon.ru"//"185.245.187.136"//"192.168.0.32"// можно запустить свой сервер с портом 8283 и смотреть во время отладки. Например https://swiddler.com/ (не отображает кодировку кириллицы)
#define SendData true // Отправлять данные на сервер (для отладки). true по умолчанию
#define postingInterval 330e6 // интервал между отправками данных в секундах (330 сек=5,5 минут)
#define MinVccSleep 4e9 // Время спячки при севших батарейках. 0 - до передергивания питания.
#define Recall 60e6 //время переподключения если нет сети или соединения с хостом
#define VccDiode -140//Падение напряжения (мВ) на диоде в питании ESP от литиевого АКБ для коректировки показаний напряжения питания. У меня показывает больше чем в реале, поэтому с минусом.
#define maxVCC 4230// Максимальное напряжение питания. При превышении ЕСП не отключается а садит батарею.
#define minVCC 3000 // Минимальное реальное напряжение питания.
#define swSCL 3 // Пины подключения датчика BMx280 IO3
#define swSDA 1 // Пины подключения датчика BMx280
#define OneWireGpio 0 // GPIO к которому подключен DS18B20
#define DS18B20Resolution 9 // точность бит.DS18B20 от 9 до 12. Чем выше разрядность тем медленее работает. 9=0,5`С 10=0,25`С
#define MeasureLightPin 2 // сюда фоторезистор и на + а также сюда конденсатор 2,2 мкФ и на минус.
#define ssid "ssid"
#define password "pasd"
#define local_IP {192, 168, 1, 5}
#define gateway {192, 168, 1, 1}
#define subnet {255, 255, 255, 0}
#define primaryDNS {192, 168, 1, 1}
#define secondaryDNS {8, 8, 4, 4}
#include <Wire.h>
#define WireClock 400e3//Разгоняем шину I2C в 4 раза до 400 кГц (только софтварная так может, хардварная 100e3)
#include <Adafruit_BMP280.h>// в менеджере библиотек стандартная + установить библиотеку adafruit unified sensor. В библиотеке Adafruit_BMP280.cpp закомментировать 105 строку delay(100);
Adafruit_BMP280 bmp;
#define bmx280AddressI2C 0x76 // Адрес датчика. Может быть 0x77.
#include <DallasTemperature.h>
OneWire oneWire(OneWireGpio);
DallasTemperature DS18B20(&oneWire);
uint32_t WaitDS18B20;// время ожидания измерения DS18B20
String DebugBuf;//строка Debug info
void ICACHE_RAM_ATTR InterruptMeasureLightPin();//ставим функцию прерываний InterruptMeasureLightPin() в RAM память для стабильной работы
uint32_t RCtime1;// тут хранится начальное время RC цепи
volatile uint32_t RCtime2;// тут хранится конечное время RC цепи
ADC_MODE(ADC_VCC);// Будем измерять напряжение на VCC внутри МК
int VCC; //Напряжение батареи
uint32_t calculateCRC32(const uint8_t *data, size_t length);
struct { //Структура, хранящаяся в RTC памяти
uint32_t crc32;
uint32_t NumberOfTransmitted; // Номер переданніх данніх после последней подачи питания
uint32_t SendDataTime; // Время работы последней отправки
bool LightSensor_not_found;
bool bmx_not_found;
bool DS18B20_not_found;
DeviceAddress DS18B20Address;
byte DS18B20Count;
} rtcData;
/[I]Расчет CRC32 RTC памяти[/I]/
uint32_t calculateCRC32(const uint8_t *data, size_t length) {// Расчет CRC RTC памяти чтоб понять битые там данные или нет
uint32_t crc = 0xffffffff;
while (length--) {
uint8_t c = *data++;
for (uint32_t i = 0x80; i > 0; i >>= 1) {
bool bit = crc & 0x80000000;
if (c & i) {
bit = !bit;
}
crc <<= 1;
if (bit) {
crc ^= 0x04c11db7;
}
}
}
return crc;
}
/[I]Читаем данные из RTC памяти[/I]/
void RTCread() {
if (ESP.rtcUserMemoryRead(0, (uint32_t*) &rtcData, sizeof(rtcData))) {
uint32_t crcOfData = calculateCRC32((uint8_t*) &rtcData.NumberOfTransmitted, sizeof(rtcData) - sizeof(rtcData.crc32)); // Вычисляем crc32 начиная с адреса хранения переменной rtcData.NumberOfTransmitted до адресса размера в байтах структуры rtcData за исключением первой переменной, хранящей crc32
if (crcOfData != rtcData.crc32) {// При первом включении и при битых данных в RTC памяти
rtcData.NumberOfTransmitted = 1; //количество включений Назначаем данные по умолчанию при первом включении
rtcData.SendDataTime = 0;// время работы
rtcData.LightSensor_not_found = false;
rtcData.bmx_not_found = false;
rtcData.DS18B20Count = 0;
}
}
}
/[I]Обновляем данные в RTC памяти[/I]/
void RTCupdate() {
rtcData.NumberOfTransmitted++;// Увеличиваем количество срабатываний
rtcData.SendDataTime = millis();// Запоминаем время передачи
rtcData.crc32 = calculateCRC32((uint8_t*) &rtcData.NumberOfTransmitted, sizeof(rtcData) - sizeof(rtcData.crc32));
ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcData, sizeof(rtcData));// Write struct to RTC memory
}
/[I]процедура ожидания подключения к Wifi. длится в идеале 129мс[/I]/
void wificonect() {
int i = 0;
if (debug) DebugBuf += String(millis()) + "ms Time not wifi \n"; //64 мс
while (WiFi.status() != WL_CONNECTED) {
delay(1);
i++; if (i > 200000) {
RTCupdate();
ESP.deepSleep(5e6, RF_NO_CAL);//СПИМ если не было соединения в течении 5 секунд. Если у вас плохой конект с wifi то следует увеличить число до 10000
}
}
if (debug) DebugBuf += String(millis()) + "ms wifi conected!\n";
}
void setup() {
if (debug) DebugBuf += "\n\nDebug info:\n" + String(millis()) + "ms void setup()\n";
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
RTCread();// Пока конектится wifi читаем переменные из RTC памяти что сохранили перед прошлым сном
if (rtcData.NumberOfTransmitted == 1) {
WiFi.begin(ssid, password); // Если уже было подключение хоть раз то ssid и pass хранятся во флеше и берутся от туда раньше чем скетч начнет исполнятся. К этому моменту соединение с wifi установлено, назначаются ip адреса
}
if (rtcData.NumberOfTransmitted == 1 || !rtcData.bmx_not_found) {// Если датчик BMP280 был обнаружен или первый запуск
Wire.setClock(WireClock);// Разгоняем шину I2C
Wire.begin(swSDA, swSCL);
}
Measure();// Запускаем измерения датчиков
SendToNarodmon();
while (VCC >= maxVCC && (millis() * 1e3 + 20e3) < postingInterval) { // Цикл разряда батарейки выполняется когда превышено напряжение и времени прошло на 20 секунд меньше чем до следующей передачи данных
VCC = ESP.getVcc() + VccDiode;
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
delay(10e3);// ждем 10 сек
}
RTCupdate();
ESP.deepSleep(postingInterval - millis() * 1e3, RF_NO_CAL); // спим до следующей передачи данных
}
void loop() {}
void Measure() { // Запуск измерения датчиков
/[I]-------------VCC-------------------[/I]/
VCC = ESP.getVcc() + VccDiode; //Корректировка напряжения АКБ
if ((VCC - VccDiode) < minVCC) {
RTCupdate();
ESP.deepSleep(MinVccSleep); // спим при низком питании
}
/[I]---------------DS18B20--------------[/I]/
DS18B20.begin(); //ds18b20
DS18B20.setWaitForConversion(false);//Асинхронный режим, т.е. функция requestTemperatures() не ждет 650 мс.
if (rtcData.NumberOfTransmitted == 1) { // При первом включении находим датчики DS18B20 и запоминаем их.
rtcData.DS18B20Count = DS18B20.getDeviceCount(); //поищем.
for (int i = 0; i < rtcData.DS18B20Count; i++) {
if (DS18B20.getAddress(rtcData.DS18B20Address, i)) DS18B20.setResolution(rtcData.DS18B20Address, DS18B20Resolution); //настроим.
}
if (debug) DebugBuf += String(millis()) + " getAddress\n";
}
if (rtcData.DS18B20Count) { //Если DS18B20 подключены то запрашиваем измерения
DS18B20.requestTemperatures(); //Начали измерение ds18b20
WaitDS18B20 = millis();
if (debug) DebugBuf += String(WaitDS18B20) + " DS18B20.requestTemperatures()\n";
}
/[I]-----Запуск измерения освещенности посредством времени RC цепи.--------[/I]/
if (rtcData.NumberOfTransmitted == 1 || !rtcData.LightSensor_not_found) {//Если датчик света обнаружен или это первый запуск
pinMode(MeasureLightPin, OUTPUT);//разряжаем конденсатор
delay(1);
attachInterrupt (digitalPinToInterrupt (MeasureLightPin), InterruptMeasureLightPin, CHANGE);// включаем прерывание которое сработает при заряде конденсатора до логической единицы
pinMode(MeasureLightPin, INPUT);// начало заряда
RCtime1 = micros();// запоминаем время начала заряда конденсатора
if (digitalRead(MeasureLightPin)) {
rtcData.LightSensor_not_found = true;
detachInterrupt (digitalPinToInterrupt(MeasureLightPin));
}
}
/[I]-------------BMX280----------------[/I]/
if (rtcData.NumberOfTransmitted == 1) { //Если это первый запуск
if (!bmp.begin(bmx280AddressI2C, 0x58)) { //I2C адрес и chip ID. В зависимости от перемычки на плате адресс может быть 77
if (debug) DebugBuf += "bmp.begin failed\n";//64 мс
rtcData.bmx_not_found = true;
} else {
/[I]Устанавливаем параметры в соответствии с рекомендациями даташита по минимальному потреблению для Weather monitoring(lowest power). Измерения рекомендовано проводить 1р/минуту[/I]/
bmp.setSampling(Adafruit_BMP280::MODE_FORCED, /*MODE_SLEEP, MODE_FORCED, MODE_NORMAL Operating Mode. */
Adafruit_BMP280::SAMPLING_X1, /* Temp. oversampling 1.2.4.8.16*/
Adafruit_BMP280::SAMPLING_X1, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16/[I], /*Filtering. FILTER_OFF X2.4.8.16[/I]/
/[I]Adafruit_BMP280::STANDBY_MS_500[/I]/); /* Standby time. 1.63.125.250.500.1000.2000.4000 используется только в MODE_NORMAL*/
}
} else {
if (!rtcData.bmx_not_found) {// если датчик біл обнаружен при первом запуске
if (!bmp.begin(bmx280AddressI2C, 0x58)) {
RTCupdate(); //при сбое датчика перезагружаемся
ESP.deepSleep(20e6, RF_NO_CAL);
}
}
}
/[I]-------------------------------------[/I]/
}
void InterruptMeasureLightPin() {// по прерыванию в момент заряда конденсатора запоминаем время
RCtime2 = micros();
}
void SendToNarodmon() { // Собственно формирование пакета и отправка.
String buf = "#ESP" + WiFi.macAddress() + "\n"; //mac адрес для авторизации датчика
buf.replace(":", "");// удаляем двоеточия из мак адреса
String worcktime;
float WTime;
if (rtcData.NumberOfTransmitted == 1) { // При первом соединении передаем тип, показания и имена датчиков, при последующих только тип и показания
if (!rtcData.bmx_not_found) { // если bmx подключен то выводим с него данные
buf += "#TEMPC#" + String(bmp.readTemperature()) + "#Датчик температуры BMP280\n" + "#PRESS#" + String(bmp.readPressure()) + "#Датчик давления BMP280\n"; //показания температуры и давления
}
//Данные от ESP ( Напряжение питания,уровень wifi
buf += "#VCC#" + String(VCC) + "#Напряжение батареи\n"; //показания температуры
worcktime = String(rtcData.SendDataTime); // Время работы при предыдущей отправке
WTime = worcktime.toInt(); WTime /= 1000;
buf += "#WORKTIME#" + String(WTime) + "#Время передачи данных\n";
buf += "#WM#" + String(rtcData.NumberOfTransmitted) + "#№ показаний\n";
if (rtcData.DS18B20Count) {
WaitDS18B20 = millis() - WaitDS18B20;
//if (debug) DebugBuf += "timeDS " + String(WaitDS18B20) + "\n" + "millis=" + String(millis()) + "\n"; //64 мс
int DelayResolutionTime = 750 / (1 << (12 - DS18B20Resolution));
if (DelayResolutionTime > WaitDS18B20)
delay(DelayResolutionTime - WaitDS18B20);
if (debug) DebugBuf += "millis=" + String(millis()) + "\n" + "DelayResolutionTime " + String(DelayResolutionTime) + "\n" + "DelayResolutionTime-WaitDS18B20=" + String(DelayResolutionTime - WaitDS18B20) + "\n";
for (int i = 0; i < rtcData.DS18B20Count; i++) { //перечисляем датчики 18b20 и их показания
DS18B20.getAddress(rtcData.DS18B20Address, i);
buf = buf + "#";
for (uint8_t i = 0; i < 8; i++) {
if (rtcData.DS18B20Address[i] < 16) buf = buf + "0"; // адрес датчика
buf = buf + String(rtcData.DS18B20Address[i], HEX);
}
buf = buf + "#" + String(DS18B20.getTempCByIndex(i)) + "#DS18B20 №" + String(i + 1) + "\n"; //и температура
}
}
} else {
if (!rtcData.bmx_not_found) { // если bmx подключен то выводим с него данные
buf += "#TEMPC#" + String(bmp.readTemperature()) + "\n" + "#PRESS#" + String(bmp.readPressure()) + "\n"; //показания температуры и давления
}
//Данные от ESP ( Напряжение питания,уровень wifi
buf += "#VCC#" + String(VCC) + "\n"; //показания температуры
worcktime = String(rtcData.SendDataTime); // Время работы при предыдущей отправке
WTime = worcktime.toInt(); WTime /= 1000;
buf += "#WORKTIME#" + String(WTime) + "\n";
buf += "#WM#" + String(rtcData.NumberOfTransmitted) + "\n";
if (rtcData.DS18B20Count) {
WaitDS18B20 = millis() - WaitDS18B20;
//if (debug) DebugBuf += "timeDS " + String(WaitDS18B20) + "\n" + "millis=" + String(millis()) + "\n"; //64 мс
int DelayResolutionTime = 750 / (1 << (12 - DS18B20Resolution));
if (DelayResolutionTime > WaitDS18B20)
delay(DelayResolutionTime - WaitDS18B20);
if (debug) DebugBuf += "millis=" + String(millis()) + "\n" + "DelayResolutionTime " + String(DelayResolutionTime) + "\n" + "DelayResolutionTime-WaitDS18B20=" + String(DelayResolutionTime - WaitDS18B20) + "\n";
for (int i = 0; i < rtcData.DS18B20Count; i++) { //перечисляем датчики 18b20 и их показания
DS18B20.getAddress(rtcData.DS18B20Address, i);
buf = buf + "#";
for (uint8_t i = 0; i < 8; i++) {
if (rtcData.DS18B20Address[i] < 16) buf = buf + "0"; // адрес датчика
buf = buf + String(rtcData.DS18B20Address[i], HEX);
}
buf = buf + "#" + String(DS18B20.getTempCByIndex(i)) + "\n"; //и температура
}
}
if (debug) DebugBuf += String(millis()) + "DS18B20.getTempCByIndex(i)\n";
}
wificonect();// ожидание установки соединения с сетью
WiFiClient client;
buf += "#WIFI#" + String(WiFi.RSSI()) + "\n"; // уровень WIFI сигнала
if (SendData) {
if (!client.connect(Host, 8283)) { // подключение
RTCupdate();
ESP.deepSleep(50e65, RF_NO_CAL);// Если не вышло подключится - засыпаем
}
}
if (!rtcData.LightSensor_not_found) { // Если датчик освещенности с конденсатором подключены
if (!RCtime2) { //Если конденсатор не успел зарядится
RCtime2 = micros();
}
uint32_t Lux = constrain((RCtime2 - RCtime1), 1, 160000);//Double тип переменной
Lux = sqrt(Lux) * 10;
Lux = map(Lux, 1, 4000, 10000, 1);//попугаи света.
//Lux = exp(Lux / 1000); //приводим к линейному значению
buf += "#LUX#" + String(Lux) + "#\n##\n";
} else buf += "##\n";
if (debug)buf += DebugBuf;
if (SendData) client.print(buf); // и отправляем данные кроме освещенности
if (debug) {
}
delay(10);// сделать 100 если нужен ответ или 10 если не нужен . Время активности увеличивается в 2 раза
if (SendData) {
while (client.available()) {
String line = client.readStringUntil('\r'); //
}
}
}
#include <Arduino.h>
#include <Arduino_JSON.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <HttpClient.h>
#include <ArduinoJson.h> // Библиотека для разбора JSON
#define number_of_sensors 3 //Количество датчиков
#define interval 60e3 // Время между запросами данных в секундах. Минимум 60 секунд по условиям народного мониторинга
String SensorID = "51831,51830,51843"; // Уникальные номера датчиков, с которых хотим видеть показания
String uuid = "xxxxxxxxxxx"; // уникальный идентификатор md5 можно сгенерировать для себя из мака http://www.md5.cz/
String api_key = "xxxxxxxxxx"; // берется на сайте народного мониторинга "профиль - мои приложения - Новый ключ и скопировать Ключ API
WiFiClient client;
void setup() {
Serial.begin(115200);
WiFi.begin("xxxxxx", "xxxxxxxx"); // логин, пароль wifi сети
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(100);
}
Serial.println(WiFi.macAddress());
}
void loop() {
if (!GetNarodmon()) {
Serial.println ("Ошибка");
} else {Serial.println ("Данные обновлены");}
delay (interval);// ждем минуту
}
bool GetNarodmon() { // Собственно формирование пакета и отправка и прием ответа с данными.
// попытка подключения
if (client.connect("narodmon.ru", 80)) {
client.println("GET /api/sensorsValues?sensors=" + SensorID + "&uuid=" + uuid + "&api_key=" + api_key + " HTTP/1.1\r\nHost:narodmon.ru\r\nConnection: close\r\n\r\n"); // и отправляем запрос.
delay(100);// сделать 100 если нужен ответ или 10 если не нужен . Время активности увеличивается в 2 раза
while (client.available()) {
delay (1);
}
char endOfHeaders[] = "\r\n\r\n"; // Системные заголовки ответа сервера отделяются от остального содержимого двойным переводом строки
if (!client.find(endOfHeaders)) { // Отбрасываем системные заголовки ответа сервера
Serial.println("Invalid response"); // Если ответ сервера не содержит системных заголовков, значит что-то пошло не так
return false;
}
const size_t capacity = 1532; // Эта константа определяет размер буфера под содержимое JSON 8ми датчиков (расчитывается тут https://arduinojson.org/v5/assistant/)
DynamicJsonDocument doc(capacity); // Инициализируем буфер под JSON
deserializeJson(doc, client); // Парсим JSON-содержимое ответа сервера
//serializeJson(doc, Serial); Serial.println(); //Выводим содержимое что прислал сервер
//serializeJsonPretty(doc, Serial); Serial.println(); //Выводим содержимое что прислал сервер красиво по строчкам
client.stop();// Разрываем соединение с сервером
for (int i = 0; i < number_of_sensors; i++) {// Парсим значение датчиков и выводим в сериал
String val = doc["sensors"][i]["value"]; // где i номер фигурных скобок из json ответа, по факту номер датчика,
/* такой ответ прийдет от сервера для конкретного датчика
* {"id":54516,"type":1,"value":26,"time":1595587168,"changed":1595587168,"trend":0},
* и такой ответ будет сидеть в JsonDocument
* {"sensors":[{"id":4309,"type":18,"value":3.53,"time":1595587168,"changed":1595587168,"trend":0},{"id":51830,"type":2,"value":35.49,"time":1595587168,"changed":1595587168,"trend":0},{"id":51843,"type":3,"value":752.49,"time":1595587168,"changed":1595587168,"trend":0},{"id":52446,"type":1,"value":26.81,"time":1595587168,"changed":1595587168,"trend":0},{"id":54516,"type":1,"value":26,"time":1595587168,"changed":1595587168,"trend":0},{"id":54519,"type":1,"value":24.75,"time":1595587168,"changed":1595587168,"trend":0},{"id":54544,"type":13,"value":3.31,"time":1595587168,"changed":1595566725,"trend":0},{"id":57282,"type":255,"value":42,"time":1595587168,"changed":1595587168,"trend":0}]}
* помимо данных можно брать все остальное что пришло включая текущее время и давность полученных данных.
*/
Serial.println(val);//тут выводятся значения, полученные с датчиков
}
return true;
}
}
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "**********";
const char* password = "**********";
const String sensor = "7237"; //Номер датчика на народном мониторинге
const String uuidNM = "******************";
const String api_keyNM = "******************"; //ключ
const String urlNM = "http://narodmon.ru/api/sensorsOnDevice?id="+sensor+"&uuid="+uuidNM+"&api_key="+api_keyNM+"&lang=ru";
WiFiClient client;
String httpData;
void httpRequest(String http) {
HTTPClient client;
Serial.print("Connecting ");
client.begin(http);
int httpCode = client.GET();
if (httpCode > 0) {
Serial.printf("successfully, code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
httpData = client.getString();
Serial.println(httpData);
}
}
else Serial.printf("failed, error: %s\n", client.errorToString(httpCode).c_str());
client.end();
}
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
httpRequest(urlNM);
StaticJsonDocument<1024> doc;
deserializeJson(doc, httpData);
JsonObject sensors_0 = doc["sensors"][0];
float temp = sensors_0["value"];
Serial.print("street temp: ");
Serial.println(temp);
}
void loop() {
// put your main code here, to run repeatedly:
}
Кажется разобрался, не тот номер датчика вводил нужно было именно у владельца который 494. И по умолчанию выводило давление вместо температуры, изменил значение sensors_0 на sensors_1 и все прекрасно показывает. Спасибо!этот код отправляет запрос один раз при старте, перенеси все в цикл loop и поставь задержку опроса какую нужно
давай строку ответа посмотрим чтобы понять почему не срабатывает с твоим датчиком
теперь можешь попробовать предыдущий код в работе, только мне кажется он написан для другой версии библиотеки json, можно понизить версию до 5 в менеджере библиотекКажется разобрался
чем плох код из первого поста темы?enemy_krs, спасибо за простой и рабочий пример для старта...
{"id":7237,"name":"ESP8266_3"....}
street temp: -13.88 *C
а не завалялся ли у Вас, аналогичный, но для публикации датчика на народмоне?
#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//коэффициент для корректировки напряжения
#define VCC_ADJ 0.96
// сигнальный провод датчика
#define ONE_WIRE_BUS 2
// создаём объект для работы с библиотекой OneWire
OneWire oneWire(ONE_WIRE_BUS);
// создадим объект для работы с библиотекой DallasTemperature
DallasTemperature sensor(&oneWire);
const char* ssid = "**********";
const char* password = "**********";
IPAddress local_IP(10, 0, 0, 11);
IPAddress gateway(10, 0, 0, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(10, 0, 0, 1);
IPAddress secondaryDNS(8, 8, 8, 8);
const char* host = "narodmon.ru";
const int httpPort = 8283;
// Пин питания датчика
int Vout = 0;
ADC_MODE (ADC_VCC);
void setup() {
pinMode(Vout, OUTPUT);
digitalWrite(Vout, HIGH);
sensor.begin();
delay(10);
sensor.setResolution(10); // устанавливаем разрешение градусника 9, 10, 11, или 12 bit
sensor.requestTemperatures();
}
void loop() {
wificonect(); // подключаемся к сети
Send(); // отправляем
ESP.deepSleep(300e6); // сон
}
// процедура подключения к Wifi
void wificonect() {
WiFi.mode(WIFI_STA);
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(false);
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
int i;
delay(1);
i++; if (i > 3000) ESP.deepSleep(300e6); // сон 5 минут если нет подключения
}
}
//данные на народмон
void Send() {
WiFiClient client;
float temp = sensor.getTempCByIndex(0);
digitalWrite(Vout, LOW);
int voltInt = ESP.getVcc();
long volt = voltInt*VCC_ADJ;
client.connect(host, httpPort);
client.print("#"+WiFi.macAddress()+"#ESP"+ESP.getChipId()+"\n#Temp#"+temp+"\n#Vcc#"+volt+"\n##");
delay(10);
//client.stop();
//WiFi.disconnect(); // отключаемся от сети
}
На народмоне раздел Справка - Arduino куча примеров. Там же Справка - API передачи показаний. Рекомендую Json запрос освоить. По ссылке из предыдущего моего сообщения можно посмотреть как устроена авторизация на народмоне, там простой пример во втором сообщении, используя API передачи показаний переделать будет не сложно.к примеру, имеем динамически меняющуюся переменную... температуры testTemp
и вот как правильно законектиться, и как правильно, какие параметры и в какой последовательности передать на сервер
далее мне было бы легче разобраться... попробую конечно, извиняюсь за ламерский вопрос
А вы не подскажите как сделать так чтобы вывод температуры был к примеру не -21.00, а -21.0 чтобы до десятых округляло, а не до сотых?C++:#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <ArduinoJson.h> const char* ssid = "**********"; const char* password = "**********"; const String sensor = "7237"; //Номер датчика на народном мониторинге const String uuidNM = "******************"; const String api_keyNM = "******************"; //ключ const String urlNM = "http://narodmon.ru/api/sensorsOnDevice?id="+sensor+"&uuid="+uuidNM+"&api_key="+api_keyNM+"&lang=ru"; WiFiClient client; String httpData; void httpRequest(String http) { HTTPClient client; Serial.print("Connecting "); client.begin(http); int httpCode = client.GET(); if (httpCode > 0) { Serial.printf("successfully, code: %d\n", httpCode); if (httpCode == HTTP_CODE_OK) { httpData = client.getString(); Serial.println(httpData); } } else Serial.printf("failed, error: %s\n", client.errorToString(httpCode).c_str()); client.end(); } void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } httpRequest(urlNM); StaticJsonDocument<1024> doc; deserializeJson(doc, httpData); JsonObject sensors_0 = doc["sensors"][0]; float temp = sensors_0["value"]; Serial.print("street temp: "); Serial.println(temp); } void loop() { // put your main code here, to run repeatedly: }
float temp = -21;А вы не подскажите как сделать так чтобы вывод температуры был к примеру не -21.00, а -21.0 чтобы до десятых округляло, а не до сотых?
#include <ESP8266WiFi.h>
#define debug false // вывод отладочных сообщений
#define postingInterval 330e6 // интервал между отправками данных в секундах (330 сек=5,5 минут)
#define ONE_WIRE_BUS 0 // GPIO к которому подключен DS18B20
#define TEMPERATURE_PRECISION 12 // точность бит.DS18B20 Если глючит или врет, уменьшить до 9
#define TEMPERATURE_MEASURE_TIME 750 // время на преобразование температуры. 9бит-94мс, 10-188,11-375,12-750
#define DS18b20_VCC 2 //Нога питания датчика температуры
// #define BMX280_VCC 13 //Нога питания датчика давления
#define ssid "ssid"
#define password "pass"
#define DHCP true
IPAddress local_IP(192, 168, 0, 199);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(192, 168, 0, 1);
IPAddress secondaryDNS(8, 8, 4, 4);
#define chanal 6//канал wifi
byte macAP[6] = {0xF8, 0x1A, 0x67, 0x86, 0x14, 0x70}; //mac роутера
unsigned long mill[2], startmillisDS18B20;// переменные для установки времени на измерение 18B20
#include <DallasTemperature.h>
#include <Wire.h>
// #include <BMx280I2C.h>
// byte bmx_not_found = false;
// BMx280I2C bmx280(0x76);
ADC_MODE(ADC_VCC);// Будем измерять напряжение на VCC внутри МК
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
byte NumberOfDevices; //сколько датчиков найдем.
int VCC; //Напряжение батареи
String Hostname; //имя железки - выглядит как ESPAABBCCDDEEFF т.е. ESP+mac адрес.
void wificonect() { // процедура подключения к Wifi.
if (DHCP) WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
WiFi.begin(ssid, password, chanal, macAP, true);
while (WiFi.status() != WL_CONNECTED) {
int i;
if (debug) if (!(i % 100))Serial.print(".");
delay(1);
i++; if (i > 3000) ESP.deepSleep(60e6);//СПИМ 1 минуту
}
if (debug) Serial.println("connected...");
Hostname = "ESP" + WiFi.macAddress();
Hostname.replace(":", "");// удаляем из названия двоеточия
// WiFi.hostname(Hostname); // Название станции внутри локальной вайфай сети
if (debug){ Serial.println(); Serial.print (millis()); Serial.println (" Подключено к wifi");}
}
void setup() {
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(true);
pinMode(DS18b20_VCC, OUTPUT); digitalWrite(DS18b20_VCC, HIGH); //d6
// pinMode(BMX280_VCC, OUTPUT); digitalWrite(BMX280_VCC, HIGH); //d7
Measure();// Запуск измерения
Serial.begin(115200);
}
void loop() {
SendToNarodmon();
if (debug) Serial.print (millis());
digitalWrite(DS18b20_VCC, LOW); //digitalWrite(BMX280_VCC, LOW);// отключаем питание датчиков
if (VCC > 3400) {
delay((postingInterval));
digitalWrite(DS18b20_VCC, HIGH);// digitalWrite(BMX280_VCC, HIGH);// отключаем питание
Measure();
} else {
ESP.deepSleep(postingInterval);
}
}
void Measure() { // Запуск измерения датчиков
VCC = ESP.getVcc() + 350; // почему то показывает на 350 мв меньше.
if (VCC < 2700) {
ESP.deepSleep(86400e6); // спим сутки при низком питании
}
//DS18B20
DeviceAddress tempDeviceAddress;
sensors.begin(); //ds18b20
NumberOfDevices = sensors.getDeviceCount(); //поищем.
for (int i = 0; i < NumberOfDevices; i++) {
if (sensors.getAddress(tempDeviceAddress, i)) sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); //настроим.
}
startmillisDS18B20=millis();
sensors.requestTemperatures(); //Начали измерение ds18b20
Wire.begin();
}
bool SendToNarodmon() { // Собственно формирование пакета и отправка.
// bmx280.measure();
DeviceAddress tempDeviceAddress;
wificonect();// подключаемся к сети
if (debug) {
Serial.println(WiFi.localIP()); Serial.println(WiFi.macAddress()); Serial.print("Narodmon ID: "); Serial.println(Hostname);
}
WiFiClient client;
String buf;
buf = "#" + Hostname + "\n"; //mac адрес для авторизации датчика
}
client.connect("narodmon.ru", 8283); // подключение
if (debug) Serial.print(buf);
//Данные от ESP ( Напряжение питания, уровень wifi
buf = buf + "#VCC#" + String(VCC) + "#Напряжение батареи\n"; //показания температуры
buf = buf + "#WIFI#" + String(WiFi.RSSI()) + "#Уровень WI-FI " + String(WiFi.SSID()) + "\n"; // уровень WIFI сигнала
if (debug) Serial.print(buf);
//DS18B20 в самом конце чтоб было время на измерения
if ((millis() < TEMPERATURE_MEASURE_TIME + startmillisDS18B20) && NumberOfDevices){// если 18b20 подключен(ы) и время на измерение менее 750мс то
delay (TEMPERATURE_MEASURE_TIME + startmillisDS18B20 - millis()); // ждем до 750 мс для преобразования данных
}
for (int i = 0; i < NumberOfDevices; i++) { //перечисляем датчики 18b20 и их показания
mill[i] = millis();
sensors.getAddress(tempDeviceAddress, i);
buf = buf + "#";
for (uint8_t i = 0; i < 8; i++) {
if (tempDeviceAddress[i] < 16) buf = buf + "0"; // адрес датчика
buf = buf + String(tempDeviceAddress[i], HEX);
}
buf = buf + "#" + String(sensors.getTempCByIndex(i)) + "#DS18B20 №" + String(i + 1) + "\n"; //и температура
}
String worcktime = String(millis());
float WTime = worcktime.toInt(); WTime /= 1000;
buf = buf + "#WORKTIME#" + String(WTime) + "#Время передачи данных" + "\n"; // уровень WIFI сигнала
buf = buf + "##\n"; //окончание передачи
client.print(buf); // и отправляем данные
if (debug) {
Serial.print(buf);
for (int i = 0; i < NumberOfDevices; i++) { //время отведенное на измерение 18b20 18b20 и их показания
Serial.print ("Время на измерения DS18B20№" + String(i) + " " + String(mill[i] - startmillisDS18B20) + "мс");
}
}
delay(10);// сделать 100 если нужен ответ или 10 если не нужен . Время активности увеличивается в 2 раза
while (client.available()) {
String line = client.readStringUntil('\r'); // если что-то в ответ будет - все в Serial
if (debug) {
Serial.println(line);
}
}
return true; //ушло
}