diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/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/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/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/lib/SHT1x-master/CHANGES.txt b/lib/SHT1x-master/CHANGES.txt new file mode 100644 index 0000000..8b56f3e --- /dev/null +++ b/lib/SHT1x-master/CHANGES.txt @@ -0,0 +1,6 @@ +2011-09-20 + * Conditionally include Arduino.h for compatibility with Arduino 1.0 + +2010-07-23 + * Added SHT7x to list of supported sensors. + * Fixed temperature offset in humidity calculation. diff --git a/lib/SHT1x-master/DISTRIBUTION b/lib/SHT1x-master/DISTRIBUTION new file mode 100644 index 0000000..f767989 --- /dev/null +++ b/lib/SHT1x-master/DISTRIBUTION @@ -0,0 +1,9 @@ +Copyright 2009 Jonathan Oxer / +Copyright 2008 Maurice Ribble / + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +http://www.gnu.org/licenses/ diff --git a/lib/SHT1x-master/README.markdown b/lib/SHT1x-master/README.markdown new file mode 100644 index 0000000..09117b9 --- /dev/null +++ b/lib/SHT1x-master/README.markdown @@ -0,0 +1,63 @@ +SHT1x Temperature / Humidity Sensor Library for Arduino +======================================================= +Copyright 2009 Jonathan Oxer jon@oxer.com.au / http://www.practicalarduino.com +Copyright 2008 Maurice Ribble ribblem@yahoo.com / http://www.glacialwanderer.com + +Provides a simple interface to the SHT1x series (SHT10, SHT11, SHT15) +and SHT7x series (SHT71, SHT75) temperature / humidity sensors from +Sensirion, http://www.sensirion.com. These sensors use a "2-wire" +communications buss that is similar to I2C and can co-exist on the same +physical wire as I2C devices. + +Installation +------------ +Download the directory "SHT1x" and move it into the "libraries" +directory inside your sketchbook directory, then restart the Arduino +IDE. You will then see it listed under File->Examples->SHT1x. + +Usage +----- +The library is instantiated as an object with methods provided to read +relative humidity and temperature. Include it in your sketch and then +create an object, specifying the pins to use for communication with the +sensor: + + #include + #define dataPin 10 + #define clockPin 11 + SHT1x sht1x(dataPin, clockPin); + +You can then call methods on that object within your program. In this +example we created an object called "sht1x", but it could have been +called whatever you like. A complete example program is included with +the library and can be accessed from the File->Examples->SHT1x menu. + +### readTemperatureC() ### + +Returns a float within the valid range of the sensor of -40 to +123.8C. +A value of -40 is returned in the event of a communication error with +the sensor. + +Example: + + float tempC = sht1x.readTemperatureC(); + +### readTemperatureF() ### + +Returns a float within the valid range of the sensor of -40 to +254.9F. +A value of -40 is returned in the event of a communication error with +the sensor. + +Example: + + float tempF = sht1x.readTemperatureF(); + +### readHumidity() ### + +Returns a float within the valid range of the sensor of 0 to 100%. +A negative value is returned in the event of a communication error with +the sensor. + +Example: + + float humidity = sht1x.readHumidity(); diff --git a/lib/SHT1x-master/SHT1x.cpp b/lib/SHT1x-master/SHT1x.cpp new file mode 100644 index 0000000..b928f9c --- /dev/null +++ b/lib/SHT1x-master/SHT1x.cpp @@ -0,0 +1,243 @@ +/** + * SHT1x Library + * + * Copyright 2009 Jonathan Oxer / + * Based on previous work by: + * Maurice Ribble: + * Wayne ?: + * + * Manages communication with SHT1x series (SHT10, SHT11, SHT15) + * temperature / humidity sensors from Sensirion (www.sensirion.com). + */ +#if (ARDUINO >= 100) +#include +#else +#include +#endif + +#include "SHT1x.h" + +SHT1x::SHT1x(int dataPin, int clockPin) +{ + _dataPin = dataPin; + _clockPin = clockPin; +} + + +/* ================ Public methods ================ */ + +/** + * Reads the current temperature in degrees Celsius + */ +float SHT1x::readTemperatureC() +{ + int _val; // Raw value returned from sensor + float _temperature; // Temperature derived from raw value + + // Conversion coefficients from SHT15 datasheet + const float D1 = -40.0; // for 14 Bit @ 5V + const float D2 = 0.01; // for 14 Bit DEGC + + // Fetch raw value + _val = readTemperatureRaw(); + + // Convert raw value to degrees Celsius + _temperature = (_val * D2) + D1; + + return (_temperature); +} + +/** + * Reads the current temperature in degrees Fahrenheit + */ +float SHT1x::readTemperatureF() +{ + int _val; // Raw value returned from sensor + float _temperature; // Temperature derived from raw value + + // Conversion coefficients from SHT15 datasheet + const float D1 = -40.0; // for 14 Bit @ 5V + const float D2 = 0.018; // for 14 Bit DEGF + + // Fetch raw value + _val = readTemperatureRaw(); + + // Convert raw value to degrees Fahrenheit + _temperature = (_val * D2) + D1; + + return (_temperature); +} + +/** + * Reads current temperature-corrected relative humidity + */ +float SHT1x::readHumidity() +{ + int _val; // Raw humidity value returned from sensor + float _linearHumidity; // Humidity with linear correction applied + float _correctedHumidity; // Temperature-corrected humidity + float _temperature; // Raw temperature value + + // Conversion coefficients from SHT15 datasheet + const float C1 = -4.0; // for 12 Bit + const float C2 = 0.0405; // for 12 Bit + const float C3 = -0.0000028; // for 12 Bit + const float T1 = 0.01; // for 14 Bit @ 5V + const float T2 = 0.00008; // for 14 Bit @ 5V + + // Command to send to the SHT1x to request humidity + int _gHumidCmd = 0b00000101; + + // Fetch the value from the sensor + sendCommandSHT(_gHumidCmd, _dataPin, _clockPin); + waitForResultSHT(_dataPin); + _val = getData16SHT(_dataPin, _clockPin); + skipCrcSHT(_dataPin, _clockPin); + + // Apply linear conversion to raw value + _linearHumidity = C1 + C2 * _val + C3 * _val * _val; + + // Get current temperature for humidity correction + _temperature = readTemperatureC(); + + // Correct humidity value for current temperature + _correctedHumidity = (_temperature - 25.0 ) * (T1 + T2 * _val) + _linearHumidity; + + return (_correctedHumidity); +} + + +/* ================ Private methods ================ */ + +/** + * Reads the current raw temperature value + */ +float SHT1x::readTemperatureRaw() +{ + int _val; + + // Command to send to the SHT1x to request Temperature + int _gTempCmd = 0b00000011; + + sendCommandSHT(_gTempCmd, _dataPin, _clockPin); + waitForResultSHT(_dataPin); + _val = getData16SHT(_dataPin, _clockPin); + skipCrcSHT(_dataPin, _clockPin); + + return (_val); +} + +/** + */ +int SHT1x::shiftIn(int _dataPin, int _clockPin, int _numBits) +{ + int ret = 0; + int i; + + for (i=0; i<_numBits; ++i) + { + digitalWrite(_clockPin, HIGH); + delay(10); // I don't know why I need this, but without it I don't get my 8 lsb of temp + ret = ret*2 + digitalRead(_dataPin); + digitalWrite(_clockPin, LOW); + } + + return(ret); +} + +/** + */ +void SHT1x::sendCommandSHT(int _command, int _dataPin, int _clockPin) +{ + int ack; + + // Transmission Start + pinMode(_dataPin, OUTPUT); + pinMode(_clockPin, OUTPUT); + digitalWrite(_dataPin, HIGH); + digitalWrite(_clockPin, HIGH); + digitalWrite(_dataPin, LOW); + digitalWrite(_clockPin, LOW); + digitalWrite(_clockPin, HIGH); + digitalWrite(_dataPin, HIGH); + digitalWrite(_clockPin, LOW); + + // The command (3 msb are address and must be 000, and last 5 bits are command) + shiftOut(_dataPin, _clockPin, MSBFIRST, _command); + + // Verify we get the correct ack + digitalWrite(_clockPin, HIGH); + pinMode(_dataPin, INPUT); + ack = digitalRead(_dataPin); + if (ack != LOW) { + //Serial.println("Ack Error 0"); + } + digitalWrite(_clockPin, LOW); + ack = digitalRead(_dataPin); + if (ack != HIGH) { + //Serial.println("Ack Error 1"); + } +} + +/** + */ +void SHT1x::waitForResultSHT(int _dataPin) +{ + int i; + int ack; + + pinMode(_dataPin, INPUT); + + for(i= 0; i < 100; ++i) + { + delay(10); + ack = digitalRead(_dataPin); + + if (ack == LOW) { + break; + } + } + + if (ack == HIGH) { + //Serial.println("Ack Error 2"); // Can't do serial stuff here, need another way of reporting errors + } +} + +/** + */ +int SHT1x::getData16SHT(int _dataPin, int _clockPin) +{ + int val; + + // Get the most significant bits + pinMode(_dataPin, INPUT); + pinMode(_clockPin, OUTPUT); + val = shiftIn(_dataPin, _clockPin, 8); + val *= 256; + + // Send the required ack + pinMode(_dataPin, OUTPUT); + digitalWrite(_dataPin, HIGH); + digitalWrite(_dataPin, LOW); + digitalWrite(_clockPin, HIGH); + digitalWrite(_clockPin, LOW); + + // Get the least significant bits + pinMode(_dataPin, INPUT); + val |= shiftIn(_dataPin, _clockPin, 8); + + return val; +} + +/** + */ +void SHT1x::skipCrcSHT(int _dataPin, int _clockPin) +{ + // Skip acknowledge to end trans (no CRC) + pinMode(_dataPin, OUTPUT); + pinMode(_clockPin, OUTPUT); + + digitalWrite(_dataPin, HIGH); + digitalWrite(_clockPin, HIGH); + digitalWrite(_clockPin, LOW); +} diff --git a/lib/SHT1x-master/SHT1x.h b/lib/SHT1x-master/SHT1x.h new file mode 100644 index 0000000..1a98190 --- /dev/null +++ b/lib/SHT1x-master/SHT1x.h @@ -0,0 +1,40 @@ +/** + * SHT1x Library + * + * Copyright 2009 Jonathan Oxer / + * Based on previous work by: + * Maurice Ribble: + * Wayne ?: + * + * Manages communication with SHT1x series (SHT10, SHT11, SHT15) + * temperature / humidity sensors from Sensirion (www.sensirion.com). + */ +#ifndef SHT1x_h +#define SHT1x_h + +#if (ARDUINO >= 100) +#include +#else +#include +#endif + +class SHT1x +{ + public: + SHT1x(int dataPin, int clockPin); + float readHumidity(); + float readTemperatureC(); + float readTemperatureF(); + private: + int _dataPin; + int _clockPin; + int _numBits; + float readTemperatureRaw(); + int shiftIn(int _dataPin, int _clockPin, int _numBits); + void sendCommandSHT(int _command, int _dataPin, int _clockPin); + void waitForResultSHT(int _dataPin); + int getData16SHT(int _dataPin, int _clockPin); + void skipCrcSHT(int _dataPin, int _clockPin); +}; + +#endif diff --git a/lib/SHT1x-master/examples/ReadSHT1xValues/ReadSHT1xValues.pde b/lib/SHT1x-master/examples/ReadSHT1xValues/ReadSHT1xValues.pde new file mode 100644 index 0000000..338664f --- /dev/null +++ b/lib/SHT1x-master/examples/ReadSHT1xValues/ReadSHT1xValues.pde @@ -0,0 +1,45 @@ +/** + * ReadSHT1xValues + * + * Read temperature and humidity values from an SHT1x-series (SHT10, + * SHT11, SHT15) sensor. + * + * Copyright 2009 Jonathan Oxer + * www.practicalarduino.com + */ + +#include + +// Specify data and clock connections and instantiate SHT1x object +#define dataPin 10 +#define clockPin 11 +SHT1x sht1x(dataPin, clockPin); + +void setup() +{ + Serial.begin(38400); // Open serial connection to report values to host + Serial.println("Starting up"); +} + +void loop() +{ + float temp_c; + float temp_f; + float humidity; + + // Read values from the sensor + temp_c = sht1x.readTemperatureC(); + temp_f = sht1x.readTemperatureF(); + humidity = sht1x.readHumidity(); + + // Print the values to the serial port + Serial.print("Temperature: "); + Serial.print(temp_c, DEC); + Serial.print("C / "); + Serial.print(temp_f, DEC); + Serial.print("F. Humidity: "); + Serial.print(humidity); + Serial.println("%"); + + delay(2000); +} diff --git a/lib/SHT1x-master/keywords.txt b/lib/SHT1x-master/keywords.txt new file mode 100644 index 0000000..57e9dcd --- /dev/null +++ b/lib/SHT1x-master/keywords.txt @@ -0,0 +1,4 @@ +SHT1x KEYWORD1 +readHumidity KEYWORD2 +readTemperatureC KEYWORD2 +readTemperatureF KEYWORD2 diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..91ed4b7 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,18 @@ +; 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:nodemcuv2] +platform = espressif8266 +board = nodemcuv2 +framework = arduino +lib_deps = + greiman/SSD1306Ascii@^1.3.3 + thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays@^4.3.0 + knolleary/PubSubClient@^2.8 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..ca5e0c5 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,306 @@ +#include + +//#include + +#include +#include +#include +#include +#include // Only needed for Arduino 1.6.5 and earlier +#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` + +// jfs NodeMCU 1.0 +// Display + +SSD1306 display(0x3c, D6, D5); +// IC +char output = 0; +char IC = 0x20; +byte i = 0; +byte ALTWERT; +byte WERT=0; + +// Timing +unsigned long readTime; +unsigned long pubTime; +// Data +float temp_c; +float humidity; +char buffer[10]; +String line0; +String line1; +String line2; + + + +// Specify data and clock connections and instantiate SHT1x object +#define dataPin D3 +#define clockPin D4 +SHT1x sht1x(dataPin, clockPin); +//#define SLEEP_DELAY_IN_SECONDS 300 +const char* host = "192.168.2.71"; +const char* ssid = "pipanet"; +const char* password = "passatvr6"; +WiFiClient net; +PubSubClient mqtt(net); + +const int mxSize=2; +String ssids[mxSize] ={"pipanet","pipanetMicro"}; +String ssidp[mxSize] = {"passatvr6","passatvr6",}; +boolean conok =false; +String netid; + +int netfound(int n){ + String vs; + int max = 0; + int wer = 0; + display.clear(); + if (n==0){ + display.drawString(0,0,"No Network Found"); + } else { + for (int i=0; i < n; i++){ + if (WiFi.RSSI(i) < max) { + max = WiFi.RSSI(i); + wer = i; + } + vs = String(WiFi.SSID(i)+ " RSSI "+WiFi.RSSI(i)); + Serial.println(vs); + display.drawString(0,i*12+14,vs); + } + } + display.display(); + Serial.println(wer); + delay(5000); + display.clear(); + display.display(); + + return wer; +} + +boolean init_wifi(){ + boolean ok = false; + String vs =""; + int wer =0; + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + delay(100); + int n = WiFi.scanNetworks(); + Serial.println("scan done"); + if (n == 0) { + Serial.println("no networks found"); + netfound(0); + } else { + Serial.print(n); + Serial.println(" networks found"); + wer = netfound(n); + String pp = ssidp[wer]; + String ss = WiFi.SSID(wer); + Serial.println(pp+" "+ss); + WiFi.begin(ss.c_str(), pp.c_str()); + ok = true; + /* + for (int i = 0; i < n; ++i) { + for (int p=0;p readTime+500){ + readTemp(); + } + if(millis() > pubTime+1000){ + pub_Temp(); + } +} + diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner 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/en/latest/advanced/unit-testing/index.html diff --git a/test/SHT1x.h b/test/SHT1x.h new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/SHT1x.h @@ -0,0 +1 @@ + diff --git a/test/jfs_esp8266_mqtt_handy.ino b/test/jfs_esp8266_mqtt_handy.ino new file mode 100644 index 0000000..e47fd28 --- /dev/null +++ b/test/jfs_esp8266_mqtt_handy.ino @@ -0,0 +1,276 @@ +//#include + +#include +#include +#include +#include +#include // Only needed for Arduino 1.6.5 and earlier +#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"` + +// jfs NodeMCU 1.0 +// Display + +SSD1306 display(0x3c, D6, D5); +// IC +char output = 0; +char IC = 0x20; +byte i = 0; +byte ALTWERT; +byte WERT=0; + +// Timing +unsigned long readTime; +unsigned long pubTime; +// Data +float temp_c; +float humidity; +char buffer[10]; +String line0; +String line1; +String line2; + + + +// Specify data and clock connections and instantiate SHT1x object +#define dataPin D3 +#define clockPin D4 +SHT1x sht1x(dataPin, clockPin); +//#define SLEEP_DELAY_IN_SECONDS 300 +const char* host = "192.168.2.71"; +const char* ssid = "pipanet"; +const char* password = "passatvr6"; +WiFiClient net; +PubSubClient mqtt(net); + +const int mxSize=2; +String ssids[mxSize] ={"pipanet","pipanetMicro"}; +String ssidp[mxSize] = {"passatvr6","passatvr6",}; +boolean conok =false; +String netid; +void netfound(int i){ + display.clear(); + display.setColor(BLACK); + display.fillRect(0, 0, 128, 10); + display.setColor(WHITE); + display.drawString(0,0,String(i)); + display.drawString(20,0,"networks found"); + display.display(); +} +boolean init_wifi(){ + boolean ok = false; + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + delay(100); + int n = WiFi.scanNetworks(); + Serial.println("scan done"); + if (n == 0) { + Serial.println("no networks found"); + netfound(0); + } else { + Serial.print(n); + Serial.println(" networks found"); + netfound(n); + for (int i = 0; i < n; ++i) { + for (int p=0;p readTime+500){ + readTemp(); + } + if(millis() > pubTime+1000){ + pub_Temp(); + } +} + +void disp_Temp(){ + String s; + long rssi = WiFi.RSSI(); + line0 = WiFi.localIP().toString(); + line0 = line0 + " "+String(rssi)+" db"; + display.clear(); + display.setFont(ArialMT_Plain_10); + display.drawString(0,0,line0); + line1=String(temp_c)+" C "; + s = String(humidity); + s = s + " %"; + line1=line1 +s ; + display.setFont(ArialMT_Plain_10); + display.drawString(0,18,line1); + line2 = WiFi.SSID().toString; + display.drawString(0,30,line2); + display.display(); +} + + +void pub_Temp(){ + pubTime = millis(); + mqtt.publish("/Handy/temp", buffer); + dtostrf(humidity, 6, 2, buffer); + mqtt.publish("/Handy/humidity", buffer); + Serial.print("Sending... "); + Serial.print("Temp: "); + Serial.print(String(temp_c)); + Serial.print(" Humidity: "); + Serial.print(String(humidity)); + long rssi = WiFi.RSSI(); + String s = String(rssi); + Serial.print(" RSSI: "); + Serial.print(s); + s.toCharArray(buffer,10); + mqtt.publish("/Handy/rssi", buffer); + netid.toCharArray(buffer,10); + mqtt.publish("/Handy/ssid", buffer); +} + +void readTemp(){ + readTime = millis(); + temp_c = sht1x.readTemperatureC(); + humidity = sht1x.readHumidity(); + dtostrf(temp_c, 6, 2, buffer); + disp_Temp(); +} + +void connect() { + while(WiFi.waitForConnectResult() != WL_CONNECTED) { + WiFi.begin(ssid, password); + Serial.println("WiFi connection failed. Retry."); + } + Serial.print("Wifi connection successful - IP-Address: "); + Serial.println(WiFi.localIP()); + while (!mqtt.connect("arduinoHandy")) { + Serial.print("."); + } + mqtt.subscribe("/Handy/in/"); + Serial.println("MQTT connected!"); +}