643.МГУЛ.150141-01_12_01. Проект «Роса-К2». Прошивка микроконтроллера. Доработка Голуновой П.
Текст программы (Первоначальная прошивка)
#include <Adafruit_ADS1015.h>
#include <LiquidCrystal_I2C.h>
#include <DallasTemperature.h>
#include <Adafruit_TCS34725.h>
#include <BH1750-HD.h>
#include <BlueDot_BME280.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <Ticker.h>
#define ROSA_VER "K2-2019-03-12"
#define Akey "*********"
int var = 1;
int testcon = 1; // 1 - сеть не подключена; 0 - есть сеть.
unsigned long when = millis();
LiquidCrystal_I2C lcd(0x27, 20, 2);
Ticker deepSleep;
HTTPClient http;
const char* ssid = "*******";
const char* password = "*********";
ESP8266WiFiMulti wifi;
Adafruit_ADS1115 ads1115;
#define ONE_WIRE_BUS 2 // Номер пина датчика 1-Wire
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature TempP(&oneWire);
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X);
BH1750 lightMeter(0x23); // объявляем переменную для работы с цифровым датчиком освещенности
float LUMf;
uint16_t LUM_CUR, LUM_MIN, LUM_MAX; // объявляем переменные показаний датчика в Люксах, за время измерений 0,5 секунд (текущее, минимальное и максимальное)
uint8_t LUM_W, LUM_BLINC; // объявляем переменные рассчитываемых показаний (мощность лампы накаливания и коэффициент мерцания)
uint32_t SEC_START = 0; // количество микросекунд на начало измерений
BlueDot_BME280 bme2;
int bh1750Detected = 1;
int bme2Detected = 0;
int tcsDetected = 0;
int ads1115Detected = 0;
int tempDetected = 0;
void funDeepSleep()
{
// Deep Sleep on 0.1s
ESP.deepSleep(1e5);
}
////////////////////////////////////////////////////////////Передача данных//
void CheckWifi()
{
if (testcon == 1) // если флаг не переданных данных возведён
{
if (wifi.run() != WL_CONNECTED) // и соединения нет
{
Serial.print("."); // ждём соединения
}
else // иначе если есть соединение
{ // передаём данные
Serial.print("WiFi connected. IP: ");
Serial.println(WiFi.localIP());
Serial.println("Initialization completed");
Serial.println("Sending data...");
String status = getStatus();
http.begin("http://***********/core/jsonadd.php");
http.addHeader("Content-Type", "application/json");
int resulthttp = http.POST(status);
Serial.print("Done: ");
Serial.println(resulthttp);
http.end();
testcon = 0; // снимаем флаг не переданных данных
}
}
}
/////////////////////////////////////////////////////////////////Проверки подключений//
void setup()
{
lcd.begin();
lcd.backlight();
lcd.home();
// Open connection to Arduino/Iskra
Serial.begin(115200);
delay(1500);
///////////////////////////////////////////////////// попытаемся определить подключение ADS1115//
// ADDR->GND => 0x48 (по умолчанию)
// ADDR->5V => 0x49
// ADDR->SDA => 0x4A
// ADDR->SCL => 0x4B
Wire.begin();
Wire.beginTransmission(0x48); // Проверяем наличие адреса ADS1115 на шине
byte error = Wire.endTransmission();
if (error == 0) {
Serial.println(F("ADS1115 ADC detected!"));
ads1115Detected = 1;
} else {
Serial.println(F("ADS1115 ADC not found!"));
ads1115Detected = 0;
}
///////////////////////////////////////////////////////Проверка датчика температуры почвы//
TempP.begin();
if (TempP.getDeviceCount() > 0) {
Serial.println(F("1-Wire Sensor detected!"));
tempDetected = 1;
} else {
Serial.println(F("1-Wire Sensor not found!"));
tempDetected = 0;
}
////////////////////////////////////////////////////////Проверка датчика освещенности//
ads1115.begin();
lightMeter.setMeasurementTime(BH1750_DEFAULT_MTREG);
if (lightMeter.begin(BH1750_CONTINUOUS_LOW_RES_MODE)) {
Serial.println(F("BH1750 Sensor detected!"));
bh1750Detected = 1;
}
else {
Serial.println(F("BH1750 Sensor not found!"));
bh1750Detected = 0;
}
/////////////////////////////////////////////////////////Проверка датчика BME280//
bme2.parameter.communication = 0;
bme2.parameter.I2CAddress = 0x76;
bme2.parameter.sensorMode = 0b11;
bme2.parameter.IIRfilter = 0b100;
bme2.parameter.humidOversampling = 0b101;
bme2.parameter.tempOversampling = 0b101;
bme2.parameter.pressOversampling = 0b101;
bme2.parameter.pressureSeaLevel = 1013.25;
bme2.parameter.tempOutsideCelsius = 15;
if (bme2.init() != 0x60) {
Serial.println(F("Second BME280 Sensor not found!"));
bme2Detected = 0;
} else {
Serial.println(F("Second BME280 Sensor detected!"));
bme2Detected = 1;
}
//////////////////////////////////////////////////////////Проверка датчика RGB спектра//
if (tcs.begin()) {
Serial.println(F("TCS34725 Sensor detected!"));
tcsDetected = 1;
} else {
Serial.println(F("TCS34725 Sensor not found!"));
tcsDetected = 0;
}
///////////////////////////////////////////////////////////Название сети WIFI и IP адрес//
Serial.print("\nConnecting to: ");
Serial.println(ssid);
wifi.addAP(ssid, password);
//Deep Sleep (reset) every 300. s
deepSleep.attach(300., funDeepSleep);
}
/////////////////////////////////////////////////////////////Вывод на LCD дисплей//
void loop(void)
{
if (millis() - when >= 2500)
{
when = millis();
switch (var)
{
case 1:
lcd.clear();
lcd.print("T:"); lcd.print(String(bme2.readTempC()) + " C"); //Температура воздуха
lcd.setCursor(0, 1); lcd.print("H:"); lcd.print(String(bme2.readHumidity()) + " %"); //Влажность воздуха
var = 2;
break;
case 2:
lcd.clear();
lcd.print("P:"); lcd.print(String(bme2.readPressure() * 0.750064) + " mm Hg"); //Давление
var = 3;
break;
case 3:
lcd.clear();
lcd.print("L:"); lcd.print(String(LUMf) + " Lux"); //Освященность
lcd.setCursor(0, 1); lcd.print("Blink:"); lcd.print(String(LUM_BLINC)); //Мерцание
var = 4;
break;
case 4:
uint16_t r, g, b, c, colorTemp;
tcs.getRawData(&r, &g, &b, &c);
colorTemp = tcs.calculateColorTemperature(r, g, b);
lcd.clear();
lcd.print("t:"); lcd.print(String(colorTemp)); //Температура цвета
lcd.setCursor(9, 0); lcd.print("R:"); lcd.print(String(r)); //красный
lcd.setCursor(0, 1); lcd.print("G:"); lcd.print(String(g)); //зеленый
lcd.setCursor(9, 1); lcd.print("B:"); lcd.print(String(b)); //синий
var = 5;
break;
case 5:
lcd.clear();
lcd.print("SoilT:"); lcd.print(TempP.getTempCByIndex(0)); lcd.print(" C"); //Температура почвы
lcd.setCursor(0, 1); lcd.print("SoilH:"); lcd.print(String(ads1115.readADC_SingleEnded(0))); //Влажность почвы
CheckWifi();
var = 1;
///////////////////////////////////////////////Вывод данных с датчиков в COM порт//
//Serial.println("\"Soil\":{\"SoilH\":\"" + String(ads1115.readADC_SingleEnded(0)) + "\",\"SoilT\":\"" + TempP.getTempCByIndex(0) + "\"}, \"Weather\":{\"Pressure\":\"" + bme2.readPressure() * 0.750064 + "\",\"Temperature\":\"" + bme2.readTempC() + "\",\"Humidity\":\"" + bme2.readHumidity() + "\"}, " + getColor() + ", " + getLight());
Serial.println(getStatus());
}
}
}
String getStatus() {
String reply = "";
// ADC
int16_t soilH;
int16_t Upit;
char soilT[10];
char UpitV[10];
if (ads1115Detected) {
soilH = ads1115.readADC_SingleEnded(0);
Upit = ads1115.readADC_SingleEnded(1);
dtostrf(6.144 / 32768 * Upit * 2, 6, 2, UpitV);
}
if (tempDetected) {
TempP.requestTemperatures();
dtostrf(TempP.getTempCByIndex(0), 6, 2, soilT);
}
reply += "{";
reply += "\"system\":{ ";
reply += "\"Akey\":\"" + String(Akey) + "\",";
reply += "\"Version\": \"" + String(ROSA_VER) + "\",";
if (ads1115Detected) {
reply += "\"Upit\":" + String(UpitV) + ",";
} else {
reply += "\"Upit\":\"none\", ";
}
reply += "\"RSSI\":" + String(WiFi.RSSI()) + ",";
reply += "\"MAC\":\"" + String(WiFi.macAddress()) + "\" },";
reply += "\"soil\":{ ";
if (ads1115Detected) {
reply += "\"soilH\":" + String((soilH)) + ",";
} else {
reply += "\"soilH\":\"none\",";
}
if (tempDetected) {
reply += "\"soilT\":" + String(soilT) ;
} else {
reply += "\"soilT\":\"none\"";
}
reply += " },";
reply += getColor() + "," + getLight() + ",";
if (bme2Detected) {
reply += "\"weather\":{";
reply += "\"temp\":" + String(bme2.readTempC()) + ",";
reply += "\"humidity\":" + String(bme2.readHumidity()) + ",";
reply += "\"pressure\":" + String(bme2.readPressure() * 0.750064) + "}";
} else {
reply += "\"weather\":{";
reply += "\"temp\":\"none\",";
reply += "\"humidity\":\"none\",";
reply += "\"pressure\":\"none\"}";
}
reply += "}";
return (reply);
}
///////////////////////////////////////////////////////////////RGB спектр//
String getColor() {
String reply = "\"color\":{";
uint16_t r, g, b, c, colorTemp, lux;
if (tcsDetected == 0) {
reply += "\"temp\":\"none\",";
reply += "\"clear\":\"none\",";
reply += "\"red\":\"none\",";
reply += "\"green\":\"none\",";
reply += "\"blue\":\"none\"}";
return (reply);
}
tcs.getRawData(&r, &g, &b, &c);
colorTemp = tcs.calculateColorTemperature(r, g, b);
lux = tcs.calculateLux(r, g, b);
reply += "\"temp\":" + String(colorTemp) + ",";
reply += "\"clear\":" + String(c) + ",";
reply += "\"red\":" + String(r) + ",";
reply += "\"green\":" + String(g) + ",";
reply += "\"blue\":" + String(b) + "}";
return (reply);
}
//////////////////////////////////////////////////////////////////Освещенность//
String getLight() {
int i;
String reply = "\"light\":{";
LUM_MAX = 0; // устанавливаем минимальное для максимального значения
LUM_MIN = 65535; // устанавливаем максимальное для минимального значения
LUM_W = 5; // устанавливаем минимальное значение освещенности в Вт
if (bh1750Detected == 0) {
reply += "\"lux\":\"none\",\"blink\":\"none\"}";
return (reply);
}
///////////////////////// Включаем режим максимальной частоты опроса
lightMeter.setMeasurementTime(BH1750_DEFAULT_MTREG);
lightMeter.begin(BH1750_CONTINUOUS_LOW_RES_MODE);
delay(20);
//////////////////////// затравочное чтение
for (i = 0; i < 10; i++) {
LUM_CUR = lightMeter.readLightLevel();
//LUM_CUR = bh1750.readLin ghtLevel(); // считываем показания с датчика
delay(16); // задержка 16 мс (цикл преобразования датчика)
}
//////////////////////// измерение
for (i = 0; i < 30; i++) {
LUM_CUR = lightMeter.readLightLevel();
//LUM_CUR = bh1750.readLightLevel(); // считываем показания с датчика
if (LUM_MIN > LUM_CUR) {
LUM_MIN = LUM_CUR; // обновляем минимальное значение
}
if (LUM_MAX < LUM_CUR) {
LUM_MAX = LUM_CUR; // обновляем максимальное значение
}
delay(16); // задержка 16 мс (цикл преобразования датчика)
}
///////////////////////Определяем коэффициент мерцания
// Правильно это называется "Процент мерцания" (Percent Flicker),
// или по нашему СНиП "Коэффициент пульсации"
if (LUM_MAX == 0 && LUM_MIN == 0) {
LUM_BLINC = 0;
}
else {
LUM_BLINC = (int)( (LUM_MAX - LUM_MIN) * 100. / (LUM_MAX + LUM_MIN) );
}
//////////////////////Читаем значение освещённости
// с максимальным разрешением датчика
lightMeter.begin(BH1750_AUTO_MODE);
delay(445);
LUMf = lightMeter.readLightLevel();
delay(445);
LUMf = lightMeter.readLightLevel();
delay(445);
LUMf = lightMeter.readLightLevel();
reply += "\"lux\":" + String(LUMf) + ",\"blink\":" + String(LUM_BLINC) + "}";
return (reply);
}
/*
Зонд \"Роса-К2\"\n\
Мытищинский филиал МГТУ им. Н. Э. Баумана\n\
Кафедра прикладной математики, информатики и вычислительной техники (К-3)\n\
\n\
Разработчики:\n\
Малашин Алексей Анатольевич malashin_a@mail.ru\n\
Чернышов Александр Викторович sch-ru@yandex.ru\n\
Виноградов Дмитрий Владимирович dmitry-vinogradov@yandex.ru\n\
Брюквина Ольга Юрьевна bryukvina_o@mail.ru\n\
Тищенко Юлия Александровна tishenko.yulya@bk.ru\n\
Курмаев Антон Мартынович warrior-rinn@yandex.ru\n\
\n\
"; */