ESP + Reorganizacja
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
/*********************************************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-2022 Gregg E. Berman
|
||||
*
|
||||
* https://github.com/HomeSpan/HomeSpan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// HomeSpan: A HomeKit implementation for the ESP32 //
|
||||
// ------------------------------------------------ //
|
||||
// //
|
||||
// Demonstrates how to use SpanPoint() to implement //
|
||||
// two remote temperature sensors on separate ESP32 //
|
||||
// devices. //
|
||||
// //
|
||||
// This sketch is for the MAIN DEVICE that contains //
|
||||
// all the usual HomeSpan logic, plus two instances //
|
||||
// of SpanPoint to read temperatures from two other //
|
||||
// remote devices. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#include "HomeSpan.h"
|
||||
|
||||
struct RemoteTempSensor : Service::TemperatureSensor {
|
||||
|
||||
SpanCharacteristic *temp;
|
||||
SpanCharacteristic *fault;
|
||||
SpanPoint *remoteTemp;
|
||||
const char *name;
|
||||
float temperature;
|
||||
|
||||
RemoteTempSensor(const char *name, const char*macAddress) : Service::TemperatureSensor(){
|
||||
|
||||
this->name=name;
|
||||
|
||||
temp=new Characteristic::CurrentTemperature(-10.0); // set initial temperature
|
||||
temp->setRange(-50,100); // expand temperature range to allow negative values
|
||||
|
||||
fault=new Characteristic::StatusFault(1); // set initial state = fault
|
||||
|
||||
remoteTemp=new SpanPoint(macAddress,0,sizeof(float)); // create a SpanPoint with send size=0 and receive size=sizeof(float)
|
||||
|
||||
} // end constructor
|
||||
|
||||
void loop(){
|
||||
|
||||
if(remoteTemp->get(&temperature)){ // if there is data from the remote sensor
|
||||
temp->setVal(temperature); // update temperature
|
||||
fault->setVal(0); // clear fault
|
||||
|
||||
LOG1("Sensor %s update: Temperature=%0.2f\n",name,temperature*9/5+32);
|
||||
|
||||
} else if(remoteTemp->time()>60000 && !fault->getVal()){ // else if it has been a while since last update (60 seconds), and there is no current fault
|
||||
fault->setVal(1); // set fault state
|
||||
LOG1("Sensor %s update: FAULT\n",name);
|
||||
}
|
||||
|
||||
} // loop
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
homeSpan.setLogLevel(1);
|
||||
|
||||
homeSpan.begin(Category::Bridges,"Sensor Hub");
|
||||
|
||||
new SpanAccessory();
|
||||
new Service::AccessoryInformation();
|
||||
new Characteristic::Identify();
|
||||
|
||||
new SpanAccessory();
|
||||
new Service::AccessoryInformation();
|
||||
new Characteristic::Identify();
|
||||
new Characteristic::Name("Indoor Temp");
|
||||
new RemoteTempSensor("Device 1","AC:67:B2:77:42:20"); // pass MAC Address of Remote Device
|
||||
|
||||
new SpanAccessory();
|
||||
new Service::AccessoryInformation();
|
||||
new Characteristic::Identify();
|
||||
new Characteristic::Name("Outdoor Temp");
|
||||
new RemoteTempSensor("Device 2","84:CC:A8:11:B4:84"); // pass MAC Address of Remote Device
|
||||
|
||||
|
||||
} // end of setup()
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
void loop(){
|
||||
|
||||
homeSpan.poll();
|
||||
|
||||
} // end of loop()
|
||||
|
||||
//////////////////////////////////////
|
||||
@@ -0,0 +1,79 @@
|
||||
|
||||
/*********************************************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-2022 Gregg E. Berman
|
||||
*
|
||||
* https://github.com/HomeSpan/HomeSpan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// HomeSpan: A HomeKit implementation for the ESP32 //
|
||||
// ------------------------------------------------ //
|
||||
// //
|
||||
// Demonstrates how to use SpanPoint() to implement //
|
||||
// two remote temperature sensors on separate ESP32 //
|
||||
// devices. //
|
||||
// //
|
||||
// This sketch is for the REMOTE DEVICES. They are //
|
||||
// very simple and don't need any of the normal //
|
||||
// HomeSpan logic (except for SpanPoint). //
|
||||
// //
|
||||
// Note this sketch only SIMULATES a temperature //
|
||||
// sensor by slowly setting the temperature from //
|
||||
// -30.0 to 35.0 C in steps of 0.5 C. The sketch //
|
||||
// does not contain logic for an actual physical //
|
||||
// temperature sensor. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#include "HomeSpan.h"
|
||||
|
||||
float temperature=-10.0;
|
||||
SpanPoint *mainDevice;
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
|
||||
Serial.printf("\n\nThis is a REMOTE Device with MAC Address = %s\n",WiFi.macAddress().c_str());
|
||||
Serial.printf("NOTE: This MAC Address must be entered into the corresponding SpanPoint() call of the MAIN Device.\n\n");
|
||||
|
||||
// In the line below, replace the MAC Address with that of your MAIN HOMESPAN DEVICE
|
||||
|
||||
mainDevice=new SpanPoint("84:CC:A8:11:B4:84",sizeof(float),0); // create a SpanPoint with send size=sizeof(float) and receive size=0
|
||||
|
||||
homeSpan.setLogLevel(1);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
boolean success = mainDevice->send(&temperature); // this will show as success as long as the MAIN DEVICE is running
|
||||
Serial.printf("Send %s\n",success?"Succeded":"Failed");
|
||||
temperature+=0.5;
|
||||
if(temperature>35.0)
|
||||
temperature=-30.0;
|
||||
|
||||
delay(20000);
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*********************************************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Gregg E. Berman
|
||||
*
|
||||
* https://github.com/HomeSpan/HomeSpan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef ARDUINO_ARCH_ESP8266
|
||||
#error ERROR: THIS SKETCH IS DESIGNED FOR ESP8266 MICROCONTROLLERS!
|
||||
#endif
|
||||
|
||||
// *** THIS SKETCH IS FOR AN ESP8266, NOT AN ESP32 *** //
|
||||
|
||||
// This sketch is similar to HomeSpan's RemoteDevice.ino example (designed for an ESP32 running HomeSpan) in which we simulate
|
||||
// a Remote Temperature Sensor using HomeSpan's SpanPoint class. However, since neither HomeSpan nor SpanPoint is designed to
|
||||
// run on an ESP8266, we will implement the BASIC communication functionality of SpanPoint by directly calling the equivalent
|
||||
// ESP-NOW commands that are supported by the ESP8266. This sketch does NOT seek to replicate all of SpanPoint's features, and
|
||||
// does not include automatic channel calibration or queue management.
|
||||
|
||||
// Start by including the following ESP8266 libraries
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <espnow.h>
|
||||
#include <Crypto.h> // this library is needed to implement the hash-code process SpanPoint uses to generate ESP-NOW encryption keys
|
||||
|
||||
float temp=-10.0; // this global variable represents our "simulated" temperature (in degrees C)
|
||||
|
||||
// Below we encode the MAC Address of the Main ESP32 Device running HomeSpan to which this ESP8266 device will connect
|
||||
|
||||
// IMPORTANT: ESP32 devices have TWO MAC Addresses. One is used when the ESP32 is operating in Station (STA) mode. It is the address returned
|
||||
// by the WiFi.macAddress() function. The other is used when the ESP32 is operating in Access Point (AP) mode. This address is returned by the
|
||||
// WiFi.softAPmacAddress() function. HomeSpan normally operates the ESP32 with both modes (STA+AP), so both MAC Addresses are active.
|
||||
|
||||
// On ESP32 devices, ESP-NOW seems to work fine when each device sends data to other devices via their STA MAC Address. The same is true for ESP8266
|
||||
// devices sending data to an ESP32 device via ESP-NOW with one critical exception: Once the ESP32 connects (via STA mode) to a WiFi network, which it must
|
||||
// do to run HomeSpan, for some reason ESP8266 devices can no longer send data via ESP-NOW to the ESP32 using its STA MAC Address.
|
||||
|
||||
// The solution is to instead have the ESP8266 send data via ESP-NOW to the ESP32's AP MAC Address. This seems to work regardless of whether or not
|
||||
// the ESP32 is connected to a central WiFi newtork. To support such use on the ESP32, the SpanPoint constructor includes a fifth, optional parameter
|
||||
// called "useAPaddress". When creating SpanPoint links of the ESP32 using HomeSpan, set useAPaddress to TRUE if the Remote Device SpanPoint is connecting
|
||||
// to is an ESP8266. Set "useAPaddress" to FALSE (or leave unspecified, since FALSE is the default) if the Remote Device is an ESP32.
|
||||
|
||||
// When HomeSpan first starts (and whenever you type 'i' into the CLI), the Serial Monitor will display the details of each SpanPoint object you instantiated
|
||||
// in your ESP32 sketch. This output includes the MAC Address at which SpanPoint will be listening for incoming data from Remote Devices. The MAC Address
|
||||
// shown for the instance of SpanPoint corresponding to this Remote Deivce (i.e. this sketch) is the MAC Address you should use below.
|
||||
|
||||
uint8_t main_mac[6]={0x84,0xCC,0xA8,0x11,0xB4,0x85}; // this is the **AP MAC Address** of the Main Device running HomeSpan on an ESP32 as reported in the HomeSpan Serial Monitor
|
||||
|
||||
// Next we create a simple, standard ESP-NOW callback function to report on the status of each data transmission
|
||||
|
||||
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
|
||||
Serial.printf("Last Packet Send Status: %s\n",sendStatus==0?"Success":"Fail");
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
Serial.printf("\nMAC Address: %s\n",WiFi.macAddress().c_str()); // enter this MAC address as the first argument of the matching SpanPoint object on the ESP32 running HomeSpan
|
||||
|
||||
WiFi.mode(WIFI_STA); // set the mode to Station
|
||||
wifi_set_channel(6); // you also need to manually set the channel to match whatever channel is used by the ESP32 after it connects to your WiFi network
|
||||
|
||||
// Hint: As an alterntive, you can add code to this sketch to connect to the same WiFi network that HomeSpan uses. Though this sketch won't make any use of that WiFi network,
|
||||
// by establishing the connection the ESP8266 automatically configures the channel, which will now match the ESP32.
|
||||
|
||||
// Next, initialize ESP-NOW
|
||||
|
||||
if (esp_now_init() != 0) {
|
||||
Serial.println("Error initializing ESP-NOW");
|
||||
return;
|
||||
}
|
||||
|
||||
// SpanPoint uses ESP-NOW encryption for all communication. This encrpytion is based on two 16-byte keys: a local master key (LMK) and a primary master key (PMK). To generate
|
||||
// these keys, SpanPoint takes a text-based password (the default is the word "HomeSpan"), creates a 32 byte (256 bit) hash of the text (using the SHA256 method), and uses
|
||||
// the first 16 bytes as the LMK and the last 16 bytes as the PMK. This is easily replicated as follows:
|
||||
|
||||
uint8_t hash[32]; // create space to store as 32-byte hash code
|
||||
char password[]="HomeSpan"; // specify the password
|
||||
|
||||
experimental::crypto::SHA256::hash(password,strlen(password),hash); // create the hash code to be used further below
|
||||
|
||||
esp_now_register_send_cb(OnDataSent); // register the callback function we defined above
|
||||
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); // set the role of this device to be a controller (i.e. it sends data to the ESP32)
|
||||
|
||||
esp_now_set_kok(hash+16,16); // next we set the PMK. For some reason this is called KOK on the ESP8266. Note you must set the PMK BEFORE adding any peers
|
||||
|
||||
esp_now_add_peer(main_mac, ESP_NOW_ROLE_COMBO, 0, hash, 16); // now we add in the peer, set its role, and specify the LMK
|
||||
|
||||
// Hint: The third argument above is the WiFi Channel. However, this is only a reference number stored by ESP-NOW. ESP-NOW does NOT actually set the channel for you.
|
||||
// We already set the WiFi channel above. To make things easier, ESP-NOW allows you to set the channel as zero, which means ESP-NOW should expect the channel to be whatever was
|
||||
// already set for the WiFi controller. Recommend always setting this to zero to avoid having any mismatches if you instead specified a real channel.
|
||||
}
|
||||
|
||||
//////////////////////
|
||||
|
||||
void loop() {
|
||||
|
||||
Serial.printf("Sending Temperature: %f\n",temp);
|
||||
esp_now_send(main_mac, (uint8_t *)&temp, sizeof(temp)); // Send the Data to the Main Device!
|
||||
|
||||
temp+=0.5; // increment the "temperature" by 0.5 C
|
||||
if(temp>35.0)
|
||||
temp=-10.0;
|
||||
|
||||
delay(5000); // wait 5 seconds before sending another update
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
/*********************************************************************************
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020-2022 Gregg E. Berman
|
||||
*
|
||||
* https://github.com/HomeSpan/HomeSpan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// HomeSpan: A HomeKit implementation for the ESP32 //
|
||||
// ------------------------------------------------ //
|
||||
// //
|
||||
// This sketch is for a Remote Temperature Sensor to //
|
||||
// be used in conjunction with the "MainDevice.ino" //
|
||||
// sketch running on a separate ESP32 //
|
||||
// //
|
||||
// The purpose of these sketches is to demonstrate //
|
||||
// how to use SpanPoint() to communication between //
|
||||
// a remote ESP32 device that takes measurements from //
|
||||
// a sensor, and a separate "main" ESP32 device that //
|
||||
// is running the full HomeSpan code, and thus //
|
||||
// connects to HomeKit. //
|
||||
// //
|
||||
// This sketch implements an Adafruit ADT7410 I2C //
|
||||
// Temperature Sensor. If you don't have such a //
|
||||
// device, please use the sketch "RemoteDevice.ino" //
|
||||
// instead. That sketch SIMULATES a temperature //
|
||||
// sensor and therefore allows you to learn how //
|
||||
// SpanPoint() works even though the temperature data //
|
||||
// itself isn't real. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#include "HomeSpan.h"
|
||||
#include <Wire.h> // include the I2C library
|
||||
|
||||
#define DIAGNOSTIC_MODE
|
||||
|
||||
#define SAMPLE_TIME 30000 // Time between temperature samples (in milliseconds)
|
||||
#define I2C_ADD 0x48 // I2C Address to use for the Adafruit ADT7410
|
||||
|
||||
SpanPoint *mainDevice;
|
||||
|
||||
void setup() {
|
||||
|
||||
setCpuFrequencyMhz(80); // reduce CPU frequency to save battery power
|
||||
|
||||
#if defined(DIAGNOSTIC_MODE)
|
||||
homeSpan.setLogLevel(1);
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
Serial.printf("Starting Remote Temperature Sensor. MAC Address of this device = %s\n",WiFi.macAddress().c_str());
|
||||
#endif
|
||||
|
||||
// In the line below, replace the MAC Address with that of your MAIN HOMESPAN DEVICE
|
||||
|
||||
mainDevice=new SpanPoint("7C:DF:A1:61:E4:A8",sizeof(float),0); // create a SpanPoint with send size=sizeof(float) and receive size=0
|
||||
|
||||
Wire.begin(); // start I2C in Controller Mode
|
||||
|
||||
#if defined(DIAGNOSTIC_MODE)
|
||||
Wire.beginTransmission(I2C_ADD); // setup transmission
|
||||
Wire.write(0x0B); // ADT7410 Identification Register
|
||||
Wire.endTransmission(0); // transmit and leave in restart mode to allow reading
|
||||
Wire.requestFrom(I2C_ADD,1); // request read of single byte
|
||||
uint8_t id = Wire.read(); // receive a byte
|
||||
LOG1("Configuring Temperature Sensor ADT7410 version 0x%02X with address 0x%02X.\n",id,I2C_ADD); // initialization message
|
||||
#endif
|
||||
|
||||
Wire.beginTransmission(I2C_ADD); // setup transmission
|
||||
Wire.write(0x03); // ADT740 Configuration Register
|
||||
Wire.write(0xC0); // set 16-bit temperature resolution, 1 sample per second
|
||||
Wire.endTransmission(); // transmit
|
||||
|
||||
Wire.beginTransmission(I2C_ADD); // setup transmission
|
||||
Wire.write(0x00); // ADT7410 2-byte Temperature
|
||||
Wire.endTransmission(0); // transmit and leave in restart mode to allow reading
|
||||
Wire.requestFrom(I2C_ADD,2); // request read of two bytes
|
||||
|
||||
int16_t iTemp = ((int16_t)Wire.read()<<8)+Wire.read();
|
||||
float temperature = iTemp/128.0;
|
||||
|
||||
boolean success = mainDevice->send(&temperature); // send temperature to main device
|
||||
|
||||
LOG1("Send temp update of %0.2f F: %s\n",temperature*9/5+32,success?"Succeded":"Failed");
|
||||
|
||||
esp_deep_sleep(SAMPLE_TIME*1000); // enter deep sleep mode -- reboot after resuming
|
||||
}
|
||||
Reference in New Issue
Block a user