2 |
3 |
4 | # [ :book: ESP32 Coop Door Documentation ](https://coop-door.vercel.app/)
5 |
6 | The goal is to document the setup & configuration of the [esp32-coop](https://github.com/ESP32-COOP) project as well as the protocol in which the two devices communicate over BLE
7 |
8 |
9 |
10 | # :memo: Summary:
11 |
12 | - [:page_facing_up: **Project Overview**](page_facing_up-project-overview): quick presentation of the mother project (goal, link device, protocol used, problematic)
13 | - [:iphone: **The App**](#iphone-app-installation): how to get the it
14 | - [:toolbox: **Build instruction**](#toolbox-build-instruction)
15 | - :clipboard: Requirement
16 | - :flashlight: Wiring
17 | - :rocket: First Boot
18 | - :house: 3D file
19 | - :signal_strength: **Communication protocol**
20 | - :electric_plug: Run-down on how BLE works
21 | - :bar_chart: The type of data required by the project (in progress)
22 | - :computer: Code snippet for each characteristic (in progress)
23 |
24 |
25 | # :page_facing_up: Project Overview
26 |
27 |
28 |
29 |
30 |
31 |
32 | The [COOP-DOOR](https://github.com/ESP32-COOP) project aims to create an intelligent and user-friendly automatic coop door system. It empowers users to customize the door's behavior based on specific conditions, such as time and light levels. To facilitate device management and monitoring, the project offers a mobile app.
33 |
34 | The app enables users to track device and sensor health, as well as configure various operating conditions. For a demonstration of the project, please refer to the demo [here](https://github.com/ESP32-COOP/ESP32-COOP-DOOR-WEB). The core of the smart coop door relies on the ESP-32 platform, and the code repository can be found [here](https://github.com/ESP32-COOP/ESP32-COOP-DOOR-CORE).
35 |
36 | This documentation page aims to guide users through the setup process, hardware requirements, and detailed workings of the system.
37 |
38 |
39 |
40 |
41 | # :iphone: App Installation
42 |
43 |
44 |
45 |
46 | The coop door application is a Progressive Web App, meaning it functions as a website and can be installed on mobile devices for offline usage.
47 |
48 |
49 |
50 | To install the app, follow these steps:
51 |
52 | 1. Visit [coop-door.vercel.app](https://coop-door.vercel.app) using your mobile device's web browser.
53 | 2. A small popup will prompt you to install the app. Tap "Install" to proceed.
54 | 3. Alternatively, if the popup doesn't appear, you can manually add the app to your home screen by:
55 | - Tapping the three dots in Chrome.
56 | - Scrolling down and selecting "Add shortcut to home screen" or "Install app."
57 | 4. The app will be installed on your device and accessible from the home screen.
58 |
59 | Now, you can conveniently use the mobile app to monitor and control your coop door system, even without an internet connection.
60 |
61 |
62 | # :toolbox: Build instruction
63 |
64 | Look out for instruction variations depending on the version of the project you're building.
65 |
66 | First of all, you will need to flash the firmware on the ESP32. Please refer to the instructions [here](https://github.com/ESP32-COOP/ESP32-COOP-DOOR-CORE). I do recommend unplugging the motor before flashing the firmware to avoid any connection problems caused by the encoder or any accidental movement of the powered motor.
67 |
68 | ## :clipboard: Requirement
69 |
70 |
71 | This projet use :
72 | - a ESP32 [WEMOS lolin32 lite](https://fr.aliexpress.com/item/4000038780903.html?spm=a2g0o.productlist.main.1.365b7074KBRyQT&algo_pvid=fa4a7510-076f-4fb9-8ed4-3253a3a69928&algo_exp_id=fa4a7510-076f-4fb9-8ed4-3253a3a69928-0&pdp_npi=4%40dis%21EUR%212.40%212.4%21%21%212.56%21%21%402132a21116927149487777888ec3b7%2112000030098281375%21sea%21FR%21821278985%21&curPageLogUid=oNK3v7tChtb8) ( can be any esp32 with BLE),
73 | - a H-Bridge [l298n](https://fr.aliexpress.com/item/1005004510885871.html?spm=a2g0o.productlist.main.1.4ab84eaai4P1f2&algo_pvid=83586f20-9cd5-4dc6-a3a3-c75def78a4cb&algo_exp_id=83586f20-9cd5-4dc6-a3a3-c75def78a4cb-0&pdp_npi=4%40dis%21EUR%211.74%211.53%21%21%211.85%21%21%402132a21116927149924648112ec3b7%2112000029421559001%21sea%21FR%21821278985%21&curPageLogUid=vMEusi5qQJYG),
74 | - a [motor with a encoder](https://fr.aliexpress.com/item/4001314473291.html?spm=a2g0o.productlist.main.1.52dd699a8YKYiK&algo_pvid=2a4b28bb-bc90-458b-ae85-f85eb2cfdece&algo_exp_id=2a4b28bb-bc90-458b-ae85-f85eb2cfdece-0&pdp_npi=4%40dis%21EUR%215.76%215.76%21%21%216.14%21%21%402132a21116927150494998265ec3b7%2110000015695661379%21sea%21FR%21821278985%21&curPageLogUid=HH3ljdlfyhi0),
75 | - and a [photoresistor](Vhttps://fr.aliexpress.com/item/32760631393.html?spm=a2g0o.productlist.main.1.5dd44f76NrlFVE&algo_pvid=25a08ae4-57ee-4d4c-91c6-76967f27dc4b&algo_exp_id=25a08ae4-57ee-4d4c-91c6-76967f27dc4b-0&pdp_npi=4%40dis%21EUR%210.72%210.6%21%21%210.77%21%21%402132f35616927151872427277e2c69%2110000001115154392%21sea%21FR%21821278985%21&curPageLogUid=ZBl0dvCbwSIm)
76 |
77 | Additionally, you'll need some basic items such as wires, soldering equipment (or soldering iron), and a 3D printer or woodworking tools, depending on your preferences.
78 |
79 | Please note that you can easily swap out any component of this project for a similar one. It will most likely work out fine, but it may require some extra work. I would recommend it only to experienced thinkers.
80 |
81 | ## :electric_plug: Wiring
82 | As illustrated below, follow these connections:
83 |
84 | ESP32:
85 | - Connect encoder signal to pin 2 (yellow) and pin 15 (green).
86 | - Attach a resistor to pin 34 for analog value.
87 | - Control the H-bridge with pins 27 (ENA), 26 (IN1), and 15 (IN2).
88 |
89 | Remember to establish a ground connection between the H-bridge and the ESP32.
90 |
91 |
92 |
93 | ## :rocket: Initial Setup
94 |
95 | **Before Coop Installation:**
96 |
97 | It's a good idea to run comprehensive tests before installing the device in the coop. Debugging is much easier and less frustrating when you're comfortably situated in a well-ventilated room.
98 |
99 | **Initial ESP32 Boot:**
100 |
101 | When the ESP32 boots up initially, it assumes the door is closed. If that's not the case, unplug either the motor or the ESP and manually close the door.
102 |
103 | **Proper Device Boot:**
104 |
105 | Now you can properly start up your device. Inside the app, go to settings and then to the door section. Set the number of rotations you want the motor to perform in order to open the door. Click the test button, and the motor will complete a full cycle (going up and then back down). Begin with a small rotation number, and gradually adjust it until you reach your desired door height.
106 |
107 | **Optimal Rotation Value:**
108 |
109 | Once you've figured out the best number of motor rotations, jot down this value along with the light sensor reading. To sync the ESP32's time, head to the app's home page and click on the time badge. A panel will appear, showing the time difference between your phone and the ESP32, along with a sync button.
110 |
111 | **Setting Conditions:**
112 |
113 | With that sorted, configure open and closing conditions in the door settings. Base these conditions solely on time, and set the door to stay open for the rest of the day.
114 |
115 | **Chicken Entry Time:**
116 |
117 | Return to the coop at the designated chicken entry time to check the light sensor value. If needed, adjust the closing condition within the app's settings.
118 |
119 | **Autonomous Operation:**
120 |
121 | To enable autonomous operation, revisit the settings and door page. Click on 'auto' and then 'apply'.
122 |
123 | ## :carpentry_saw: Casing Details
124 |
125 | You can find the 3D model at this [link](https://github.com/ESP32-COOP/JS-BLE-DOC/blob/main/3D_file_esp32_coop.stl), and the technical drawing is available //todo.
126 |
127 | # :signal_strength: Wireless comunication
128 | ## :loudspeaker: BLE Protocol
129 |
130 |
131 |
132 | To better understand the following, you must understand the basics of the Bluetooth Low Energy (BLE) protocol.
133 | The key part to understand is that it uses a fixed-size array of bytes to send data to an endpoint.
134 |
135 |
136 |
137 |
138 |
139 | Each endpoint can have three properties: writable, readable, and notifyable.
140 |
141 | - Writable: It allows the external user to write/edit the endpoint (officially called characteristic in BLE).
142 | - Readable: It allows reading the characteristic's value.
143 | - Notifyable: It allows getting notified when that value is updated.
144 |
145 | A byte is made out of 8 bits, and its value can go from 0 to 255.
146 |
147 | To send the desired value in bytes, you must think it through:
148 |
149 | - You will need to figure out the array size you will need and the function to convert it back and forth in C and in JS.
150 |
151 | Currently, there are five communication subjects:
152 | 1. The light sensor (made out of 4 bytes).
153 | 2. The time (made out of 9 bytes, 8 to represent UNIX time and 1 to represent the UTC offset).
154 | 3. The closing condition
155 | 4. The opening condition
156 | 5. Door settings
157 |
158 | ## :bulb: Data size
159 |
160 | With BLE the goal is to send the smallest array posible
161 |
162 | for each communication subjects i will justify each bytes and explain it's encoding
163 |
164 | 1. **The light sensor** produces 4 bytes of data. Our objective is to transmit the current value, along with the minimum and maximum values recorded by the sensor. To achieve this, we need an additional variable called a "divider." The maximum sensor value is fixed at 1024, while the highest value representable by a byte is 255.
165 |
166 | Calculating the divider is straightforward: we divide the maximum sensor value of 1024 by 255. This gives us the scaling factor needed for our encoding.
167 |
168 | With the divider in hand, we can create an encoded transmission as follows:
169 | - Current Value: current_value / divider
170 | - Minimum Value: min_value / divider
171 | - Maximum Value: max_value / divider
172 | - Unused Placeholder: (for the divider value)
173 |
174 | Reverting back to the original values is easy: simply multiply by the divider. This process maintains the integrity of the data throughout the encoding and decoding stages.
175 | 2. **The time** use 9 bytes The initial 8 bytes encode the UNIX time, while the ninth byte stores the user's country time offset.
176 |
177 | **Encoding UNIX Time**:
178 | To encode the UNIX time:
179 | - Begin by taking the lowest 8 bits of the time value using a bitwise AND operation with 0xff.
180 | - Place this extracted value in the current byte of the array.
181 | - Divide the time value by 256 to discard the lowest 8 bits for the next step.
182 |
183 | **Decoding UNIX Time**:
184 | To decode the UNIX time:
185 | - Set up a variable to hold the decoded time value.
186 | - Iterate eight times (for each byte), starting from the most significant byte down to the least:
187 | - Multiply the current result by 256 (shift left by 8 bits) to make room for the next byte.
188 | - Add the value of the current byte to the result.
189 |
190 | **Encoding Time Offset**:
191 | Encoding the time offset is simple. You subtract the time offset from 12 and then add back 12 during decoding. This process is necessary because the time offset ranges from -12 to 12.
192 |
193 | 3. **Door Condition** use 4 bytes, used by both open condtion and closing condtion.
194 | We ne the following value: the door mode (checking for light or time), the threshold and finaly the time
195 | The array is form like this [door_mode, light_treshold / 4, time hour, time minutes]
196 | The door mode is represented by a single digit, reflecting various modes:
197 | - 0 : do nothing
198 | - 1 : change on light condition
199 | - 2 : change on time condition
200 | - 3 : change on light and time condition
201 | - 4 : change on light or time condition
202 | By adopting this array format and the corresponding door modes, we efficiently handle door conditions during both opening and closing situations.
203 | 4. **Door settings** use 2 bytes, with the following needed value the door mode and the number of turn.
204 |
205 | The door mode can take on various values:
206 | - 0: Door closed
207 | - 1: Door open
208 | - 2: Test door (opens and closes immediately)
209 | - 10: Automatic mode with the door closed
210 | - 11: Automatic mode with the door open
211 |
212 | **Number of Turns Encoding**:
213 | To encode the number of turns, we simply multiply the value by 10.
214 |
215 | Here's the array structure for encoding: [door_mode, number_of_turns * 10].
216 |
217 | ## :gear: Code Snippette
218 | Certainly, here's your code snippet presented in a more readable manner:
219 |
220 | ## Encoding and Decoding Long Numbers to Bytes
221 |
222 | Here, we present functions for encoding and decoding long numbers into bytes. These functions are particularly relevant for working with the UNIX time standard. We provide the code snippets for both C and JavaScript:
223 |
224 | ### C Implementation
225 |
226 | ```c
227 | byte* getBytesFromLong(long x) {
228 | byte* bytes = new byte[8];
229 | for (int i = 0; i < 8; i++) {
230 | bytes[i] = x & 0xff;
231 | x = (x - bytes[i]) / 256;
232 | }
233 | return bytes;
234 | }
235 |
236 | long getLongFromBytes(const byte* bytes) {
237 | long result = 0;
238 | for (int i = 7; i >= 0; i--) {
239 | result = (result * 256) + bytes[i];
240 | }
241 | return result;
242 | }
243 | ```
244 |
245 | ### JavaScript Implementation
246 |
247 | ```javascript
248 | export function getLongFromBytesBuffer(bytes) {
249 | let result = 0;
250 | for (let i = 7; i >= 0; i--) {
251 | result = result * 256 + bytes.getUint8(i);
252 | }
253 | return result;
254 | }
255 |
256 | export function getArrayFromBuffer(bytes, len) {
257 | let result = [];
258 | for (let i = 0; i < len; i++) {
259 | result.push(bytes.getUint8(i));
260 | }
261 | return result;
262 | }
263 | ```
264 |
265 | These functions offer efficient ways to convert long numbers to byte arrays and vice versa, which is particularly useful for working with the UNIX time standard. The C and JavaScript implementations cater to different programming environments, ensuring flexibility in usage.
266 |
267 |
268 | ## Tutorial
269 | Here is a video that explain how the BLE work
270 | //todo
271 | 
272 |
--------------------------------------------------------------------------------
/exemple/BLE.js:
--------------------------------------------------------------------------------
1 | let id;
2 | let bluetoothDeviceDetected;
3 | let service;
4 | let GATT_date;
5 |
6 |
7 | let dateService = '1ce76320-2d32-41af-b4c4-46836ea7a62a'.toLowerCase();
8 | let dateChar = 'ad804469-19ec-406a-b949-31ae17e43813'.toLowerCase();
9 |
10 | const deviceName = 'COOP-DOOR';
11 |
12 |
13 | function iSWebBLEAvailable() {
14 | if (!navigator.bluetooth){
15 | console.log('not available');
16 | return false;
17 | }
18 | return true;
19 |
20 | }
21 | function getDeviceInfo() {
22 | let options = {
23 | //acceptAllDevices: true,
24 | optionalServices : [dateService, dateChar ],
25 | filters : [
26 | {namePrefix: deviceName}
27 | ]
28 | }
29 |
30 | console.log("Requestion BLE device info...")
31 | return navigator.bluetooth.requestDevice(options).then(device => {
32 | bluetoothDeviceDetected = device;
33 | console.log('name '+device.name);
34 | }).catch(error => {
35 | console.log('Request device error: '+error);
36 | })
37 | }
38 |
39 | async function connectGATT(){
40 |
41 | deviceConnected = await bluetoothDeviceDetected.gatt.connected;
42 | server = await bluetoothDeviceDetected.gatt.connect()
43 |
44 | service2 = await server.getPrimaryService(dateService);
45 | GATT_date = await service2.getCharacteristic(dateChar);
46 |
47 | }
48 | async function readChar(char) {
49 | const dump = await char.readValue()
50 | return dump
51 | }
52 |
53 | async function readDate() {
54 | const dump = await readChar(GATT_date)
55 | console.log(dump)
56 | return getLongFromBytesBuffer(dump)
57 | }
58 |
59 | function writeDate(){
60 |
61 | let now = Math.round(Date.now() / 1000); //Date.now();
62 | let bytes = getBytesFromLong(now);
63 | console.log(now,bytes,getLongFromBytes(bytes))
64 | let buffer = new Uint8Array(bytes).buffer;
65 | GATT_date.writeValue(buffer);
66 | }
67 |
68 | function getBytesFromLong(x) {
69 | let bytes = new Array(8);
70 | for (let i = 0; i < 8; i++) {
71 | bytes[i] = x & 0xff;
72 | x = (x - bytes[i]) / 256;
73 | }
74 | return bytes;
75 | }
76 |
77 |
78 |
79 |
80 |
81 | function getLongFromBytes(bytes) {
82 | let result = 0;
83 | for (let i = 7; i >= 0; i--) {
84 | result = (result * 256) + bytes[i];
85 | }
86 | return result;
87 | }
88 | function getLongFromBytesBuffer(bytes) {
89 | let result = 0;
90 | for (let i = 7; i >= 0; i--) {
91 | result = (result * 256) + bytes.getUint8(i);
92 | }
93 | return result;
94 | }
95 |
96 |
--------------------------------------------------------------------------------
/exemple/blinkBLE/blinkBLE.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Bluetooth® Low Energy LED Service
4 |
5 | // Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
6 | BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
7 | BLEByteCharacteristic switchCharacteristic2("77a57c66-3bc9-463a-bc52-1ee5763b9c0f", BLERead | BLENotify);
8 |
9 | const int ledPin = LED_BUILTIN; // pin to use for the LED
10 | uint8_t ble_value = 0x0;
11 |
12 | void setup() {
13 | Serial.begin(9600);
14 | while (!Serial);
15 |
16 | // set LED pin to output mode
17 | pinMode(ledPin, OUTPUT);
18 |
19 | // begin initialization
20 | if (!BLE.begin()) {
21 | Serial.println("starting Bluetooth® Low Energy module failed!");
22 |
23 | while (1);
24 | }
25 |
26 | // set advertised local name and service UUID:
27 | BLE.setLocalName("COOP-DOOR");
28 | BLE.setAdvertisedService(ledService);
29 |
30 | // add the characteristic to the service
31 | ledService.addCharacteristic(switchCharacteristic);
32 | ledService.addCharacteristic(switchCharacteristic2);
33 |
34 | // add service
35 | BLE.addService(ledService);
36 |
37 | // set the initial value for the characeristic:
38 | switchCharacteristic.writeValue(0);
39 | switchCharacteristic2.writeValue(0);
40 |
41 | // start advertising
42 | BLE.advertise();
43 |
44 | Serial.println("BLE LED Peripheral");
45 | }
46 |
47 | void loop() {
48 | // listen for Bluetooth® Low Energy peripherals to connect:
49 | BLEDevice central = BLE.central();
50 |
51 | // if a central is connected to peripheral:
52 | if (central) {
53 | Serial.print("Connected to central: ");
54 | // print the central's MAC address:
55 | Serial.println(central.address());
56 |
57 | // while the central is still connected to peripheral:
58 | while (central.connected()) {
59 | // if the remote device wrote to the characteristic,
60 | // use the value to control the LED:
61 | if (switchCharacteristic.written()) {
62 | Serial.println("update");
63 | if (switchCharacteristic.value()) { // any value other than 0
64 | Serial.println("LED on");
65 | digitalWrite(ledPin, HIGH); // will turn the LED on
66 | } else { // a 0 value
67 | Serial.println("LED off");
68 | digitalWrite(ledPin, LOW); // will turn the LED off
69 | }
70 | }
71 | ble_value = random(0, 11);
72 | switchCharacteristic2.writeValue(ble_value);
73 | }
74 |
75 | // when the central disconnects, print it out:
76 | Serial.print(F("Disconnected from central: "));
77 | Serial.println(central.address());
78 | }
79 |
80 |
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/exemple/blinkBLEv2/blinkBLEv2.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Bluetooth® Low Energy LED Service
4 |
5 | // Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
6 | BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
7 | BLEByteCharacteristic switchCharacteristic2("77a57c66-3bc9-463a-bc52-1ee5763b9c0f", BLERead | BLENotify);
8 |
9 | BLEService dateService("1ce76320-2d32-41af-b4c4-46836ea7a62a"); // Bluetooth® Low Energy LED Service
10 | BLECharacteristic dateCharacteristic("ad804469-19ec-406a-b949-31ae17e43813", BLERead | BLENotify | BLEWrite,5);
11 |
12 | const int ledPin = LED_BUILTIN; // pin to use for the LED
13 | uint8_t ble_value = 0x0;
14 |
15 | void setup() {
16 | Serial.begin(9600);
17 | while (!Serial);
18 |
19 | // set LED pin to output mode
20 | pinMode(ledPin, OUTPUT);
21 |
22 | // begin initialization
23 | if (!BLE.begin()) {
24 | Serial.println("starting Bluetooth® Low Energy module failed!");
25 |
26 | while (1);
27 | }
28 |
29 | // set advertised local name and service UUID:
30 | BLE.setLocalName("COOP-DOOR");
31 | BLE.setAdvertisedService(ledService);
32 | BLE.setAdvertisedService(dateService);
33 |
34 | // add the characteristic to the service
35 | ledService.addCharacteristic(switchCharacteristic);
36 | ledService.addCharacteristic(switchCharacteristic2);
37 |
38 | dateService.addCharacteristic(dateCharacteristic);
39 |
40 | // add service
41 | BLE.addService(ledService);
42 |
43 | BLE.addService(dateService);
44 |
45 | // set the initial value for the characeristic:
46 | switchCharacteristic.writeValue(0);
47 | switchCharacteristic2.writeValue(0);
48 |
49 | dateCharacteristic.writeValue(0);
50 |
51 | // start advertising
52 | BLE.advertise();
53 |
54 | Serial.println("BLE LED Peripheral");
55 | }
56 |
57 | void loop() {
58 | // listen for Bluetooth® Low Energy peripherals to connect:
59 | BLEDevice central = BLE.central();
60 |
61 | // if a central is connected to peripheral:
62 | if (central) {
63 | Serial.print("Connected to central: ");
64 | // print the central's MAC address:
65 | Serial.println(central.address());
66 |
67 | // while the central is still connected to peripheral:
68 | while (central.connected()) {
69 | // if the remote device wrote to the characteristic,
70 | // use the value to control the LED:
71 |
72 | if (switchCharacteristic.written()) {
73 | Serial.println("update");
74 | if (switchCharacteristic.value()) { // any value other than 0
75 | Serial.println("LED on");
76 | digitalWrite(ledPin, HIGH); // will turn the LED on
77 | } else { // a 0 value
78 | Serial.println("LED off");
79 | digitalWrite(ledPin, LOW); // will turn the LED off
80 | }
81 | }
82 |
83 | if (dateCharacteristic.written()){
84 | Serial.println("Date update");
85 | Serial.println(dateCharacteristic.value()[0]);
86 | Serial.println(dateCharacteristic.value()[1]);
87 | Serial.println(dateCharacteristic.value()[2]);
88 | Serial.println(dateCharacteristic.value()[3]);
89 | Serial.println(dateCharacteristic.value()[4]);
90 | }
91 | ble_value = random(0, 11);
92 | switchCharacteristic2.writeValue(ble_value);
93 | }
94 |
95 | // when the central disconnects, print it out:
96 | Serial.print(F("Disconnected from central: "));
97 | Serial.println(central.address());
98 | }
99 |
100 |
101 |
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/exemple/esp32time/esp32time.ino:
--------------------------------------------------------------------------------
1 | /*
2 | MIT License
3 |
4 | Copyright (c) 2021 Felix Biego
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
23 | */
24 |
25 | #include
26 |
27 | //ESP32Time rtc;
28 | ESP32Time rtc(3600); // offset in seconds GMT+1
29 |
30 | void setup() {
31 | Serial.begin(115200);
32 | rtc.setTime(30, 24, 15, 17, 1, 2021); // 17th Jan 2021 15:24:30
33 | //rtc.setTime(1609459200); // 1st Jan 2021 00:00:00
34 | //rtc.offset = 7200; // change offset value
35 |
36 | /*---------set with NTP---------------*/
37 | // configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
38 | // struct tm timeinfo;
39 | // if (getLocalTime(&timeinfo)){
40 | // rtc.setTimeStruct(timeinfo);
41 | // }
42 | }
43 |
44 | void loop() {
45 | // Serial.println(rtc.getTime()); // (String) 15:24:38
46 | // Serial.println(rtc.getDate()); // (String) Sun, Jan 17 2021
47 | // Serial.println(rtc.getDate(true)); // (String) Sunday, January 17 2021
48 | // Serial.println(rtc.getDateTime()); // (String) Sun, Jan 17 2021 15:24:38
49 | // Serial.println(rtc.getDateTime(true)); // (String) Sunday, January 17 2021 15:24:38
50 | // Serial.println(rtc.getTimeDate()); // (String) 15:24:38 Sun, Jan 17 2021
51 | // Serial.println(rtc.getTimeDate(true)); // (String) 15:24:38 Sunday, January 17 2021
52 | //
53 | // Serial.println(rtc.getMicros()); // (long) 723546
54 | // Serial.println(rtc.getMillis()); // (long) 723
55 | // Serial.println(rtc.getEpoch()); // (long) 1609459200
56 | // Serial.println(rtc.getSecond()); // (int) 38 (0-59)
57 | // Serial.println(rtc.getMinute()); // (int) 24 (0-59)
58 | // Serial.println(rtc.getHour()); // (int) 3 (0-12)
59 | // Serial.println(rtc.getHour(true)); // (int) 15 (0-23)
60 | // Serial.println(rtc.getAmPm()); // (String) pm
61 | // Serial.println(rtc.getAmPm(true)); // (String) PM
62 | // Serial.println(rtc.getDay()); // (int) 17 (1-31)
63 | // Serial.println(rtc.getDayofWeek()); // (int) 0 (0-6)
64 | // Serial.println(rtc.getDayofYear()); // (int) 16 (0-365)
65 | // Serial.println(rtc.getMonth()); // (int) 0 (0-11)
66 | // Serial.println(rtc.getYear()); // (int) 2021
67 |
68 | // Serial.println(rtc.getLocalEpoch()); // (long) 1609459200 epoch without offset
69 | Serial.println(rtc.getTime("%A, %B %d %Y %H:%M:%S")); // (String) returns time with specified format
70 | // formating options http://www.cplusplus.com/reference/ctime/strftime/
71 |
72 |
73 | struct tm timeinfo = rtc.getTimeStruct();
74 | //Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); // (tm struct) Sunday, January 17 2021 07:24:38
75 |
76 | delay(1000);
77 | }
78 |
--------------------------------------------------------------------------------
/exemple/index.html:
--------------------------------------------------------------------------------
1 |
4 |
5 |
--------------------------------------------------------------------------------
/exemple/index2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |