diff --git a/ESP12SmallRoom/platformio.ini b/ESP12SmallRoom/platformio.ini index 851892e..2a41d1d 100644 --- a/ESP12SmallRoom/platformio.ini +++ b/ESP12SmallRoom/platformio.ini @@ -16,3 +16,7 @@ board_build.ldscript = eagle.flash.1m.ld board_build.f_cpu = 26000000L upload_protocol = espota upload_port = 192.168.1.7 +lib_deps = + Adafruit HTU21DF Library @ ^1.1.0 + PubSubClient @ ^2.8 +; ESP_EEPROM @ ^2.0.0 \ No newline at end of file diff --git a/ESP12SmallRoom/src/main.cpp b/ESP12SmallRoom/src/main.cpp index 21ed795..95f265e 100644 --- a/ESP12SmallRoom/src/main.cpp +++ b/ESP12SmallRoom/src/main.cpp @@ -7,11 +7,13 @@ #include #include #include +#include #define LED_BLUE D5 //GPIO14 #define LED_GREEN D6 //GPIO12 #define LED_RED D7 //GPIO13 -#define PWR_SENS D8 //GPIO13 +#define PWR_SENS D8 //GPIO15 +#define MOVE_SENS D0 //GPIO16 Adafruit_HTU21DF htu = Adafruit_HTU21DF(); WiFiClient espClient; @@ -29,10 +31,13 @@ bool izm = false; unsigned long cRun; int minCnt = 0; int measCnt = 1; +uint8_t mv, oldmv; +int adc, oldadc, delta; void reconnect(); void publishMin(); void publishSec(); +void callback(char* topic, byte* payload, unsigned int length); void setup() { Serial.begin(9600); @@ -64,6 +69,7 @@ void setup() { pinMode(LED_BLUE, OUTPUT); pinMode(LED_RED, OUTPUT); pinMode(PWR_SENS, OUTPUT); + pinMode(MOVE_SENS, INPUT); digitalWrite(LED_GREEN, LOW); digitalWrite(LED_BLUE, LOW); digitalWrite(LED_RED, LOW); @@ -79,10 +85,14 @@ void setup() { rel_hum = htu.readHumidity(); //digitalWrite(PWR_SENS, LOW); client.setServer(mqtt_server, 1883); + client.setCallback(callback); + EEPROM.begin(8); + EEPROM.get(0, delta); cRun = millis(); } void loop() { + static bool lsSent = false, lbSent = false; ArduinoOTA.handle(); lGreen.tick(); lRed.tick(); @@ -93,23 +103,38 @@ void loop() { } client.loop(); - if(cRun + 999 < millis()){ + if(cRun + 99 < millis()){ cRun = millis(); + adc = analogRead(A0); + mv = digitalRead(MOVE_SENS); + if(mv != oldmv){ + oldmv = mv; + client.publish("/home/smallroom/move", mv == 0 ? "0" : "1"); + }; + //if(abs(adc - oldadc) > delta){ + if(((adc < delta) && !lsSent) || ((adc >= (delta + 5)) && !lbSent)){ + char strFVal[6]; + itoa(adc, strFVal, 10); + client.publish("/home/smallroom/light", strFVal); + oldadc = adc; + if(adc < delta) {lsSent = true; lbSent = false;} + else {lbSent = true; lsSent = false;} + } if(measCnt == 0){ temp += (htu.readTemperature() - temp) / 6.0f; rel_hum += (htu.readHumidity() - rel_hum) / 6.0f; digitalWrite(PWR_SENS, LOW); } - if(++measCnt == 29){ + if(++measCnt == 299){ digitalWrite(PWR_SENS, HIGH); measCnt = 0; } //Serial.print("T: ");Serial.print(temp);Serial.print("\tH: ");Serial.println(rel_hum); - if(++minCnt == 59){ + if(++minCnt == 599){ publishMin(); minCnt = 0; } - if(minCnt % 10 == 0) publishSec(); + if(minCnt % 100 == 0) publishSec(); } } @@ -123,6 +148,10 @@ void reconnect() { //Serial.println("connected"); // "подключен" // подписываемся или переподписываемся на топик; // можно подписаться не только на один, а на несколько топиков + char v[6]; + ltoa(delta, v, 10); + client.publish("/home/smallroom/ldelta", v); + client.subscribe("/home/smallroom/ldelta"); } else { //Serial.print("failed, rc="); // "подключение не удалось" //Serial.print(client.state()); @@ -146,8 +175,10 @@ void publishMin() dtostrf(rel_hum, 6, 1, strFVal); client.publish("/home/smallroom/rel_hum", strFVal); } - // itoa(cRun, strFVal, 10); - // client.publish("/home/smallroom/millis", strFVal); + ultoa(adc, strFVal, 10); + client.publish("/home/smallroom/light", strFVal); + ultoa(cRun, strFVal, 10); + client.publish("/home/smallroom/millis", strFVal); //digitalWrite(LED_BLUE, LOW); } } @@ -168,8 +199,20 @@ void publishSec() } itoa(WiFi.RSSI(), strFVal, 10); client.publish("/hometest/smallroom/RSSI", strFVal); - itoa(cRun, strFVal, 10); + ultoa(cRun, strFVal, 10); client.publish("/hometest/smallroom/millis", strFVal); + ltoa(adc, strFVal, 10); + client.publish("/hometest/smallroom/light", strFVal); + ultoa(delta, strFVal, 10); + client.publish("/hometest/smallroom/ldelta", strFVal); //digitalWrite(LED_GREEN, LOW); } } + +void callback(char* topic, byte* payload, unsigned int length) { + if(strcmp(topic,"/home/smallroom/ldelta") == 0){ + delta = atoi((char*)payload); + EEPROM.put(0, delta); + EEPROM.commit(); + } +} diff --git a/ExtSens/.gitignore b/ExtSens/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/ExtSens/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/ExtSens/.vscode/extensions.json b/ExtSens/.vscode/extensions.json new file mode 100644 index 0000000..0f0d740 --- /dev/null +++ b/ExtSens/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/ExtSens/include/README b/ExtSens/include/README new file mode 100644 index 0000000..45496b1 --- /dev/null +++ b/ExtSens/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/ExtSens/lib/README b/ExtSens/lib/README new file mode 100644 index 0000000..8c9c29c --- /dev/null +++ b/ExtSens/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/ExtSens/platformio.ini b/ExtSens/platformio.ini new file mode 100644 index 0000000..bd66ae7 --- /dev/null +++ b/ExtSens/platformio.ini @@ -0,0 +1,16 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:pro8MHzatmega328] +platform = atmelavr +board = pro8MHzatmega328 +framework = arduino +monitor_speed = 115200 +lib_deps = enjoyneering/AHT10@^1.1.0 diff --git a/ExtSens/src/main.cpp b/ExtSens/src/main.cpp new file mode 100644 index 0000000..d445731 --- /dev/null +++ b/ExtSens/src/main.cpp @@ -0,0 +1,69 @@ +#include + +#define MY_DEBUG +#define MY_RADIO_RF24 +#define MY_RF24_PA_LEVEL RF24_PA_HIGH +#include +#include + +uint32_t cRun; +int BATTERY_SENSE_PIN = A0; +int sensorValue, batteryPcnt; +float v; +int oldBatteryPcnt = 0; + +void presentation(); +MyMessage msgTemp(0, V_TEMP); +MyMessage msgHum(1, V_HUM); +MyMessage msgMillis(2, V_VAR1); +MyMessage msgVolts(2, V_VAR2); + +AHT10 myAHT10(AHT10_ADDRESS_0X38); + +void setup() { + analogReference(INTERNAL); + sensorValue = analogRead(BATTERY_SENSE_PIN); + v = sensorValue * 0.004659498; + batteryPcnt = (v * 100) / 4.2; + while (myAHT10.begin() != true) + { + Serial.println(F("AHT10 not connected or fail to load calibration coefficient")); //(F()) save string to flash & keeps dynamic memory free + delay(5000); + } + Serial.println(F("AHT10 OK")); + Serial.print(F("Temperature: ")); Serial.print(myAHT10.readTemperature(AHT10_FORCE_READ_DATA)); Serial.println(F(" +-0.3C")); + Serial.print(F("Humidity...: ")); Serial.print(myAHT10.readHumidity(AHT10_USE_READ_DATA)); Serial.println(F(" +-2%")); + + cRun = millis(); + send(msgMillis.set(cRun)); +} + +void loop() { + float temp, hum; + //if((cRun + 29999) < millis()){ + cRun = millis(); + temp = myAHT10.readTemperature(AHT10_FORCE_READ_DATA); + hum = myAHT10.readHumidity(AHT10_USE_READ_DATA); + Serial.print(F("Temperature: ")); Serial.print(temp); Serial.println(F(" +-0.3C")); + Serial.print(F("Humidity...: ")); Serial.print(hum); Serial.println(F(" +-2%")); + if (temp < 200){ + send(msgTemp.set(temp, 1)); + send(msgHum.set(hum, 1)); + } + send(msgMillis.set(cRun)); + sensorValue = analogRead(BATTERY_SENSE_PIN); + v = sensorValue * 0.004659498; + batteryPcnt = (v-3 * 100) / 1.2; + sendBatteryLevel(batteryPcnt); + send(msgVolts.set(v, 2)); + //} + sleep(60000 - (millis() - cRun)); +} + +void presentation() +{ + sendSketchInfo("ExtSens", "1.2"); + present(0, S_TEMP, "Temp"); + present(1, S_HUM, "Humid"); + present(2, S_CUSTOM, "ESMillis"); +} diff --git a/ExtSens/test/README b/ExtSens/test/README new file mode 100644 index 0000000..e7d1588 --- /dev/null +++ b/ExtSens/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html diff --git a/Kuhnya/src/main.cpp b/Kuhnya/src/main.cpp index 0a5cb11..0d13dd1 100644 --- a/Kuhnya/src/main.cpp +++ b/Kuhnya/src/main.cpp @@ -120,6 +120,8 @@ void setup() { void loop() { float tempT(NAN), humT(NAN), pressT(NAN); + static int gint = 1; + static bool gdir = true; ArduinoOTA.handle(); @@ -131,16 +133,23 @@ void loop() { } if((crun + 199) < millis()){ crun = millis(); + minCount++; + + if(gdir) gint += 25; + else gint -= 25; + if((gint > 499) || (gint < 2)) gdir = !gdir; + analogWrite(GREEN, gint); + adc = analogRead(A0); mv = digitalRead(MOVE_S); if(mv != prMV){ if(mv){ - //mv = true; + mv = true; lcd.setBacklight(255); mqttClient.publish("/home/kuh/move", 1, false, "1"); } else{ - //mv = false; + mv = false; lcd.setBacklight(0); mqttClient.publish("/home/kuh/move", 1, false, "0"); } @@ -155,22 +164,21 @@ void loop() { lightOn = true; } - //if(((minCount+5) % 10) == 0){ //Once in Second + if(((minCount+5) % 10) == 0){ //Once in 2 Second bme.read(pressT, tempT, humT, tempUnit, presUnit); if(!isnan(pressT)){ - if(!isnan(press)) press += (pressT / 133.322f - press) / 600.0f; + if(!isnan(press)) press += (pressT / 133.322f - press) / 30.0f; else press = pressT / 133.322f; } if(!isnan(tempT)){ - if(!isnan(tempIn)) tempIn += (tempT - tempIn) / 300.0f; + if(!isnan(tempIn)) tempIn += (tempT - tempIn) / 30.0f; else tempIn = tempT; } if(!isnan(humT)){ - if(!isnan(hum)) hum += (humT - hum) / 300.0f; + if(!isnan(hum)) hum += (humT - hum) / 30.0f; else hum = humT; } - //} - minCount++; + } if (minCount == 300){ //Once in Minute lcd.begin(16, 2); publishMin(); @@ -178,7 +186,8 @@ void loop() { } if((minCount % 5) == 0){ //Once in Second getTemp(); - publishSec(); + //digitalWrite(GREEN, !digitalRead(GREEN)); + //publishSec(); showLCD(LCDpage, mv); } } @@ -221,7 +230,7 @@ void showLCD(int page, bool l_on) void publishSec() { - digitalWrite(GREEN, HIGH); +/* digitalWrite(GREEN, HIGH); dtostrf(tempOut, 6, 1, strFVal); mqttClient.publish("/hometest/kuh1s/temp_out", 1, false, strFVal); dtostrf(tempIn, 6, 1, strFVal); @@ -240,8 +249,7 @@ void publishSec() mqttClient.publish("/hometest/kuh1s/moroz", 1, false, strFVal); itoa(crun, strFVal, 10); mqttClient.publish("/hometest/kuh1s/millis", 1, false, strFVal); - digitalWrite(GREEN, LOW); - //} + digitalWrite(GREEN, LOW);*/ } void publishMin() @@ -263,10 +271,10 @@ void publishMin() dtostrf(press, 6, 1, strFVal); mqttClient.publish("/home/kuh/pressure", 1, false, strFVal); } - itoa(lightSP, strFVal, 10); - mqttClient.publish("/home/kuh/light_sp", 1, false, strFVal); - itoa(lightDB, strFVal, 10); - mqttClient.publish("/home/kuh/light_db", 1, false, strFVal); + //itoa(lightSP, strFVal, 10); + //mqttClient.publish("/home/kuh/light_sp", 1, false, strFVal); + //itoa(lightDB, strFVal, 10); + //mqttClient.publish("/home/kuh/light_db", 1, false, strFVal); itoa(adc, strFVal, 10); mqttClient.publish("/home/kuh/light_cur", 1, false, strFVal); if(!isnan(tempHol)){ @@ -346,8 +354,10 @@ void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) { void onMqttConnect(bool sessionPresent) { char v[6]; itoa(lightData.SP, v, 10); + mqttClient.publish("/home/kuh/light_sp", 1, false, v); mqttClient.publish("/home/kuh/light_sp_set", 1, false, v); itoa(lightData.DB, v, 10); + mqttClient.publish("/home/kuh/light_db", 1, false, v); mqttClient.publish("/home/kuh/light_db_set", 1, false, v); mqttClient.publish("/home/kuh/move", 1, false, mv == 1 ? "1" : "0"); mqttClient.subscribe("/home/kuh/light_sp_set", 1); @@ -364,13 +374,18 @@ void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) { void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) { bool w = false; + char v[6]; if(strcmp(topic, "/home/kuh/light_sp_set") == 0){ lightSP = atoi(payload); w = true; + itoa(lightData.SP, v, 10); + mqttClient.publish("/home/kuh/light_sp", 1, false, v); } if(strcmp(topic, "/home/kuh/light_db_set") == 0){ lightDB = atoi(payload); w = true; + itoa(lightData.DB, v, 10); + mqttClient.publish("/home/kuh/light_db", 1, false, v); } if(w){ lightData.SP = lightSP; diff --git a/MYS_Home.code-workspace b/MYS_Home.code-workspace index 1229dbf..6272b00 100644 --- a/MYS_Home.code-workspace +++ b/MYS_Home.code-workspace @@ -65,6 +65,10 @@ }, { "path": "Kuhnya" + }, + { + "name": "ExtSens", + "path": "ExtSens" } ], "settings": { diff --git a/MidRoomNLight/src/main.cpp b/MidRoomNLight/src/main.cpp index 6d83674..fc96644 100644 --- a/MidRoomNLight/src/main.cpp +++ b/MidRoomNLight/src/main.cpp @@ -1,62 +1,21 @@ #include -/* - * The MySensors Arduino library handles the wireless radio link and protocol - * between your home built sensors/actuators and HA controller of choice. - * The sensors forms a self healing radio network with optional repeaters. Each - * repeater and gateway builds a routing tables in EEPROM which keeps track of the - * network topology allowing messages to be routed to nodes. - * - * Created by Henrik Ekblad - * Copyright (C) 2013-2019 Sensnology AB - * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors - * - * Documentation: http://www.mysensors.org - * Support Forum: http://forum.mysensors.org - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - ******************************* - * - * REVISION HISTORY - * Version 1.0 - Henrik Ekblad - * - * DESCRIPTION - * Example sketch showing how to control physical relays. - * This example will remember relay state after power failure. - * http://www.mysensors.org/build/relay - */ - -// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_RF24 -//#define MY_RADIO_NRF5_ESB -//#define MY_RADIO_RFM69 -//#define MY_RADIO_RFM95 - -// Enable repeater functionality for this node -//#define MY_REPEATER_FEATURE - #include -#define RELAY_PIN 4 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) -#define NUMBER_OF_RELAYS 1 // Total number of attached relays -#define RELAY_ON 1 // GPIO value to write to turn on attached relay -#define RELAY_OFF 0 // GPIO value to write to turn off attached relay +#define RELAY_PIN 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) +//MyMessage msgLev(1, V_DIMMER); +uint16_t lightLevel; +bool lightOn = false; void before() { - for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { - // Then set relay pins in output mode - pinMode(pin, OUTPUT); - // Set relay to last known state (using eeprom storage) - digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF); - } + pinMode(RELAY_PIN, OUTPUT); + lightLevel = loadState(0); } void setup() @@ -67,12 +26,8 @@ void setup() void presentation() { // Send the sketch version information to the gateway and Controller - sendSketchInfo("Relay", "1.0"); - - for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { - // Register all sensors to gw (they will be created as child devices) - present(sensor, S_BINARY); - } + sendSketchInfo("Night Light", "2.0"); + present(0, S_DIMMER, "Dimmer"); } @@ -83,16 +38,29 @@ void loop() void receive(const MyMessage &message) { - // We only expect one type of message from controller. But we better check anyway. - if (message.getType()==V_STATUS) { - // Change relay state - digitalWrite(message.getSensor()-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF); - // Store state in eeprom - saveState(message.getSensor(), message.getBool()); - // Write some debug info - Serial.print("Incoming change for sensor:"); - Serial.print(message.getSensor()); - Serial.print(", New status: "); - Serial.println(message.getBool()); + switch(message.getType()){ + case V_STATUS: + if(message.getBool() == true) { + analogWrite(RELAY_PIN, lightLevel); + lightOn = true; + } + else { + analogWrite(RELAY_PIN, 0); + lightOn = false; + } + Serial.print("Incoming change for sensor:"); + Serial.print(message.getSensor()); + Serial.print(", New status: "); + Serial.println(message.getBool()); + break; + case V_PERCENTAGE: + saveState(0, message.getUInt()); + lightLevel = message.getUInt(); + if(lightOn) analogWrite(RELAY_PIN, lightLevel); + Serial.print("Incoming change for dimmer:"); + Serial.print(message.getSensor()); + Serial.print(", New value: "); + Serial.println(message.getUInt()); + break; } }