├── .gitattributes ├── .gitignore ├── ESP8266_APRS_6.apk ├── README.md ├── T5-Esp8266 ├── DHT-sensor-library │ ├── .github │ │ ├── ISSUE_TEMPLATE.md │ │ └── PULL_REQUEST_TEMPLATE.md │ ├── Adafruit_Sensor.h │ ├── DHT.cpp │ ├── DHT.h │ ├── DHT_U.cpp │ ├── DHT_U.h │ ├── README.md │ ├── examples │ │ ├── DHT_Unified_Sensor │ │ │ └── DHT_Unified_Sensor.ino │ │ └── DHTtester │ │ │ └── DHTtester.ino │ ├── keywords.txt │ └── library.properties ├── T5-Esp8266.bin ├── T5-Esp8266.ino └── cablage.jpg ├── Weather station.zip ├── bme_V06 └── bme_V06.ino ├── bme_V07.cpp.bin └── bme_V07 └── bme_V07.ino /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /ESP8266_APRS_6.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f4goh/Weather/35c7be8217c05d62b959716cc144bfe20eea2857/ESP8266_APRS_6.apk -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Weather 2 | ESP8266 Weather Station 3 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/Adafruit_Sensor.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f4goh/Weather/35c7be8217c05d62b959716cc144bfe20eea2857/T5-Esp8266/DHT-sensor-library/Adafruit_Sensor.h -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/DHT.cpp: -------------------------------------------------------------------------------- 1 | /* DHT library 2 | 3 | MIT license 4 | written by Adafruit Industries 5 | */ 6 | 7 | #include "DHT.h" 8 | 9 | #define MIN_INTERVAL 2000 10 | 11 | DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) { 12 | _pin = pin; 13 | _type = type; 14 | #ifdef __AVR 15 | _bit = digitalPinToBitMask(pin); 16 | _port = digitalPinToPort(pin); 17 | #endif 18 | _maxcycles = microsecondsToClockCycles(1000); // 1 millisecond timeout for 19 | // reading pulses from DHT sensor. 20 | // Note that count is now ignored as the DHT reading algorithm adjusts itself 21 | // basd on the speed of the processor. 22 | } 23 | 24 | void DHT::begin(void) { 25 | // set up the pins! 26 | pinMode(_pin, INPUT_PULLUP); 27 | // Using this value makes sure that millis() - lastreadtime will be 28 | // >= MIN_INTERVAL right away. Note that this assignment wraps around, 29 | // but so will the subtraction. 30 | _lastreadtime = -MIN_INTERVAL; 31 | DEBUG_PRINT("Max clock cycles: "); DEBUG_PRINTLN(_maxcycles, DEC); 32 | } 33 | 34 | //boolean S == Scale. True == Fahrenheit; False == Celcius 35 | float DHT::readTemperature(bool S, bool force) { 36 | float f = NAN; 37 | 38 | if (read(force)) { 39 | switch (_type) { 40 | case DHT11: 41 | f = data[2]; 42 | if(S) { 43 | f = convertCtoF(f); 44 | } 45 | break; 46 | case DHT22: 47 | case DHT21: 48 | f = data[2] & 0x7F; 49 | f *= 256; 50 | f += data[3]; 51 | f *= 0.1; 52 | if (data[2] & 0x80) { 53 | f *= -1; 54 | } 55 | if(S) { 56 | f = convertCtoF(f); 57 | } 58 | break; 59 | } 60 | } 61 | return f; 62 | } 63 | 64 | float DHT::convertCtoF(float c) { 65 | return c * 1.8 + 32; 66 | } 67 | 68 | float DHT::convertFtoC(float f) { 69 | return (f - 32) * 0.55555; 70 | } 71 | 72 | float DHT::readHumidity(bool force) { 73 | float f = NAN; 74 | if (read()) { 75 | switch (_type) { 76 | case DHT11: 77 | f = data[0]; 78 | break; 79 | case DHT22: 80 | case DHT21: 81 | f = data[0]; 82 | f *= 256; 83 | f += data[1]; 84 | f *= 0.1; 85 | break; 86 | } 87 | } 88 | return f; 89 | } 90 | 91 | //boolean isFahrenheit: True == Fahrenheit; False == Celcius 92 | float DHT::computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit) { 93 | // Using both Rothfusz and Steadman's equations 94 | // http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml 95 | float hi; 96 | 97 | if (!isFahrenheit) 98 | temperature = convertCtoF(temperature); 99 | 100 | hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) + (percentHumidity * 0.094)); 101 | 102 | if (hi > 79) { 103 | hi = -42.379 + 104 | 2.04901523 * temperature + 105 | 10.14333127 * percentHumidity + 106 | -0.22475541 * temperature*percentHumidity + 107 | -0.00683783 * pow(temperature, 2) + 108 | -0.05481717 * pow(percentHumidity, 2) + 109 | 0.00122874 * pow(temperature, 2) * percentHumidity + 110 | 0.00085282 * temperature*pow(percentHumidity, 2) + 111 | -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2); 112 | 113 | if((percentHumidity < 13) && (temperature >= 80.0) && (temperature <= 112.0)) 114 | hi -= ((13.0 - percentHumidity) * 0.25) * sqrt((17.0 - abs(temperature - 95.0)) * 0.05882); 115 | 116 | else if((percentHumidity > 85.0) && (temperature >= 80.0) && (temperature <= 87.0)) 117 | hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2); 118 | } 119 | 120 | return isFahrenheit ? hi : convertFtoC(hi); 121 | } 122 | 123 | boolean DHT::read(bool force) { 124 | // Check if sensor was read less than two seconds ago and return early 125 | // to use last reading. 126 | uint32_t currenttime = millis(); 127 | if (!force && ((currenttime - _lastreadtime) < 2000)) { 128 | return _lastresult; // return last correct measurement 129 | } 130 | _lastreadtime = currenttime; 131 | 132 | // Reset 40 bits of received data to zero. 133 | data[0] = data[1] = data[2] = data[3] = data[4] = 0; 134 | 135 | // Send start signal. See DHT datasheet for full signal diagram: 136 | // http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf 137 | 138 | // Go into high impedence state to let pull-up raise data line level and 139 | // start the reading process. 140 | digitalWrite(_pin, HIGH); 141 | delay(250); 142 | 143 | // First set data line low for 20 milliseconds. 144 | pinMode(_pin, OUTPUT); 145 | digitalWrite(_pin, LOW); 146 | delay(20); 147 | 148 | uint32_t cycles[80]; 149 | { 150 | // Turn off interrupts temporarily because the next sections are timing critical 151 | // and we don't want any interruptions. 152 | InterruptLock lock; 153 | 154 | // End the start signal by setting data line high for 40 microseconds. 155 | digitalWrite(_pin, HIGH); 156 | delayMicroseconds(40); 157 | 158 | // Now start reading the data line to get the value from the DHT sensor. 159 | pinMode(_pin, INPUT_PULLUP); 160 | delayMicroseconds(10); // Delay a bit to let sensor pull data line low. 161 | 162 | // First expect a low signal for ~80 microseconds followed by a high signal 163 | // for ~80 microseconds again. 164 | if (expectPulse(LOW) == 0) { 165 | DEBUG_PRINTLN(F("Timeout waiting for start signal low pulse.")); 166 | _lastresult = false; 167 | return _lastresult; 168 | } 169 | if (expectPulse(HIGH) == 0) { 170 | DEBUG_PRINTLN(F("Timeout waiting for start signal high pulse.")); 171 | _lastresult = false; 172 | return _lastresult; 173 | } 174 | 175 | // Now read the 40 bits sent by the sensor. Each bit is sent as a 50 176 | // microsecond low pulse followed by a variable length high pulse. If the 177 | // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds 178 | // then it's a 1. We measure the cycle count of the initial 50us low pulse 179 | // and use that to compare to the cycle count of the high pulse to determine 180 | // if the bit is a 0 (high state cycle count < low state cycle count), or a 181 | // 1 (high state cycle count > low state cycle count). Note that for speed all 182 | // the pulses are read into a array and then examined in a later step. 183 | for (int i=0; i<80; i+=2) { 184 | cycles[i] = expectPulse(LOW); 185 | cycles[i+1] = expectPulse(HIGH); 186 | } 187 | } // Timing critical code is now complete. 188 | 189 | // Inspect pulses and determine which ones are 0 (high state cycle count < low 190 | // state cycle count), or 1 (high state cycle count > low state cycle count). 191 | for (int i=0; i<40; ++i) { 192 | uint32_t lowCycles = cycles[2*i]; 193 | uint32_t highCycles = cycles[2*i+1]; 194 | if ((lowCycles == 0) || (highCycles == 0)) { 195 | DEBUG_PRINTLN(F("Timeout waiting for pulse.")); 196 | _lastresult = false; 197 | return _lastresult; 198 | } 199 | data[i/8] <<= 1; 200 | // Now compare the low and high cycle times to see if the bit is a 0 or 1. 201 | if (highCycles > lowCycles) { 202 | // High cycles are greater than 50us low cycle count, must be a 1. 203 | data[i/8] |= 1; 204 | } 205 | // Else high cycles are less than (or equal to, a weird case) the 50us low 206 | // cycle count so this must be a zero. Nothing needs to be changed in the 207 | // stored data. 208 | } 209 | 210 | DEBUG_PRINTLN(F("Received:")); 211 | DEBUG_PRINT(data[0], HEX); DEBUG_PRINT(F(", ")); 212 | DEBUG_PRINT(data[1], HEX); DEBUG_PRINT(F(", ")); 213 | DEBUG_PRINT(data[2], HEX); DEBUG_PRINT(F(", ")); 214 | DEBUG_PRINT(data[3], HEX); DEBUG_PRINT(F(", ")); 215 | DEBUG_PRINT(data[4], HEX); DEBUG_PRINT(F(" =? ")); 216 | DEBUG_PRINTLN((data[0] + data[1] + data[2] + data[3]) & 0xFF, HEX); 217 | 218 | // Check we read 40 bits and that the checksum matches. 219 | if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) { 220 | _lastresult = true; 221 | return _lastresult; 222 | } 223 | else { 224 | DEBUG_PRINTLN(F("Checksum failure!")); 225 | _lastresult = false; 226 | return _lastresult; 227 | } 228 | } 229 | 230 | // Expect the signal line to be at the specified level for a period of time and 231 | // return a count of loop cycles spent at that level (this cycle count can be 232 | // used to compare the relative time of two pulses). If more than a millisecond 233 | // ellapses without the level changing then the call fails with a 0 response. 234 | // This is adapted from Arduino's pulseInLong function (which is only available 235 | // in the very latest IDE versions): 236 | // https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c 237 | uint32_t DHT::expectPulse(bool level) { 238 | uint32_t count = 0; 239 | // On AVR platforms use direct GPIO port access as it's much faster and better 240 | // for catching pulses that are 10's of microseconds in length: 241 | #ifdef __AVR 242 | uint8_t portState = level ? _bit : 0; 243 | while ((*portInputRegister(_port) & _bit) == portState) { 244 | if (count++ >= _maxcycles) { 245 | return 0; // Exceeded timeout, fail. 246 | } 247 | } 248 | // Otherwise fall back to using digitalRead (this seems to be necessary on ESP8266 249 | // right now, perhaps bugs in direct port access functions?). 250 | #else 251 | while (digitalRead(_pin) == level) { 252 | if (count++ >= _maxcycles) { 253 | return 0; // Exceeded timeout, fail. 254 | } 255 | } 256 | #endif 257 | 258 | return count; 259 | } 260 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/DHT.h: -------------------------------------------------------------------------------- 1 | /* DHT library 2 | 3 | MIT license 4 | written by Adafruit Industries 5 | */ 6 | #ifndef DHT_H 7 | #define DHT_H 8 | 9 | #if ARDUINO >= 100 10 | #include "Arduino.h" 11 | #else 12 | #include "WProgram.h" 13 | #endif 14 | 15 | 16 | // Uncomment to enable printing out nice debug messages. 17 | //#define DHT_DEBUG 18 | 19 | // Define where debug output will be printed. 20 | #define DEBUG_PRINTER Serial 21 | 22 | // Setup debug printing macros. 23 | #ifdef DHT_DEBUG 24 | #define DEBUG_PRINT(...) { DEBUG_PRINTER.print(__VA_ARGS__); } 25 | #define DEBUG_PRINTLN(...) { DEBUG_PRINTER.println(__VA_ARGS__); } 26 | #else 27 | #define DEBUG_PRINT(...) {} 28 | #define DEBUG_PRINTLN(...) {} 29 | #endif 30 | 31 | // Define types of sensors. 32 | #define DHT11 11 33 | #define DHT22 22 34 | #define DHT21 21 35 | #define AM2301 21 36 | 37 | 38 | class DHT { 39 | public: 40 | DHT(uint8_t pin, uint8_t type, uint8_t count=6); 41 | void begin(void); 42 | float readTemperature(bool S=false, bool force=false); 43 | float convertCtoF(float); 44 | float convertFtoC(float); 45 | float computeHeatIndex(float temperature, float percentHumidity, bool isFahrenheit=true); 46 | float readHumidity(bool force=false); 47 | boolean read(bool force=false); 48 | 49 | private: 50 | uint8_t data[5]; 51 | uint8_t _pin, _type; 52 | #ifdef __AVR 53 | // Use direct GPIO access on an 8-bit AVR so keep track of the port and bitmask 54 | // for the digital pin connected to the DHT. Other platforms will use digitalRead. 55 | uint8_t _bit, _port; 56 | #endif 57 | uint32_t _lastreadtime, _maxcycles; 58 | bool _lastresult; 59 | 60 | uint32_t expectPulse(bool level); 61 | 62 | }; 63 | 64 | class InterruptLock { 65 | public: 66 | InterruptLock() { 67 | noInterrupts(); 68 | } 69 | ~InterruptLock() { 70 | interrupts(); 71 | } 72 | 73 | }; 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/DHT_U.cpp: -------------------------------------------------------------------------------- 1 | // DHT Temperature & Humidity Unified Sensor Library 2 | // Copyright (c) 2014 Adafruit Industries 3 | // Author: Tony DiCola 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | #include "DHT_U.h" 23 | 24 | DHT_Unified::DHT_Unified(uint8_t pin, uint8_t type, uint8_t count, int32_t tempSensorId, int32_t humiditySensorId): 25 | _dht(pin, type, count), 26 | _type(type), 27 | _temp(this, tempSensorId), 28 | _humidity(this, humiditySensorId) 29 | {} 30 | 31 | void DHT_Unified::begin() { 32 | _dht.begin(); 33 | } 34 | 35 | void DHT_Unified::setName(sensor_t* sensor) { 36 | switch(_type) { 37 | case DHT11: 38 | strncpy(sensor->name, "DHT11", sizeof(sensor->name) - 1); 39 | break; 40 | case DHT21: 41 | strncpy(sensor->name, "DHT21", sizeof(sensor->name) - 1); 42 | break; 43 | case DHT22: 44 | strncpy(sensor->name, "DHT22", sizeof(sensor->name) - 1); 45 | break; 46 | default: 47 | // TODO: Perhaps this should be an error? However main DHT library doesn't enforce 48 | // restrictions on the sensor type value. Pick a generic name for now. 49 | strncpy(sensor->name, "DHT?", sizeof(sensor->name) - 1); 50 | break; 51 | } 52 | sensor->name[sizeof(sensor->name)- 1] = 0; 53 | } 54 | 55 | void DHT_Unified::setMinDelay(sensor_t* sensor) { 56 | switch(_type) { 57 | case DHT11: 58 | sensor->min_delay = 1000000L; // 1 second (in microseconds) 59 | break; 60 | case DHT21: 61 | sensor->min_delay = 2000000L; // 2 seconds (in microseconds) 62 | break; 63 | case DHT22: 64 | sensor->min_delay = 2000000L; // 2 seconds (in microseconds) 65 | break; 66 | default: 67 | // Default to slowest sample rate in case of unknown type. 68 | sensor->min_delay = 2000000L; // 2 seconds (in microseconds) 69 | break; 70 | } 71 | } 72 | 73 | DHT_Unified::Temperature::Temperature(DHT_Unified* parent, int32_t id): 74 | _parent(parent), 75 | _id(id) 76 | {} 77 | 78 | bool DHT_Unified::Temperature::getEvent(sensors_event_t* event) { 79 | // Clear event definition. 80 | memset(event, 0, sizeof(sensors_event_t)); 81 | // Populate sensor reading values. 82 | event->version = sizeof(sensors_event_t); 83 | event->sensor_id = _id; 84 | event->type = SENSOR_TYPE_AMBIENT_TEMPERATURE; 85 | event->timestamp = millis(); 86 | event->temperature = _parent->_dht.readTemperature(); 87 | 88 | return true; 89 | } 90 | 91 | void DHT_Unified::Temperature::getSensor(sensor_t* sensor) { 92 | // Clear sensor definition. 93 | memset(sensor, 0, sizeof(sensor_t)); 94 | // Set sensor name. 95 | _parent->setName(sensor); 96 | // Set version and ID 97 | sensor->version = DHT_SENSOR_VERSION; 98 | sensor->sensor_id = _id; 99 | // Set type and characteristics. 100 | sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE; 101 | _parent->setMinDelay(sensor); 102 | switch (_parent->_type) { 103 | case DHT11: 104 | sensor->max_value = 50.0F; 105 | sensor->min_value = 0.0F; 106 | sensor->resolution = 2.0F; 107 | break; 108 | case DHT21: 109 | sensor->max_value = 80.0F; 110 | sensor->min_value = -40.0F; 111 | sensor->resolution = 0.1F; 112 | break; 113 | case DHT22: 114 | sensor->max_value = 125.0F; 115 | sensor->min_value = -40.0F; 116 | sensor->resolution = 0.1F; 117 | break; 118 | default: 119 | // Unknown type, default to 0. 120 | sensor->max_value = 0.0F; 121 | sensor->min_value = 0.0F; 122 | sensor->resolution = 0.0F; 123 | break; 124 | } 125 | } 126 | 127 | DHT_Unified::Humidity::Humidity(DHT_Unified* parent, int32_t id): 128 | _parent(parent), 129 | _id(id) 130 | {} 131 | 132 | bool DHT_Unified::Humidity::getEvent(sensors_event_t* event) { 133 | // Clear event definition. 134 | memset(event, 0, sizeof(sensors_event_t)); 135 | // Populate sensor reading values. 136 | event->version = sizeof(sensors_event_t); 137 | event->sensor_id = _id; 138 | event->type = SENSOR_TYPE_RELATIVE_HUMIDITY; 139 | event->timestamp = millis(); 140 | event->relative_humidity = _parent->_dht.readHumidity(); 141 | 142 | return true; 143 | } 144 | 145 | void DHT_Unified::Humidity::getSensor(sensor_t* sensor) { 146 | // Clear sensor definition. 147 | memset(sensor, 0, sizeof(sensor_t)); 148 | // Set sensor name. 149 | _parent->setName(sensor); 150 | // Set version and ID 151 | sensor->version = DHT_SENSOR_VERSION; 152 | sensor->sensor_id = _id; 153 | // Set type and characteristics. 154 | sensor->type = SENSOR_TYPE_RELATIVE_HUMIDITY; 155 | _parent->setMinDelay(sensor); 156 | switch (_parent->_type) { 157 | case DHT11: 158 | sensor->max_value = 80.0F; 159 | sensor->min_value = 20.0F; 160 | sensor->resolution = 5.0F; 161 | break; 162 | case DHT21: 163 | sensor->max_value = 100.0F; 164 | sensor->min_value = 0.0F; 165 | sensor->resolution = 0.1F; 166 | break; 167 | case DHT22: 168 | sensor->max_value = 100.0F; 169 | sensor->min_value = 0.0F; 170 | sensor->resolution = 0.1F; 171 | break; 172 | default: 173 | // Unknown type, default to 0. 174 | sensor->max_value = 0.0F; 175 | sensor->min_value = 0.0F; 176 | sensor->resolution = 0.0F; 177 | break; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/DHT_U.h: -------------------------------------------------------------------------------- 1 | // DHT Temperature & Humidity Unified Sensor Library 2 | // Copyright (c) 2014 Adafruit Industries 3 | // Author: Tony DiCola 4 | 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | 12 | // The above copyright notice and this permission notice shall be included in all 13 | // copies or substantial portions of the Software. 14 | 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | // SOFTWARE. 22 | #ifndef DHT_U_H 23 | #define DHT_U_H 24 | 25 | #include 26 | #include 27 | 28 | #define DHT_SENSOR_VERSION 1 29 | 30 | class DHT_Unified { 31 | public: 32 | DHT_Unified(uint8_t pin, uint8_t type, uint8_t count=6, int32_t tempSensorId=-1, int32_t humiditySensorId=-1); 33 | void begin(); 34 | 35 | class Temperature : public Adafruit_Sensor { 36 | public: 37 | Temperature(DHT_Unified* parent, int32_t id); 38 | bool getEvent(sensors_event_t* event); 39 | void getSensor(sensor_t* sensor); 40 | 41 | private: 42 | DHT_Unified* _parent; 43 | int32_t _id; 44 | 45 | }; 46 | 47 | class Humidity : public Adafruit_Sensor { 48 | public: 49 | Humidity(DHT_Unified* parent, int32_t id); 50 | bool getEvent(sensors_event_t* event); 51 | void getSensor(sensor_t* sensor); 52 | 53 | private: 54 | DHT_Unified* _parent; 55 | int32_t _id; 56 | 57 | }; 58 | 59 | Temperature temperature() { 60 | return _temp; 61 | } 62 | 63 | Humidity humidity() { 64 | return _humidity; 65 | } 66 | 67 | private: 68 | DHT _dht; 69 | uint8_t _type; 70 | Temperature _temp; 71 | Humidity _humidity; 72 | 73 | void setName(sensor_t* sensor); 74 | void setMinDelay(sensor_t* sensor); 75 | 76 | }; 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/README.md: -------------------------------------------------------------------------------- 1 | This is an Arduino library for the DHT series of low cost temperature/humidity sensors. 2 | 3 | Tutorial: https://learn.adafruit.com/dht 4 | 5 | To download. click the DOWNLOADS button in the top right corner, rename the uncompressed folder DHT. Check that the DHT folder contains DHT.cpp and DHT.h. Place the DHT library folder your /libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE. 6 | 7 | # Adafruit DHT Humidity & Temperature Unified Sensor Library 8 | 9 | This library also includes an optional class for the 10 | [DHT humidity and temperature sensor](https://learn.adafruit.com/dht/overview) 11 | which is designed to work with the [Adafruit unified sensor library](https://learn.adafruit.com/using-the-adafruit-unified-sensor-driver/introduction). 12 | 13 | You must have the following Arduino libraries installed to use this class: 14 | 15 | - [Adafruit Unified Sensor Library](https://github.com/adafruit/Adafruit_Sensor) 16 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino: -------------------------------------------------------------------------------- 1 | // DHT Temperature & Humidity Sensor 2 | // Unified Sensor Library Example 3 | // Written by Tony DiCola for Adafruit Industries 4 | // Released under an MIT license. 5 | 6 | // Depends on the following Arduino libraries: 7 | // - Adafruit Unified Sensor Library: https://github.com/adafruit/Adafruit_Sensor 8 | // - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #define DHTPIN 2 // Pin which is connected to the DHT sensor. 15 | 16 | // Uncomment the type of sensor in use: 17 | //#define DHTTYPE DHT11 // DHT 11 18 | #define DHTTYPE DHT22 // DHT 22 (AM2302) 19 | //#define DHTTYPE DHT21 // DHT 21 (AM2301) 20 | 21 | // See guide for details on sensor wiring and usage: 22 | // https://learn.adafruit.com/dht/overview 23 | 24 | DHT_Unified dht(DHTPIN, DHTTYPE); 25 | 26 | uint32_t delayMS; 27 | 28 | void setup() { 29 | Serial.begin(9600); 30 | // Initialize device. 31 | dht.begin(); 32 | Serial.println("DHTxx Unified Sensor Example"); 33 | // Print temperature sensor details. 34 | sensor_t sensor; 35 | dht.temperature().getSensor(&sensor); 36 | Serial.println("------------------------------------"); 37 | Serial.println("Temperature"); 38 | Serial.print ("Sensor: "); Serial.println(sensor.name); 39 | Serial.print ("Driver Ver: "); Serial.println(sensor.version); 40 | Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); 41 | Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" *C"); 42 | Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" *C"); 43 | Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" *C"); 44 | Serial.println("------------------------------------"); 45 | // Print humidity sensor details. 46 | dht.humidity().getSensor(&sensor); 47 | Serial.println("------------------------------------"); 48 | Serial.println("Humidity"); 49 | Serial.print ("Sensor: "); Serial.println(sensor.name); 50 | Serial.print ("Driver Ver: "); Serial.println(sensor.version); 51 | Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); 52 | Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println("%"); 53 | Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println("%"); 54 | Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println("%"); 55 | Serial.println("------------------------------------"); 56 | // Set delay between sensor readings based on sensor details. 57 | delayMS = sensor.min_delay / 1000; 58 | } 59 | 60 | void loop() { 61 | // Delay between measurements. 62 | delay(delayMS); 63 | // Get temperature event and print its value. 64 | sensors_event_t event; 65 | dht.temperature().getEvent(&event); 66 | if (isnan(event.temperature)) { 67 | Serial.println("Error reading temperature!"); 68 | } 69 | else { 70 | Serial.print("Temperature: "); 71 | Serial.print(event.temperature); 72 | Serial.println(" *C"); 73 | } 74 | // Get humidity event and print its value. 75 | dht.humidity().getEvent(&event); 76 | if (isnan(event.relative_humidity)) { 77 | Serial.println("Error reading humidity!"); 78 | } 79 | else { 80 | Serial.print("Humidity: "); 81 | Serial.print(event.relative_humidity); 82 | Serial.println("%"); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/examples/DHTtester/DHTtester.ino: -------------------------------------------------------------------------------- 1 | // Example testing sketch for various DHT humidity/temperature sensors 2 | // Written by ladyada, public domain 3 | 4 | #include "DHT.h" 5 | 6 | #define DHTPIN 2 // what digital pin we're connected to 7 | 8 | // Uncomment whatever type you're using! 9 | //#define DHTTYPE DHT11 // DHT 11 10 | #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 11 | //#define DHTTYPE DHT21 // DHT 21 (AM2301) 12 | 13 | // Connect pin 1 (on the left) of the sensor to +5V 14 | // NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1 15 | // to 3.3V instead of 5V! 16 | // Connect pin 2 of the sensor to whatever your DHTPIN is 17 | // Connect pin 4 (on the right) of the sensor to GROUND 18 | // Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor 19 | 20 | // Initialize DHT sensor. 21 | // Note that older versions of this library took an optional third parameter to 22 | // tweak the timings for faster processors. This parameter is no longer needed 23 | // as the current DHT reading algorithm adjusts itself to work on faster procs. 24 | DHT dht(DHTPIN, DHTTYPE); 25 | 26 | void setup() { 27 | Serial.begin(9600); 28 | Serial.println("DHTxx test!"); 29 | 30 | dht.begin(); 31 | } 32 | 33 | void loop() { 34 | // Wait a few seconds between measurements. 35 | delay(2000); 36 | 37 | // Reading temperature or humidity takes about 250 milliseconds! 38 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 39 | float h = dht.readHumidity(); 40 | // Read temperature as Celsius (the default) 41 | float t = dht.readTemperature(); 42 | // Read temperature as Fahrenheit (isFahrenheit = true) 43 | float f = dht.readTemperature(true); 44 | 45 | // Check if any reads failed and exit early (to try again). 46 | if (isnan(h) || isnan(t) || isnan(f)) { 47 | Serial.println("Failed to read from DHT sensor!"); 48 | return; 49 | } 50 | 51 | // Compute heat index in Fahrenheit (the default) 52 | float hif = dht.computeHeatIndex(f, h); 53 | // Compute heat index in Celsius (isFahreheit = false) 54 | float hic = dht.computeHeatIndex(t, h, false); 55 | 56 | Serial.print("Humidity: "); 57 | Serial.print(h); 58 | Serial.print(" %\t"); 59 | Serial.print("Temperature: "); 60 | Serial.print(t); 61 | Serial.print(" *C "); 62 | Serial.print(f); 63 | Serial.print(" *F\t"); 64 | Serial.print("Heat index: "); 65 | Serial.print(hic); 66 | Serial.print(" *C "); 67 | Serial.print(hif); 68 | Serial.println(" *F"); 69 | } 70 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/keywords.txt: -------------------------------------------------------------------------------- 1 | ########################################### 2 | # Syntax Coloring Map For DHT-sensor-library 3 | ########################################### 4 | 5 | ########################################### 6 | # Datatypes (KEYWORD1) 7 | ########################################### 8 | 9 | DHT KEYWORD1 10 | 11 | ########################################### 12 | # Methods and Functions (KEYWORD2) 13 | ########################################### 14 | 15 | begin KEYWORD2 16 | readTemperature KEYWORD2 17 | convertCtoF KEYWORD2 18 | convertFtoC KEYWORD2 19 | computeHeatIndex KEYWORD2 20 | readHumidity KEYWORD2 21 | read KEYWORD2 22 | 23 | -------------------------------------------------------------------------------- /T5-Esp8266/DHT-sensor-library/library.properties: -------------------------------------------------------------------------------- 1 | name=DHT sensor library 2 | version=1.3.0 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Arduino library for DHT11, DHT22, etc Temp & Humidity Sensors 6 | paragraph=Arduino library for DHT11, DHT22, etc Temp & Humidity Sensors 7 | category=Sensors 8 | url=https://github.com/adafruit/DHT-sensor-library 9 | architectures=* 10 | -------------------------------------------------------------------------------- /T5-Esp8266/T5-Esp8266.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f4goh/Weather/35c7be8217c05d62b959716cc144bfe20eea2857/T5-Esp8266/T5-Esp8266.bin -------------------------------------------------------------------------------- /T5-Esp8266/T5-Esp8266.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | esp8266 with DHT11 Ai thinker t5 board 4 | - config menu with serial 5 | - ntp update 6 | - upload weather data on aprs servers 7 | - local web page for weather informations and configuration 8 | - add GMT menu 9 | f4goh@orange.fr 10 | */ 11 | 12 | //#include 13 | //#include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | #include 20 | 21 | #include "FS.h" 22 | 23 | NTPtime NTPch("ch.pool.ntp.org"); 24 | //NTPtime NTPch("time.nist.gov"); 25 | 26 | 27 | 28 | #define DHTPIN 2 // DHT11 sensor on GPIO2. 29 | #include "DHT.h" // We're using the Adafruit version. 30 | DHT dht(DHTPIN, DHT11, 15); 31 | 32 | 33 | 34 | ESP8266WebServer server(80); 35 | 36 | strDateTime dateTime; 37 | byte nextMinTx; 38 | 39 | 40 | typedef struct { 41 | int temperatureC; 42 | int temperatureF; 43 | int pression ; 44 | int humidite; 45 | } WeatherStruct; 46 | WeatherStruct wx; //declare la structure 47 | 48 | typedef struct { 49 | char ssid[50]; 50 | char password[50]; 51 | } configStruct; 52 | configStruct internet; //declare la structure 53 | 54 | typedef struct { 55 | char callsign[10]; 56 | char longitude[10]; 57 | char latitude[10]; 58 | char clientAdress[20]; 59 | int clientPort; 60 | long transmitDelay; 61 | byte logger; 62 | byte gmt; 63 | } positionStruct; 64 | positionStruct station; //declare la structure 65 | 66 | long previousMillis = 0; 67 | long currentMillis; 68 | long EcratMillis; 69 | 70 | 71 | void setup(void) 72 | { 73 | strcpy(station.clientAdress, "cwop.aprs.net"); 74 | station.clientPort = 14580; 75 | station.transmitDelay = 10; 76 | station.logger = 0; 77 | station.gmt = 1; 78 | 79 | Serial.begin(115200); 80 | Serial.println(); 81 | delay(10); 82 | SPIFFS.begin(); 83 | if (SPIFFS.exists("/ssid.txt") == 0) { 84 | configMenu(); 85 | } 86 | else 87 | { 88 | readSsidFile(); 89 | } 90 | if (SPIFFS.exists("/station.txt") == 0) { 91 | configMenu(); 92 | } 93 | else 94 | { 95 | readStationFile(); 96 | } 97 | if (detectMenu() == 1) configMenu(); 98 | ssidConnect(); 99 | dht.begin(); 100 | printDht(); 101 | 102 | delay(1000); 103 | 104 | 105 | server.on("/", handleRoot); 106 | /* 107 | server.on("/inline", []() { 108 | server.send(200, "text/plain", "this works as well"); 109 | }); 110 | server.on ( "/test.svg", drawGraph ); 111 | */ 112 | server.onNotFound(handleNotFound); 113 | server.begin(); 114 | 115 | ntp(); 116 | previousMillis = millis(); 117 | 118 | } 119 | 120 | 121 | void handleRoot() { 122 | char temp[600]; 123 | snprintf ( temp, 600, 124 | "\ 125 | \ 126 | \ 127 | %s Weather Station\ 128 | \ 131 | \ 132 | \ 133 |

%s Weather Station

\ 134 |

Uptime: %02d:%02d:%02d


\ 135 |

Temperature: %d degC


\ 136 |

Humidity: %d %


\ 137 | \ 138 | ", 139 | station.callsign, station.callsign, dateTime.hour, dateTime.minute, dateTime.second, wx.temperatureC / 10, wx.humidite 140 | ); 141 | server.send ( 200, "text/html", temp ); 142 | } 143 | 144 | 145 | 146 | 147 | 148 | void handleNotFound() { 149 | //digitalWrite(led, 1); 150 | String message = "File Not Found\n\n"; 151 | message += "URI: "; 152 | message += server.uri(); 153 | message += "\nMethod: "; 154 | message += (server.method() == HTTP_GET) ? "GET" : "POST"; 155 | message += "\nArguments: "; 156 | message += server.args(); 157 | message += "\n"; 158 | for (uint8_t i = 0; i < server.args(); i++) { 159 | message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; 160 | } 161 | server.send(404, "text/plain", message); 162 | //digitalWrite(led, 0); 163 | } 164 | /* 165 | void drawGraph() { 166 | String out = ""; 167 | char temp[100]; 168 | out += "\n"; 169 | out += "\n"; 170 | out += "\n"; 171 | int y = rand() % 130; 172 | for (int x = 10; x < 390; x += 10) { 173 | int y2 = rand() % 130; 174 | sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); 175 | out += temp; 176 | y = y2; 177 | } 178 | out += "\n\n"; 179 | 180 | server.send ( 200, "image/svg+xml", out); 181 | } 182 | */ 183 | 184 | void loop() 185 | { 186 | //Each loop, take a reading. 187 | //Start with temperature, as that data is needed for accurate compensation. 188 | //Reading the temperature updates the compensators of the other functions 189 | //in the background. 190 | server.handleClient(); 191 | 192 | updateTime(); 193 | 194 | 195 | if ((dateTime.minute >= nextMinTx) && (dateTime.second == 0)) { 196 | updateServer(); 197 | previousMillis = millis(); 198 | } 199 | 200 | if (Serial.available() > 0) { 201 | if (Serial.read() == 'm') { 202 | while (Serial.read() != '\n') {}; 203 | configMenu(); 204 | ntp(); 205 | } 206 | if (Serial.read() == 'f') { 207 | while (Serial.read() != '\n') {}; 208 | updateServer(); 209 | } 210 | } 211 | } 212 | 213 | 214 | void updateTime() 215 | { 216 | currentMillis = millis(); 217 | EcratMillis = currentMillis - previousMillis; 218 | if (EcratMillis > 1000) { 219 | previousMillis = currentMillis; 220 | dateTime.second = (dateTime.second + 1) % 60; 221 | char currentTime[10]; 222 | sprintf(currentTime, "%02d:%02d:%02d", dateTime.hour, dateTime.minute, dateTime.second); 223 | Serial.println(currentTime); 224 | if (dateTime.second == 0) { 225 | dateTime.minute = (dateTime.minute + 1) % 60; 226 | if (dateTime.minute == 0) { 227 | dateTime.hour = (dateTime.hour + 1) % 24; 228 | } 229 | } 230 | } 231 | } 232 | 233 | 234 | void updateServer() 235 | { 236 | if (WiFi.status() == WL_CONNECTED) 237 | { 238 | printDht(); 239 | ntp(); 240 | connexion(); 241 | } 242 | if (station.logger == 1) { 243 | if (SPIFFS.exists("/logger.txt") == 1) { 244 | String s; 245 | //long sizefile; 246 | File f = SPIFFS.open("/logger.txt", "a"); 247 | if (!f) { 248 | Serial.println("file open failed"); 249 | } 250 | Serial.println("====== add data logger ========="); 251 | char buffer[50]; 252 | sprintf(buffer, "%02d/%02d/%04d;", dateTime.day, dateTime.month, dateTime.year); 253 | f.print(buffer); 254 | sprintf(buffer, "%02d:%02d:%02d;", dateTime.hour, dateTime.minute, dateTime.second); 255 | f.print(buffer); 256 | // sprintf(buffer, "%03d;%02d;%05d\n", wx.temperatureF / 10, wx.humidite, wx.pression / 10); 257 | sprintf(buffer, "%03d;%02d\n", wx.temperatureF / 10, wx.humidite); 258 | f.print(buffer); 259 | f.close(); 260 | } 261 | } 262 | } 263 | 264 | /* 265 | connexion ntp et acces au serveur meto pour uploder les donnees 266 | */ 267 | 268 | /* 269 | * The structure contains following fields: 270 | * struct strDateTime 271 | { 272 | byte hour; 273 | byte minute; 274 | byte second; 275 | int year; 276 | byte month; 277 | byte day; 278 | byte dayofWeek; 279 | boolean valid; 280 | }; 281 | */ 282 | void ntp() 283 | { 284 | if (WiFi.status() == WL_CONNECTED) 285 | { 286 | // first parameter: Time zone in floating point (for India); second parameter: 1 for European summer time; 2 for US daylight saving time (not implemented yet) 287 | do 288 | { 289 | dateTime = NTPch.getNTPtime(0.0, station.gmt); 290 | NTPch.printDateTime(dateTime); 291 | } 292 | while (!dateTime.valid); 293 | nextMinTx = (dateTime.minute + station.transmitDelay) % 60; 294 | Serial.print("->>>>> next tx at : "); 295 | char buffer[20]; 296 | sprintf(buffer, "%02d:%02d:%02d", dateTime.hour, nextMinTx, 0); 297 | Serial.println(buffer); 298 | } 299 | } 300 | 301 | 302 | void connexion() 303 | { 304 | char login[60]; 305 | char sentence[150]; 306 | //wx.temperatureF = wx.temperatureF * -1; 307 | 308 | sprintf(login, "user %s pass -1 vers VERSION ESP8266", station.callsign); 309 | // sprintf(sentence, "%s>APRS,TCPXX*:@%02d%02d%02dz%s/%s_.../...g...t%03dr...p...P...h%02db%05d", station.callsign, dateTime.hour, dateTime.minute, dateTime.second, station.latitude, station.longitude, wx.temperatureF / 10, wx.humidite, wx.pression / 10); 310 | sprintf(sentence, "%s>APRS,TCPXX*:@%02d%02d%02dz%s/%s_.../...g...t%03dr...p...P...h%02db.....", station.callsign, dateTime.hour, dateTime.minute, dateTime.second, station.latitude, station.longitude, wx.temperatureF / 10, wx.humidite); 311 | Serial.println(sentence); 312 | //Serial.println("compare"); 313 | //Serial.println("FW0383>APRS,TCPXX*:@164300z4759.75N/00012.21Et034h91b10032"); 314 | // 315 | 316 | WiFiClient client; 317 | //const int httpPort = 14580; 318 | 319 | if (!client.connect(station.clientAdress, station.clientPort)) { 320 | Serial.println("connection failed"); 321 | return; 322 | } 323 | //client.println("user FW0383 pass -1 vers VERSION ESP8266"); 324 | client.println(login); 325 | 326 | 327 | unsigned long timeout = millis(); 328 | while (client.available() == 0) { 329 | if (millis() - timeout > 5000) { 330 | Serial.println(">>> Client Timeout !"); 331 | client.stop(); 332 | return; 333 | } 334 | } 335 | while (client.available()) { 336 | String line = client.readStringUntil('\r'); 337 | Serial.print(line); 338 | } 339 | //client.println("FW0383>APRS,TCPXX*:@164300z4759.75N/00012.21E_256/013g020t034r000p013P001h91b10032"); 340 | //client.println("FW0383>APRS,TCPXX*:@164300z4759.75N/00012.21Et034h91b10032"); 341 | client.println(sentence); 342 | 343 | Serial.println(); 344 | Serial.println("closing connection"); 345 | 346 | client.stop(); 347 | 348 | } 349 | 350 | // sensor 351 | 352 | void printDht() 353 | { 354 | /* 355 | temperature = dht.readTemperature(); 356 | humidity = dht.readHumidity(); 357 | while ((isnan(temperature) || isnan(humidity)) 358 | || (temperature == 0 && humidity == 0)) { 359 | Serial.print("!"); 360 | delay(500); 361 | temperature = dht.readTemperature(); 362 | humidity = dht.readHumidity(); 363 | } 364 | Serial.println(""); 365 | */ 366 | 367 | 368 | wx.temperatureC = (int) (dht.readTemperature() * 10); 369 | wx.temperatureF = (int) ((dht.readTemperature() * 1.8 + 32) * 10); 370 | // wx.pression = (int) mySensor.readFloatPressure(); 371 | wx.humidite = (int) dht.readHumidity(); 372 | 373 | 374 | Serial.print("Temperature: "); 375 | Serial.print(dht.readTemperature(), 2); 376 | Serial.println(" degrees C"); 377 | /* 378 | Serial.print("Temperature: "); 379 | Serial.print(mySensor.readTempF(), 2); 380 | Serial.println(" degrees F"); 381 | 382 | Serial.print("Pressure: "); 383 | Serial.print(mySensor.readFloatPressure(), 2); 384 | Serial.println(" Pa"); 385 | */ 386 | Serial.print("%RH: "); 387 | Serial.print(dht.readHumidity(), 2); 388 | Serial.println(" %"); 389 | 390 | Serial.println(); 391 | 392 | 393 | } 394 | 395 | /**************************************************************************** 396 | * menu 397 | * */ 398 | 399 | 400 | byte detectMenu() 401 | { 402 | long previousMillisSerial = 0; 403 | long currentMillisSerial; 404 | long EcratMillisSerial; 405 | int countDown = 0; 406 | Serial.println(F("m for boot menu")); 407 | previousMillisSerial = millis(); 408 | do { 409 | currentMillisSerial = millis(); 410 | EcratMillisSerial = currentMillisSerial - previousMillisSerial; 411 | if (Serial.available() > 0) { 412 | if (Serial.read() == 'm') { 413 | while (Serial.read() != '\n') {}; 414 | return 1; 415 | } 416 | } 417 | if ((EcratMillisSerial / 1000) != countDown) { 418 | countDown++; 419 | Serial.write(countDown + 0x30); 420 | } 421 | } 422 | while (EcratMillisSerial < 15000); 423 | Serial.println(); 424 | return 0; 425 | } 426 | 427 | void configMenu() 428 | { 429 | char carMenu; 430 | do { 431 | carMenu = 0; 432 | Serial.println(F("-----------")); 433 | Serial.println(F("Config menu")); 434 | Serial.println(F("0 Quit menu")); 435 | Serial.println(F("1 format file system")); 436 | Serial.println(F("2 config wifi access point")); 437 | Serial.println(F("3 config weather station")); 438 | Serial.println(F("4 test ntp")); 439 | Serial.println(F("5 test DHT 11")); 440 | Serial.println(F("6 test server upload")); 441 | Serial.println(F("7 print weather data logger (historic)")); 442 | Serial.println(F("8 create and erase weather data logger")); 443 | Serial.println(F("-----------")); 444 | carMenu = readCarMenu(); 445 | switch (carMenu) { 446 | case '1' : 447 | Serial.println("Please wait 30 secs for SPIFFS to be formatted"); 448 | //SPIFFS.format(); 449 | Serial.println("Spiffs formatted"); 450 | break; 451 | case '2' : configAcessPoint(); 452 | break; 453 | case '3' : configWeather(); 454 | break; 455 | case '4' : ssidConnect(); ntp(); //prévoir un test de connexion 456 | break; 457 | case '5' : dht.begin(); printDht(); 458 | break; 459 | case '6' : dht.begin(); printDht(); ssidConnect(); ntp(); connexion(); 460 | break; 461 | case '7' : showlogger(); 462 | break; 463 | case '8' : createEraselogger(); 464 | break; 465 | case '0' : 466 | break; 467 | default : Serial.println(F("error")); 468 | } 469 | } while (carMenu != '0'); 470 | } 471 | 472 | void configAcessPoint() 473 | { 474 | if (SPIFFS.exists("/ssid.txt") == 1) { 475 | readSsidFile(); 476 | } 477 | else 478 | { 479 | Serial.println(F("no ssid config file")); 480 | } 481 | char carMenu; 482 | do { 483 | carMenu = 0; 484 | Serial.println(F("-----------")); 485 | Serial.println(F("Config wifi access point menu")); 486 | Serial.println(F("0 Save and exit acess point menu")); 487 | Serial.println(F("1 ssid list")); 488 | Serial.println(F("2 set ssid")); 489 | Serial.println(F("3 set ssid password")); 490 | Serial.println(F("4 show ssid config")); 491 | Serial.println(F("5 test ssid")); 492 | Serial.println(F("-----------")); 493 | carMenu = readCarMenu(); 494 | switch (carMenu) { 495 | case '1' : 496 | wifiScan(); 497 | break; 498 | case '2' : 499 | Serial.println(F("type your ssid")); 500 | readCharArray(internet.ssid); 501 | break; 502 | case '3' : 503 | Serial.println(F("type your password")); 504 | readCharArray(internet.password); 505 | break; 506 | case '4' : 507 | Serial.println(F("your wifi ssid config is")); 508 | Serial.println(internet.ssid); 509 | Serial.println(internet.password); 510 | break; 511 | case '5' : 512 | Serial.println(F("test ssid internet access")); 513 | ssidConnect(); 514 | break; 515 | default : Serial.println(F("error")); 516 | } 517 | } while (carMenu != '0'); 518 | writeSsidFile(); 519 | } 520 | 521 | void configWeather() 522 | { 523 | if (SPIFFS.exists("/station.txt") == 1) { 524 | readStationFile(); 525 | } 526 | else 527 | { 528 | Serial.println(F("no station config file")); 529 | } 530 | char carMenu; 531 | char buffer[10]; 532 | do { 533 | carMenu = 0; 534 | Serial.println(F("-----------")); 535 | Serial.println(F("Config weather station")); 536 | Serial.println(F("0 Save and exit weather station menu")); 537 | Serial.println(F("1 set callsign station")); 538 | Serial.println(F("2 set longitude")); 539 | Serial.println(F("3 set latitude")); 540 | Serial.println(F("4 set server address")); 541 | Serial.println(F("5 set server port")); 542 | Serial.println(F("6 set transmit delay")); 543 | Serial.println(F("7 logger enable")); 544 | Serial.println(F("8 set GMT")); 545 | Serial.println(F("9 show weather config")); 546 | Serial.println(F("-----------")); 547 | carMenu = readCarMenu(); 548 | switch (carMenu) { 549 | case '1' : 550 | Serial.println(F("type your callsign station ex: FWxxxx")); 551 | readCharArray(station.callsign); 552 | break; 553 | case '2' : 554 | Serial.println(F("type your longitude ex: 00012.21E")); 555 | readCharArray(station.longitude); 556 | break; 557 | case '3' : 558 | Serial.println(F("type your latitude ex: 4759.75N")); 559 | readCharArray(station.latitude); 560 | break; 561 | case '4' : 562 | Serial.println(F("type your server address, default : cwop.aprs.net")); 563 | readCharArray(station.clientAdress); 564 | break; 565 | case '5' : 566 | Serial.println(F("type your server port, default : 14580")); 567 | readCharArray(buffer); 568 | station.clientPort = atoi(buffer); 569 | break; 570 | case '6' : 571 | Serial.println(F("type transmit delay, default 10 minutes")); 572 | readCharArray(buffer); 573 | station.transmitDelay = atoi(buffer); 574 | break; 575 | case '7' : 576 | Serial.println(F("logger enable 0/1, defaut 0")); 577 | readCharArray(buffer); 578 | station.logger = atoi(buffer); 579 | break; 580 | case '8' : 581 | Serial.println(F("set GMT, defaut 1")); 582 | readCharArray(buffer); 583 | station.gmt = atoi(buffer); 584 | break; 585 | case '9' : 586 | Serial.print(F("callsign : ")); 587 | Serial.println(station.callsign); 588 | Serial.print(F("longitude : ")); 589 | Serial.println(station.longitude); 590 | Serial.print(F("latitude : ")); 591 | Serial.println(station.latitude); 592 | Serial.print(F("server address : ")); 593 | Serial.println(station.clientAdress); 594 | Serial.print(F("server port : ")); 595 | Serial.println(station.clientPort); 596 | Serial.print(F("tx delay : ")); 597 | Serial.println(station.transmitDelay); 598 | Serial.print(F("logger enable : ")); 599 | Serial.println(station.logger); 600 | Serial.print(F("GMT is : ")); 601 | Serial.println(station.gmt); 602 | break; 603 | case '0' : 604 | break; 605 | default : Serial.println(F("error")); 606 | } 607 | } while (carMenu != '0'); 608 | writeStationFile(); 609 | } 610 | 611 | void readCharArray(char *buffer) 612 | { 613 | char car; 614 | int ptr = 0; 615 | do 616 | { 617 | if (Serial.available() > 0) { 618 | car = Serial.read(); 619 | if (car != '\n') { 620 | buffer[ptr++] = car; 621 | } 622 | } 623 | } 624 | while (car != '\n'); 625 | buffer[ptr] = 0; 626 | } 627 | 628 | char readCarMenu() 629 | { 630 | char car = 0; 631 | char ret = 0; 632 | while (car != '\n') 633 | { 634 | if (Serial.available() > 0) { 635 | car = Serial.read(); 636 | if ((car >= '0') && (car <= '9')) { 637 | ret = car; 638 | } 639 | } 640 | } 641 | return ret; 642 | } 643 | 644 | void wifiScan() 645 | { 646 | Serial.println(F("scan start")); 647 | // WiFi.scanNetworks will return the number of networks found 648 | int n = WiFi.scanNetworks(); 649 | Serial.println(F("scan done")); 650 | if (n == 0) 651 | Serial.println(F("no networks found")); 652 | else 653 | { 654 | Serial.print(n); 655 | Serial.println(F(" networks found")); 656 | for (int i = 0; i < n; ++i) 657 | { 658 | // Print SSID and RSSI for each network found 659 | Serial.print(i + 1); 660 | Serial.print(F(": ")); 661 | Serial.print(WiFi.SSID(i)); 662 | Serial.print(F(" (")); 663 | Serial.print(WiFi.RSSI(i)); 664 | Serial.print(F(")")); 665 | Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*"); 666 | delay(10); 667 | } 668 | } 669 | Serial.println(""); 670 | } 671 | 672 | void writeSsidFile() 673 | { 674 | File f = SPIFFS.open("/ssid.txt", "w+"); 675 | if (!f) { 676 | Serial.println(F("file open failed")); 677 | return; 678 | } 679 | Serial.println(F("====== Writing to ssid.txt file =========")); 680 | for (int i = 0; i < sizeof(configStruct); i++) { 681 | f.write(*((char*)&internet + i)); 682 | } 683 | f.close(); 684 | return; 685 | } 686 | 687 | 688 | void readSsidFile() 689 | { 690 | File f = SPIFFS.open("/ssid.txt", "r+"); 691 | if (!f) { 692 | Serial.println(F("file open failed")); 693 | return; 694 | } 695 | Serial.println(F("====== Reading ssid.txt file =========")); 696 | for (int i = 0; i < sizeof(configStruct); i++) { 697 | *((char*)&internet + i) = f.read(); 698 | } 699 | f.close(); 700 | return; 701 | } 702 | 703 | void writeStationFile() 704 | { 705 | File f = SPIFFS.open("/station.txt", "w+"); 706 | if (!f) { 707 | Serial.println(F("file open failed")); 708 | return; 709 | } 710 | Serial.println(F("====== Writing to station.txt file =========")); 711 | for (int i = 0; i < sizeof(positionStruct); i++) { 712 | f.write(*((char*)&station + i)); 713 | } 714 | f.close(); 715 | return; 716 | } 717 | 718 | void readStationFile() 719 | { 720 | File f = SPIFFS.open("/station.txt", "r+"); 721 | if (!f) { 722 | Serial.println(F("file open failed")); 723 | return; 724 | } 725 | Serial.println(F("====== Reading station.txt file =========")); 726 | for (int i = 0; i < sizeof(positionStruct); i++) { 727 | *((char*)&station + i) = f.read(); 728 | } 729 | f.close(); 730 | return; 731 | } 732 | 733 | 734 | void createEraselogger() 735 | { 736 | File f = SPIFFS.open("/logger.txt", "w"); 737 | if (!f) { 738 | Serial.println("file open failed"); 739 | } 740 | Serial.println("====== new logger file ========="); 741 | f.println("date;time;temperature;humidity;pressure"); 742 | f.close(); 743 | } 744 | 745 | 746 | void showlogger() 747 | { 748 | if (SPIFFS.exists("/logger.txt") == 1) { 749 | String s; 750 | //long sizefile; 751 | File f = SPIFFS.open("/logger.txt", "r"); 752 | if (!f) { 753 | Serial.println("file open failed"); 754 | } 755 | //sizefile=f.size()-42; 756 | Serial.println("====== read logger file ========="); 757 | do { 758 | s = f.readStringUntil('\n'); 759 | Serial.println(s); 760 | } 761 | while (s.length() > 0); 762 | f.close(); 763 | } 764 | } 765 | 766 | 767 | 768 | 769 | void ssidConnect() 770 | { 771 | Serial.println(internet.ssid); 772 | Serial.println(internet.password); 773 | if (WiFi.status() != WL_CONNECTED) 774 | { 775 | Serial.print(F("Connecting to ")); 776 | Serial.println(internet.ssid); 777 | WiFi.mode(WIFI_AP_STA); 778 | // WiFi.mode(WIFI_STA); 779 | WiFi.begin(internet.ssid, internet.password); 780 | Serial.println(); 781 | // Wait for connection 782 | while (WiFi.status() != WL_CONNECTED) { 783 | delay(500); 784 | Serial.print(F(".")); 785 | } 786 | } 787 | Serial.println(); 788 | Serial.print(F("Connected to ")); 789 | Serial.println(internet.ssid); 790 | Serial.print(F("IP address: ")); 791 | Serial.println(WiFi.localIP()); 792 | } 793 | 794 | -------------------------------------------------------------------------------- /T5-Esp8266/cablage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f4goh/Weather/35c7be8217c05d62b959716cc144bfe20eea2857/T5-Esp8266/cablage.jpg -------------------------------------------------------------------------------- /Weather station.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f4goh/Weather/35c7be8217c05d62b959716cc144bfe20eea2857/Weather station.zip -------------------------------------------------------------------------------- /bme_V06/bme_V06.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | esp8266 with BME280 4 | - config menu with serial 5 | - ntp update 6 | - upload weather data on aprs servers 7 | - local web page for weather informations and configuration 8 | f4goh@orange.fr 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | #include 19 | 20 | #include "FS.h" 21 | 22 | NTPtime NTPch("ch.pool.ntp.org"); 23 | //NTPtime NTPch("time.nist.gov"); 24 | 25 | 26 | 27 | #include 28 | //Global sensor object 29 | BME280 mySensor; 30 | 31 | /* 32 | const char* ssid = "Livebox-0E00"; 33 | const char* password = "xxxx"; 34 | const char* host = "cwop.aprs.net"; 35 | */ 36 | 37 | ESP8266WebServer server(80); 38 | 39 | strDateTime dateTime; 40 | byte nextMinTx; 41 | 42 | 43 | typedef struct { 44 | int temperatureC; 45 | int temperatureF; 46 | int pression ; 47 | int humidite; 48 | } WeatherStruct; 49 | WeatherStruct wx; //declare la structure 50 | 51 | typedef struct { 52 | char ssid[50]; 53 | char password[50]; 54 | } configStruct; 55 | configStruct internet; //declare la structure 56 | 57 | typedef struct { 58 | char callsign[10]; 59 | char longitude[10]; 60 | char latitude[10]; 61 | char clientAdress[20]; 62 | int clientPort; 63 | long transmitDelay; 64 | byte logger; 65 | int altitude; 66 | } positionStruct; 67 | positionStruct station; //declare la structure 68 | 69 | long previousMillis = 0; 70 | long currentMillis; 71 | long EcratMillis; 72 | char car; 73 | 74 | void setup(void) 75 | { 76 | strcpy(station.clientAdress, "cwop.aprs.net"); 77 | station.clientPort = 14580; 78 | station.transmitDelay = 10; 79 | station.logger = 0; 80 | 81 | Serial.begin(115200); 82 | Serial.println(); 83 | delay(10); 84 | 85 | SPIFFS.begin(); 86 | if (SPIFFS.exists("/ssid.txt") == 0) { 87 | configMenu(); 88 | } 89 | else 90 | { 91 | readSsidFile(); 92 | } 93 | if (SPIFFS.exists("/station.txt") == 0) { 94 | configMenu(); 95 | } 96 | else 97 | { 98 | readStationFile(); 99 | } 100 | if (detectMenu() == 1) configMenu(); 101 | ssidConnect(); 102 | initBme(); 103 | printBme(); 104 | 105 | delay(1000); 106 | 107 | 108 | server.on("/", handleRoot); 109 | /* 110 | server.on("/inline", []() { 111 | server.send(200, "text/plain", "this works as well"); 112 | }); 113 | server.on ( "/test.svg", drawGraph ); 114 | */ 115 | server.onNotFound(handleNotFound); 116 | server.begin(); 117 | 118 | ntp(); 119 | previousMillis = millis(); 120 | 121 | } 122 | 123 | 124 | void handleRoot() { 125 | char temp[600]; 126 | snprintf ( temp, 600, 127 | "\ 128 | \ 129 | \ 130 | %s Weather Station\ 131 | \ 134 | \ 135 | \ 136 |

%s Weather Station

\ 137 |

Uptime: %02d:%02d:%02d


\ 138 |

Temperature: %d degC


\ 139 |

Pressure: %d pa


\ 140 |

Humidity: %d %


\ 141 | \ 142 | ", 143 | station.callsign,station.callsign,dateTime.hour, dateTime.minute, dateTime.second, wx.temperatureC / 10, wx.pression, wx.humidite 144 | ); 145 | server.send ( 200, "text/html", temp ); 146 | } 147 | 148 | 149 | 150 | 151 | 152 | void handleNotFound() { 153 | //digitalWrite(led, 1); 154 | String message = "File Not Found\n\n"; 155 | message += "URI: "; 156 | message += server.uri(); 157 | message += "\nMethod: "; 158 | message += (server.method() == HTTP_GET) ? "GET" : "POST"; 159 | message += "\nArguments: "; 160 | message += server.args(); 161 | message += "\n"; 162 | for (uint8_t i = 0; i < server.args(); i++) { 163 | message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; 164 | } 165 | server.send(404, "text/plain", message); 166 | //digitalWrite(led, 0); 167 | } 168 | 169 | void loop() 170 | { 171 | 172 | server.handleClient(); 173 | 174 | updateTime(); 175 | 176 | 177 | if ((dateTime.minute >= nextMinTx) && (dateTime.second == 0)) { 178 | updateServer(); 179 | previousMillis = millis(); 180 | } 181 | 182 | if (Serial.available() > 0) { 183 | car= Serial.read(); 184 | if (car == 'm') { 185 | while (Serial.read() != '\n') {}; 186 | configMenu(); 187 | ntp(); 188 | } 189 | if (car == 'f') { 190 | while (Serial.read() != '\n') {}; 191 | updateServer(); 192 | } 193 | } 194 | } 195 | 196 | 197 | void updateTime() 198 | { 199 | currentMillis = millis(); 200 | EcratMillis = currentMillis - previousMillis; 201 | if (EcratMillis > 1000) { 202 | previousMillis = currentMillis; 203 | dateTime.second = (dateTime.second + 1) % 60; 204 | char currentTime[10]; 205 | sprintf(currentTime, "%02d:%02d:%02d", dateTime.hour, dateTime.minute, dateTime.second); 206 | Serial.println(currentTime); 207 | if (dateTime.second == 0) { 208 | dateTime.minute = (dateTime.minute + 1) % 60; 209 | if (dateTime.minute == 0) { 210 | dateTime.hour = (dateTime.hour + 1) % 24; 211 | } 212 | } 213 | } 214 | } 215 | 216 | 217 | void updateServer() 218 | { 219 | if (WiFi.status() == WL_CONNECTED) 220 | { 221 | printBme(); 222 | ntp(); 223 | connexion(); 224 | } 225 | if (station.logger == 1) { 226 | if (SPIFFS.exists("/logger.txt") == 1) { 227 | String s; 228 | //long sizefile; 229 | File f = SPIFFS.open("/logger.txt", "a"); 230 | if (!f) { 231 | Serial.println("file open failed"); 232 | } 233 | Serial.println("====== add data logger ========="); 234 | char buffer[50]; 235 | sprintf(buffer, "%02d/%02d/%04d;", dateTime.day, dateTime.month, dateTime.year); 236 | f.print(buffer); 237 | sprintf(buffer, "%02d:%02d:%02d;", dateTime.hour, dateTime.minute, dateTime.second); 238 | f.print(buffer); 239 | sprintf(buffer, "%03d;%02d;%05d\n", wx.temperatureC / 10, wx.humidite, wx.pression / 10); 240 | f.print(buffer); 241 | f.close(); 242 | } 243 | } 244 | } 245 | 246 | /* 247 | connexion ntp et acces au serveur meto pour uploder les donnees 248 | */ 249 | 250 | /* 251 | * The structure contains following fields: 252 | * struct strDateTime 253 | { 254 | byte hour; 255 | byte minute; 256 | byte second; 257 | int year; 258 | byte month; 259 | byte day; 260 | byte dayofWeek; 261 | boolean valid; 262 | }; 263 | */ 264 | void ntp() 265 | { 266 | if (WiFi.status() == WL_CONNECTED) 267 | { 268 | // first parameter: Time zone in floating point (for India); second parameter: 1 for European summer time; 2 for US daylight saving time (not implemented yet) 269 | dateTime = NTPch.getNTPtime(0.0, 1); 270 | NTPch.printDateTime(dateTime); 271 | 272 | nextMinTx = (dateTime.minute + station.transmitDelay) % 60; 273 | Serial.print("->>>>> next tx at : "); 274 | char buffer[20]; 275 | sprintf(buffer, "%02d:%02d:%02d", dateTime.hour, nextMinTx, 0); 276 | Serial.println(buffer); 277 | } 278 | } 279 | 280 | 281 | void connexion() 282 | { 283 | char login[60]; 284 | char sentence[150]; 285 | 286 | sprintf(login, "user %s pass -1 vers VERSION ESP8266", station.callsign); 287 | sprintf(sentence, "%s>APRS,TCPXX*:@%02d%02d%02dz%s/%s_.../...g...t%03dr...p...P...h%02db%05d", station.callsign, dateTime.hour, dateTime.minute, dateTime.second, station.latitude, station.longitude, wx.temperatureF / 10, wx.humidite, wx.pression / 10); 288 | Serial.println(sentence); 289 | WiFiClient client; 290 | 291 | if (!client.connect(station.clientAdress, station.clientPort)) { 292 | Serial.println("connection failed"); 293 | return; 294 | } 295 | client.println(login); 296 | 297 | 298 | unsigned long timeout = millis(); 299 | while (client.available() == 0) { 300 | if (millis() - timeout > 5000) { 301 | Serial.println(">>> Client Timeout !"); 302 | client.stop(); 303 | return; 304 | } 305 | } 306 | while (client.available()) { 307 | String line = client.readStringUntil('\r'); 308 | Serial.print(line); 309 | } 310 | client.println(sentence); 311 | 312 | Serial.println(); 313 | Serial.println("closing connection"); 314 | 315 | client.stop(); 316 | 317 | } 318 | 319 | 320 | void initBme() 321 | { 322 | //***Driver settings********************************// 323 | //commInterface can be I2C_MODE or SPI_MODE 324 | //specify chipSelectPin using arduino pin names 325 | //specify I2C address. Can be 0x77(default) or 0x76 326 | 327 | //For I2C, enable the following and disable the SPI section 328 | mySensor.settings.commInterface = I2C_MODE; 329 | mySensor.settings.I2CAddress = 0x77; 330 | 331 | //For SPI enable the following and dissable the I2C section 332 | //mySensor.settings.commInterface = SPI_MODE; 333 | //mySensor.settings.chipSelectPin = 10; 334 | 335 | 336 | //***Operation settings*****************************// 337 | 338 | //renMode can be: 339 | // 0, Sleep mode 340 | // 1 or 2, Forced mode 341 | // 3, Normal mode 342 | mySensor.settings.runMode = 3; //Normal mode 343 | 344 | //tStandby can be: 345 | // 0, 0.5ms 346 | // 1, 62.5ms 347 | // 2, 125ms 348 | // 3, 250ms 349 | // 4, 500ms 350 | // 5, 1000ms 351 | // 6, 10ms 352 | // 7, 20ms 353 | mySensor.settings.tStandby = 0; 354 | 355 | //filter can be off or number of FIR coefficients to use: 356 | // 0, filter off 357 | // 1, coefficients = 2 358 | // 2, coefficients = 4 359 | // 3, coefficients = 8 360 | // 4, coefficients = 16 361 | mySensor.settings.filter = 0; 362 | 363 | //tempOverSample can be: 364 | // 0, skipped 365 | // 1 through 5, oversampling *1, *2, *4, *8, *16 respectively 366 | mySensor.settings.tempOverSample = 1; 367 | 368 | //pressOverSample can be: 369 | // 0, skipped 370 | // 1 through 5, oversampling *1, *2, *4, *8, *16 respectively 371 | mySensor.settings.pressOverSample = 1; 372 | 373 | //humidOverSample can be: 374 | // 0, skipped 375 | // 1 through 5, oversampling *1, *2, *4, *8, *16 respectively 376 | mySensor.settings.humidOverSample = 1; 377 | 378 | 379 | Serial.print("Program Started\n"); 380 | Serial.print("Starting BME280... result of .begin(): 0x"); 381 | 382 | //Calling .begin() causes the settings to be loaded 383 | delay(10); //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up. 384 | Serial.println(mySensor.begin(), HEX); 385 | 386 | Serial.print("Displaying ID, reset and ctrl regs\n"); 387 | 388 | Serial.print("ID(0xD0): 0x"); 389 | Serial.println(mySensor.readRegister(BME280_CHIP_ID_REG), HEX); 390 | Serial.print("Reset register(0xE0): 0x"); 391 | Serial.println(mySensor.readRegister(BME280_RST_REG), HEX); 392 | Serial.print("ctrl_meas(0xF4): 0x"); 393 | Serial.println(mySensor.readRegister(BME280_CTRL_MEAS_REG), HEX); 394 | Serial.print("ctrl_hum(0xF2): 0x"); 395 | Serial.println(mySensor.readRegister(BME280_CTRL_HUMIDITY_REG), HEX); 396 | 397 | Serial.print("\n\n"); 398 | 399 | Serial.print("Displaying all regs\n"); 400 | uint8_t memCounter = 0x80; 401 | uint8_t tempReadData; 402 | for (int rowi = 8; rowi < 16; rowi++ ) 403 | { 404 | Serial.print("0x"); 405 | Serial.print(rowi, HEX); 406 | Serial.print("0:"); 407 | for (int coli = 0; coli < 16; coli++ ) 408 | { 409 | tempReadData = mySensor.readRegister(memCounter); 410 | Serial.print((tempReadData >> 4) & 0x0F, HEX);//Print first hex nibble 411 | Serial.print(tempReadData & 0x0F, HEX);//Print second hex nibble 412 | Serial.print(" "); 413 | memCounter++; 414 | } 415 | Serial.print("\n"); 416 | } 417 | 418 | 419 | Serial.print("\n\n"); 420 | 421 | Serial.print("Displaying concatenated calibration words\n"); 422 | Serial.print("dig_T1, uint16: "); 423 | Serial.println(mySensor.calibration.dig_T1); 424 | Serial.print("dig_T2, int16: "); 425 | Serial.println(mySensor.calibration.dig_T2); 426 | Serial.print("dig_T3, int16: "); 427 | Serial.println(mySensor.calibration.dig_T3); 428 | 429 | Serial.print("dig_P1, uint16: "); 430 | Serial.println(mySensor.calibration.dig_P1); 431 | Serial.print("dig_P2, int16: "); 432 | Serial.println(mySensor.calibration.dig_P2); 433 | Serial.print("dig_P3, int16: "); 434 | Serial.println(mySensor.calibration.dig_P3); 435 | Serial.print("dig_P4, int16: "); 436 | Serial.println(mySensor.calibration.dig_P4); 437 | Serial.print("dig_P5, int16: "); 438 | Serial.println(mySensor.calibration.dig_P5); 439 | Serial.print("dig_P6, int16: "); 440 | Serial.println(mySensor.calibration.dig_P6); 441 | Serial.print("dig_P7, int16: "); 442 | Serial.println(mySensor.calibration.dig_P7); 443 | Serial.print("dig_P8, int16: "); 444 | Serial.println(mySensor.calibration.dig_P8); 445 | Serial.print("dig_P9, int16: "); 446 | Serial.println(mySensor.calibration.dig_P9); 447 | 448 | Serial.print("dig_H1, uint8: "); 449 | Serial.println(mySensor.calibration.dig_H1); 450 | Serial.print("dig_H2, int16: "); 451 | Serial.println(mySensor.calibration.dig_H2); 452 | Serial.print("dig_H3, uint8: "); 453 | Serial.println(mySensor.calibration.dig_H3); 454 | Serial.print("dig_H4, int16: "); 455 | Serial.println(mySensor.calibration.dig_H4); 456 | Serial.print("dig_H5, int16: "); 457 | Serial.println(mySensor.calibration.dig_H5); 458 | Serial.print("dig_H6, uint8: "); 459 | Serial.println(mySensor.calibration.dig_H6); 460 | 461 | Serial.println(); 462 | 463 | } 464 | 465 | 466 | void printBme() 467 | { 468 | wx.temperatureC = (int) (mySensor.readTempC() * 10); 469 | wx.temperatureF = (int) (mySensor.readTempF() * 10); 470 | // wx.pression = (int) mySensor.readFloatPressure(); 471 | wx.humidite = (int) mySensor.readFloatHumidity(); 472 | 473 | float temp=mySensor.readTempC(); 474 | float pres= mySensor.readFloatPressure(); 475 | 476 | Serial.print("Pressure at home level: "); 477 | Serial.print(pres, 2); 478 | Serial.println(" Pa"); 479 | 480 | pres= pres * ( pow(1.0 -(0.0065 * (float) station.altitude * -1 /(273.15+temp)), 5.255)); 481 | 482 | wx.pression=(int) pres; 483 | 484 | Serial.print("Pressure at sea level: "); 485 | Serial.print(pres, 2); 486 | Serial.println(" Pa"); 487 | 488 | 489 | Serial.print("Temperature: "); 490 | Serial.print(temp, 2); 491 | Serial.println(" degrees C"); 492 | 493 | Serial.print("Temperature: "); 494 | Serial.print(mySensor.readTempF(), 2); 495 | Serial.println(" degrees F"); 496 | 497 | Serial.print("%RH: "); 498 | Serial.print(mySensor.readFloatHumidity(), 2); 499 | Serial.println(" %"); 500 | 501 | Serial.println(); 502 | 503 | } 504 | 505 | /**************************************************************************** 506 | * menu 507 | * */ 508 | 509 | 510 | byte detectMenu() 511 | { 512 | long previousMillisSerial = 0; 513 | long currentMillisSerial; 514 | long EcratMillisSerial; 515 | int countDown = 0; 516 | Serial.println(F("m for boot menu")); 517 | previousMillisSerial = millis(); 518 | do { 519 | currentMillisSerial = millis(); 520 | EcratMillisSerial = currentMillisSerial - previousMillisSerial; 521 | if (Serial.available() > 0) { 522 | if (Serial.read() == 'm') { 523 | while (Serial.read() != '\n') {}; 524 | return 1; 525 | } 526 | } 527 | if ((EcratMillisSerial / 1000) != countDown) { 528 | countDown++; 529 | Serial.write(countDown + 0x30); 530 | } 531 | } 532 | while (EcratMillisSerial < 10000); 533 | Serial.println(); 534 | return 0; 535 | } 536 | 537 | void configMenu() 538 | { 539 | char carMenu; 540 | do { 541 | carMenu = 0; 542 | Serial.println(F("-----------")); 543 | Serial.println(F("Config menu")); 544 | Serial.println(F("0 Quit menu")); 545 | Serial.println(F("1 format file system")); 546 | Serial.println(F("2 config wifi access point")); 547 | Serial.println(F("3 config weather station")); 548 | Serial.println(F("4 test ntp")); 549 | Serial.println(F("5 test bme 280")); 550 | Serial.println(F("6 test server upload")); 551 | Serial.println(F("7 print weather data logger (historic)")); 552 | Serial.println(F("8 create and erase weather data logger")); 553 | Serial.println(F("-----------")); 554 | carMenu = readCarMenu(); 555 | switch (carMenu) { 556 | case '1' : 557 | Serial.println("Please wait 30 secs for SPIFFS to be formatted"); 558 | SPIFFS.format(); 559 | Serial.println("Spiffs formatted"); 560 | break; 561 | case '2' : configAcessPoint(); 562 | break; 563 | case '3' : configWeather(); 564 | break; 565 | case '4' : ssidConnect(); ntp(); //prévoir un test de connexion 566 | break; 567 | case '5' : initBme(); printBme(); 568 | break; 569 | case '6' : initBme(); printBme(); ssidConnect(); ntp(); connexion(); 570 | break; 571 | case '7' : showlogger(); 572 | break; 573 | case '8' : createEraselogger(); 574 | break; 575 | case '0' : 576 | break; 577 | default : Serial.println(F("error")); 578 | } 579 | } while (carMenu != '0'); 580 | } 581 | 582 | void configAcessPoint() 583 | { 584 | if (SPIFFS.exists("/ssid.txt") == 1) { 585 | readSsidFile(); 586 | } 587 | else 588 | { 589 | Serial.println(F("no ssid config file")); 590 | } 591 | char carMenu; 592 | do { 593 | carMenu = 0; 594 | Serial.println(F("-----------")); 595 | Serial.println(F("Config wifi access point menu")); 596 | Serial.println(F("0 Save and exit acess point menu")); 597 | Serial.println(F("1 ssid list")); 598 | Serial.println(F("2 set ssid")); 599 | Serial.println(F("3 set ssid password")); 600 | Serial.println(F("4 show ssid config")); 601 | Serial.println(F("5 test ssid")); 602 | Serial.println(F("-----------")); 603 | carMenu = readCarMenu(); 604 | switch (carMenu) { 605 | case '1' : 606 | wifiScan(); 607 | break; 608 | case '2' : 609 | Serial.println(F("type your ssid")); 610 | readCharArray(internet.ssid); 611 | break; 612 | case '3' : 613 | Serial.println(F("type your password")); 614 | readCharArray(internet.password); 615 | break; 616 | case '4' : 617 | Serial.println(F("your wifi ssid config is")); 618 | Serial.println(internet.ssid); 619 | Serial.println(internet.password); 620 | break; 621 | case '5' : 622 | Serial.println(F("test ssid internet access")); 623 | ssidConnect(); 624 | break; 625 | default : Serial.println(F("error")); 626 | } 627 | } while (carMenu != '0'); 628 | writeSsidFile(); 629 | } 630 | 631 | void configWeather() 632 | { 633 | if (SPIFFS.exists("/station.txt") == 1) { 634 | readStationFile(); 635 | } 636 | else 637 | { 638 | Serial.println(F("no station config file")); 639 | } 640 | char carMenu; 641 | char buffer[10]; 642 | do { 643 | carMenu = 0; 644 | Serial.println(F("-----------")); 645 | Serial.println(F("Config weather station")); 646 | Serial.println(F("0 Save and exit weather station menu")); 647 | Serial.println(F("1 set callsign station")); 648 | Serial.println(F("2 set longitude")); 649 | Serial.println(F("3 set latitude")); 650 | Serial.println(F("4 set altitude")); 651 | Serial.println(F("5 set server address")); 652 | Serial.println(F("6 set server port")); 653 | Serial.println(F("7 set transmit delay")); 654 | Serial.println(F("8 logger enable")); 655 | Serial.println(F("9 show weather config")); 656 | Serial.println(F("-----------")); 657 | carMenu = readCarMenu(); 658 | switch (carMenu) { 659 | case '1' : 660 | Serial.println(F("type your callsign station ex: FWxxxx")); 661 | readCharArray(station.callsign); 662 | break; 663 | case '2' : 664 | Serial.println(F("type your longitude ex: 00012.21E")); 665 | readCharArray(station.longitude); 666 | break; 667 | case '3' : 668 | Serial.println(F("type your latitude ex: 4759.75N")); 669 | readCharArray(station.latitude); 670 | break; 671 | case '4' : 672 | Serial.println(F("type your altitude (meters) ex: 78")); 673 | readCharArray(buffer); 674 | station.altitude=atoi(buffer); 675 | break; 676 | case '5' : 677 | Serial.println(F("type your server address, default : cwop.aprs.net")); 678 | readCharArray(station.clientAdress); 679 | break; 680 | case '6' : 681 | Serial.println(F("type your server port, default : 14580")); 682 | readCharArray(buffer); 683 | station.clientPort = atoi(buffer); 684 | break; 685 | case '7' : 686 | Serial.println(F("type transmit delay, default 10 minutes")); 687 | readCharArray(buffer); 688 | station.transmitDelay = atoi(buffer); 689 | break; 690 | case '8' : 691 | Serial.println(F("logger enable 0/1, defaut 0")); 692 | readCharArray(buffer); 693 | station.logger = atoi(buffer); 694 | break; 695 | case '9' : 696 | Serial.print(F("callsign : ")); 697 | Serial.println(station.callsign); 698 | Serial.print(F("longitude : ")); 699 | Serial.println(station.longitude); 700 | Serial.print(F("latitude : ")); 701 | Serial.println(station.latitude); 702 | Serial.print(F("altitude : ")); 703 | Serial.println(station.altitude); 704 | Serial.print(F("server address : ")); 705 | Serial.println(station.clientAdress); 706 | Serial.print(F("server port : ")); 707 | Serial.println(station.clientPort); 708 | Serial.print(F("tx delay : ")); 709 | Serial.println(station.transmitDelay); 710 | Serial.print(F("logger enable : ")); 711 | Serial.println(station.logger); 712 | break; 713 | case '0' : 714 | break; 715 | default : Serial.println(F("error")); 716 | } 717 | } while (carMenu != '0'); 718 | writeStationFile(); 719 | } 720 | 721 | void readCharArray(char *buffer) 722 | { 723 | char car; 724 | int ptr = 0; 725 | do 726 | { 727 | if (Serial.available() > 0) { 728 | car = Serial.read(); 729 | if (car != '\n') { 730 | buffer[ptr++] = car; 731 | } 732 | } 733 | } 734 | while (car != '\n'); 735 | buffer[ptr] = 0; 736 | } 737 | 738 | char readCarMenu() 739 | { 740 | char car = 0; 741 | char ret = 0; 742 | while (car != '\n') 743 | { 744 | if (Serial.available() > 0) { 745 | car = Serial.read(); 746 | if ((car >= '0') && (car <= '9')) { 747 | ret = car; 748 | } 749 | } 750 | } 751 | return ret; 752 | } 753 | 754 | void wifiScan() 755 | { 756 | Serial.println(F("scan start")); 757 | // WiFi.scanNetworks will return the number of networks found 758 | int n = WiFi.scanNetworks(); 759 | Serial.println(F("scan done")); 760 | if (n == 0) 761 | Serial.println(F("no networks found")); 762 | else 763 | { 764 | Serial.print(n); 765 | Serial.println(F(" networks found")); 766 | for (int i = 0; i < n; ++i) 767 | { 768 | // Print SSID and RSSI for each network found 769 | Serial.print(i + 1); 770 | Serial.print(F(": ")); 771 | Serial.print(WiFi.SSID(i)); 772 | Serial.print(F(" (")); 773 | Serial.print(WiFi.RSSI(i)); 774 | Serial.print(F(")")); 775 | Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*"); 776 | delay(10); 777 | } 778 | } 779 | Serial.println(""); 780 | } 781 | 782 | void writeSsidFile() 783 | { 784 | File f = SPIFFS.open("/ssid.txt", "w+"); 785 | if (!f) { 786 | Serial.println(F("file open failed")); 787 | return; 788 | } 789 | Serial.println(F("====== Writing to ssid.txt file =========")); 790 | for (int i = 0; i < sizeof(configStruct); i++) { 791 | f.write(*((char*)&internet + i)); 792 | } 793 | f.close(); 794 | return; 795 | } 796 | 797 | 798 | void readSsidFile() 799 | { 800 | File f = SPIFFS.open("/ssid.txt", "r+"); 801 | if (!f) { 802 | Serial.println(F("file open failed")); 803 | return; 804 | } 805 | Serial.println(F("====== Reading ssid.txt file =========")); 806 | for (int i = 0; i < sizeof(configStruct); i++) { 807 | *((char*)&internet + i) = f.read(); 808 | } 809 | f.close(); 810 | return; 811 | } 812 | 813 | void writeStationFile() 814 | { 815 | File f = SPIFFS.open("/station.txt", "w+"); 816 | if (!f) { 817 | Serial.println(F("file open failed")); 818 | return; 819 | } 820 | Serial.println(F("====== Writing to station.txt file =========")); 821 | for (int i = 0; i < sizeof(positionStruct); i++) { 822 | f.write(*((char*)&station + i)); 823 | } 824 | f.close(); 825 | return; 826 | } 827 | 828 | void readStationFile() 829 | { 830 | File f = SPIFFS.open("/station.txt", "r+"); 831 | if (!f) { 832 | Serial.println(F("file open failed")); 833 | return; 834 | } 835 | Serial.println(F("====== Reading station.txt file =========")); 836 | for (int i = 0; i < sizeof(positionStruct); i++) { 837 | *((char*)&station + i) = f.read(); 838 | } 839 | f.close(); 840 | return; 841 | } 842 | 843 | 844 | void createEraselogger() 845 | { 846 | File f = SPIFFS.open("/logger.txt", "w"); 847 | if (!f) { 848 | Serial.println("file open failed"); 849 | } 850 | Serial.println("====== new logger file ========="); 851 | f.println("date;time;temperature;humidity;pressure"); 852 | f.close(); 853 | } 854 | 855 | 856 | void showlogger() 857 | { 858 | if (SPIFFS.exists("/logger.txt") == 1) { 859 | String s; 860 | //long sizefile; 861 | File f = SPIFFS.open("/logger.txt", "r"); 862 | if (!f) { 863 | Serial.println("file open failed"); 864 | } 865 | //sizefile=f.size()-42; 866 | Serial.println("====== read logger file ========="); 867 | do { 868 | s = f.readStringUntil('\n'); 869 | Serial.println(s); 870 | } 871 | while (s.length() > 0); 872 | f.close(); 873 | } 874 | } 875 | 876 | 877 | 878 | 879 | void ssidConnect() 880 | { 881 | Serial.println(internet.ssid); 882 | Serial.println(internet.password); 883 | if (WiFi.status() != WL_CONNECTED) 884 | { 885 | Serial.print(F("Connecting to ")); 886 | Serial.println(internet.ssid); 887 | WiFi.mode(WIFI_AP_STA); 888 | // WiFi.mode(WIFI_STA); 889 | WiFi.begin(internet.ssid, internet.password); 890 | Serial.println(); 891 | // Wait for connection 892 | while (WiFi.status() != WL_CONNECTED) { 893 | delay(500); 894 | Serial.print(F(".")); 895 | } 896 | } 897 | Serial.println(); 898 | Serial.print(F("Connected to ")); 899 | Serial.println(internet.ssid); 900 | Serial.print(F("IP address: ")); 901 | Serial.println(WiFi.localIP()); 902 | } 903 | 904 | -------------------------------------------------------------------------------- /bme_V07.cpp.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/f4goh/Weather/35c7be8217c05d62b959716cc144bfe20eea2857/bme_V07.cpp.bin -------------------------------------------------------------------------------- /bme_V07/bme_V07.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | esp8266 with BME280 4 | - config menu with serial 5 | - ntp update 6 | - upload weather data on aprs servers 7 | - local web page for weather informations and configuration 8 | - add GMT menu 9 | f4goh@orange.fr 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | #include 20 | 21 | #include "FS.h" 22 | 23 | NTPtime NTPch("ch.pool.ntp.org"); 24 | //NTPtime NTPch("time.nist.gov"); 25 | 26 | 27 | 28 | #include 29 | //Global sensor object 30 | BME280 mySensor; 31 | 32 | 33 | ESP8266WebServer server(80); 34 | 35 | strDateTime dateTime; 36 | byte nextMinTx; 37 | 38 | 39 | typedef struct { 40 | int temperatureC; 41 | int temperatureF; 42 | int pression ; 43 | int humidite; 44 | } WeatherStruct; 45 | WeatherStruct wx; //declare la structure 46 | 47 | typedef struct { 48 | char ssid[50]; 49 | char password[50]; 50 | } configStruct; 51 | configStruct internet; //declare la structure 52 | 53 | typedef struct { 54 | char callsign[10]; 55 | char longitude[10]; 56 | char latitude[10]; 57 | char clientAdress[20]; 58 | int clientPort; 59 | long transmitDelay; 60 | byte logger; 61 | byte gmt; 62 | } positionStruct; 63 | positionStruct station; //declare la structure 64 | 65 | long previousMillis = 0; 66 | long currentMillis; 67 | long EcratMillis; 68 | 69 | 70 | void setup(void) 71 | { 72 | strcpy(station.clientAdress, "cwop.aprs.net"); 73 | station.clientPort = 14580; 74 | station.transmitDelay = 10; 75 | station.logger = 0; 76 | station.gmt = 1; 77 | Serial.begin(115200); 78 | Serial.println(); 79 | delay(10); 80 | SPIFFS.begin(); 81 | if (SPIFFS.exists("/ssid.txt") == 0) { 82 | configMenu(); 83 | } 84 | else 85 | { 86 | readSsidFile(); 87 | } 88 | if (SPIFFS.exists("/station.txt") == 0) { 89 | configMenu(); 90 | } 91 | else 92 | { 93 | readStationFile(); 94 | } 95 | if (detectMenu() == 1) configMenu(); 96 | ssidConnect(); 97 | initBme(); 98 | printBme(); 99 | 100 | delay(1000); 101 | 102 | 103 | server.on("/", handleRoot); 104 | /* 105 | server.on("/inline", []() { 106 | server.send(200, "text/plain", "this works as well"); 107 | }); 108 | server.on ( "/test.svg", drawGraph ); 109 | */ 110 | server.onNotFound(handleNotFound); 111 | server.begin(); 112 | 113 | ntp(); 114 | previousMillis = millis(); 115 | 116 | } 117 | 118 | 119 | void handleRoot() { 120 | char temp[600]; 121 | snprintf ( temp, 600, 122 | "\ 123 | \ 124 | \ 125 | %s Weather Station\ 126 | \ 129 | \ 130 | \ 131 |

%s Weather Station

\ 132 |

Uptime: %02d:%02d:%02d


\ 133 |

Temperature: %d degC


\ 134 |

Pressure: %d pa


\ 135 |

Humidity: %d %


\ 136 | \ 137 | ", 138 | station.callsign, station.callsign, dateTime.hour, dateTime.minute, dateTime.second, wx.temperatureC / 10, wx.pression, wx.humidite 139 | ); 140 | server.send ( 200, "text/html", temp ); 141 | } 142 | 143 | 144 | 145 | 146 | 147 | void handleNotFound() { 148 | //digitalWrite(led, 1); 149 | String message = "File Not Found\n\n"; 150 | message += "URI: "; 151 | message += server.uri(); 152 | message += "\nMethod: "; 153 | message += (server.method() == HTTP_GET) ? "GET" : "POST"; 154 | message += "\nArguments: "; 155 | message += server.args(); 156 | message += "\n"; 157 | for (uint8_t i = 0; i < server.args(); i++) { 158 | message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; 159 | } 160 | server.send(404, "text/plain", message); 161 | //digitalWrite(led, 0); 162 | } 163 | /* 164 | void drawGraph() { 165 | String out = ""; 166 | char temp[100]; 167 | out += "\n"; 168 | out += "\n"; 169 | out += "\n"; 170 | int y = rand() % 130; 171 | for (int x = 10; x < 390; x += 10) { 172 | int y2 = rand() % 130; 173 | sprintf(temp, "\n", x, 140 - y, x + 10, 140 - y2); 174 | out += temp; 175 | y = y2; 176 | } 177 | out += "\n\n"; 178 | 179 | server.send ( 200, "image/svg+xml", out); 180 | } 181 | */ 182 | 183 | void loop() 184 | { 185 | //Each loop, take a reading. 186 | //Start with temperature, as that data is needed for accurate compensation. 187 | //Reading the temperature updates the compensators of the other functions 188 | //in the background. 189 | server.handleClient(); 190 | 191 | updateTime(); 192 | 193 | 194 | if ((dateTime.minute >= nextMinTx) && (dateTime.second == 0)) { 195 | updateServer(); 196 | previousMillis = millis(); 197 | } 198 | 199 | if (Serial.available() > 0) { 200 | if (Serial.read() == 'm') { 201 | while (Serial.read() != '\n') {}; 202 | configMenu(); 203 | ntp(); 204 | } 205 | if (Serial.read() == 'f') { 206 | while (Serial.read() != '\n') {}; 207 | updateServer(); 208 | } 209 | } 210 | } 211 | 212 | 213 | void updateTime() 214 | { 215 | currentMillis = millis(); 216 | EcratMillis = currentMillis - previousMillis; 217 | if (EcratMillis > 1000) { 218 | previousMillis = currentMillis; 219 | dateTime.second = (dateTime.second + 1) % 60; 220 | char currentTime[10]; 221 | sprintf(currentTime, "%02d:%02d:%02d", dateTime.hour, dateTime.minute, dateTime.second); 222 | Serial.println(currentTime); 223 | if (dateTime.second == 0) { 224 | dateTime.minute = (dateTime.minute + 1) % 60; 225 | if (dateTime.minute == 0) { 226 | dateTime.hour = (dateTime.hour + 1) % 24; 227 | } 228 | } 229 | } 230 | } 231 | 232 | 233 | void updateServer() 234 | { 235 | if (WiFi.status() == WL_CONNECTED) 236 | { 237 | printBme(); 238 | ntp(); 239 | connexion(); 240 | } 241 | if (station.logger == 1) { 242 | if (SPIFFS.exists("/logger.txt") == 1) { 243 | String s; 244 | //long sizefile; 245 | File f = SPIFFS.open("/logger.txt", "a"); 246 | if (!f) { 247 | Serial.println("file open failed"); 248 | } 249 | Serial.println("====== add data logger ========="); 250 | char buffer[50]; 251 | sprintf(buffer, "%02d/%02d/%04d;", dateTime.day, dateTime.month, dateTime.year); 252 | f.print(buffer); 253 | sprintf(buffer, "%02d:%02d:%02d;", dateTime.hour, dateTime.minute, dateTime.second); 254 | f.print(buffer); 255 | sprintf(buffer, "%03d;%02d;%05d\n", wx.temperatureF / 10, wx.humidite, wx.pression / 10); 256 | f.print(buffer); 257 | f.close(); 258 | } 259 | } 260 | } 261 | 262 | /* 263 | connexion ntp et acces au serveur meto pour uploder les donnees 264 | */ 265 | 266 | /* 267 | * The structure contains following fields: 268 | * struct strDateTime 269 | { 270 | byte hour; 271 | byte minute; 272 | byte second; 273 | int year; 274 | byte month; 275 | byte day; 276 | byte dayofWeek; 277 | boolean valid; 278 | }; 279 | */ 280 | 281 | void ntp() 282 | { 283 | if (WiFi.status() == WL_CONNECTED) 284 | { 285 | // first parameter: Time zone in floating point (for India); second parameter: 1 for European summer time; 2 for US daylight saving time (not implemented yet) 286 | do 287 | { 288 | dateTime = NTPch.getNTPtime(0.0, station.gmt); 289 | NTPch.printDateTime(dateTime); 290 | } 291 | while (!dateTime.valid); 292 | nextMinTx = (dateTime.minute + station.transmitDelay) % 60; 293 | Serial.print("->>>>> next tx at : "); 294 | char buffer[20]; 295 | sprintf(buffer, "%02d:%02d:%02d", dateTime.hour, nextMinTx, 0); 296 | Serial.println(buffer); 297 | } 298 | } 299 | 300 | 301 | void connexion() 302 | { 303 | char login[60]; 304 | char sentence[150]; 305 | //wx.temperatureF = wx.temperatureF * -1; 306 | 307 | sprintf(login, "user %s pass -1 vers VERSION ESP8266", station.callsign); 308 | sprintf(sentence, "%s>APRS,TCPXX*:@%02d%02d%02dz%s/%s_.../...g...t%03dr...p...P...h%02db%05d", station.callsign, dateTime.hour, dateTime.minute, dateTime.second, station.latitude, station.longitude, wx.temperatureF / 10, wx.humidite, wx.pression / 10); 309 | Serial.println(sentence); 310 | //Serial.println("compare"); 311 | //Serial.println("FW0383>APRS,TCPXX*:@164300z4759.75N/00012.21Et034h91b10032"); 312 | // 313 | 314 | WiFiClient client; 315 | //const int httpPort = 14580; 316 | 317 | if (!client.connect(station.clientAdress, station.clientPort)) { 318 | Serial.println("connection failed"); 319 | return; 320 | } 321 | //client.println("user FW0383 pass -1 vers VERSION ESP8266"); 322 | client.println(login); 323 | 324 | 325 | unsigned long timeout = millis(); 326 | while (client.available() == 0) { 327 | if (millis() - timeout > 5000) { 328 | Serial.println(">>> Client Timeout !"); 329 | client.stop(); 330 | return; 331 | } 332 | } 333 | while (client.available()) { 334 | String line = client.readStringUntil('\r'); 335 | Serial.print(line); 336 | } 337 | //client.println("FW0383>APRS,TCPXX*:@164300z4759.75N/00012.21E_256/013g020t034r000p013P001h91b10032"); 338 | //client.println("FW0383>APRS,TCPXX*:@164300z4759.75N/00012.21Et034h91b10032"); 339 | client.println(sentence); 340 | 341 | Serial.println(); 342 | Serial.println("closing connection"); 343 | 344 | client.stop(); 345 | 346 | } 347 | 348 | 349 | void initBme() 350 | { 351 | //***Driver settings********************************// 352 | //commInterface can be I2C_MODE or SPI_MODE 353 | //specify chipSelectPin using arduino pin names 354 | //specify I2C address. Can be 0x77(default) or 0x76 355 | 356 | //For I2C, enable the following and disable the SPI section 357 | mySensor.settings.commInterface = I2C_MODE; 358 | mySensor.settings.I2CAddress = 0x77; 359 | 360 | //For SPI enable the following and dissable the I2C section 361 | //mySensor.settings.commInterface = SPI_MODE; 362 | //mySensor.settings.chipSelectPin = 10; 363 | 364 | 365 | //***Operation settings*****************************// 366 | 367 | //renMode can be: 368 | // 0, Sleep mode 369 | // 1 or 2, Forced mode 370 | // 3, Normal mode 371 | mySensor.settings.runMode = 3; //Normal mode 372 | 373 | //tStandby can be: 374 | // 0, 0.5ms 375 | // 1, 62.5ms 376 | // 2, 125ms 377 | // 3, 250ms 378 | // 4, 500ms 379 | // 5, 1000ms 380 | // 6, 10ms 381 | // 7, 20ms 382 | mySensor.settings.tStandby = 0; 383 | 384 | //filter can be off or number of FIR coefficients to use: 385 | // 0, filter off 386 | // 1, coefficients = 2 387 | // 2, coefficients = 4 388 | // 3, coefficients = 8 389 | // 4, coefficients = 16 390 | mySensor.settings.filter = 0; 391 | 392 | //tempOverSample can be: 393 | // 0, skipped 394 | // 1 through 5, oversampling *1, *2, *4, *8, *16 respectively 395 | mySensor.settings.tempOverSample = 1; 396 | 397 | //pressOverSample can be: 398 | // 0, skipped 399 | // 1 through 5, oversampling *1, *2, *4, *8, *16 respectively 400 | mySensor.settings.pressOverSample = 1; 401 | 402 | //humidOverSample can be: 403 | // 0, skipped 404 | // 1 through 5, oversampling *1, *2, *4, *8, *16 respectively 405 | mySensor.settings.humidOverSample = 1; 406 | 407 | 408 | Serial.print("Program Started\n"); 409 | Serial.print("Starting BME280... result of .begin(): 0x"); 410 | 411 | //Calling .begin() causes the settings to be loaded 412 | delay(10); //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up. 413 | Serial.println(mySensor.begin(), HEX); 414 | 415 | Serial.print("Displaying ID, reset and ctrl regs\n"); 416 | 417 | Serial.print("ID(0xD0): 0x"); 418 | Serial.println(mySensor.readRegister(BME280_CHIP_ID_REG), HEX); 419 | Serial.print("Reset register(0xE0): 0x"); 420 | Serial.println(mySensor.readRegister(BME280_RST_REG), HEX); 421 | Serial.print("ctrl_meas(0xF4): 0x"); 422 | Serial.println(mySensor.readRegister(BME280_CTRL_MEAS_REG), HEX); 423 | Serial.print("ctrl_hum(0xF2): 0x"); 424 | Serial.println(mySensor.readRegister(BME280_CTRL_HUMIDITY_REG), HEX); 425 | 426 | Serial.print("\n\n"); 427 | 428 | Serial.print("Displaying all regs\n"); 429 | uint8_t memCounter = 0x80; 430 | uint8_t tempReadData; 431 | for (int rowi = 8; rowi < 16; rowi++ ) 432 | { 433 | Serial.print("0x"); 434 | Serial.print(rowi, HEX); 435 | Serial.print("0:"); 436 | for (int coli = 0; coli < 16; coli++ ) 437 | { 438 | tempReadData = mySensor.readRegister(memCounter); 439 | Serial.print((tempReadData >> 4) & 0x0F, HEX);//Print first hex nibble 440 | Serial.print(tempReadData & 0x0F, HEX);//Print second hex nibble 441 | Serial.print(" "); 442 | memCounter++; 443 | } 444 | Serial.print("\n"); 445 | } 446 | 447 | 448 | Serial.print("\n\n"); 449 | 450 | Serial.print("Displaying concatenated calibration words\n"); 451 | Serial.print("dig_T1, uint16: "); 452 | Serial.println(mySensor.calibration.dig_T1); 453 | Serial.print("dig_T2, int16: "); 454 | Serial.println(mySensor.calibration.dig_T2); 455 | Serial.print("dig_T3, int16: "); 456 | Serial.println(mySensor.calibration.dig_T3); 457 | 458 | Serial.print("dig_P1, uint16: "); 459 | Serial.println(mySensor.calibration.dig_P1); 460 | Serial.print("dig_P2, int16: "); 461 | Serial.println(mySensor.calibration.dig_P2); 462 | Serial.print("dig_P3, int16: "); 463 | Serial.println(mySensor.calibration.dig_P3); 464 | Serial.print("dig_P4, int16: "); 465 | Serial.println(mySensor.calibration.dig_P4); 466 | Serial.print("dig_P5, int16: "); 467 | Serial.println(mySensor.calibration.dig_P5); 468 | Serial.print("dig_P6, int16: "); 469 | Serial.println(mySensor.calibration.dig_P6); 470 | Serial.print("dig_P7, int16: "); 471 | Serial.println(mySensor.calibration.dig_P7); 472 | Serial.print("dig_P8, int16: "); 473 | Serial.println(mySensor.calibration.dig_P8); 474 | Serial.print("dig_P9, int16: "); 475 | Serial.println(mySensor.calibration.dig_P9); 476 | 477 | Serial.print("dig_H1, uint8: "); 478 | Serial.println(mySensor.calibration.dig_H1); 479 | Serial.print("dig_H2, int16: "); 480 | Serial.println(mySensor.calibration.dig_H2); 481 | Serial.print("dig_H3, uint8: "); 482 | Serial.println(mySensor.calibration.dig_H3); 483 | Serial.print("dig_H4, int16: "); 484 | Serial.println(mySensor.calibration.dig_H4); 485 | Serial.print("dig_H5, int16: "); 486 | Serial.println(mySensor.calibration.dig_H5); 487 | Serial.print("dig_H6, uint8: "); 488 | Serial.println(mySensor.calibration.dig_H6); 489 | 490 | Serial.println(); 491 | 492 | } 493 | 494 | 495 | void printBme() 496 | { 497 | wx.temperatureC = (int) (mySensor.readTempC() * 10); 498 | wx.temperatureF = (int) (mySensor.readTempF() * 10); 499 | wx.pression = (int) mySensor.readFloatPressure(); 500 | wx.humidite = (int) mySensor.readFloatHumidity(); 501 | 502 | 503 | Serial.print("Temperature: "); 504 | Serial.print(mySensor.readTempC(), 2); 505 | Serial.println(" degrees C"); 506 | 507 | Serial.print("Temperature: "); 508 | Serial.print(mySensor.readTempF(), 2); 509 | Serial.println(" degrees F"); 510 | 511 | Serial.print("Pressure: "); 512 | Serial.print(mySensor.readFloatPressure(), 2); 513 | Serial.println(" Pa"); 514 | 515 | Serial.print("%RH: "); 516 | Serial.print(mySensor.readFloatHumidity(), 2); 517 | Serial.println(" %"); 518 | 519 | Serial.println(); 520 | 521 | 522 | } 523 | 524 | /**************************************************************************** 525 | * menu 526 | * */ 527 | 528 | 529 | byte detectMenu() 530 | { 531 | long previousMillisSerial = 0; 532 | long currentMillisSerial; 533 | long EcratMillisSerial; 534 | int countDown = 0; 535 | Serial.println(F("m for boot menu")); 536 | previousMillisSerial = millis(); 537 | do { 538 | currentMillisSerial = millis(); 539 | EcratMillisSerial = currentMillisSerial - previousMillisSerial; 540 | if (Serial.available() > 0) { 541 | if (Serial.read() == 'm') { 542 | while (Serial.read() != '\n') {}; 543 | return 1; 544 | } 545 | } 546 | if ((EcratMillisSerial / 1000) != countDown) { 547 | countDown++; 548 | Serial.write(countDown + 0x30); 549 | } 550 | } 551 | while (EcratMillisSerial < 15000); 552 | Serial.println(); 553 | return 0; 554 | } 555 | 556 | void configMenu() 557 | { 558 | char carMenu; 559 | do { 560 | carMenu = 0; 561 | Serial.println(F("-----------")); 562 | Serial.println(F("Config menu")); 563 | Serial.println(F("0 Quit menu")); 564 | Serial.println(F("1 format file system")); 565 | Serial.println(F("2 config wifi access point")); 566 | Serial.println(F("3 config weather station")); 567 | Serial.println(F("4 test ntp")); 568 | Serial.println(F("5 test bme 280")); 569 | Serial.println(F("6 test server upload")); 570 | Serial.println(F("7 print weather data logger (historic)")); 571 | Serial.println(F("8 create and erase weather data logger")); 572 | Serial.println(F("-----------")); 573 | carMenu = readCarMenu(); 574 | switch (carMenu) { 575 | case '1' : 576 | Serial.println("Please wait 30 secs for SPIFFS to be formatted"); 577 | //SPIFFS.format(); 578 | Serial.println("Spiffs formatted"); 579 | break; 580 | case '2' : configAcessPoint(); 581 | break; 582 | case '3' : configWeather(); 583 | break; 584 | case '4' : ssidConnect(); ntp(); //prévoir un test de connexion 585 | break; 586 | case '5' : initBme(); printBme(); 587 | break; 588 | case '6' : initBme(); printBme(); ssidConnect(); ntp(); connexion(); 589 | break; 590 | case '7' : showlogger(); 591 | break; 592 | case '8' : createEraselogger(); 593 | break; 594 | case '0' : 595 | break; 596 | default : Serial.println(F("error")); 597 | } 598 | } while (carMenu != '0'); 599 | } 600 | 601 | void configAcessPoint() 602 | { 603 | if (SPIFFS.exists("/ssid.txt") == 1) { 604 | readSsidFile(); 605 | } 606 | else 607 | { 608 | Serial.println(F("no ssid config file")); 609 | } 610 | char carMenu; 611 | do { 612 | carMenu = 0; 613 | Serial.println(F("-----------")); 614 | Serial.println(F("Config wifi access point menu")); 615 | Serial.println(F("0 Save and exit acess point menu")); 616 | Serial.println(F("1 ssid list")); 617 | Serial.println(F("2 set ssid")); 618 | Serial.println(F("3 set ssid password")); 619 | Serial.println(F("4 show ssid config")); 620 | Serial.println(F("5 test ssid")); 621 | Serial.println(F("-----------")); 622 | carMenu = readCarMenu(); 623 | switch (carMenu) { 624 | case '1' : 625 | wifiScan(); 626 | break; 627 | case '2' : 628 | Serial.println(F("type your ssid")); 629 | readCharArray(internet.ssid); 630 | break; 631 | case '3' : 632 | Serial.println(F("type your password")); 633 | readCharArray(internet.password); 634 | break; 635 | case '4' : 636 | Serial.println(F("your wifi ssid config is")); 637 | Serial.println(internet.ssid); 638 | Serial.println(internet.password); 639 | break; 640 | case '5' : 641 | Serial.println(F("test ssid internet access")); 642 | ssidConnect(); 643 | break; 644 | default : Serial.println(F("error")); 645 | } 646 | } while (carMenu != '0'); 647 | writeSsidFile(); 648 | } 649 | 650 | void configWeather() 651 | { 652 | if (SPIFFS.exists("/station.txt") == 1) { 653 | readStationFile(); 654 | } 655 | else 656 | { 657 | Serial.println(F("no station config file")); 658 | } 659 | char carMenu; 660 | char buffer[10]; 661 | do { 662 | carMenu = 0; 663 | Serial.println(F("-----------")); 664 | Serial.println(F("Config weather station")); 665 | Serial.println(F("0 Save and exit weather station menu")); 666 | Serial.println(F("1 set callsign station")); 667 | Serial.println(F("2 set longitude")); 668 | Serial.println(F("3 set latitude")); 669 | Serial.println(F("4 set server address")); 670 | Serial.println(F("5 set server port")); 671 | Serial.println(F("6 set transmit delay")); 672 | Serial.println(F("7 logger enable")); 673 | Serial.println(F("8 set GMT")); 674 | Serial.println(F("9 show weather config")); 675 | Serial.println(F("-----------")); 676 | carMenu = readCarMenu(); 677 | switch (carMenu) { 678 | case '1' : 679 | Serial.println(F("type your callsign station ex: FWxxxx")); 680 | readCharArray(station.callsign); 681 | break; 682 | case '2' : 683 | Serial.println(F("type your longitude ex: 00012.21E")); 684 | readCharArray(station.longitude); 685 | break; 686 | case '3' : 687 | Serial.println(F("type your latitude ex: 4759.75N")); 688 | readCharArray(station.latitude); 689 | break; 690 | case '4' : 691 | Serial.println(F("type your server address, default : cwop.aprs.net")); 692 | readCharArray(station.clientAdress); 693 | break; 694 | case '5' : 695 | Serial.println(F("type your server port, default : 14580")); 696 | readCharArray(buffer); 697 | station.clientPort = atoi(buffer); 698 | break; 699 | case '6' : 700 | Serial.println(F("type transmit delay, default 10 minutes")); 701 | readCharArray(buffer); 702 | station.transmitDelay = atoi(buffer); 703 | break; 704 | case '7' : 705 | Serial.println(F("logger enable 0/1, defaut 0")); 706 | readCharArray(buffer); 707 | station.logger = atoi(buffer); 708 | break; 709 | case '8' : 710 | Serial.println(F("set GMT, defaut 1")); 711 | readCharArray(buffer); 712 | station.gmt = atoi(buffer); 713 | break; 714 | case '9' : 715 | Serial.print(F("callsign : ")); 716 | Serial.println(station.callsign); 717 | Serial.print(F("longitude : ")); 718 | Serial.println(station.longitude); 719 | Serial.print(F("latitude : ")); 720 | Serial.println(station.latitude); 721 | Serial.print(F("server address : ")); 722 | Serial.println(station.clientAdress); 723 | Serial.print(F("server port : ")); 724 | Serial.println(station.clientPort); 725 | Serial.print(F("tx delay : ")); 726 | Serial.println(station.transmitDelay); 727 | Serial.print(F("logger enable : ")); 728 | Serial.println(station.logger); 729 | Serial.print(F("GMT is : ")); 730 | Serial.println(station.gmt); 731 | break; 732 | case '0' : 733 | break; 734 | default : Serial.println(F("error")); 735 | } 736 | } while (carMenu != '0'); 737 | writeStationFile(); 738 | } 739 | 740 | void readCharArray(char *buffer) 741 | { 742 | char car; 743 | int ptr = 0; 744 | do 745 | { 746 | if (Serial.available() > 0) { 747 | car = Serial.read(); 748 | if (car != '\n') { 749 | buffer[ptr++] = car; 750 | } 751 | } 752 | } 753 | while (car != '\n'); 754 | buffer[ptr] = 0; 755 | } 756 | 757 | char readCarMenu() 758 | { 759 | char car = 0; 760 | char ret = 0; 761 | while (car != '\n') 762 | { 763 | if (Serial.available() > 0) { 764 | car = Serial.read(); 765 | if ((car >= '0') && (car <= '9')) { 766 | ret = car; 767 | } 768 | } 769 | } 770 | return ret; 771 | } 772 | 773 | void wifiScan() 774 | { 775 | Serial.println(F("scan start")); 776 | // WiFi.scanNetworks will return the number of networks found 777 | int n = WiFi.scanNetworks(); 778 | Serial.println(F("scan done")); 779 | if (n == 0) 780 | Serial.println(F("no networks found")); 781 | else 782 | { 783 | Serial.print(n); 784 | Serial.println(F(" networks found")); 785 | for (int i = 0; i < n; ++i) 786 | { 787 | // Print SSID and RSSI for each network found 788 | Serial.print(i + 1); 789 | Serial.print(F(": ")); 790 | Serial.print(WiFi.SSID(i)); 791 | Serial.print(F(" (")); 792 | Serial.print(WiFi.RSSI(i)); 793 | Serial.print(F(")")); 794 | Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*"); 795 | delay(10); 796 | } 797 | } 798 | Serial.println(""); 799 | } 800 | 801 | void writeSsidFile() 802 | { 803 | File f = SPIFFS.open("/ssid.txt", "w+"); 804 | if (!f) { 805 | Serial.println(F("file open failed")); 806 | return; 807 | } 808 | Serial.println(F("====== Writing to ssid.txt file =========")); 809 | for (int i = 0; i < sizeof(configStruct); i++) { 810 | f.write(*((char*)&internet + i)); 811 | } 812 | f.close(); 813 | return; 814 | } 815 | 816 | 817 | void readSsidFile() 818 | { 819 | File f = SPIFFS.open("/ssid.txt", "r+"); 820 | if (!f) { 821 | Serial.println(F("file open failed")); 822 | return; 823 | } 824 | Serial.println(F("====== Reading ssid.txt file =========")); 825 | for (int i = 0; i < sizeof(configStruct); i++) { 826 | *((char*)&internet + i) = f.read(); 827 | } 828 | f.close(); 829 | return; 830 | } 831 | 832 | void writeStationFile() 833 | { 834 | File f = SPIFFS.open("/station.txt", "w+"); 835 | if (!f) { 836 | Serial.println(F("file open failed")); 837 | return; 838 | } 839 | Serial.println(F("====== Writing to station.txt file =========")); 840 | for (int i = 0; i < sizeof(positionStruct); i++) { 841 | f.write(*((char*)&station + i)); 842 | } 843 | f.close(); 844 | return; 845 | } 846 | 847 | void readStationFile() 848 | { 849 | File f = SPIFFS.open("/station.txt", "r+"); 850 | if (!f) { 851 | Serial.println(F("file open failed")); 852 | return; 853 | } 854 | Serial.println(F("====== Reading station.txt file =========")); 855 | for (int i = 0; i < sizeof(positionStruct); i++) { 856 | *((char*)&station + i) = f.read(); 857 | } 858 | f.close(); 859 | return; 860 | } 861 | 862 | 863 | void createEraselogger() 864 | { 865 | File f = SPIFFS.open("/logger.txt", "w"); 866 | if (!f) { 867 | Serial.println("file open failed"); 868 | } 869 | Serial.println("====== new logger file ========="); 870 | f.println("date;time;temperature;humidity;pressure"); 871 | f.close(); 872 | } 873 | 874 | 875 | void showlogger() 876 | { 877 | if (SPIFFS.exists("/logger.txt") == 1) { 878 | String s; 879 | //long sizefile; 880 | File f = SPIFFS.open("/logger.txt", "r"); 881 | if (!f) { 882 | Serial.println("file open failed"); 883 | } 884 | //sizefile=f.size()-42; 885 | Serial.println("====== read logger file ========="); 886 | do { 887 | s = f.readStringUntil('\n'); 888 | Serial.println(s); 889 | } 890 | while (s.length() > 0); 891 | f.close(); 892 | } 893 | } 894 | 895 | 896 | 897 | 898 | void ssidConnect() 899 | { 900 | Serial.println(internet.ssid); 901 | Serial.println(internet.password); 902 | if (WiFi.status() != WL_CONNECTED) 903 | { 904 | Serial.print(F("Connecting to ")); 905 | Serial.println(internet.ssid); 906 | WiFi.mode(WIFI_AP_STA); 907 | // WiFi.mode(WIFI_STA); 908 | WiFi.begin(internet.ssid, internet.password); 909 | Serial.println(); 910 | // Wait for connection 911 | while (WiFi.status() != WL_CONNECTED) { 912 | delay(500); 913 | Serial.print(F(".")); 914 | } 915 | } 916 | Serial.println(); 917 | Serial.print(F("Connected to ")); 918 | Serial.println(internet.ssid); 919 | Serial.print(F("IP address: ")); 920 | Serial.println(WiFi.localIP()); 921 | } 922 | 923 | --------------------------------------------------------------------------------