push lib
21
IOT/receiver LoRa/lib/Farm-Data-Relay-System/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 timmbogner
|
||||
|
||||
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.
|
80
IOT/receiver LoRa/lib/Farm-Data-Relay-System/README.md
Normal file
@ -0,0 +1,80 @@
|
||||
<p align="center"><img src="extras/fdrs_logo.svg" width="325">
|
||||
|
||||
# <p align="center">Farm Data Relay System
|
||||
|
||||
##### <p align="center">[***In loving memory of Gay Holman, an extraordinary woman.***](https://www.facebook.com/CFECI/posts/2967989419953119) #####
|
||||
|
||||
Farm Data Relay System is an easy way to communicate with remote IoT devices without relying on WiFi or LoRaWAN infrastructure. It establishes a series of inexpensive, low-power access points and repeaters to provide ESP-NOW and LoRa coverage for remote devices. FDRS can be used to transport sensor readings and control messages in situations where it would be too cumbersome to provide full WiFi/LoRaWAN coverage. While the system was designed with farming in mind, FDRS could also be beneficial in a classroom, home, or research setting.
|
||||
|
||||
Devices are classified into two types: **Gateways** and **Nodes**. Gateways comprise the infrastructure of the network, moving data along pre-directed routes and providing coverage to all devices. Nodes allow the user to exchange data with a gateway. Each gateway is identified with an 8-bit physical hex address (MAC), while nodes use 16-bit integers to identify datapoints as they move through the system.
|
||||
|
||||
|
||||
If you are having fun with FDRS, **[please consider supporting me](https://www.buymeacoffee.com/TimmB)** so that I can spend more time building it.
|
||||
|
||||
## Getting Started
|
||||
**Libraries Required:**
|
||||
- [ArduinoJson](https://arduinojson.org/)
|
||||
- [RadioLib](https://github.com/jgromes/RadioLib) for LoRa
|
||||
- [PubSubClient](https://github.com/knolleary/pubsubclient/) for MQTT
|
||||
|
||||
**Included:**
|
||||
- [ThingPulse OLED Library for ESP](https://github.com/ThingPulse/esp8266-oled-ssd1306)
|
||||
#
|
||||
**To install FDRS:**
|
||||
1. Download or clone this repository and copy it into your Arduino **'libraries'** folder.
|
||||
|
||||
2. After installing, edit the **'src/fdrs_globals.h'** file with your WiFi credentials and other global parameters.
|
||||
|
||||
3. The first sketch you'll want to try is the **1_UART_Gateway.ino** example. This device will listen for incoming ESP-NOW packets, then route them to the serial port (and vice versa). Next, flash the **ESPNOW_Sensor.ino** example to see how to send data to the gateway.
|
||||
|
||||
4. To use MQTT: Connect the second gateway to the first via the Rx and Tx pins (crossed), and flash it with the **0_MQTT_Gateway.ino** example. If your WiFi and MQTT configurations are correct, data will be published to the topic 'fdrs/data'.
|
||||
|
||||
5. To extend your range, try the **2_ESPNOW_Repeater.ino** or **3_LoRa_Repeater.ino**. Just change the *GTWY_MAC* of your sensor to the address of your new repeater.
|
||||
|
||||
|
||||
## Nodes
|
||||
**[Node Documentation](/extras/Node.md)**
|
||||
|
||||
Nodes can be described as *sensors, controllers, or both*:
|
||||
- A **Sensor node** aggregates data into a packet, then sends it to a gateway via ESP-NOW or LoRa.
|
||||
- A **Controller node** subscribes to one or more reading IDs. When data arrives from an ID the device is subscribed to, a callback function is called where the user can access the incoming data.
|
||||
|
||||
## Gateways
|
||||
**[Gateway Documentation](extras/Gateway.md)**
|
||||
|
||||
Gateways are modular and configurable microcontroller devices that can perform a variety of useful functions including collecting, distributing, and relaying wireless data. They provide a flexible and cohesive interface between various wired and wireless protocols, and are generally arranged in a line or star topology. As a general rule, the gateway that uses MQTT always has the address 0x00, and ESP-NOW and LoRa gateways start at 0x01.
|
||||
|
||||
In its most common usage, an FDRS gateway is deployed as an access point for remote ESP-NOW and LoRa user nodes. If it receives a packet from an unknown ESP-NOW or LoRa address, the gateway assumes that these are sensor readings and passes them downstream towards the front-end. The gateway will also broadcast packets coming *from* the front-end out to any controller nodes that are registered/listening.
|
||||
|
||||
Gateways can also be configured as simple repeaters; passing data from one neighbor directly to another neighbor or vice versa. This can create a data wormhole that will carry packets upstream or downstream ad infinitum. You can configure your gateways to share data headed upstream with connected peers, thus providing them with any data being sent from the front-end.
|
||||
|
||||
## Front-end
|
||||
The front-end is where all data is entered or consumed by another application. This could be anything from a microcontroller communicating through UART and displaying data on a screen to a server/database platform logging the data via MQTT.
|
||||
|
||||
My recommended method of accessing your data is using a computer, server, or Raspberry Pi linked to an FDRS Gateway device via either MQTT or UART. Node-RED is my favorite platform for accessing/manipulating data on the front-end, and InfluxDB+Grafana is the dream team for storage and visualization.
|
||||
|
||||
|
||||
## Future Plans
|
||||
Upcoming goals for FDRS include:
|
||||
- A method for FDRS gateways to keep track of the time via NTP or an RTC module, then seamlessly distribute it amongst its neighbors and connected nodes.
|
||||
- More sensor and controller examples. If you are using a device or sensor that is not covered in the examples, feel free to contribute an example of its basic usage!
|
||||
- Support for cellular radios with [TinyGSM](https://github.com/vshymanskyy/TinyGSM).
|
||||
- Channel Activity Detection (CAD) for LoRa.
|
||||
|
||||
## Thank you
|
||||
**...very much for checking out my project!** I truly appreciate everyone who has reached out with contributions and assistance, especially those featured in the "Contributors" section. If you have any questions, comments, issues, or suggestions please don't hesitate to contact me at timmbogner@gmail.com or open a discussion here on Github.
|
||||
|
||||
Many thanks go to the ever-instructional [**Andreas Spiess**](https://www.youtube.com/channel/UCu7_D0o48KbfhpEohoP7YSQ). His insight and ideas took this project from a roughly-hewn stone to the "[diamond](https://youtu.be/6JI5wZABWmA)" you see today.
|
||||
|
||||
Thanks to [**LilyGo**](https://www.lilygo.cc/) for sending me new [LoRa32 modules](https://www.lilygo.cc/products/lora32-v1-0-lora-868mhz-915mhz) when mine were damaged. Much of this project was [created](https://github.com/timmbogner/Farm-Data-Relay-System/tree/main/examples/Sensor_Examples/LilyGo_HiGrow_32) using [TTGO devices](https://www.lilygo.cc/products/t-higrow), and I highly recommend their [products](https://www.lilygo.cc/products/lilygo%C2%AE-ttgo-t-display-1-14-inch-lcd-esp32-control-board)!
|
||||
|
||||
It is a great honor to have been [featured on **Hackaday**](https://hackaday.com/2022/07/02/farm-data-relay-system/) and [**hackster.io!**](https://www.hackster.io/news/timm-bogner-s-farm-data-relay-system-uses-esp8266-esp32-nodes-and-gateways-for-sensor-networks-b87a75c69f46)
|
||||
|
||||
I started this project with instructions from [**Random Nerd Tutorials**](https://randomnerdtutorials.com/). If you are a beginner and trying to learn more about microcontrollers, I highly recommend starting there.
|
||||
|
||||
#
|
||||

|
||||
#
|
||||
#
|
||||

|
||||
#
|
@ -0,0 +1,17 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// GATEWAY 2.000
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
//
|
||||
|
||||
#include "fdrs_gateway_config.h"
|
||||
#include <fdrs_gateway.h>
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// GATEWAY CONFIGURATION
|
||||
|
||||
//Addresses
|
||||
#define UNIT_MAC 0x00 // The address of this gateway
|
||||
|
||||
#define ESPNOW_NEIGHBOR_1 0x00 // Address of ESP-NOW neighbor #1
|
||||
#define ESPNOW_NEIGHBOR_2 0x00 // Address of ESP-NOW neighbor #2
|
||||
#define LORA_NEIGHBOR_1 0x00 // Address of LoRa neighbor #1
|
||||
#define LORA_NEIGHBOR_2 0x00 // Address of LoRa neighbor #2
|
||||
|
||||
// Interfaces
|
||||
//#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define USE_WIFI // Will cause errors if used with ESP-NOW. Use a serial link instead!
|
||||
//#define USE_ETHERNET
|
||||
|
||||
// Routing
|
||||
// Options: sendESPNowNbr(1 or 2); sendESPNowPeers(); sendLoRaNbr(1 or 2); broadcastLoRa(); sendSerial(); sendMQTT();
|
||||
#define ESPNOWG_ACT
|
||||
#define LORAG_ACT
|
||||
#define SERIAL_ACT sendMQTT();
|
||||
#define MQTT_ACT sendSerial();
|
||||
#define INTERNAL_ACT sendMQTT();
|
||||
#define ESPNOW1_ACT
|
||||
#define ESPNOW2_ACT
|
||||
#define LORA1_ACT
|
||||
#define LORA2_ACT
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
|
||||
//#define CUSTOM_SPI
|
||||
#define LORA_SPI_SCK 5
|
||||
#define LORA_SPI_MISO 19
|
||||
#define LORA_SPI_MOSI 27
|
||||
|
||||
#define FDRS_DEBUG // Enable USB-Serial debugging
|
||||
|
||||
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
|
||||
///#define USE_OLED
|
||||
#define OLED_HEADER "FDRS"
|
||||
#define OLED_PAGE_SECS 30
|
||||
#define OLED_SDA 4
|
||||
#define OLED_SCL 15
|
||||
#define OLED_RST 16
|
||||
|
||||
// UART data interface pins (if available)
|
||||
#define RXD2 14
|
||||
#define TXD2 15
|
||||
|
||||
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
|
||||
|
||||
// WiFi and MQTT Credentials -- These will override the global settings
|
||||
//#define WIFI_SSID "Your SSID"
|
||||
//#define WIFI_PASS "Your Password"
|
||||
|
||||
//#define MQTT_ADDR "192.168.0.8"
|
||||
//#define MQTT_PORT 1883 // Default MQTT port is 1883
|
||||
//#define MQTT_AUTH //Enable MQTT authentication
|
||||
//#define MQTT_USER "Your MQTT Username"
|
||||
//#define MQTT_PASS "Your MQTT Password"
|
||||
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// GATEWAY 2.000
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
//
|
||||
|
||||
#include "fdrs_gateway_config.h"
|
||||
#include <fdrs_gateway.h>
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// GATEWAY CONFIGURATION
|
||||
|
||||
//Addresses
|
||||
#define UNIT_MAC 0x01 // The address of this gateway
|
||||
|
||||
#define ESPNOW_NEIGHBOR_1 0x00 // Address of ESP-NOW neighbor #1
|
||||
#define ESPNOW_NEIGHBOR_2 0x02 // Address of ESP-NOW neighbor #2
|
||||
#define LORA_NEIGHBOR_1 0x00 // Address of LoRa neighbor #1
|
||||
#define LORA_NEIGHBOR_2 0x03 // Address of LoRa neighbor #2
|
||||
|
||||
// Interfaces
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
//#define USE_WIFI // Will cause errors if used with ESP-NOW. Use a serial link instead!
|
||||
//#define USE_ETHERNET
|
||||
|
||||
// Routing
|
||||
// Options: sendESPNowNbr(1 or 2); sendESPNowPeers(); sendLoRaNbr(1 or 2); broadcastLoRa(); sendSerial(); sendMQTT();
|
||||
#define ESPNOWG_ACT sendSerial();
|
||||
#define LORAG_ACT sendSerial();
|
||||
#define SERIAL_ACT sendESPNowNbr(2); sendESPNowPeers(); sendLoRaNbr(2); broadcastLoRa();
|
||||
#define MQTT_ACT
|
||||
#define INTERNAL_ACT sendSerial();
|
||||
#define ESPNOW1_ACT
|
||||
#define ESPNOW2_ACT sendSerial();
|
||||
#define LORA1_ACT
|
||||
#define LORA2_ACT sendSerial();
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
|
||||
//#define CUSTOM_SPI
|
||||
#define LORA_SPI_SCK 5
|
||||
#define LORA_SPI_MISO 19
|
||||
#define LORA_SPI_MOSI 27
|
||||
|
||||
#define FDRS_DEBUG // Enable USB-Serial debugging
|
||||
|
||||
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
|
||||
///#define USE_OLED
|
||||
#define OLED_HEADER "FDRS"
|
||||
#define OLED_PAGE_SECS 30
|
||||
#define OLED_SDA 4
|
||||
#define OLED_SCL 15
|
||||
#define OLED_RST 16
|
||||
|
||||
// UART data interface pins (if available)
|
||||
#define RXD2 14
|
||||
#define TXD2 15
|
||||
|
||||
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
|
||||
|
||||
// WiFi and MQTT Credentials -- These will override the global settings
|
||||
//#define WIFI_SSID "Your SSID"
|
||||
//#define WIFI_PASS "Your Password"
|
||||
|
||||
//#define MQTT_ADDR "192.168.0.8"
|
||||
//#define MQTT_PORT 1883 // Default MQTT port is 1883
|
||||
//#define MQTT_AUTH //Enable MQTT authentication
|
||||
//#define MQTT_USER "Your MQTT Username"
|
||||
//#define MQTT_PASS "Your MQTT Password"
|
||||
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// GATEWAY 2.000
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
//
|
||||
|
||||
#include "fdrs_gateway_config.h"
|
||||
#include <fdrs_gateway.h>
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// GATEWAY CONFIGURATION
|
||||
|
||||
//Addresses
|
||||
#define UNIT_MAC 0x02 // The address of this gateway
|
||||
|
||||
#define ESPNOW_NEIGHBOR_1 0x01 // Address of ESP-NOW neighbor #1
|
||||
#define ESPNOW_NEIGHBOR_2 0x04 // Address of ESP-NOW neighbor #2
|
||||
#define LORA_NEIGHBOR_1 0x00 // Address of LoRa neighbor #1
|
||||
#define LORA_NEIGHBOR_2 0x00 // Address of LoRa neighbor #2
|
||||
|
||||
// Interfaces
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
//#define USE_WIFI // Will cause errors if used with ESP-NOW. Use a serial link instead!
|
||||
//#define USE_ETHERNET
|
||||
|
||||
// Routing
|
||||
// Options: sendESPNowNbr(1 or 2); sendESPNowPeers(); sendLoRaNbr(1 or 2); broadcastLoRa(); sendSerial(); sendMQTT();
|
||||
#define ESPNOWG_ACT sendESPNowNbr(1);
|
||||
#define LORAG_ACT
|
||||
#define SERIAL_ACT
|
||||
#define MQTT_ACT
|
||||
#define INTERNAL_ACT sendESPNowNbr(1);
|
||||
#define ESPNOW1_ACT sendESPNowNbr(2); sendESPNowPeers();
|
||||
#define ESPNOW2_ACT sendESPNowNbr(1);
|
||||
#define LORA1_ACT
|
||||
#define LORA2_ACT
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
|
||||
//#define CUSTOM_SPI
|
||||
#define LORA_SPI_SCK 5
|
||||
#define LORA_SPI_MISO 19
|
||||
#define LORA_SPI_MOSI 27
|
||||
|
||||
#define FDRS_DEBUG // Enable USB-Serial debugging
|
||||
|
||||
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
|
||||
///#define USE_OLED
|
||||
#define OLED_HEADER "FDRS"
|
||||
#define OLED_PAGE_SECS 30
|
||||
#define OLED_SDA 4
|
||||
#define OLED_SCL 15
|
||||
#define OLED_RST 16
|
||||
|
||||
// UART data interface pins (if available)
|
||||
#define RXD2 14
|
||||
#define TXD2 15
|
||||
|
||||
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
|
||||
|
||||
// WiFi and MQTT Credentials -- These will override the global settings
|
||||
//#define WIFI_SSID "Your SSID"
|
||||
//#define WIFI_PASS "Your Password"
|
||||
|
||||
//#define MQTT_ADDR "192.168.0.8"
|
||||
//#define MQTT_PORT 1883 // Default MQTT port is 1883
|
||||
//#define MQTT_AUTH //Enable MQTT authentication
|
||||
//#define MQTT_USER "Your MQTT Username"
|
||||
//#define MQTT_PASS "Your MQTT Password"
|
||||
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// GATEWAY 2.000
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
//
|
||||
|
||||
#include "fdrs_gateway_config.h"
|
||||
#include <fdrs_gateway.h>
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// GATEWAY CONFIGURATION
|
||||
|
||||
//Addresses
|
||||
#define UNIT_MAC 0x03 // The address of this gateway
|
||||
|
||||
#define ESPNOW_NEIGHBOR_1 0x00 // Address of ESP-NOW neighbor #1
|
||||
#define ESPNOW_NEIGHBOR_2 0x00 // Address of ESP-NOW neighbor #2
|
||||
#define LORA_NEIGHBOR_1 0x01 // Address of LoRa neighbor #1
|
||||
#define LORA_NEIGHBOR_2 0x05 // Address of LoRa neighbor #2
|
||||
|
||||
// Interfaces
|
||||
//#define USE_ESPNOW
|
||||
#define USE_LORA
|
||||
//#define USE_WIFI // Will cause errors if used with ESP-NOW. Use a serial link instead!
|
||||
//#define USE_ETHERNET
|
||||
|
||||
// Routing
|
||||
// Options: sendESPNowNbr(1 or 2); sendESPNowPeers(); sendLoRaNbr(1 or 2); broadcastLoRa(); sendSerial(); sendMQTT();
|
||||
#define ESPNOWG_ACT
|
||||
#define LORAG_ACT sendLoRaNbr(1);
|
||||
#define SERIAL_ACT
|
||||
#define MQTT_ACT
|
||||
#define INTERNAL_ACT sendLoRaNbr(1);
|
||||
#define ESPNOW1_ACT
|
||||
#define ESPNOW2_ACT
|
||||
#define LORA1_ACT sendLoRaNbr(2); broadcastLoRa();
|
||||
#define LORA2_ACT sendLoRaNbr(1);
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
|
||||
//#define CUSTOM_SPI
|
||||
#define LORA_SPI_SCK 5
|
||||
#define LORA_SPI_MISO 19
|
||||
#define LORA_SPI_MOSI 27
|
||||
|
||||
#define FDRS_DEBUG // Enable USB-Serial debugging
|
||||
|
||||
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
|
||||
///#define USE_OLED
|
||||
#define OLED_HEADER "FDRS"
|
||||
#define OLED_PAGE_SECS 30
|
||||
#define OLED_SDA 4
|
||||
#define OLED_SCL 15
|
||||
#define OLED_RST 16
|
||||
|
||||
// UART data interface pins (if available)
|
||||
#define RXD2 14
|
||||
#define TXD2 15
|
||||
|
||||
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
|
||||
|
||||
// WiFi and MQTT Credentials -- These will override the global settings
|
||||
//#define WIFI_SSID "Your SSID"
|
||||
//#define WIFI_PASS "Your Password"
|
||||
|
||||
//#define MQTT_ADDR "192.168.0.8"
|
||||
//#define MQTT_PORT 1883 // Default MQTT port is 1883
|
||||
//#define MQTT_AUTH //Enable MQTT authentication
|
||||
//#define MQTT_USER "Your MQTT Username"
|
||||
//#define MQTT_PASS "Your MQTT Password"
|
||||
|
||||
|
||||
|
@ -0,0 +1,139 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// FastLED Lantern
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
// Rest in Peace, Daniel Garcia. Thank you for bringing so much light to the world!
|
||||
|
||||
// Type
|
||||
// 1: Red
|
||||
// 2: Green
|
||||
// 3: Blue
|
||||
// 4: Hue
|
||||
// 5: Saturation
|
||||
// 6: Brightness
|
||||
//
|
||||
//
|
||||
|
||||
#define USE_PWM //If using an RGB LED
|
||||
// #define PIN_R 18 //ESP32 WeMos
|
||||
// #define PIN_G 19
|
||||
// #define PIN_B 23
|
||||
|
||||
#define PIN_R 14 //8266 WeMos
|
||||
#define PIN_G 12
|
||||
#define PIN_B 13
|
||||
|
||||
#define PIN_DATA 4 // If using a NeoPixel
|
||||
#define NUM_LEDS 24 // Number of physical LEDs.
|
||||
|
||||
#include <FastLED.h>
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
CRGB rgb_color = CRGB::Black;
|
||||
CHSV hsv_color(0, 255, 255);
|
||||
bool hsv_mode = false;
|
||||
bool new_data = false;
|
||||
|
||||
CRGB leds[NUM_LEDS];
|
||||
|
||||
void fdrs_recv_cb(DataReading theData) {
|
||||
|
||||
new_data = true;
|
||||
int id = (int)theData.id;
|
||||
uint8_t type = (uint8_t)theData.t;
|
||||
uint8_t data = (uint8_t)theData.d;
|
||||
switch (type) {
|
||||
case 1:
|
||||
rgb_color.red = data;
|
||||
hsv_mode = false;
|
||||
break;
|
||||
case 2:
|
||||
rgb_color.green = data;
|
||||
hsv_mode = false;
|
||||
break;
|
||||
case 3:
|
||||
rgb_color.blue = data;
|
||||
hsv_mode = false;
|
||||
break;
|
||||
case 4:
|
||||
hsv_color.hue = data;
|
||||
hsv_mode = true;
|
||||
break;
|
||||
case 5:
|
||||
hsv_color.sat = data;
|
||||
hsv_mode = true;
|
||||
break;
|
||||
case 6:
|
||||
hsv_color.val = data;
|
||||
hsv_mode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void setup_pwm() {
|
||||
#ifdef ESP8266
|
||||
pinMode(PIN_R, OUTPUT);
|
||||
pinMode(PIN_G, OUTPUT);
|
||||
pinMode(PIN_B, OUTPUT);
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
ledcSetup(0, 5000, 8);
|
||||
ledcSetup(1, 5000, 8);
|
||||
ledcSetup(2, 5000, 8);
|
||||
ledcAttachPin(PIN_R, 0);
|
||||
ledcAttachPin(PIN_G, 1);
|
||||
ledcAttachPin(PIN_B, 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_color(CRGB new_color) {
|
||||
#ifdef USE_PWM
|
||||
#ifdef ESP8266
|
||||
analogWrite(PIN_R, new_color.r);
|
||||
analogWrite(PIN_G, new_color.g);
|
||||
analogWrite(PIN_B, new_color.b);
|
||||
#elif ESP32
|
||||
ledcWrite(0, new_color.r);
|
||||
ledcWrite(1, new_color.g);
|
||||
ledcWrite(2, new_color.b);
|
||||
#endif
|
||||
#else
|
||||
fill_solid(leds, NUM_LEDS, new_color);
|
||||
FastLED.show();
|
||||
#endif // USE_PWM
|
||||
}
|
||||
|
||||
void color_bars() {
|
||||
set_color(CRGB::Red);
|
||||
delay(250);
|
||||
set_color(CRGB::Green);
|
||||
delay(250);
|
||||
set_color(CRGB::Blue);
|
||||
delay(250);
|
||||
set_color(CRGB::Black);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
#ifdef USE_PWM
|
||||
setup_pwm();
|
||||
#else
|
||||
FastLED.addLeds<WS2812B, PIN_DATA, GRB>(leds, NUM_LEDS);
|
||||
#endif
|
||||
color_bars();
|
||||
|
||||
beginFDRS();
|
||||
addFDRS(1000, fdrs_recv_cb);
|
||||
subscribeFDRS(READING_ID);
|
||||
}
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
if (new_data) {
|
||||
new_data = false;
|
||||
if (hsv_mode) {
|
||||
set_color(hsv_color);
|
||||
} else {
|
||||
set_color(rgb_color);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
#include <fdrs_globals.h>
|
||||
|
||||
#define READING_ID 104 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
//#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,179 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Irrigation Controller
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
//
|
||||
//
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
#define CONTROL_1 101 //Address for controller 1
|
||||
#define CONTROL_2 102 //Address for controller 2
|
||||
#define CONTROL_3 103 //Address for controller 3
|
||||
#define CONTROL_4 104 //Address for controller 4
|
||||
|
||||
#define COIL_1 4 //Coil Pin 1
|
||||
#define COIL_2 5 //Coil Pin 2
|
||||
#define COIL_3 13 //Coil Pin 3
|
||||
#define COIL_4 14 //Coil Pin 4
|
||||
|
||||
int status_1 = 0;
|
||||
int status_2 = 0;
|
||||
int status_3 = 0;
|
||||
int status_4 = 0;
|
||||
|
||||
bool isData = false;
|
||||
bool newStatus = false;
|
||||
|
||||
void fdrs_recv_cb(DataReading theData) {
|
||||
DBG(String(theData.id));
|
||||
switch (theData.t) {
|
||||
case 0: // Incoming command is to SET a value
|
||||
|
||||
switch (theData.id) {
|
||||
case CONTROL_1:
|
||||
status_1 = (int)theData.d;
|
||||
isData = true;
|
||||
break;
|
||||
case CONTROL_2:
|
||||
status_2 = (int)theData.d;
|
||||
isData = true;
|
||||
break;
|
||||
case CONTROL_3:
|
||||
status_3 = (int)theData.d;
|
||||
isData = true;
|
||||
break;
|
||||
case CONTROL_4:
|
||||
status_4 = (int)theData.d;
|
||||
isData = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // Incoming command is to GET a value
|
||||
switch (theData.id) {
|
||||
case CONTROL_1:
|
||||
if (digitalRead(COIL_1) == HIGH) {
|
||||
loadFDRS(1, STATUS_T, CONTROL_1);
|
||||
} else {
|
||||
loadFDRS(0, STATUS_T, CONTROL_1);
|
||||
}
|
||||
break;
|
||||
case CONTROL_2:
|
||||
if (digitalRead(COIL_2) == HIGH) {
|
||||
loadFDRS(1, STATUS_T, CONTROL_2);
|
||||
} else {
|
||||
loadFDRS(0, STATUS_T, CONTROL_2);
|
||||
}
|
||||
break;
|
||||
case CONTROL_3:
|
||||
if (digitalRead(COIL_3) == HIGH) {
|
||||
loadFDRS(1, STATUS_T, CONTROL_3);
|
||||
} else {
|
||||
loadFDRS(0, STATUS_T, CONTROL_3);
|
||||
}
|
||||
break;
|
||||
case CONTROL_4:
|
||||
if (digitalRead(COIL_4) == HIGH) {
|
||||
loadFDRS(1, STATUS_T, CONTROL_4);
|
||||
} else {
|
||||
loadFDRS(0, STATUS_T, CONTROL_4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
newStatus = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void checkCoils() { // Sends back a status report for each coil pin.
|
||||
if (digitalRead(COIL_1) == HIGH) {
|
||||
loadFDRS(1, STATUS_T, CONTROL_1);
|
||||
} else {
|
||||
loadFDRS(0, STATUS_T, CONTROL_1);
|
||||
}
|
||||
if (digitalRead(COIL_2) == HIGH) {
|
||||
loadFDRS(1, STATUS_T, CONTROL_2);
|
||||
} else {
|
||||
loadFDRS(0, STATUS_T, CONTROL_2);
|
||||
}
|
||||
if (digitalRead(COIL_3) == HIGH) {
|
||||
loadFDRS(1, STATUS_T, CONTROL_3);
|
||||
} else {
|
||||
loadFDRS(0, STATUS_T, CONTROL_3);
|
||||
}
|
||||
if (digitalRead(COIL_4) == HIGH) {
|
||||
loadFDRS(1, STATUS_T, CONTROL_4);
|
||||
} else {
|
||||
loadFDRS(0, STATUS_T, CONTROL_4);
|
||||
}
|
||||
if (sendFDRS()) {
|
||||
DBG("Packet received by gateway");
|
||||
} else {
|
||||
DBG("Unable to communicate with gateway!");
|
||||
}
|
||||
}
|
||||
|
||||
void updateCoils() { //These are set up for relay module which are active-LOW. Swap 'HIGH'and 'LOW' in this function to use the inverse.
|
||||
if (status_1) {
|
||||
digitalWrite(COIL_1, LOW);
|
||||
} else {
|
||||
digitalWrite(COIL_1, HIGH);
|
||||
}
|
||||
if (status_2) {
|
||||
digitalWrite(COIL_2, LOW);
|
||||
} else {
|
||||
digitalWrite(COIL_2, HIGH);
|
||||
}
|
||||
if (status_3) {
|
||||
digitalWrite(COIL_3, LOW);
|
||||
} else {
|
||||
digitalWrite(COIL_3, HIGH);
|
||||
}
|
||||
if (status_4) {
|
||||
digitalWrite(COIL_4, LOW);
|
||||
} else {
|
||||
digitalWrite(COIL_4, HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
pingFDRS(1000);
|
||||
if (addFDRS(1000, fdrs_recv_cb)) {
|
||||
subscribeFDRS(CONTROL_1);
|
||||
subscribeFDRS(CONTROL_2);
|
||||
subscribeFDRS(CONTROL_3);
|
||||
subscribeFDRS(CONTROL_4);
|
||||
} else {
|
||||
DBG("Not Connected");
|
||||
}
|
||||
pinMode(COIL_1, OUTPUT);
|
||||
digitalWrite(COIL_1, HIGH);
|
||||
pinMode(COIL_2, OUTPUT);
|
||||
digitalWrite(COIL_2, HIGH);
|
||||
pinMode(COIL_3, OUTPUT);
|
||||
digitalWrite(COIL_3, HIGH);
|
||||
pinMode(COIL_4, OUTPUT);
|
||||
digitalWrite(COIL_4, HIGH);
|
||||
|
||||
DBG("FARM DATA RELAY SYSTEM :: Irrigation Module");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
if (isData) {
|
||||
isData = false;
|
||||
updateCoils();
|
||||
checkCoils();
|
||||
}
|
||||
if (newStatus) {
|
||||
newStatus = false;
|
||||
if (sendFDRS()) {
|
||||
DBG("Packet received by gateway");
|
||||
} else {
|
||||
DBG("Unable to communicate with gateway!");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
#include <fdrs_globals.h>
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
//#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,23 @@
|
||||
#define READING_ID 31
|
||||
#define GTWY_MAC 0x01
|
||||
#define USE_ESPNOW
|
||||
#define COIL_PIN 5
|
||||
|
||||
#include <fdrs_node.h>
|
||||
|
||||
bool status = 0;
|
||||
|
||||
void fdrs_recv_cb(DataReading theData) {
|
||||
status = (bool)theData.d;
|
||||
}
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
if (addFDRS(1000, fdrs_recv_cb))
|
||||
subscribeFDRS(READING_ID);
|
||||
pinMode(COIL_PIN, OUTPUT);
|
||||
}
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
if (status) digitalWrite(COIL_PIN, HIGH);
|
||||
else digitalWrite(COIL_PIN, LOW);
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// TFT_eSPI Example
|
||||
//
|
||||
// Listens for datareading IDs #101-104 and displays their data in the four corners of a TFT screen.
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
//
|
||||
//
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
#include <TFT_eSPI.h>
|
||||
|
||||
TFT_eSPI tft = TFT_eSPI();
|
||||
|
||||
#define CONTROL_A 101 //ID for datapoint A
|
||||
#define CONTROL_B 102 //ID for datapoint B
|
||||
#define CONTROL_C 103 //ID for datapoint C
|
||||
#define CONTROL_D 104 //ID for datapoint D
|
||||
|
||||
float value_A = 0;
|
||||
float value_B = 0;
|
||||
float value_C = 0;
|
||||
float value_D = 0;
|
||||
|
||||
bool newData = false;
|
||||
|
||||
void fdrs_recv_cb(DataReading theData) {
|
||||
switch (theData.id) {
|
||||
case CONTROL_A:
|
||||
value_A = theData.d;
|
||||
newData = true;
|
||||
break;
|
||||
case CONTROL_B:
|
||||
value_B = theData.d;
|
||||
newData = true;
|
||||
break;
|
||||
case CONTROL_C:
|
||||
value_C = theData.d;
|
||||
newData = true;
|
||||
break;
|
||||
case CONTROL_D:
|
||||
value_D = theData.d;
|
||||
newData = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void updateScreen() {
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextDatum(TL_DATUM);
|
||||
tft.drawFloat(value_A, 3, 0, 0, 2);
|
||||
tft.setTextDatum(TR_DATUM);
|
||||
tft.drawFloat(value_B, 3, tft.width(), 0, 2);
|
||||
tft.setTextDatum(BL_DATUM);
|
||||
tft.drawFloat(value_C, 3, 0, tft.height(), 2);
|
||||
tft.setTextDatum(BR_DATUM);
|
||||
tft.drawFloat(value_D, 3, tft.width(), tft.height(), 2);
|
||||
|
||||
}
|
||||
|
||||
void setup() {
|
||||
tft.init();
|
||||
tft.setRotation(1);
|
||||
tft.fillScreen(TFT_BLACK);
|
||||
tft.setTextColor(TFT_WHITE, TFT_BLACK);
|
||||
tft.setTextSize(2);
|
||||
updateScreen();
|
||||
beginFDRS();
|
||||
DBG("W:" +String(tft.width()));
|
||||
DBG("FARM DATA RELAY SYSTEM :: TFT_eSPI Example -- thanks Bodmer!");
|
||||
if (addFDRS(1000, fdrs_recv_cb)) {
|
||||
subscribeFDRS(CONTROL_A);
|
||||
subscribeFDRS(CONTROL_B);
|
||||
subscribeFDRS(CONTROL_C);
|
||||
subscribeFDRS(CONTROL_D);
|
||||
} else {
|
||||
DBG("Not Connected");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
loopFDRS();
|
||||
if (newData) {
|
||||
newData = false;
|
||||
updateScreen();
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
#include <fdrs_globals.h>
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
//#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,29 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// ESP-NOW Sensor Example
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
// An example of how to send data via ESP-NOW using FDRS.
|
||||
//
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
void fdrs_recv_cb(DataReading theData)
|
||||
{
|
||||
DBG("ID: " + String(theData.id));
|
||||
DBG("Type: " + String(theData.t));
|
||||
DBG("Data: " + String(theData.d));
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
beginFDRS();
|
||||
pingFDRS(1000);
|
||||
addFDRS(fdrs_recv_cb);
|
||||
subscribeFDRS(READING_ID);
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
loopFDRS();
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
#include <fdrs_globals.h>
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
//#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,38 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// ESP-NOW Sensor Example
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
// An example of how to send data via ESP-NOW using FDRS.
|
||||
//
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
float data1;
|
||||
float data2;
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
}
|
||||
void loop() {
|
||||
data1 = readHum();
|
||||
loadFDRS(data1, HUMIDITY_T);
|
||||
data2 = readTemp();
|
||||
loadFDRS(data2, TEMP_T);
|
||||
// DBG(sendFDRS());
|
||||
if(sendFDRS()){
|
||||
DBG("Big Success!");
|
||||
} else {
|
||||
DBG("Nope, not so much.");
|
||||
}
|
||||
sleepFDRS(10); //Sleep time in seconds
|
||||
}
|
||||
|
||||
float readTemp() {
|
||||
return 22.069;
|
||||
}
|
||||
|
||||
float readHum() {
|
||||
return random(0, 100);
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
#include <fdrs_globals.h>
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,20 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// ESP-NOW Stress Tester or "Spammer"
|
||||
//
|
||||
// Sends ESP-NOW packets at approximately 60Hz.
|
||||
//
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
}
|
||||
void loop() {
|
||||
for (uint8_t i=0; i < 255; i++) {
|
||||
loadFDRS(float(i), IT_T);
|
||||
sendFDRS();
|
||||
delay(15);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
#include <fdrs_globals.h>
|
||||
|
||||
#define READING_ID 3 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
//#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
//#define FDRS_DEBUG
|
||||
//
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,22 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// ETHERNET GATEWAY
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
|
||||
// Configuration for the ThingPulse ESPGateway: https://thingpulse.com/product/espgateway-ethernet-esp32-wifi-ble-gateway-with-rj45-ethernet-connector/
|
||||
#define ETH_CLK_MODE ETH_CLOCK_GPIO16_OUT
|
||||
#define ETH_POWER_PIN 5
|
||||
|
||||
#include "fdrs_gateway_config.h"
|
||||
#include <fdrs_gateway.h>
|
||||
|
||||
void setup() {
|
||||
pinMode(ETH_POWER_PIN, OUTPUT);
|
||||
digitalWrite(ETH_POWER_PIN, HIGH);
|
||||
beginFDRS();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// ETHERNET GATEWAY CONFIGURATION
|
||||
|
||||
//Addresses
|
||||
#define UNIT_MAC 0x01 // The address of this gateway
|
||||
|
||||
#define ESPNOW_NEIGHBOR_1 0x00 // Address of ESP-NOW neighbor #1
|
||||
#define ESPNOW_NEIGHBOR_2 0x02 // Address of ESP-NOW neighbor #2
|
||||
#define LORA_NEIGHBOR_1 0x00 // Address of LoRa neighbor #1
|
||||
#define LORA_NEIGHBOR_2 0x00 // Address of LoRa neighbor #2
|
||||
|
||||
// Interfaces
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
//#define USE_WIFI // Will cause errors if used with ESP-NOW. Use a serial link instead!
|
||||
#define USE_ETHERNET
|
||||
|
||||
// Routing
|
||||
// Options: sendESPNowNbr(1 or 2); sendESPNowPeers(); sendLoRaNbr(1 or 2); broadcastLoRa(); sendSerial(); sendMQTT();
|
||||
#define ESPNOWG_ACT sendMQTT();
|
||||
#define LORAG_ACT
|
||||
#define SERIAL_ACT sendESPNowNbr(2); sendESPNowPeers();
|
||||
#define MQTT_ACT
|
||||
#define INTERNAL_ACT sendMQTT();
|
||||
#define ESPNOW1_ACT
|
||||
#define ESPNOW2_ACT sendMQTT();
|
||||
#define LORA1_ACT
|
||||
#define LORA2_ACT
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
|
||||
//#define CUSTOM_SPI
|
||||
#define LORA_SPI_SCK 5
|
||||
#define LORA_SPI_MISO 19
|
||||
#define LORA_SPI_MOSI 27
|
||||
|
||||
#define FDRS_DEBUG // Enable USB-Serial debugging
|
||||
|
||||
// OLED -- Displays console debugging messages on an SSD1306 I²C OLED
|
||||
///#define USE_OLED
|
||||
#define OLED_HEADER "FDRS"
|
||||
#define OLED_PAGE_SECS 30
|
||||
#define OLED_SDA 4
|
||||
#define OLED_SCL 15
|
||||
#define OLED_RST 16
|
||||
|
||||
// UART data interface pins (if available)
|
||||
#define RXD2 14
|
||||
#define TXD2 15
|
||||
|
||||
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
|
||||
|
||||
// WiFi and MQTT Credentials -- These will override the global settings
|
||||
//#define WIFI_SSID "Your SSID"
|
||||
//#define WIFI_PASS "Your Password"
|
||||
|
||||
#define MQTT_ADDR "192.168.2.3"
|
||||
//#define MQTT_PORT 1883 // Default MQTT port is 1883
|
||||
//#define MQTT_AUTH //Enable MQTT authentication
|
||||
//#define MQTT_USER "Your MQTT Username"
|
||||
//#define MQTT_PASS "Your MQTT Password"
|
||||
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// ESP-NOW Sensor Example
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
// An example of how to send data via ESP-NOW using FDRS.
|
||||
//
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
void fdrs_recv_cb(DataReading theData)
|
||||
{
|
||||
DBG("ID: " + String(theData.id));
|
||||
DBG("Type: " + String(theData.t));
|
||||
DBG("Data: " + String(theData.d));
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
beginFDRS();
|
||||
pingFDRS(1000);
|
||||
addFDRS(fdrs_recv_cb);
|
||||
subscribeFDRS(READING_ID);
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
loopFDRS();
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
// Node Configuration
|
||||
|
||||
#include <fdrs_globals.h>
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
//#define USE_ESPNOW
|
||||
#define USE_LORA
|
||||
//#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,33 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// LoRa Sensor Example
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
// An example of how to send data via LoRa using FDRS.
|
||||
//
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
float data1;
|
||||
float data2;
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
}
|
||||
void loop() {
|
||||
data1 = readHum();
|
||||
loadFDRS(data1, HUMIDITY_T);
|
||||
data2 = readTemp();
|
||||
loadFDRS(data2, TEMP_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(10); //Sleep time in seconds
|
||||
}
|
||||
|
||||
float readTemp() {
|
||||
return 21.0;
|
||||
}
|
||||
|
||||
float readHum() {
|
||||
return random(0,100);
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
#include <fdrs_globals.h>
|
||||
|
||||
#define READING_ID 2 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
//#define USE_ESPNOW
|
||||
#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
||||
|
||||
//#define CUSTOM_SPI
|
||||
#define LORA_SPI_SCK 5
|
||||
#define LORA_SPI_MISO 19
|
||||
#define LORA_SPI_MOSI 27
|
@ -0,0 +1,29 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// AHT20 SENSOR MODULE
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <Adafruit_AHTX0.h>
|
||||
#include <fdrs_node.h>
|
||||
|
||||
Adafruit_AHTX0 aht;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
beginFDRS();
|
||||
if (! aht.begin()) {
|
||||
Serial.println("Could not find AHT? Check wiring");
|
||||
while (1) delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
sensors_event_t humidity, temp;
|
||||
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
|
||||
loadFDRS(temp.temperature, TEMP_T);
|
||||
loadFDRS(humidity.relative_humidity, HUMIDITY_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(60); //Sleep time in seconds
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,28 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// BME280 SENSOR MODULE
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <Adafruit_BME280.h>
|
||||
#include <fdrs_node.h>
|
||||
|
||||
Adafruit_BME280 bme;
|
||||
|
||||
void setup() {
|
||||
//Serial.begin(115200);
|
||||
beginFDRS();
|
||||
while (!bme.begin(0x76)) {
|
||||
//Serial.println("BME not initializing!");
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loadFDRS(bme.readTemperature(), TEMP_T);
|
||||
loadFDRS(bme.readHumidity(), HUMIDITY_T);
|
||||
loadFDRS(bme.readPressure() / 100.0F, PRESSURE_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(60); //Sleep time in seconds
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,28 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// BMP280 SENSOR MODULE
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
// Connect sensor SDA and SCL pins to those of the ESP.
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <Adafruit_BMP280.h>
|
||||
#include <fdrs_node.h>
|
||||
|
||||
Adafruit_BMP280 bmp;
|
||||
|
||||
void setup() {
|
||||
//Serial.begin(115200);
|
||||
beginFDRS();
|
||||
while (!bmp.begin(0x76)) {
|
||||
//Serial.println("BMP not initializing!");
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loadFDRS(bmp.readTemperature(), TEMP_T);
|
||||
loadFDRS(bmp.readPressure() / 100.0F, PRESSURE_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(60); //Sleep time in seconds
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,26 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// CAPACITIVE SOIL MOISTURE SENSOR MODULE
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
// Connect the sensor to an analog pin of your MCU.
|
||||
//
|
||||
|
||||
#define SOIL_PIN 36 // Ignored on ESP8266
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
delay(50); //let the sensor warm up
|
||||
}
|
||||
void loop() {
|
||||
#ifdef ESP8266
|
||||
uint16_t s = analogRead(0);
|
||||
#else
|
||||
uint16_t s = analogRead(SOIL_PIN);
|
||||
#endif
|
||||
loadFDRS(s, SOIL_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(60 * 5);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 21 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
//#define USE_ESPNOW
|
||||
#define USE_LORA
|
||||
|
||||
//#define USE_LR // Enables 802.11LR on ESP32 ESP-NOW devices
|
||||
|
||||
//#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 // ESP32 SX1276 (TTGO)
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
//#define USE_SX126X
|
||||
|
||||
//#define CUSTOM_SPI
|
||||
#define LORA_SPI_SCK 5
|
||||
#define LORA_SPI_MISO 19
|
||||
#define LORA_SPI_MOSI 27
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
||||
|
||||
//#define USE_OLED
|
||||
#define OLED_HEADER "FDRS"
|
||||
#define OLED_SDA 4
|
||||
#define OLED_SCL 15
|
||||
#define OLED_RST 16
|
@ -0,0 +1,42 @@
|
||||
// Example testing sketch for various DHT humidity/temperature sensors
|
||||
// Written by ladyada, public domain
|
||||
|
||||
// Modified by Timm Bogner for Farm Data Relay System -- Untested because I don't have a DHT sensor onhand.
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
#include "DHT.h"
|
||||
|
||||
#define DHTPIN 2 // Digital pin connected to the DHT sensor
|
||||
|
||||
// Uncomment whatever type you're using!
|
||||
//#define DHTTYPE DHT11 // DHT 11
|
||||
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
|
||||
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
|
||||
|
||||
DHT dht(DHTPIN, DHTTYPE);
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
DBG("DHTxx Sketch!");
|
||||
dht.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Wait a few seconds between measurements.
|
||||
// Reading temperature or humidity takes about 250 milliseconds!
|
||||
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
|
||||
float h = dht.readHumidity();
|
||||
// Read temperature as Celsius (the default)
|
||||
float t = dht.readTemperature();
|
||||
|
||||
// Check if any reads failed and exit early (to try again).
|
||||
if (isnan(h) || isnan(t)) {
|
||||
DBG("Failed to read from DHT sensor!");
|
||||
return;
|
||||
}
|
||||
loadFDRS(h, HUMIDITY_T);
|
||||
loadFDRS(t, TEMP_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(10); //Sleep time in seconds
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,27 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// DS18B20 SENSOR MODULE
|
||||
//
|
||||
|
||||
#define ONE_WIRE_BUS 13 //Pin that the DS18B20 is connected to
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
#include <OneWire.h>
|
||||
#include <DallasTemperature.h>
|
||||
|
||||
OneWire oneWire(ONE_WIRE_BUS);
|
||||
DallasTemperature sensors(&oneWire);
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
sensors.begin();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
sensors.requestTemperatures(); // Send the command to get temperatures
|
||||
float tempC = sensors.getTempCByIndex(0);
|
||||
loadFDRS(tempC, TEMP_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(60);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,51 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Gypsum-based Soil Moisture Sensor
|
||||
//
|
||||
// Uses a Ezsbc.com Dev board, a Kisssys moisture sensor board, and a DS3231 RTC.
|
||||
// Deep sleep current is less than 20µA.
|
||||
// https://www.printables.com/model/176752-gypson-water-sensor
|
||||
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
|
||||
#define BUTTON_PIN_BITMASK 0x100000000 // 2^32 in hex the pin that is connected to SQW
|
||||
#define CLOCK_INTERRUPT_PIN 32 // yep same pin
|
||||
|
||||
|
||||
const int FreqIn1 = 5;
|
||||
volatile uint16_t Freq1 = 0;
|
||||
static uint16_t FreqOut1;
|
||||
|
||||
ICACHE_RAM_ATTR void SensorInt1() {
|
||||
// If the pin is Rising, increment counter
|
||||
Freq1++;
|
||||
};
|
||||
|
||||
|
||||
void readFrequency() {
|
||||
// for one second we count the pulses and get our moisture reading in pps
|
||||
attachInterrupt(FreqIn1, SensorInt1, RISING);
|
||||
delay(1000); // delay in ms is 1 seconds-- not the most accurate way to do this but more than accurate enough for our low frequency and 10 second read
|
||||
FreqOut1 = Freq1; // our frequency * 10
|
||||
detachInterrupt(FreqIn1); // only reading once so turn off the interrupt
|
||||
|
||||
}
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
pinMode(FreqIn1, INPUT);
|
||||
Freq1 = 0;
|
||||
delay(50);
|
||||
readFrequency();
|
||||
//DBG("Frequency = " + String(FreqOut1));
|
||||
loadFDRS(FreqOut1, SOIL_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(1800); //Sleep time in seconds
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// nuttin honey
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 23 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
#define POWER_CTRL 22
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,172 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Generic GPS Sensor
|
||||
//
|
||||
// Developed by Sascha Juch (sascha.juch@gmail.com).
|
||||
// Reads in GPS data from serial and sends latitude, longitude and altitude to a gateway.
|
||||
//
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
#define SERIAL1_RX 13 // TX pin of GPS sensor
|
||||
#define SERIAL1_TX 12 // RX pin of GPS sensor
|
||||
#define MAX_NMEA_LENGTH 82 //maximum allowed length of a NMEA 0183 sentences.
|
||||
|
||||
char currentNMEALine[MAX_NMEA_LENGTH];
|
||||
|
||||
void setup() {
|
||||
// ToDo: This works well on a board with a second hardware serial port like the ESP32. But what if there is no hardware serial on the device?
|
||||
// Unfortunately I do not have a GPS (standalone) sensor atm with which I could test. Help and advice appreciated.
|
||||
Serial1.begin(9600, SERIAL_8N1, SERIAL1_RX, SERIAL1_TX);
|
||||
|
||||
beginFDRS();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// read in line by line of the NMEA input and get rid of trailing whitespaces
|
||||
Serial1.readBytesUntil('\n', currentNMEALine, MAX_NMEA_LENGTH);
|
||||
trimwhitespace(currentNMEALine);
|
||||
|
||||
// we are only interested in GPGGA (U-Blox M6N) or GNGGA (U-Blox M8N)lines.
|
||||
if (startsWith(currentNMEALine, "$GNGGA") || startsWith(currentNMEALine, "$GPGGA")) {
|
||||
|
||||
DBG(currentNMEALine);
|
||||
|
||||
// just in case someone needs UTC, quality or #satelites, just uncomment and do what you have to do with them. :)
|
||||
//char * gpsUTC = getNthValueOf(currentNMEALine, ',', 1);
|
||||
char * gpsLatitude = getNthValueOf(currentNMEALine, ',', 2);
|
||||
char * gpsLatitudeOrientation = getNthValueOf(currentNMEALine, ',', 3);
|
||||
char * gpsLongitude = getNthValueOf(currentNMEALine, ',', 4);
|
||||
char * gpsLongitudeOrientation = getNthValueOf(currentNMEALine, ',', 5);
|
||||
//char * gpsQuality = getNthValueOf(currentNMEALine, ',', 6);
|
||||
char * gpsAltitude = getNthValueOf(currentNMEALine, ',', 7);
|
||||
//char * gpsNoOfSatelites = getNthValueOf(currentNMEALine, ',', 9);
|
||||
|
||||
// convert latitude and altitude to decimal degree values (as used in most maps programs)
|
||||
// negative values mean "S" or "W", positive values mean "N" and "E"
|
||||
float latitude = convertGpsCoordinates(atof(gpsLatitude), gpsLatitudeOrientation);
|
||||
float longitude = convertGpsCoordinates(atof(gpsLongitude), gpsLongitudeOrientation);
|
||||
|
||||
float altitude = atof(gpsAltitude);
|
||||
|
||||
/*
|
||||
loadFDRS(latitude, HUMIDITY_T);
|
||||
loadFDRS(longitude, TEMP_T);
|
||||
loadFDRS(altitude, TEMP2_T);
|
||||
*/
|
||||
|
||||
// extended sensor types - not officially atm!
|
||||
loadFDRS(latitude, LATITUDE_T);
|
||||
loadFDRS(longitude, LONGITUDE_T);
|
||||
loadFDRS(altitude, ALTITUDE_T);
|
||||
if(sendFDRS()){
|
||||
DBG("Big Success!");
|
||||
} else {
|
||||
DBG("Nope, not so much.");
|
||||
}
|
||||
sleepFDRS(10); //Sleep time in seconds
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// cudos for the trimming function go to: https://stackoverflow.com/questions/122616/how-do-i-trim-leading-trailing-whitespace-in-a-standard-way
|
||||
// Thanks! That was a time saver. :)
|
||||
// Note: This function returns a pointer to a substring of the original string.
|
||||
// If the given string was allocated dynamically, the caller must not overwrite
|
||||
// that pointer with the returned value, since the original pointer must be
|
||||
// deallocated using the same allocator with which it was allocated. The return
|
||||
// value must NOT be deallocated using free() etc.
|
||||
char *trimwhitespace(char *str)
|
||||
{
|
||||
char *end;
|
||||
|
||||
// Trim leading space
|
||||
while(isspace((unsigned char)*str)) str++;
|
||||
|
||||
if(*str == 0) // All spaces?
|
||||
return str;
|
||||
|
||||
// Trim trailing space
|
||||
end = str + strlen(str) - 1;
|
||||
while(end > str && isspace((unsigned char)*end)) end--;
|
||||
|
||||
// Write new null terminator character
|
||||
end[1] = '\0';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// check, if a given char* fullString starts with a given char* startString.
|
||||
// If that's the case, return true, false otherwise
|
||||
bool startsWith(const char *fullString, const char *startString)
|
||||
{
|
||||
if (strncmp(fullString, startString, strlen(startString)) == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Cudos for the substr function go to: https://www.techiedelight.com/implement-substr-function-c/
|
||||
// Thanks! That helped a lot :)
|
||||
// Following function extracts characters present in `src`
|
||||
// between `m` and `n` (excluding `n`)
|
||||
char* substr(const char *src, int m, int n)
|
||||
{
|
||||
// get the length of the destination string
|
||||
int len = n - m;
|
||||
|
||||
// allocate (len + 1) chars for destination (+1 for extra null character)
|
||||
char *dest = (char*)malloc(sizeof(char) * (len + 1));
|
||||
|
||||
// extracts characters between m'th and n'th index from source string
|
||||
// and copy them into the destination string
|
||||
for (int i = m; i < n && (*(src + i) != '\0'); i++)
|
||||
{
|
||||
*dest = *(src + i);
|
||||
dest++;
|
||||
}
|
||||
|
||||
// null-terminate the destination string
|
||||
*dest = '\0';
|
||||
|
||||
// return the destination string
|
||||
return dest - len;
|
||||
}
|
||||
|
||||
// returns the value of the n-th occurance within a delimiter-separated string
|
||||
char * getNthValueOf (char *inputString, const char delimiter, uint8_t index) {
|
||||
uint8_t i = 0;
|
||||
uint8_t currentIndex = 0;
|
||||
uint8_t startOfValue = 0;
|
||||
uint8_t endOfValue = 0;
|
||||
|
||||
while (i < strlen(inputString) && inputString[i] && currentIndex < index) {
|
||||
if (inputString[i] == delimiter) {
|
||||
currentIndex++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
startOfValue = i;
|
||||
|
||||
while (i < strlen(inputString) && inputString[i] && currentIndex <= index) {
|
||||
if (inputString[i] == delimiter) {
|
||||
currentIndex++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
endOfValue = i;
|
||||
|
||||
char* valueAtIndex = substr(inputString, startOfValue, endOfValue-1);
|
||||
|
||||
return valueAtIndex;
|
||||
}
|
||||
|
||||
// convert NMEA0183 degrees minutes coordinates to decimal degrees
|
||||
float convertGpsCoordinates(float degreesMinutes, char* orientation) {
|
||||
double gpsMinutes = fmod((double)degreesMinutes, 100.0);
|
||||
uint8_t gpsDegrees = degreesMinutes / 100;
|
||||
double decimalDegrees = gpsDegrees + ( gpsMinutes / 60 );
|
||||
if (strcmp(orientation, "W") == 0 || strcmp(orientation, "S") == 0) {
|
||||
decimalDegrees = 0 - decimalDegrees;
|
||||
}
|
||||
return decimalDegrees;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x03 //Address of the nearest gateway
|
||||
|
||||
//#define USE_ESPNOW
|
||||
#define USE_LORA
|
||||
//#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 // ESP32 SX1276 (TTGO)
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
#define LORA_BUSY 33
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
||||
|
||||
#define USE_OLED
|
||||
#define OLED_HEADER "FDRS"
|
||||
#define OLED_SDA 4
|
||||
#define OLED_SCL 15
|
||||
#define OLED_RST 16
|
@ -0,0 +1,117 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Gypsum-based Soil Moisture Sensor
|
||||
//
|
||||
// Uses a Ezsbc.com Dev board, a Kisssys moisture sensor board, and a DS3231 RTC.
|
||||
// Deep sleep current is less than 20µA.
|
||||
// https://www.printables.com/model/176752-gypson-water-sensor
|
||||
|
||||
#define DEBUG
|
||||
#define CREDENTIALS
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
#include <RTClib.h>
|
||||
RTC_DS3231 rtc;
|
||||
|
||||
#define BUTTON_PIN_BITMASK 0x100000000 // 2^32 in hex the pin that is connected to SQW
|
||||
#define CLOCK_INTERRUPT_PIN 32 // yep same pin
|
||||
//#define SupplyPin 33 // power to DS3231
|
||||
#define BatteryReadPin 35 // read battey voltage on this pin
|
||||
|
||||
|
||||
const int FreqIn1 = 18; // gpio32
|
||||
const int FreqPower = 19;
|
||||
const int RTCPower = 25;
|
||||
volatile uint16_t Freq1 = 0;
|
||||
static uint16_t FreqOut1;
|
||||
|
||||
void SensorInt1() {
|
||||
// If the pin is Rising, increment counter
|
||||
Freq1++;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
DBG(__FILE__);
|
||||
pinMode(FreqIn1, INPUT);
|
||||
pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP); // On deep sleep the pin needs and external 330k pullup
|
||||
pinMode(RTCPower, OUTPUT); // for the SQW pin to stay high when RTC power is removed
|
||||
digitalWrite(RTCPower, HIGH); // DS3231 needs the SQW pullup removed on the board to
|
||||
pinMode(FreqPower, OUTPUT); // lower the deepsleep current by 60ua's
|
||||
digitalWrite(FreqPower, HIGH);
|
||||
|
||||
Freq1 = 0;
|
||||
delay(50);
|
||||
|
||||
Wire.begin(13, 14); // moved from 21 22 normal I2C pins because it allows me to set these pins to input later
|
||||
if (!rtc.begin()) {
|
||||
DBG("Couldn't find RTC!");
|
||||
Serial.flush();
|
||||
while (1) delay(10);
|
||||
}
|
||||
|
||||
if (rtc.lostPower()) {
|
||||
// this will adjust to the date and time at compilation
|
||||
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
|
||||
}
|
||||
|
||||
rtc.disable32K(); // Don't use this so we shut it down on the board
|
||||
// set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
|
||||
// if not done, this easily leads to problems, as both register aren't reset on reboot/recompile
|
||||
rtc.clearAlarm(1);
|
||||
rtc.clearAlarm(2);
|
||||
|
||||
// stop oscillating signals at SQW Pin
|
||||
// otherwise setAlarm1 will fail
|
||||
rtc.writeSqwPinMode(DS3231_OFF);
|
||||
|
||||
// turn off alarm 2 (in case it isn't off already)
|
||||
// again, this isn't done at reboot, so a previously set alarm could easily go overlooked
|
||||
rtc.disableAlarm(2);
|
||||
|
||||
|
||||
// for one second we count the pulses and get our moisture reading in pps
|
||||
attachInterrupt(FreqIn1, SensorInt1, RISING);
|
||||
delay(1000); // delay in ms is 1 seconds-- not the most accurate way to do this but more than accurate enough for our low frequency and 10 second read
|
||||
FreqOut1 = Freq1; // our frequency * 10
|
||||
detachInterrupt(FreqIn1); // only reading once so turn off the interrupt
|
||||
|
||||
|
||||
if (rtc.alarmFired(1)) {
|
||||
rtc.clearAlarm(1);
|
||||
Serial.println("Alarm cleared");
|
||||
}
|
||||
|
||||
float supply = analogRead(BatteryReadPin) * .001833;
|
||||
DBG("WaterSensor 1 = " + String(FreqOut1));
|
||||
DBG("Supply Voltage = " + String(supply));
|
||||
|
||||
loadFDRS(FreqOut1, SOIL_T);
|
||||
loadFDRS(supply, VOLTAGE_T);
|
||||
sendFDRS();
|
||||
// Lowers SQW int pin32 every 10 seconds
|
||||
rtc.setAlarm1(DateTime(0, 0, 0, 00, 00, 10), DS3231_A1_Second); //DateTime (year,month,day,hour,min,sec)
|
||||
|
||||
esp_sleep_enable_ext1_wakeup(BUTTON_PIN_BITMASK, ESP_EXT1_WAKEUP_ALL_LOW);
|
||||
|
||||
char date[10] = "hh:mm:ss";
|
||||
rtc.now().toString(date);
|
||||
Serial.println(date); // Print the time
|
||||
Serial.println("Going to sleep soon");
|
||||
|
||||
// prepare for low current shutdown
|
||||
digitalWrite(FreqPower, LOW);
|
||||
digitalWrite(RTCPower, LOW);
|
||||
pinMode(13, INPUT);
|
||||
pinMode(14, INPUT);
|
||||
|
||||
esp_deep_sleep_start();
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// nuttin honey
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,117 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// LILYGO HIGROW SENSOR MODULE
|
||||
//
|
||||
|
||||
|
||||
#define I2C_SDA 25
|
||||
#define I2C_SCL 26
|
||||
#define DHT12_PIN 16
|
||||
#define BAT_ADC 33
|
||||
#define SALT_PIN 34
|
||||
#define SOIL_PIN 32
|
||||
#define BOOT_PIN 0
|
||||
#define USER_BUTTON 35
|
||||
#define DS18B20_PIN 21
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
#include <BH1750.h>
|
||||
#include <Adafruit_BME280.h>
|
||||
|
||||
BH1750 lightMeter(0x23); //0x23
|
||||
Adafruit_BME280 bme; //0x77
|
||||
RTC_DATA_ATTR int the_count = 0;
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
|
||||
//Init Sensors
|
||||
Wire.begin(I2C_SDA, I2C_SCL);
|
||||
// while (!bme.begin()) {
|
||||
// Serial.println("bme");
|
||||
// delay(10);
|
||||
// }
|
||||
|
||||
if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
|
||||
Serial.println(F("BH1750 Advanced begin"));
|
||||
} else {
|
||||
Serial.println(F("Error initialising BH1750"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void loadData() {
|
||||
float s_battery = readBattery();
|
||||
// float bme_temp = bme.readTemperature();
|
||||
// float bme_pressure = (bme.readPressure() / 100.0F);
|
||||
//float bme_altitude = bme.readAltitude(1013.25);
|
||||
// float bme_humidity = bme.readHumidity();
|
||||
float s_soil = readSoil();
|
||||
float s_salt = readSalt();
|
||||
while (! lightMeter.measurementReady()) {
|
||||
delay(10);
|
||||
}
|
||||
float lux = lightMeter.readLightLevel();
|
||||
the_count++;
|
||||
|
||||
Serial.println();
|
||||
// Serial.println("Temp: " + String(bme_temp));
|
||||
// Serial.println("Humidity: " + String(bme_humidity));
|
||||
Serial.println("Light: " + String(lux));
|
||||
// Serial.println("Pressure: " + String(bme_pressure));
|
||||
Serial.println("Salt: " + String(s_salt));
|
||||
Serial.println("Soil: " + String(s_soil));
|
||||
Serial.println("Voltage: " + String(s_battery));
|
||||
Serial.println("Count: " + String(the_count));
|
||||
|
||||
// loadFDRS(bme_temp, TEMP_T);
|
||||
|
||||
// loadFDRS(bme_humidity, HUMIDITY_T);
|
||||
|
||||
|
||||
loadFDRS(lux, LIGHT_T);
|
||||
// loadFDRS(bme_pressure, PRESSURE_T);
|
||||
loadFDRS(s_salt, SOILR_T);
|
||||
loadFDRS(s_soil, SOIL_T);
|
||||
loadFDRS(s_battery, VOLTAGE_T);
|
||||
loadFDRS(float(the_count), IT_T);
|
||||
|
||||
}
|
||||
|
||||
uint32_t readSalt() //Soil Electrodes: This code came from the LilyGo documentation.
|
||||
{
|
||||
uint8_t samples = 120;
|
||||
uint32_t humi = 0;
|
||||
uint16_t array[120];
|
||||
for (int i = 0; i < samples; i++) {
|
||||
array[i] = analogRead(SALT_PIN);
|
||||
delay(2);
|
||||
}
|
||||
std::sort(array, array + samples);
|
||||
for (int i = 0; i < samples; i++) {
|
||||
if (i == 0 || i == samples - 1)continue;
|
||||
humi += array[i];
|
||||
}
|
||||
humi /= samples - 2;
|
||||
return humi;
|
||||
}
|
||||
|
||||
uint16_t readSoil() //Soil Capacitance
|
||||
{
|
||||
uint16_t soil = analogRead(SOIL_PIN);
|
||||
return soil;
|
||||
}
|
||||
|
||||
float readBattery() //Battery Voltage: This code came from the LilyGo documentation.
|
||||
{
|
||||
int vref = 1100;
|
||||
uint16_t volt = analogRead(BAT_ADC);
|
||||
float battery_voltage = ((float)volt / 4095.0) * 2.0 * 3.3 * (vref);
|
||||
return battery_voltage;
|
||||
}
|
||||
void loop() {
|
||||
loadData();
|
||||
sendFDRS();
|
||||
sleepFDRS(30);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
#define POWER_CTRL 4
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,45 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Multifunction ESP8266 Sensor Board by Phil Grant
|
||||
//
|
||||
// https://github.com/gadjet/Multifunction-ESP8266-Sensor-board
|
||||
//
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <Adafruit_AHT10.h>
|
||||
#include <fdrs_node.h>
|
||||
|
||||
Adafruit_AHT10 aht;
|
||||
|
||||
const int reedSwitch = 13;
|
||||
|
||||
void setup() {
|
||||
aht.begin();
|
||||
|
||||
// Init Serial Monitor
|
||||
//Serial.begin(115200);
|
||||
// initialize the reed switch pin as an input:
|
||||
pinMode(reedSwitch, INPUT);
|
||||
// initialize the wakeup pin as an input:
|
||||
pinMode(16, WAKEUP_PULLUP);
|
||||
beginFDRS();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
sensors_event_t humidity, temp;
|
||||
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
|
||||
// Read the state of the reed switch and send open or closed
|
||||
if (digitalRead(reedSwitch) == HIGH) {
|
||||
loadFDRS(1.0, MOTION_T);
|
||||
}
|
||||
else {
|
||||
loadFDRS(0.0, MOTION_T);
|
||||
}
|
||||
loadFDRS((analogRead(A0) * 4.2 * 10 / 1023), VOLTAGE_T);
|
||||
loadFDRS(humidity.relative_humidity, HUMIDITY_T);
|
||||
loadFDRS(temp.temperature, TEMP_T);
|
||||
// Send message via FDRS
|
||||
sendFDRS();
|
||||
sleepFDRS(15); //15 Min's sleep
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,28 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// MLX90614 INFRARED TEMPERATURE SENSOR MODULE
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <Adafruit_MLX90614.h>
|
||||
#include <fdrs_node.h>
|
||||
|
||||
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
delay(250);
|
||||
DBG("Adafruit MLX90614 test");
|
||||
if (!mlx.begin()) {
|
||||
DBG("Error connecting to MLX sensor. Check wiring.");
|
||||
while (1);
|
||||
};
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loadFDRS(mlx.readAmbientTempC(), TEMP_T);
|
||||
loadFDRS(mlx.readObjectTempC(), TEMP2_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(60); //Sleep time in seconds
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,19 @@
|
||||
# FDRS Sensors
|
||||
Out of date- Needs improvement.
|
||||
| Sensor Name | Maker/Datasheet | Library |
|
||||
| --- | --- | --- |
|
||||
| AHT20 | [ASAIR](http://www.aosong.com/userfiles/files/media/Data%20Sheet%20AHT20.pdf) | [Adafruit](https://github.com/adafruit/Adafruit_AHTX0) |
|
||||
| BME280 | [Bosch](https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf) | [Adafruit](https://github.com/adafruit/Adafruit_BME280_Library) |
|
||||
| BMP280 | [Bosch](https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bmp280-ds001.pdf) | [Adafruit](https://github.com/adafruit/Adafruit_BMP280_Library) |
|
||||
| DHT22 | [Aosong](https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf) |[adafruit](https://github.com/adafruit/DHT-sensor-library) |
|
||||
| DS18B20 | [Dallas](https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf) | [milesburton](https://github.com/adafruit/Adafruit_AHTX0) |
|
||||
| LilyGo HiGrow | [TTGO](http://www.lilygo.cn/prod_view.aspx?TypeId=50033&Id=1172) |
|
||||
| Multifunction ESP8266 Sensor Board | [Phil Grant](https://github.com/gadjet/Multifunction-ESP8266-Sensor-board) |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
I would like to use this spot as a showcase for open source PCB designs. If **you** have designed a sensor module that runs on either ESP8266 or ESP32, please contact me at timmbogner@gmail.com. I will make a custom sensor sketch, along with a link and description available here.
|
@ -0,0 +1,24 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// SENSIRION SHT20 SENSOR MODULE
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
// If you are using the sensor for air monitoring, change SOIL_T to HUMIDITY_T.
|
||||
//
|
||||
#include "DFRobot_SHT20.h"
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
DFRobot_SHT20 sht20(&Wire, SHT20_I2C_ADDR);
|
||||
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
sht20.initSHT20();
|
||||
}
|
||||
void loop() {
|
||||
loadFDRS(sht20.readHumidity(), SOIL_T);
|
||||
loadFDRS(sht20.readTemperature(), TEMP_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(300); //Sleep time in seconds
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 11 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,67 @@
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_Sensor.h>
|
||||
#include <Adafruit_TSL2561_U.h>
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Configures the gain and integration time for the TSL2561
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void configureSensor(void)
|
||||
{
|
||||
/* You can also manually set the gain or enable auto-gain support */
|
||||
// tsl.setGain(TSL2561_GAIN_1X); /* No gain ... use in bright light to avoid sensor saturation */
|
||||
// tsl.setGain(TSL2561_GAIN_16X); /* 16x gain ... use in low light to boost sensitivity */
|
||||
tsl.enableAutoRange(true); /* Auto-gain ... switches automatically between 1x and 16x */
|
||||
|
||||
/* Changing the integration time gives you better sensor resolution (402ms = 16-bit data) */
|
||||
tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); /* fast but low resolution */
|
||||
// tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS); /* medium resolution and speed */
|
||||
// tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS); /* 16-bit data but slowest conversions */
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/*
|
||||
Arduino setup function (automatically called at startup)
|
||||
*/
|
||||
/**************************************************************************/
|
||||
void setup(void)
|
||||
{
|
||||
beginFDRS();
|
||||
/* Initialise the sensor */
|
||||
//use tsl.begin() to default to Wire,
|
||||
//tsl.begin(&Wire2) directs api to use Wire2, etc.
|
||||
if(!tsl.begin())
|
||||
{
|
||||
DBG("Ooops, no TSL2561 detected ... Check your wiring or I2C ADDR!");
|
||||
while(1);
|
||||
}
|
||||
configureSensor();
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
sensors_event_t event;
|
||||
tsl.getEvent(&event);
|
||||
if (event.light)
|
||||
{
|
||||
DBG(String(event.light) + " lux");
|
||||
loadFDRS(float(event.light), LIGHT_T);
|
||||
sendFDRS();
|
||||
sleepFDRS(10); //Sleep time in seconds
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If event.light = 0 lux the sensor is probably saturated
|
||||
and no reliable data could be generated! */
|
||||
Serial.println("Sensor overload");
|
||||
}
|
||||
delay(250);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
@ -0,0 +1,37 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// TIPPING BUCKET RAINFALL SENSOR MODULE
|
||||
//
|
||||
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
|
||||
|
||||
#define REED_PIN 2
|
||||
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
unsigned int theCount = 0;
|
||||
unsigned long lastTrigger = 0;
|
||||
boolean clicked = false;
|
||||
|
||||
ICACHE_RAM_ATTR void detectsMovement() {
|
||||
clicked = true;
|
||||
lastTrigger = millis();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
pinMode(REED_PIN, INPUT_PULLUP);
|
||||
attachInterrupt(digitalPinToInterrupt(REED_PIN), detectsMovement, FALLING);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (clicked && millis() - lastTrigger > 100) {
|
||||
theCount++;
|
||||
Serial.print("DINK.");
|
||||
Serial.println(theCount);
|
||||
clicked = false;
|
||||
loadFDRS(theCount, RAINFALL_T);
|
||||
sendFDRS();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
// FARM DATA RELAY SYSTEM
|
||||
//
|
||||
// Sensor Configuration
|
||||
|
||||
|
||||
#define READING_ID 1 //Unique ID for this sensor
|
||||
#define GTWY_MAC 0x01 //Address of the nearest gateway
|
||||
|
||||
#define USE_ESPNOW
|
||||
//#define USE_LORA
|
||||
#define DEEP_SLEEP
|
||||
//#define POWER_CTRL 14
|
||||
#define FDRS_DEBUG
|
||||
// LoRa Configuration
|
||||
#define RADIOLIB_MODULE SX1276 //Tested on SX1276
|
||||
#define LORA_SS 18
|
||||
#define LORA_RST 14
|
||||
#define LORA_DIO 26
|
||||
|
||||
#define LORA_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
|
||||
#define LORA_ACK // Request LoRa acknowledgment.
|
After Width: | Height: | Size: 228 KiB |
After Width: | Height: | Size: 238 KiB |
After Width: | Height: | Size: 241 KiB |
After Width: | Height: | Size: 221 KiB |
196
IOT/receiver LoRa/lib/Farm-Data-Relay-System/extras/Gateway.md
Normal file
@ -0,0 +1,196 @@
|
||||
# FDRS Gateway
|
||||
|
||||
The FDRS Gateway listens for packets over ESP-NOW, UART, LoRa, and/or MQTT, then retransmits the packets over these interfaces using rules defined in the "Routing" section of the configuration file.
|
||||
|
||||
A basic FDRS gateway's sketch file (.ino) will look like this:
|
||||
|
||||
``` cpp
|
||||
#include "fdrs_gateway_config.h"
|
||||
#include <fdrs_gateway.h>
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
}
|
||||
```
|
||||
|
||||
## Addresses
|
||||
#### ```#define UNIT_MAC 0xNN```
|
||||
The ESP-NOW and LoRa address of the gateway. This is the address that nodes and other gateways will use to pass data to this device.
|
||||
#### ```#define ESPNOW_NEIGHBOR_1 0xNN```, ```ESPNOW_NEIGHBOR_2 0xNN```
|
||||
The addresses of any ESP-NOW repeaters neighboring this gateway.
|
||||
#### ```#define LORA_NEIGHBOR_1 0xNN```, ```LORA_NEIGHBOR_2 0xNN```
|
||||
The addresses of any LoRa repeaters neighboring this gateway.
|
||||
## Interfaces
|
||||
#### ```#define USE_ESPNOW```
|
||||
Enables ESP-NOW.
|
||||
|
||||
#### ```#define USE_LORA```
|
||||
Enables LoRa. Ensure your pins are configured correctly.
|
||||
#### ```#define USE_WIFI```
|
||||
Enables WiFi for use by MQTT. Do not enable WiFi and ESP-NOW simultaneously.
|
||||
#### ```#define USE_ETHERNET```
|
||||
Enables ethernet to be used by MQTT.
|
||||
|
||||
## Routing
|
||||
**Events** occur when data arrives at the gateway via its various interfaces. When an event occurs it triggers one or more **actions**, which are functions that re-send the incoming data over the same or different interfaces.
|
||||
|
||||
**Example:** In the following configuration, a packet that arrives at the serial port will be sent to the gateway's neighbor #2, and then to all ESP-NOW nodes that are connected:
|
||||
```
|
||||
#define SERIAL_ACT sendESPNowNbr(2); sendESPNowPeers();
|
||||
```
|
||||
#
|
||||
### Events
|
||||
|
||||
#### ```#define ESPNOWG_ACT ```
|
||||
Actions that occur when data arrives from an ESP-NOW device that is *not* listed as a neighbor.
|
||||
#### ```#define LORAG_ACT ```
|
||||
Actions that occur when data arrives from a LoRa device that is *not* listed as a neighbor.
|
||||
#### ```#define SERIAL_ACT ```
|
||||
Actions that occur when JSON data arrives over UART.
|
||||
#### ```#define MQTT_ACT ```
|
||||
Actions that occur when JSON data is posted to the MQTT topic defined by ```TOPIC_COMMAND``` in 'src/fdrs_globals.h'.
|
||||
#### ```#define INTERNAL_ACT ```
|
||||
Actions that occur when data is entered by a user-defined function. Used for sending the gateway's own voltage or temperature.
|
||||
#### ```#define ESPNOW1_ACT ``` and ```ESPNOW2_ACT ```
|
||||
Actions that occur when data arrives from the devices defined by ```ESPNOW_NEIGHBOR_1``` and ```ESPNOW_NEIGHBOR_2```.
|
||||
#### ```#define LORA1_ACT ``` and ```LORA2_ACT ```
|
||||
Actions that occur when data arrives from the devices defined by ```LORA_NEIGHBOR_1``` and ```LORA_NEIGHBOR_2```.
|
||||
#
|
||||
### Actions
|
||||
#### ```sendSerial();```
|
||||
Transmits the data in JSON format via both the debugging terminal as well as a second UART interface. (If available. See below.)
|
||||
#### ```sendMQTT();```
|
||||
Posts the data in JSON format to the MQTT topic defined by ```TOPIC_DATA```
|
||||
#### ```sendESPNowNbr(1 or 2);```
|
||||
Sends the data to the address defined by ```ESPNOW_NEIGHBOR_1``` or ```ESPNOW_NEIGHBOR_2```
|
||||
#### ```sendESPNowPeers();```
|
||||
Sends the data to any ESP-NOW controller node that has registered with this gateway as a peer.
|
||||
#### ```sendLoRaNbr(1 or 2);```
|
||||
Sends the data to the address defined by ```LORA_NEIGHBOR_1``` or ```LORA_NEIGHBOR_2```
|
||||
#### ```broadcastLoRa();```
|
||||
Broadcasts the data to any LoRa controller node that is listening to this gateway. No registration is needed to pair with a LoRa controller.
|
||||
#### ```sendESPNow(0xNN);```
|
||||
Sends the data directly to the ESP-NOW gateway address provided. There is no LoRa equivalent of this function.
|
||||
|
||||
#
|
||||
## LoRa Configuration
|
||||
#### ```#define RADIOLIB_MODULE cccc```
|
||||
The name of the RadioLib module being used. Tested modules: SX1276, SX1278, SX1262.
|
||||
#### ```#define LORA_SS n```
|
||||
LoRa chip select pin.
|
||||
#### ```#define LORA_RST n```
|
||||
LoRa reset pin.
|
||||
#### ```#define LORA_DIO n```
|
||||
LoRa DIO pin. This refers to DIO0 on SX127x chips and DIO1 on SX126x chips.
|
||||
#### ```#define LORA_BUSY n```
|
||||
For SX126x chips: LoRa BUSY pin. For SX127x: DIO1 pin, or "RADIOLIB_NC" to leave it blank.
|
||||
#### ```#define LORA_TXPWR n```
|
||||
LoRa TX power in dBm.
|
||||
#### ```#define USE_SX126X```
|
||||
Enable this if using the SX126x series of LoRa chips.
|
||||
|
||||
#### ```#define CUSTOM_SPI```
|
||||
Enable this to define non-default SPI pins.
|
||||
#### ```#define LORA_SPI_SCK n```, ```LORA_SPI_MISO n```, ```LORA_SPI_MOSI n```
|
||||
Custom SPI pin definitions.
|
||||
|
||||
#
|
||||
**LoRa radio parameters are generally configured in the 'src/fdrs_globals.h' file.** The following values may be set in the gateway configuration file if the user wishes to override the global value:
|
||||
|
||||
The actual allowed values may vary by chip. Check the datasheet and/or RadioLib documentation.
|
||||
#
|
||||
#### ```#define LORA_FREQUENCY n```
|
||||
LoRa frequency in MHz. Allowed values range from 137.0 MHz to 1020.0 MHz.
|
||||
#### ```#define LORA_SF n```
|
||||
LoRa spreading factor. Allowed values range from 6 to 12.
|
||||
#### ```#define LORA_BANDWIDTH n```
|
||||
LoRa bandwidth in kHz. Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
|
||||
#### ```#define LORA_CR n```
|
||||
LoRa coding rate denominator. Allowed values range from 5 to 8.
|
||||
#### ```#define LORA_SYNCWORD n```
|
||||
LoRa sync word. Can be used to distinguish different networks. Note that 0x34 is reserved for LoRaWAN.
|
||||
#### ```#define LORA_INTERVAL n```
|
||||
Interval between LoRa buffer releases. Must be longer than transmission time-on-air.
|
||||
|
||||
## WiFi and MQTT Configuration
|
||||
WiFi and MQTT parameters are generally configured in the 'src/fdrs_globals.h' file. The following values may be set in the gateway configuration file if the user wishes to override the global value:
|
||||
#### ```#define WIFI_SSID "cccc"``` and ``` WIFI_PASS "cccc" ```
|
||||
WiFi credentials
|
||||
#### ```#define MQTT_ADDR "n.n.n.n"``` or ```MQTT_ADDR "cccc"```
|
||||
The address of the MQTT server, either the IP address or domain name.
|
||||
#### ```#define MQTT_PORT n ```
|
||||
The port of the MQTT server.
|
||||
#### ```#define MQTT_AUTH ```
|
||||
Enable this if using MQTT authentication
|
||||
#### ```#define MQTT_USER "cccc"``` and ```MQTT_PASS "cccc"```
|
||||
|
||||
#
|
||||
### SSD1306 OLED Display
|
||||
Built on the [ThingPulse OLED SSD1306 Library](https://github.com/ThingPulse/esp8266-oled-ssd1306)
|
||||
#### ```#define OLED_HEADER "cccc"```
|
||||
The message to be displayed at the top of the screen.
|
||||
#### ```#define OLED_SDA n``` and ```OLED_SCL n```
|
||||
OLED I²C pins.
|
||||
#### ```#define OLED_RST n```
|
||||
OLED reset pin. Use '-1' if not present or known.
|
||||
#
|
||||
### Miscellaneous
|
||||
#### ```#define FDRS_DEBUG```
|
||||
Enables debugging messages to be sent over the serial port and OLED display.
|
||||
#### ```#define RXD2 (pin)``` and ```TXD2 (pin)```
|
||||
Configures a second, data-only UART interface on ESP32. The ESP8266 serial interface is not configurable, and thus these options don't apply.
|
||||
|
||||
#### ```#define USE_LR```
|
||||
Enables ESP-NOW Long-Range mode. Requires ESP32.
|
||||
## Neighbors
|
||||
*To-do: Describe neighbors and how to use them to make repeaters.*
|
||||
|
||||
## User-Defined Functions
|
||||
This feature allows the user to send data from the gateway itself. For example: the battery level or ambient temperature at the gateway.
|
||||
|
||||
Calling ```scheduleFDRS(function, interval);``` after initializing FDRS will schedule ```function()``` to be called every ```interval``` milliseconds.
|
||||
|
||||
Within this function, the user may utilize the same ```loadFDRS()``` and ```sendFDRS()``` commands used by sensors. After the data is sent, it triggers ```INTERNAL_ACT``` where it can be routed to the front-end.
|
||||
|
||||
#### ```loadFDRS(float data, uint8_t type, uint16_t id);```
|
||||
Loads some data into the current packet. 'data' is a float, 'type' is the data type, and 'id' is the DataReading id.
|
||||
#### ```sendFDRS();```
|
||||
Sends the current packet using actions defined by ```INTERNAL_ACT```. Does not return any value.
|
||||
|
||||
**Example:**
|
||||
``` cpp
|
||||
#define GTWY_READING_ID 42
|
||||
#define INTERVAL_SECONDS 60
|
||||
|
||||
#include "fdrs_gateway_config.h"
|
||||
#include <fdrs_gateway.h>
|
||||
#include <your_bms.h>
|
||||
|
||||
void sendReading() {
|
||||
float v = bms.readVoltage();
|
||||
loadFDRS(v, VOLTAGE_T, GTWY_READING_ID);
|
||||
sendFDRS();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
beginFDRS();
|
||||
scheduleFDRS(sendReading, INTERVAL_SECONDS * 1000);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
loopFDRS();
|
||||
}
|
||||
```
|
||||
|
||||
#
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
166
IOT/receiver LoRa/lib/Farm-Data-Relay-System/extras/Node.md
Normal file
@ -0,0 +1,166 @@
|
||||
# FDRS Node
|
||||
A node is a device that sends and receives data from a nearby gateway. A node can be a **sensor**, **controller**, ***or both***.
|
||||
## Addresses
|
||||
#### ```#define READING_ID n```
|
||||
The unique ID that the node will use when sending sensor values. Can be any integer 0 - 65535. Nodes are not necessarily tied to this parameter. They can be subscribed to up to 256 different IDs or send using several different IDs.
|
||||
#### ```#define GTWY_MAC 0xnn```
|
||||
The ```UNIT_MAC``` of the gateway that this device will be paired with.
|
||||
|
||||
## Usage
|
||||
#### ```beginFDRS();```
|
||||
Initializes FDRS, powers up the sensor array, and begins ESP-NOW and/or LoRa.
|
||||
#### ```uint32_t pingFDRS(timeout);```
|
||||
Sends a ping request to the device's paired gateway with a timeout in ms. Returns the ping time in ms as well as displaying it on the debugging console.
|
||||
|
||||
## Sensor API
|
||||
#### ```loadFDRS(float data, uint8_t type, uint16_t id);```
|
||||
Loads some data into the current packet. 'data' is a float, 'type' is the data type (see below), and 'id' is the DataReading id.
|
||||
#### ```loadFDRS((float data, uint8_t type);```
|
||||
Same as above, but the 'id' is preset to the node's ```READING_ID```.
|
||||
#### ```bool sendFDRS();```
|
||||
Sends the current packet using ESP-NOW and/or LoRa. Returns true if packet is confirmed to have been recieved successfully by the gateway.
|
||||
#### ```sleepFDRS(seconds)```
|
||||
Time to sleep in seconds. If ```DEEP_SLEEP``` is enabled, the device will enter sleep. Otherwise it will use a simple ```delay()```.
|
||||
|
||||
## Controller API
|
||||
#### ```addFDRS(void callback);```
|
||||
Initializes controller functionality by selecting the function to be called when incoming commands are recieved. If using LoRa, the controller will automatically recieve any packets sent with broadcastLoRa(), provided they were sent by the paired gateway. ESP-NOW requires the device to register with its gateway before it will recieve incoming commands. This is done automatically, and the ESP-NOW node will continue recieving data until the paired gateway is reset. A maximum of 16 ESP-NOW controllers can recieve data from a single gateway. There is no limit to how many LoRa controllers can listen to the same gateway.
|
||||
#### ```subscribeFDRS(uint16_t sub_id);```
|
||||
Sets the device to listen for a specific DataReading id. When a DataReading with id ```sub_id``` is received, the callback function will be called and given the full DataReading as a parameter.
|
||||
#### ```unsubscribeFDRS(uint16_t sub_id);```
|
||||
Removes ```sub_id``` from subscription list.
|
||||
#### ```loopFDRS();```
|
||||
Always add this to ```loop()``` to handle the controller's listening capabilities.
|
||||
|
||||
## Basic Examples:
|
||||
### Sensor
|
||||
Sensors load a packet with data, then send the packet to the gateway that they are addressed to.
|
||||
``` cpp
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
void setup() {
|
||||
beginFDRS(); // Start the system
|
||||
pingFDRS(2000); // Send ping and wait 2000ms for response
|
||||
}
|
||||
void loop() {
|
||||
loadFDRS(21.0, TEMP_T); // Load a temperature of 21.0 into the queued packet
|
||||
sendFDRS(); // Send the queued packet
|
||||
sleepFDRS(60); // Sleep for 60 seconds
|
||||
}
|
||||
```
|
||||
|
||||
### Controller
|
||||
Controllers register with the gateway they are addressed to, then receive data from it.
|
||||
|
||||
``` cpp
|
||||
#include "fdrs_node_config.h"
|
||||
#include <fdrs_node.h>
|
||||
|
||||
void fdrs_recv_cb(DataReading theData) {
|
||||
DBG("ID: " + String(theData.id));
|
||||
DBG("Type: " + String(theData.t));
|
||||
DBG("Data: " + String(theData.d));
|
||||
}
|
||||
|
||||
void setup() {
|
||||
beginFDRS(); // Start the system
|
||||
addFDRS(fdrs_recv_cb); // Call fdrs_recv_cb() when data arrives.
|
||||
subscribeFDRS(READING_ID); // Subscribe to DataReadings with ID matching READING_ID
|
||||
}
|
||||
void loop() {
|
||||
loopFDRS(); // Listen for data
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
#### ```#define USE_ESPNOW```
|
||||
Enables/disables ESP-NOW.
|
||||
#### ```#define USE_LORA```
|
||||
Enables/disables LoRa.
|
||||
#### ```#define LORA_ACK```
|
||||
Enables LoRa packet acknowledgement. The device will use CRC to ensure that the data arrived at its destination correctly. If disabled, ```sendFDRS()``` will always return true when sending LoRa packets.
|
||||
|
||||
Thanks to [aviateur17](https://github.com/aviateur17) for this feature!
|
||||
#### ```#define FDRS_DEBUG```
|
||||
This definition enables debug messages to be sent over the serial port. If disabled, no serial debug interface will be initialized.
|
||||
#### ```#define DEEP_SLEEP```
|
||||
If enabled, device will enter deep-sleep when the sleepFDRS() command is used. If using ESP8266, be sure that you connect the WAKE pin (GPIO 16) to RST or your device will not wake up.
|
||||
#### ```#define POWER_CTRL n```
|
||||
If defined, power control will bring a GPIO pin high when FDRS is initialized. This is useful for powering sensors while running on battery.
|
||||
#
|
||||
## LoRa Configuration
|
||||
#### ```#define RADIOLIB_MODULE cccc```
|
||||
The name of the RadioLib module being used. Tested modules: SX1276, SX1278, SX1262.
|
||||
#### ```#define LORA_SS n```
|
||||
LoRa chip select pin.
|
||||
#### ```#define LORA_RST n```
|
||||
LoRa reset pin.
|
||||
#### ```#define LORA_DIO n```
|
||||
LoRa DIO pin. This refers to DIO1 on SX127x chips and DIO1 on SX126x chips.
|
||||
#### ```#define LORA_BUSY n```
|
||||
For SX126x chips: LoRa BUSY pin. For SX127x: DIO1 pin, or "RADIOLIB_NC" to leave it blank.
|
||||
#### ```#define LORA_TXPWR n```
|
||||
LoRa TX power in dBm.
|
||||
#### ```#define USE_SX126X```
|
||||
Enable this if using the SX126x series of LoRa chips.
|
||||
#
|
||||
### SSD1306 OLED Display
|
||||
Built on the [ThingPulse OLED SSD1306 Library](https://github.com/ThingPulse/esp8266-oled-ssd1306)
|
||||
##### ```#define OLED_HEADER "cccc"```
|
||||
The message to be displayed at the top of the screen.
|
||||
#### ```#define OLED_SDA n``` and ```OLED_SCL n```
|
||||
OLED I²C pins.
|
||||
#### ```#define OLED_RST n```
|
||||
OLED reset pin. Use '-1' if not present or known.
|
||||
#
|
||||
## Callback Function
|
||||
The callback function is executed when data arrives with an ID that the controller is subscribed to. Inside of this function, the user has access to the incoming DataReading. If multiple readings are recieved, the function will be called for each of them. While you should always be brief in interrupt callbacks (ISRs), it's okay to do more in this one.
|
||||
## Type Definitions
|
||||
For the moment, my thought is to reserve the first two bits of the type. I might use them in the future to indicate the data size or type (bool, char, int, float, etc?). This leaves us with 64 possible type definitions. If you have more types to add, please get in touch!
|
||||
```
|
||||
#define STATUS_T 0 // Status
|
||||
#define TEMP_T 1 // Temperature
|
||||
#define TEMP2_T 2 // Temperature #2
|
||||
#define HUMIDITY_T 3 // Relative Humidity
|
||||
#define PRESSURE_T 4 // Atmospheric Pressure
|
||||
#define LIGHT_T 5 // Light (lux)
|
||||
#define SOIL_T 6 // Soil Moisture
|
||||
#define SOIL2_T 7 // Soil Moisture #2
|
||||
#define SOILR_T 8 // Soil Resistance
|
||||
#define SOILR2_T 9 // Soil Resistance #2
|
||||
#define OXYGEN_T 10 // Oxygen
|
||||
#define CO2_T 11 // Carbon Dioxide
|
||||
#define WINDSPD_T 12 // Wind Speed
|
||||
#define WINDHDG_T 13 // Wind Direction
|
||||
#define RAINFALL_T 14 // Rainfall
|
||||
#define MOTION_T 15 // Motion
|
||||
#define VOLTAGE_T 16 // Voltage
|
||||
#define VOLTAGE2_T 17 // Voltage #2
|
||||
#define CURRENT_T 18 // Current
|
||||
#define CURRENT2_T 19 // Current #2
|
||||
#define IT_T 20 // Iterations
|
||||
#define LATITUDE_T 21 // GPS Latitude
|
||||
#define LONGITUDE_T 22 // GPS Longitude
|
||||
#define ALTITUDE_T 23 // GPS Altitude
|
||||
#define HDOP_T 24 // GPS HDOP
|
||||
#define LEVEL_T 25 // Fluid Level
|
||||
#define UV_T 26 // UV
|
||||
#define PM1_T 27 // 1 Particles
|
||||
#define PM2_5_T 28 // 2.5 Particles
|
||||
#define PM10_T 29 // 10 Particles
|
||||
#define POWER_T 30 // Power
|
||||
#define POWER2_T 31 // Power #2
|
||||
#define ENERGY_T 32 // Energy
|
||||
#define ENERGY2_T 33 // Energy #2
|
||||
```
|
||||
## Under the Hood
|
||||
```
|
||||
typedef struct __attribute__((packed)) DataReading {
|
||||
float d;
|
||||
uint16_t id;
|
||||
uint8_t t;
|
||||
} DataReading;
|
||||
```
|
||||
Each node in the system sends its data inside of a structure called a DataReading. Its global sensor address is represented by an integer 'id', and each type of reading is represented by a single byte 't'. If a sensor or gateway needs to send multiple DataReadings, then they are sent in an array. A single DataReading.id may have readings of multiple types ('t') associated with it.
|
After Width: | Height: | Size: 478 KiB |
After Width: | Height: | Size: 459 KiB |
After Width: | Height: | Size: 18 KiB |
87
IOT/receiver LoRa/lib/Farm-Data-Relay-System/keywords.txt
Normal file
@ -0,0 +1,87 @@
|
||||
#######################################################################
|
||||
# Syntax Coloring Map For Farm-Data-Relay-System
|
||||
#######################################################################
|
||||
#
|
||||
# Format for each line:
|
||||
# KEYWORD KEYWORD_TOKENTYPE REFERENCE_LINK RSYNTAXTEXTAREA_TOKENTYPE
|
||||
# (only the first two are used)
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Datatypes and Class names (KEYWORD1)
|
||||
#######################################################################
|
||||
DataReading KEYWORD1
|
||||
SystemPacket KEYWORD1
|
||||
FDRSBase KEYWORD1
|
||||
FDRSLoRa KEYWORD1
|
||||
FDRS_EspNow KEYWORD1
|
||||
|
||||
#######################################################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################################################
|
||||
FDRS_DBG KEYWORD2
|
||||
begin KEYWORD2
|
||||
beginFDRS KEYWORD2
|
||||
begin_espnow KEYWORD2
|
||||
begin_FS KEYWORD2
|
||||
begin_lora KEYWORD2
|
||||
begin_SD KEYWORD2
|
||||
bufferESPNOW KEYWORD2
|
||||
bufferLoRa KEYWORD2
|
||||
bufferMQTT KEYWORD2
|
||||
bufferSerial KEYWORD2
|
||||
crc16_update KEYWORD2
|
||||
getLoRa KEYWORD2
|
||||
getSerial KEYWORD2
|
||||
handleCommands KEYWORD2
|
||||
load KEYWORD2
|
||||
loadFDRS KEYWORD2
|
||||
OnDataSent KEYWORD2
|
||||
OnDataRecv KEYWORD2
|
||||
pingFDRS KEYWORD2
|
||||
printLoraPacket KEYWORD2
|
||||
reconnect KEYWORD2
|
||||
releaseLogBuffer KEYWORD2
|
||||
releaseMQTT KEYWORD2
|
||||
sendESPNOW KEYWORD2
|
||||
sendFDRS KEYWORD2
|
||||
sendLog KEYWORD2
|
||||
sendMQTT KEYWORD2
|
||||
sendSerial KEYWORD2
|
||||
sleep KEYWORD2
|
||||
sleepFDRS KEYWORD2
|
||||
transmitLoRa KEYWORD2
|
||||
|
||||
#######################################################################
|
||||
# structures (KEYWORD3)
|
||||
#######################################################################
|
||||
|
||||
|
||||
#######################################################################
|
||||
# Literals (LITERAL1)
|
||||
#######################################################################
|
||||
DEBUG_CONFIG LITERAL1
|
||||
DEEP_SLEEP LITERAL1
|
||||
FDRS_BAND LITERAL1
|
||||
FDRS_DEBUG LITERAL1
|
||||
FDRS_GLOBALS LITERAL1
|
||||
FDRS_SF LITERAL1
|
||||
GTWY_MAC LITERAL1
|
||||
GTWY_MAC LITERAL1
|
||||
LORA_DIO0 LITERAL1
|
||||
LORA_RST LITERAL1
|
||||
LORA_SS LITERAL1
|
||||
MAC_PREFIX LITERAL1
|
||||
POWER_CTRL LITERAL1
|
||||
READING_ID LITERAL1
|
||||
SPI_MISO LITERAL1
|
||||
SPI_MOSI LITERAL1
|
||||
SPI_SCK LITERAL1
|
||||
UNIT_MAC LITERAL1
|
||||
USE_LORA LITERAL1
|
||||
|
||||
#######################################################################
|
||||
# ? (LITERAL2)
|
||||
#######################################################################
|
@ -0,0 +1,10 @@
|
||||
name=Farm-Data-Relay-System
|
||||
version=2.0.1
|
||||
author=Timm Bogner <timmbogner@gmail.com>
|
||||
maintainer=Timm Bogner <timmbogner@gmail.com>
|
||||
sentence=Farm-Data-Relay-System - a infrastructure and cloud-less network
|
||||
paragraph=FDRS is a highly configurable cloud-agnostic network utilizing LoRa and ESPNow. Easily define nodes as sensors or routers and easily configure the way different protocols are forwarded.
|
||||
category=Communication
|
||||
url=https://github.com/timmbogner/Farm-Data-Relay-System
|
||||
architectures=*
|
||||
depends=ArduinoJson
|
@ -0,0 +1,4 @@
|
||||
set(COMPONENT_ADD_INCLUDEDIRS src)
|
||||
set(COMPONENT_PRIV_REQUIRES arduino-esp32)
|
||||
set(COMPONENT_SRCDIRS src)
|
||||
register_component()
|
@ -0,0 +1,70 @@
|
||||
# Contributing to ThingPulse OLED SSD1306
|
||||
|
||||
:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
|
||||
|
||||
The following is a set of guidelines for contributing to the ThingPulse OLED SSD1306 library on GitHub. These are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request.
|
||||
|
||||
It is appreciated if you raise an issue _before_ you start changing the code, discussing the proposed change; emphasizing that you are proposing to develop the patch yourself, and outlining the strategy for implementation. This type of discussion is what we should be doing on the issues list and it is better to do this before or in parallel to developing the patch rather than having "you should have done it this way" type of feedback on the PR itself.
|
||||
|
||||
### Table Of Contents
|
||||
* [General remarks](#general-remarks)
|
||||
* [Writing Documentation](#writing-documentation)
|
||||
* [Working with Git and GitHub](#working-with-git-and-github)
|
||||
* [General flow](#general-flow)
|
||||
* [Keeping your fork in sync](#keeping-your-fork-in-sync)
|
||||
* [Commit messages](#commit-messages)
|
||||
|
||||
## General remarks
|
||||
We are a friendly and welcoming community and look forward to your contributions. Once your contribution is integrated into this repository we feel responsible for it. Therefore, be prepared for constructive feedback. Before we merge anything we need to ensure that it fits in and is consistent with the rest of code.
|
||||
If you made something really cool but won't spend the time to integrate it into this upstream project please still share it in your fork on GitHub. If you mention it in an issue we'll take a look at it anyway.
|
||||
|
||||
## Writing Documentation
|
||||
ThingPulse maintains documentation for its products at [https://github.com/thingpulse/docs/](https://github.com/thingpulse/docs/). If you contribute features for this project that require altering the respective product guide then we ask you to prepare a pull request with the necessary documentation changes as well.
|
||||
|
||||
## Working with Git and GitHub
|
||||
|
||||
Avoid intermediate merge commits. [Rebase](https://www.atlassian.com/git/tutorials/merging-vs-rebasing) your feature branch onto `master` to pull updates and verify your local changes against them before placing the pull request.
|
||||
|
||||
### General flow
|
||||
1. [Fork](https://help.github.com/articles/fork-a-repo) this repository on GitHub.
|
||||
1. [Create a branch](https://help.github.com/articles/creating-and-deleting-branches-within-your-repository/#creating-a-branch) in your fork on GitHub **based on the `master` branch**.
|
||||
1. Clone the fork on your machine with `git clone https://github.com/<your-account>/<esp8266-oled-ssd1306>.git`
|
||||
1. `cd <weather-station-fork>` then run `git remote add upstream https://github.com/ThingPulse/esp8266-oled-ssd1306`
|
||||
1. `git checkout <branch-name>`
|
||||
1. Make changes to the code base and commit them using e.g. `git commit -a -m 'Look ma, I did it'`
|
||||
1. When you're done bring your fork up-to-date with the upstream repo ([see below](#keeping-your-fork-in-sync)). Then rebase your branch on `master` running `git rebase master`.
|
||||
1. `git push`
|
||||
1. [Create a pull request](https://help.github.com/articles/creating-a-pull-request/) (PR) on GitHub.
|
||||
|
||||
This is just one way of doing things. If you're proficient in Git matters you're free to choose your own. If you want to read more then the [GitHub chapter in the Git book](http://git-scm.com/book/en/v2/GitHub-Contributing-to-a-Project#The-GitHub-Flow) is a way to start. [GitHub's own documentation](https://help.github.com/categories/collaborating/) contains a wealth of information as well.
|
||||
|
||||
### Keeping your fork in sync
|
||||
You need to sync your fork with the upstream repository from time to time, latest before you rebase (see flow above).
|
||||
|
||||
1. `git fetch upstream`
|
||||
1. `git checkout master`
|
||||
1. `git merge upstream/master`
|
||||
|
||||
### Commit messages
|
||||
|
||||
From: [http://git-scm.com/book/ch5-2.html](http://git-scm.com/book/ch5-2.html)
|
||||
<pre>
|
||||
Short (50 chars or less) summary of changes
|
||||
|
||||
More detailed explanatory text, if necessary. Wrap it to about 72
|
||||
characters or so. In some contexts, the first line is treated as the
|
||||
subject of an email and the rest of the text as the body. The blank
|
||||
line separating the summary from the body is critical (unless you omit
|
||||
the body entirely); tools like rebase can get confused if you run the
|
||||
two together.
|
||||
|
||||
Further paragraphs come after blank lines.
|
||||
|
||||
- Bullet points are okay, too
|
||||
- Typically a hyphen or asterisk is used for the bullet, preceded by a
|
||||
single space, with blank lines in between, but conventions vary here
|
||||
</pre>
|
||||
|
||||
Don't forget to [reference affected issues](https://help.github.com/articles/closing-issues-via-commit-messages/) in the commit message to have them closed automatically on GitHub.
|
||||
|
||||
[Amend](https://help.github.com/articles/changing-a-commit-message/) your commit messages if necessary to make sure what the world sees on GitHub is as expressive and meaningful as possible.
|
@ -0,0 +1,441 @@
|
||||
[](https://github.com/ThingPulse/esp8266-oled-ssd1306/actions)
|
||||
|
||||
# ThingPulse OLED SSD1306 (ESP8266/ESP32/Mbed-OS)
|
||||
|
||||
This is a driver for SSD1306 128x64, 128x32, 64x48 and 64x32 OLED displays running on the Arduino/ESP8266 & ESP32 and mbed-os platforms.
|
||||
Can be used with either the I2C or SPI version of the display.
|
||||
|
||||
This library drives the OLED display included in the [ThingPulse IoT starter kit](https://thingpulse.com/product/esp8266-iot-electronics-starter-kit-weatherstation-planespotter-worldclock/) aka classic kit aka weather station kit.
|
||||
|
||||
[](https://thingpulse.com/product/esp8266-iot-electronics-starter-kit-weatherstation-planespotter-worldclock/)
|
||||
|
||||
You can either download this library as a zip file and unpack it to your Arduino/libraries folder or find it in the Arduino library manager under "ESP8266 and ESP32 Oled Driver for SSD1306 display". For mbed-os a copy of the files are available as an mbed-os library.
|
||||
|
||||
It is also available as a [PlatformIO library](https://platformio.org/lib/show/2978/ESP8266%20and%20ESP32%20OLED%20driver%20for%20SSD1306%20displays/examples). Just execute the following command:
|
||||
```
|
||||
platformio lib install 2978
|
||||
```
|
||||
|
||||
## Service level promise
|
||||
|
||||
<table><tr><td><img src="https://thingpulse.com/assets/ThingPulse-open-source-prime.png" width="150">
|
||||
</td><td>This is a ThingPulse <em>prime</em> project. See our <a href="https://thingpulse.com/about/open-source-commitment/">open-source commitment declaration</a> for what this means.</td></tr></table>
|
||||
|
||||
## Credits
|
||||
|
||||
This library has initially been written by [Daniel Eichhorn](https://github.com/squix78). Many thanks go to [Fabrice Weinberg](https://github.com/FWeinb) for optimizing and refactoring many aspects of the library. Also many thanks to the many committers who helped to add new features and who fixed many bugs. Mbed-OS support and other improvements were contributed by [Helmut Tschemernjak](https://github.com/helmut64).
|
||||
|
||||
The init sequence for the SSD1306 was inspired by Adafruit's library for the same display.
|
||||
|
||||
## mbed-os
|
||||
This library has been adopted to support the ARM mbed-os environment. A copy of this library is available in mbed-os under the name OLED_SSD1306 by Helmut Tschemernjak. An alternate installation option is to copy the following files into your mbed-os project: OLEDDisplay.cpp OLEDDisplay.h OLEDDisplayFonts.h OLEDDisplayUi.cpp OLEDDisplayUi.h SSD1306I2C.h
|
||||
|
||||
## Usage
|
||||
|
||||
Check out the examples folder for a few comprehensive demonstrations how to use the library. Also check out the [ESP8266 Weather Station](https://github.com/ThingPulse/esp8266-weather-station) library which uses the OLED library to display beautiful weather information.
|
||||
|
||||
## Upgrade
|
||||
|
||||
The API changed a lot with the 3.0 release. If you were using this library with older versions please have a look at the [Upgrade Guide](UPGRADE-3.0.md).
|
||||
|
||||
Going from 3.x version to 4.0 a lot of internals changed and compatibility for more displays was added. Please read the [Upgrade Guide](UPGRADE-4.0.md).
|
||||
|
||||
## Features
|
||||
|
||||
* Draw pixels at given coordinates
|
||||
* Draw lines from given coordinates to given coordinates
|
||||
* Draw or fill a rectangle with given dimensions
|
||||
* Draw Text at given coordinates:
|
||||
* Define Alignment: Left, Right and Center
|
||||
* Set the Fontface you want to use (see section Fonts below)
|
||||
* Limit the width of the text by an amount of pixels. Before this widths will be reached, the renderer will wrap the text to a new line if possible
|
||||
* Display content in automatically side scrolling carousel
|
||||
* Define transition cycles
|
||||
* Define how long one frame will be displayed
|
||||
* Draw the different frames in callback methods
|
||||
* One indicator per frame will be automatically displayed. The active frame will be displayed from inactive once
|
||||
|
||||
## Fonts
|
||||
|
||||
Fonts are defined in a proprietary but open format. You can create new font files by choosing from a given list
|
||||
of open sourced Fonts from this web app: http://oleddisplay.squix.ch
|
||||
Choose the font family, style and size, check the preview image and if you like what you see click the "Create" button. This will create the font array in a text area form where you can copy and paste it into a new or existing header file.
|
||||
|
||||
|
||||

|
||||
|
||||
## Hardware Abstraction
|
||||
|
||||
The library supports different protocols to access the OLED display. Currently there is support for I2C using the built in Wire.h library, I2C by using the much faster [BRZO I2C library](https://github.com/pasko-zh/brzo_i2c) written in assembler and it also supports displays which come with the SPI interface.
|
||||
|
||||
### I2C with Wire.h
|
||||
|
||||
```C++
|
||||
#include <Wire.h>
|
||||
#include "SSD1306Wire.h"
|
||||
|
||||
// for 128x64 displays:
|
||||
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
// for 128x32 displays:
|
||||
// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32); // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64)
|
||||
// for using 2nd Hardware I2C (if available)
|
||||
// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_TWO); //default value is I2C_ONE if not mentioned
|
||||
// By default SD1306Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value
|
||||
// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz
|
||||
// SSD1306Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency
|
||||
```
|
||||
|
||||
for a SH1106:
|
||||
```C++
|
||||
#include <Wire.h>
|
||||
#include "SH1106Wire.h"
|
||||
|
||||
SH1106Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
// By default SH1106Wire set I2C frequency to 700000, you can use set either another frequency or skip setting the frequency by providing -1 value
|
||||
// SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, 400000); //set I2C frequency to 400kHz
|
||||
// SH1106Wire(0x3c, SDA, SCL, GEOMETRY_128_64, I2C_ONE, -1); //skip setting the I2C bus frequency
|
||||
```
|
||||
|
||||
### I2C with brzo_i2c
|
||||
|
||||
```C++
|
||||
#include <brzo_i2c.h>
|
||||
#include "SSD1306Brzo.h"
|
||||
|
||||
SSD1306Brzo display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
```
|
||||
or for the SH1106:
|
||||
```C++
|
||||
#include <brzo_i2c.h>
|
||||
#include "SH1106Brzo.h"
|
||||
|
||||
SH1106Brzo display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
```
|
||||
|
||||
### SPI
|
||||
|
||||
```C++
|
||||
#include <SPI.h>
|
||||
#include "SSD1306Spi.h"
|
||||
|
||||
SSD1306Spi display(D0, D2, D8); // RES, DC, CS
|
||||
```
|
||||
or for the SH1106:
|
||||
```C++
|
||||
#include <SPI.h>
|
||||
#include "SH1106Spi.h"
|
||||
|
||||
SH1106Spi display(D0, D2); // RES, DC
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Display Control
|
||||
|
||||
```C++
|
||||
// Initialize the display
|
||||
void init();
|
||||
|
||||
// Free the memory used by the display
|
||||
void end();
|
||||
|
||||
// Cycle through the initialization
|
||||
void resetDisplay(void);
|
||||
|
||||
// Connect again to the display through I2C
|
||||
void reconnect(void);
|
||||
|
||||
// Turn the display on
|
||||
void displayOn(void);
|
||||
|
||||
// Turn the display offs
|
||||
void displayOff(void);
|
||||
|
||||
// Clear the local pixel buffer
|
||||
void clear(void);
|
||||
|
||||
// Write the buffer to the display memory
|
||||
void display(void);
|
||||
|
||||
// Inverted display mode
|
||||
void invertDisplay(void);
|
||||
|
||||
// Normal display mode
|
||||
void normalDisplay(void);
|
||||
|
||||
// Set display contrast
|
||||
// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0
|
||||
// normal brightness & contrast: contrast = 100
|
||||
void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);
|
||||
|
||||
// Convenience method to access
|
||||
void setBrightness(uint8_t);
|
||||
|
||||
// Turn the display upside down
|
||||
void flipScreenVertically();
|
||||
|
||||
// Draw the screen mirrored
|
||||
void mirrorScreen();
|
||||
```
|
||||
|
||||
## Pixel drawing
|
||||
|
||||
```C++
|
||||
|
||||
/* Drawing functions */
|
||||
// Sets the color of all pixel operations
|
||||
// color : BLACK, WHITE, INVERSE
|
||||
void setColor(OLEDDISPLAY_COLOR color);
|
||||
|
||||
// Draw a pixel at given position
|
||||
void setPixel(int16_t x, int16_t y);
|
||||
|
||||
// Draw a line from position 0 to position 1
|
||||
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1);
|
||||
|
||||
// Draw the border of a rectangle at the given location
|
||||
void drawRect(int16_t x, int16_t y, int16_t width, int16_t height);
|
||||
|
||||
// Fill the rectangle
|
||||
void fillRect(int16_t x, int16_t y, int16_t width, int16_t height);
|
||||
|
||||
// Draw the border of a circle
|
||||
void drawCircle(int16_t x, int16_t y, int16_t radius);
|
||||
|
||||
// Fill circle
|
||||
void fillCircle(int16_t x, int16_t y, int16_t radius);
|
||||
|
||||
// Draw an empty triangle i.e. only the outline
|
||||
void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
|
||||
|
||||
// Draw a solid triangle i.e. filled
|
||||
void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
|
||||
|
||||
// Draw a line horizontally
|
||||
void drawHorizontalLine(int16_t x, int16_t y, int16_t length);
|
||||
|
||||
// Draw a lin vertically
|
||||
void drawVerticalLine(int16_t x, int16_t y, int16_t length);
|
||||
|
||||
// Draws a rounded progress bar with the outer dimensions given by width and height. Progress is
|
||||
// a unsigned byte value between 0 and 100
|
||||
void drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t progress);
|
||||
|
||||
// Draw a bitmap in the internal image format
|
||||
void drawFastImage(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *image);
|
||||
|
||||
// Draw a XBM
|
||||
void drawXbm(int16_t x, int16_t y, int16_t width, int16_t height, const uint8_t *xbm);
|
||||
```
|
||||
|
||||
## Text operations
|
||||
|
||||
``` C++
|
||||
// Draws a string at the given location, returns how many chars have been written
|
||||
uint16_t drawString(int16_t x, int16_t y, const String &text);
|
||||
|
||||
// Draws a String with a maximum width at the given location.
|
||||
// If the given String is wider than the specified width
|
||||
// The text will be wrapped to the next line at a space or dash
|
||||
// returns 0 if everything fits on the screen or the numbers of characters in the
|
||||
// first line if not
|
||||
uint16_t drawStringMaxWidth(int16_t x, int16_t y, uint16_t maxLineWidth, const String &text);
|
||||
|
||||
// Returns the width of the const char* with the current
|
||||
// font settings
|
||||
uint16_t getStringWidth(const char* text, uint16_t length, bool utf8 = false);
|
||||
|
||||
// Convencience method for the const char version
|
||||
uint16_t getStringWidth(const String &text);
|
||||
|
||||
// Specifies relative to which anchor point
|
||||
// the text is rendered. Available constants:
|
||||
// TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER_BOTH
|
||||
void setTextAlignment(OLEDDISPLAY_TEXT_ALIGNMENT textAlignment);
|
||||
|
||||
// Sets the current font. Available default fonts
|
||||
// ArialMT_Plain_10, ArialMT_Plain_16, ArialMT_Plain_24
|
||||
// Or create one with the font tool at http://oleddisplay.squix.ch
|
||||
void setFont(const uint8_t* fontData);
|
||||
```
|
||||
|
||||
## Ui Library (OLEDDisplayUi)
|
||||
|
||||
The Ui Library is used to provide a basic set of user interface elements called `Frames` and `Overlays`. A `Frame` is used to provide
|
||||
information to the user. The default behaviour is to display a `Frame` for a defined time and than move to the next `Frame`. The library also
|
||||
provides an `Indicator` element that will be updated accordingly. An `Overlay` on the other hand is a piece of information (e.g. a clock) that
|
||||
is always displayed at the same position.
|
||||
|
||||
```C++
|
||||
/**
|
||||
* Initialise the display
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Configure the internal used target FPS
|
||||
*/
|
||||
void setTargetFPS(uint8_t fps);
|
||||
|
||||
/**
|
||||
* Enable automatic transition to next frame after the some time can be configured with
|
||||
* `setTimePerFrame` and `setTimePerTransition`.
|
||||
*/
|
||||
void enableAutoTransition();
|
||||
|
||||
/**
|
||||
* Disable automatic transition to next frame.
|
||||
*/
|
||||
void disableAutoTransition();
|
||||
|
||||
/**
|
||||
* Set the direction if the automatic transitioning
|
||||
*/
|
||||
void setAutoTransitionForwards();
|
||||
void setAutoTransitionBackwards();
|
||||
|
||||
/**
|
||||
* Set the approx. time a frame is displayed
|
||||
*/
|
||||
void setTimePerFrame(uint16_t time);
|
||||
|
||||
/**
|
||||
* Set the approx. time a transition will take
|
||||
*/
|
||||
void setTimePerTransition(uint16_t time);
|
||||
|
||||
/**
|
||||
* Draw the indicator.
|
||||
* This is the default state for all frames if
|
||||
* the indicator was hidden on the previous frame
|
||||
* it will be slided in.
|
||||
*/
|
||||
void enableIndicator();
|
||||
|
||||
/**
|
||||
* Don't draw the indicator.
|
||||
* This will slide out the indicator
|
||||
* when transitioning to the next frame.
|
||||
*/
|
||||
void disableIndicator();
|
||||
|
||||
/**
|
||||
* Enable drawing of all indicators.
|
||||
*/
|
||||
void enableAllIndicators();
|
||||
|
||||
/**
|
||||
* Disable drawing of all indicators.
|
||||
*/
|
||||
void disableAllIndicators();
|
||||
|
||||
/**
|
||||
* Set the position of the indicator bar.
|
||||
*/
|
||||
void setIndicatorPosition(IndicatorPosition pos);
|
||||
|
||||
/**
|
||||
* Set the direction of the indicator bar. Defining the order of frames ASCENDING / DESCENDING
|
||||
*/
|
||||
void setIndicatorDirection(IndicatorDirection dir);
|
||||
|
||||
/**
|
||||
* Set the symbol to indicate an active frame in the indicator bar.
|
||||
*/
|
||||
void setActiveSymbol(const uint8_t* symbol);
|
||||
|
||||
/**
|
||||
* Set the symbol to indicate an inactive frame in the indicator bar.
|
||||
*/
|
||||
void setInactiveSymbol(const uint8_t* symbol);
|
||||
|
||||
/**
|
||||
* Configure what animation is used to transition from one frame to another
|
||||
*/
|
||||
void setFrameAnimation(AnimationDirection dir);
|
||||
|
||||
/**
|
||||
* Add frame drawing functions
|
||||
*/
|
||||
void setFrames(FrameCallback* frameFunctions, uint8_t frameCount);
|
||||
|
||||
/**
|
||||
* Add overlays drawing functions that are draw independent of the Frames
|
||||
*/
|
||||
void setOverlays(OverlayCallback* overlayFunctions, uint8_t overlayCount);
|
||||
|
||||
/**
|
||||
* Set the function that will draw each step
|
||||
* in the loading animation
|
||||
*/
|
||||
void setLoadingDrawFunction(LoadingDrawFunction loadingDrawFunction);
|
||||
|
||||
/**
|
||||
* Run the loading process
|
||||
*/
|
||||
void runLoadingProcess(LoadingStage* stages, uint8_t stagesCount);
|
||||
|
||||
// Manual control
|
||||
void nextFrame();
|
||||
void previousFrame();
|
||||
|
||||
/**
|
||||
* Switch without transition to frame `frame`.
|
||||
*/
|
||||
void switchToFrame(uint8_t frame);
|
||||
|
||||
/**
|
||||
* Transition to frame `frame`. When the `frame` number is bigger than the current
|
||||
* frame the forward animation will be used, otherwise the backwards animation is used.
|
||||
*/
|
||||
void transitionToFrame(uint8_t frame);
|
||||
|
||||
// State Info
|
||||
OLEDDisplayUiState* getUiState();
|
||||
|
||||
// This needs to be called in the main loop
|
||||
// the returned value is the remaining time (in ms)
|
||||
// you have to draw after drawing to keep the frame budget.
|
||||
int8_t update();
|
||||
```
|
||||
|
||||
## Example: SSD1306Demo
|
||||
|
||||
### Frame 1
|
||||

|
||||
|
||||
This frame shows three things:
|
||||
* How to draw an XMB image
|
||||
* How to draw static text which is not moved by the frame transition
|
||||
* The active/inactive frame indicators
|
||||
|
||||
### Frame 2
|
||||

|
||||
|
||||
Currently there are one fontface with three sizes included in the library: Arial 10, 16 and 24. Once the converter is published you will be able to convert any ttf font into the used format.
|
||||
|
||||
### Frame 3
|
||||
|
||||

|
||||
|
||||
This frame demonstrates the text alignment. The coordinates in the frame show relative to which position the texts have been rendered.
|
||||
|
||||
### Frame 4
|
||||
|
||||

|
||||
|
||||
This shows how to use define a maximum width after which the driver automatically wraps a word to the next line. This comes in very handy if you have longer texts to display.
|
||||
|
||||
### SPI version
|
||||
|
||||

|
||||
|
||||
This shows the code working on the SPI version of the display. See demo code for ESP8266 pins used.
|
||||
|
||||
## Selection of projects using this library
|
||||
|
||||
* [QRCode ESP8266](https://github.com/anunpanya/ESP8266_QRcode) (by @anunpanya)
|
||||
* [Scan I2C](https://github.com/hallard/Scan-I2C-WiFi) (by @hallard)
|
||||
* [ThingPulse Weather Station](https://github.com/ThingPulse/esp8266-weather-station)
|
||||
* [Meshtastic](https://www.meshtastic.org/) - an open source GPS communicator mesh radio
|
||||
* Yours?
|
@ -0,0 +1,20 @@
|
||||
# GEOMETRY_64_48
|
||||
|
||||
The 64x48 geometry setting are working with the `Wire.h` and `brzo_i2c` libraries.
|
||||
|
||||
I've tested it successfully with a WEMOS D1 mini Lite and a WEMOS OLED shield
|
||||
|
||||
Initialization code:
|
||||
|
||||
- Wire
|
||||
```
|
||||
#include <Wire.h>
|
||||
#include <SSD1306Wire.h>
|
||||
SSD1306Wire display(0x3c, D2, D1, GEOMETRY_64_48 ); // WEMOS OLED shield
|
||||
```
|
||||
|
||||
- BRZO i2c
|
||||
```
|
||||
#include <SSD1306Brzo.h>
|
||||
SSD1306Brzo display(0x3c, D2, D1, GEOMETRY_64_48 ); // WEMOS OLED Shield
|
||||
```
|
@ -0,0 +1,125 @@
|
||||
# Upgrade from 2.0 to 3.0
|
||||
|
||||
While developing version 3.0 we made some breaking changes to the public
|
||||
API of this library. This document will help you update your code to work with
|
||||
version 3.0
|
||||
|
||||
## Font Definitions
|
||||
|
||||
To get better performance and a smaller font definition format, we change the memory
|
||||
layout of the font definition format. If you are using custom fonts not included in
|
||||
this library we updated the font generator [here](http://oleddisplay.squix.ch/#/home).
|
||||
Please update your fonts to be working with 3.0 by selecting the respective version in the dropdown.
|
||||
|
||||
|
||||
## Architectural Changes
|
||||
|
||||
To become a more versatile library for the SSD1306 chipset we abstracted the
|
||||
hardware connection into subclasses of the base display class now called `OLEDDisplay`.
|
||||
This library is currently shipping with three implementations:
|
||||
|
||||
* `SSD1306Wire` implementing the I2C protocol using the Wire Library.
|
||||
* `SSD1306Brzo` implementing the I2C protocol using the faster [`brzo_i2c`](https://github.com/pasko-zh/brzo_i2c) library.
|
||||
* `SSD1306Spi` implementing the SPI protocol.
|
||||
|
||||
To keep backwards compatiblity with the old API `SSD1306` is an alias of `SSD1306Wire`.
|
||||
If you are not using the UI components you don't have to change anything to keep your code working.
|
||||
|
||||
## Name Changes
|
||||
|
||||
[Naming things is hard](http://martinfowler.com/bliki/TwoHardThings.html), to better reflect our intention with this library
|
||||
we changed the name of the base class to `OLEDDisplay` and the UI library accordingly to `OLEDDisplayUi`.
|
||||
As a consequence the type definitions of all frame and overlay related functions changed.
|
||||
This means that you have to update all your frame drawing callbacks from:
|
||||
|
||||
```c
|
||||
bool frame1(SSD1306 *display, SSD1306UiState* state, int x, int y);
|
||||
```
|
||||
|
||||
too
|
||||
|
||||
```c
|
||||
void frame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y);
|
||||
```
|
||||
|
||||
And your overlay drawing functions from:
|
||||
|
||||
```c
|
||||
bool overlay1(SSD1306 *display, SSD1306UiState* state);
|
||||
```
|
||||
|
||||
too
|
||||
|
||||
```c
|
||||
void overlay1(OLEDDisplay *display, OLEDDisplayUiState* state);
|
||||
```
|
||||
|
||||
## New Features
|
||||
|
||||
### Loading Animation
|
||||
|
||||
While using this library ourself we noticed a pattern emerging. We want to drawing
|
||||
a loading progress while connecting to WiFi and updating weather data etc.
|
||||
|
||||
The simplest thing was to add the function `drawProgressBar(x, y, width, height, progress)`
|
||||
,where `progress` is between `0` and `100`, right to the `OLEDDisplay` class.
|
||||
|
||||
But we didn't stop there. We added a new feature to the `OLEDDisplayUi` called `LoadingStages`.
|
||||
You can define your loading process like this:
|
||||
|
||||
```c++
|
||||
LoadingStage loadingStages[] = {
|
||||
{
|
||||
.process = "Connect to WiFi",
|
||||
.callback = []() {
|
||||
// Connect to WiFi
|
||||
}
|
||||
},
|
||||
{
|
||||
.process = "Get time from NTP",
|
||||
.callback = []() {
|
||||
// Get current time via NTP
|
||||
}
|
||||
}
|
||||
// more steps
|
||||
};
|
||||
|
||||
int LOADING_STAGES_COUNT = sizeof(loadingStages) / sizeof(LoadingStage);
|
||||
```
|
||||
|
||||
After defining your array of `LoadingStages` you can then run the loading process by using
|
||||
`ui.runLoadingProcess(loadingStages, LOADING_STAGES_COUNT)`. This will give you a
|
||||
nice little loading animation you can see in the beginning of [this](https://vimeo.com/168362918)
|
||||
video.
|
||||
|
||||
To further customize this you are free to define your own `LoadingDrawFunction` like this:
|
||||
|
||||
```c
|
||||
void myLoadingDraw(OLEDDisplay *display, LoadingStage* stage, uint8_t progress) {
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
// stage->process contains the text of the current progress e.q. "Connect to WiFi"
|
||||
display->drawString(64, 18, stage->process);
|
||||
// you could just print the current process without the progress bar
|
||||
display->drawString(64, 28, progress);
|
||||
}
|
||||
```
|
||||
|
||||
After defining a function like that, you can pass it to the Ui library by use
|
||||
`ui.setLoadingDrawFunction(myLoadingDraw)`.
|
||||
|
||||
|
||||
### Text Logging
|
||||
|
||||
It is always useful to display some text on the display without worrying to much
|
||||
where it goes and managing it. In 3.0 we made the `OLEDDisplay` class implement
|
||||
[`Print`](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/Print.h)
|
||||
so you can use it like you would use `Serial`. We calls this feature `LogBuffer`
|
||||
and the only thing you have to do is to define how many lines you want to display
|
||||
and how many characters there are on average on each. This is done by calling
|
||||
`setLogBuffer(lines, chars);`. If there is not enough memory the function will
|
||||
return false.
|
||||
|
||||
After that you can draw the `LogBuffer` anywhere you want by calling `drawLogBuffer(x, y)`.
|
||||
(Note: You have to call `display()` to update the screen)
|
||||
We made a [video](https://www.youtube.com/watch?v=8Fiss77A3TE) showing this feature in action.
|
@ -0,0 +1,27 @@
|
||||
# Upgrade from 3.x to 4.0
|
||||
|
||||
There are changes that breaks compatibility with older versions.
|
||||
|
||||
1. You'll have to change data type for all your binary resources such as images and fonts from
|
||||
|
||||
```c
|
||||
const char MySymbol[] PROGMEM = {
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```c
|
||||
const uint8_t MySymbol[] PROGMEM = {
|
||||
```
|
||||
|
||||
1. Arguments of `setContrast` from `char` to `uint8_t`
|
||||
|
||||
```c++
|
||||
void OLEDDisplay::setContrast(char contrast, char precharge, char comdetect);
|
||||
```
|
||||
|
||||
to
|
||||
|
||||
```c++
|
||||
void OLEDDisplay::setContrast(uint8_t contrast, uint8_t precharge, uint8_t comdetect);
|
||||
```
|
@ -0,0 +1,3 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := src
|
||||
COMPONENT_SRCDIRS := src
|
||||
CXXFLAGS += -Wno-ignored-qualifiers
|
@ -0,0 +1,212 @@
|
||||
/**
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
|
||||
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.
|
||||
|
||||
ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
Please support us by buying our products (and not the clones) from
|
||||
https://thingpulse.com
|
||||
|
||||
*/
|
||||
|
||||
// Install https://github.com/PaulStoffregen/Time
|
||||
#include <TimeLib.h>
|
||||
|
||||
// Include the correct display library
|
||||
// For a connection via I2C using Wire include
|
||||
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
|
||||
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
|
||||
// For a connection via I2C using brzo_i2c (must be installed) include
|
||||
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Brzo.h"
|
||||
// #include "SH1106Brzo.h"
|
||||
// For a connection via SPI include
|
||||
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Spi.h"
|
||||
// #include "SH1106SPi.h"
|
||||
|
||||
// Include the UI lib
|
||||
#include "OLEDDisplayUi.h"
|
||||
|
||||
// Include custom images
|
||||
#include "images.h"
|
||||
|
||||
// Use the corresponding display class:
|
||||
|
||||
// Initialize the OLED display using SPI
|
||||
// D5 -> CLK
|
||||
// D7 -> MOSI (DOUT)
|
||||
// D0 -> RES
|
||||
// D2 -> DC
|
||||
// D8 -> CS
|
||||
// SSD1306Spi display(D0, D2, D8);
|
||||
// or
|
||||
// SH1106Spi display(D0, D2);
|
||||
|
||||
// Initialize the OLED display using brzo_i2c
|
||||
// D3 -> SDA
|
||||
// D5 -> SCL
|
||||
// SSD1306Brzo display(0x3c, D3, D5);
|
||||
// or
|
||||
// SH1106Brzo display(0x3c, D3, D5);
|
||||
|
||||
// Initialize the OLED display using Wire library
|
||||
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL - SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h
|
||||
// SH1106Wire display(0x3c, SDA, SCL);
|
||||
|
||||
OLEDDisplayUi ui ( &display );
|
||||
|
||||
int screenW = 128;
|
||||
int screenH = 64;
|
||||
int clockCenterX = screenW / 2;
|
||||
int clockCenterY = ((screenH - 16) / 2) + 16; // top yellow part is 16 px height
|
||||
int clockRadius = 23;
|
||||
|
||||
// utility function for digital clock display: prints leading 0
|
||||
String twoDigits(int digits) {
|
||||
if (digits < 10) {
|
||||
String i = '0' + String(digits);
|
||||
return i;
|
||||
}
|
||||
else {
|
||||
return String(digits);
|
||||
}
|
||||
}
|
||||
|
||||
void clockOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
|
||||
|
||||
}
|
||||
|
||||
void analogClockFrame(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
|
||||
// ui.disableIndicator();
|
||||
|
||||
// Draw the clock face
|
||||
// display->drawCircle(clockCenterX + x, clockCenterY + y, clockRadius);
|
||||
display->drawCircle(clockCenterX + x, clockCenterY + y, 2);
|
||||
//
|
||||
//hour ticks
|
||||
for ( int z = 0; z < 360; z = z + 30 ) {
|
||||
//Begin at 0° and stop at 360°
|
||||
float angle = z ;
|
||||
angle = ( angle / 57.29577951 ) ; //Convert degrees to radians
|
||||
int x2 = ( clockCenterX + ( sin(angle) * clockRadius ) );
|
||||
int y2 = ( clockCenterY - ( cos(angle) * clockRadius ) );
|
||||
int x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 8 ) ) ) );
|
||||
int y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 8 ) ) ) );
|
||||
display->drawLine( x2 + x , y2 + y , x3 + x , y3 + y);
|
||||
}
|
||||
|
||||
// display second hand
|
||||
float angle = second() * 6 ;
|
||||
angle = ( angle / 57.29577951 ) ; //Convert degrees to radians
|
||||
int x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 5 ) ) ) );
|
||||
int y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 5 ) ) ) );
|
||||
display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y);
|
||||
//
|
||||
// display minute hand
|
||||
angle = minute() * 6 ;
|
||||
angle = ( angle / 57.29577951 ) ; //Convert degrees to radians
|
||||
x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 4 ) ) ) );
|
||||
y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 4 ) ) ) );
|
||||
display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y);
|
||||
//
|
||||
// display hour hand
|
||||
angle = hour() * 30 + int( ( minute() / 12 ) * 6 ) ;
|
||||
angle = ( angle / 57.29577951 ) ; //Convert degrees to radians
|
||||
x3 = ( clockCenterX + ( sin(angle) * ( clockRadius - ( clockRadius / 2 ) ) ) );
|
||||
y3 = ( clockCenterY - ( cos(angle) * ( clockRadius - ( clockRadius / 2 ) ) ) );
|
||||
display->drawLine( clockCenterX + x , clockCenterY + y , x3 + x , y3 + y);
|
||||
}
|
||||
|
||||
void digitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
|
||||
String timenow = String(hour()) + ":" + twoDigits(minute()) + ":" + twoDigits(second());
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(ArialMT_Plain_24);
|
||||
display->drawString(clockCenterX + x , clockCenterY + y, timenow );
|
||||
}
|
||||
|
||||
// This array keeps function pointers to all frames
|
||||
// frames are the single views that slide in
|
||||
FrameCallback frames[] = { analogClockFrame, digitalClockFrame };
|
||||
|
||||
// how many frames are there?
|
||||
int frameCount = 2;
|
||||
|
||||
// Overlays are statically drawn on top of a frame eg. a clock
|
||||
OverlayCallback overlays[] = { clockOverlay };
|
||||
int overlaysCount = 1;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
|
||||
// The ESP is capable of rendering 60fps in 80Mhz mode
|
||||
// but that won't give you much time for anything else
|
||||
// run it in 160Mhz mode or just set it to 30 fps
|
||||
ui.setTargetFPS(60);
|
||||
|
||||
// Customize the active and inactive symbol
|
||||
ui.setActiveSymbol(activeSymbol);
|
||||
ui.setInactiveSymbol(inactiveSymbol);
|
||||
|
||||
// You can change this to
|
||||
// TOP, LEFT, BOTTOM, RIGHT
|
||||
ui.setIndicatorPosition(TOP);
|
||||
|
||||
// Defines where the first frame is located in the bar.
|
||||
ui.setIndicatorDirection(LEFT_RIGHT);
|
||||
|
||||
// You can change the transition that is used
|
||||
// SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN
|
||||
ui.setFrameAnimation(SLIDE_LEFT);
|
||||
|
||||
// Add frames
|
||||
ui.setFrames(frames, frameCount);
|
||||
|
||||
// Add overlays
|
||||
ui.setOverlays(overlays, overlaysCount);
|
||||
|
||||
// Initialising the UI will init the display too.
|
||||
ui.init();
|
||||
|
||||
display.flipScreenVertically();
|
||||
|
||||
unsigned long secsSinceStart = millis();
|
||||
// Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
|
||||
const unsigned long seventyYears = 2208988800UL;
|
||||
// subtract seventy years:
|
||||
unsigned long epoch = secsSinceStart - seventyYears * SECS_PER_HOUR;
|
||||
setTime(epoch);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
int remainingTimeBudget = ui.update();
|
||||
|
||||
if (remainingTimeBudget > 0) {
|
||||
// You can do some work here
|
||||
// Don't do stuff if you are below your
|
||||
// time budget.
|
||||
delay(remainingTimeBudget);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
const uint8_t activeSymbol[] PROGMEM = {
|
||||
B00000000,
|
||||
B00000000,
|
||||
B00011000,
|
||||
B00100100,
|
||||
B01000010,
|
||||
B01000010,
|
||||
B00100100,
|
||||
B00011000
|
||||
};
|
||||
|
||||
const uint8_t inactiveSymbol[] PROGMEM = {
|
||||
B00000000,
|
||||
B00000000,
|
||||
B00000000,
|
||||
B00000000,
|
||||
B00011000,
|
||||
B00011000,
|
||||
B00000000,
|
||||
B00000000
|
||||
};
|
@ -0,0 +1,233 @@
|
||||
/**
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
Copyright (c) 2018 by Fabrice Weinberg
|
||||
|
||||
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.
|
||||
|
||||
ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
Please support us by buying our products (and not the clones) from
|
||||
https://thingpulse.com
|
||||
|
||||
*/
|
||||
|
||||
// Include the correct display library
|
||||
// For a connection via I2C using Wire include
|
||||
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
|
||||
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
|
||||
// For a connection via I2C using brzo_i2c (must be installed) include
|
||||
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Brzo.h"
|
||||
// #include "SH1106Brzo.h"
|
||||
// For a connection via SPI include
|
||||
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Spi.h"
|
||||
// #include "SH1106SPi.h"
|
||||
|
||||
// Use the corresponding display class:
|
||||
|
||||
// Initialize the OLED display using SPI
|
||||
// D5 -> CLK
|
||||
// D7 -> MOSI (DOUT)
|
||||
// D0 -> RES
|
||||
// D2 -> DC
|
||||
// D8 -> CS
|
||||
// SSD1306Spi display(D0, D2, D8);
|
||||
// or
|
||||
// SH1106Spi display(D0, D2);
|
||||
|
||||
// Initialize the OLED display using brzo_i2c
|
||||
// D3 -> SDA
|
||||
// D5 -> SCL
|
||||
// SSD1306Brzo display(0x3c, D3, D5);
|
||||
// or
|
||||
// SH1106Brzo display(0x3c, D3, D5);
|
||||
|
||||
// Initialize the OLED display using Wire library
|
||||
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL - SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h
|
||||
// SH1106Wire display(0x3c, SDA, SCL);
|
||||
|
||||
// Adapted from Adafruit_SSD1306
|
||||
void drawLines() {
|
||||
for (int16_t i = 0; i < display.getWidth(); i += 4) {
|
||||
display.drawLine(0, 0, i, display.getHeight() - 1);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
for (int16_t i = 0; i < display.getHeight(); i += 4) {
|
||||
display.drawLine(0, 0, display.getWidth() - 1, i);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
delay(250);
|
||||
|
||||
display.clear();
|
||||
for (int16_t i = 0; i < display.getWidth(); i += 4) {
|
||||
display.drawLine(0, display.getHeight() - 1, i, 0);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
for (int16_t i = display.getHeight() - 1; i >= 0; i -= 4) {
|
||||
display.drawLine(0, display.getHeight() - 1, display.getWidth() - 1, i);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
delay(250);
|
||||
|
||||
display.clear();
|
||||
for (int16_t i = display.getWidth() - 1; i >= 0; i -= 4) {
|
||||
display.drawLine(display.getWidth() - 1, display.getHeight() - 1, i, 0);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
for (int16_t i = display.getHeight() - 1; i >= 0; i -= 4) {
|
||||
display.drawLine(display.getWidth() - 1, display.getHeight() - 1, 0, i);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
delay(250);
|
||||
display.clear();
|
||||
for (int16_t i = 0; i < display.getHeight(); i += 4) {
|
||||
display.drawLine(display.getWidth() - 1, 0, 0, i);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
for (int16_t i = 0; i < display.getWidth(); i += 4) {
|
||||
display.drawLine(display.getWidth() - 1, 0, i, display.getHeight() - 1);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
delay(250);
|
||||
}
|
||||
|
||||
// Adapted from Adafruit_SSD1306
|
||||
void drawRect(void) {
|
||||
for (int16_t i = 0; i < display.getHeight() / 2; i += 2) {
|
||||
display.drawRect(i, i, display.getWidth() - 2 * i, display.getHeight() - 2 * i);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from Adafruit_SSD1306
|
||||
void fillRect(void) {
|
||||
uint8_t color = 1;
|
||||
for (int16_t i = 0; i < display.getHeight() / 2; i += 3) {
|
||||
display.setColor((color % 2 == 0) ? BLACK : WHITE); // alternate colors
|
||||
display.fillRect(i, i, display.getWidth() - i * 2, display.getHeight() - i * 2);
|
||||
display.display();
|
||||
delay(10);
|
||||
color++;
|
||||
}
|
||||
// Reset back to WHITE
|
||||
display.setColor(WHITE);
|
||||
}
|
||||
|
||||
// Adapted from Adafruit_SSD1306
|
||||
void drawCircle(void) {
|
||||
for (int16_t i = 0; i < display.getHeight(); i += 2) {
|
||||
display.drawCircle(display.getWidth() / 2, display.getHeight() / 2, i);
|
||||
display.display();
|
||||
delay(10);
|
||||
}
|
||||
delay(1000);
|
||||
display.clear();
|
||||
|
||||
// This will draw the part of the circel in quadrant 1
|
||||
// Quadrants are numberd like this:
|
||||
// 0010 | 0001
|
||||
// ------|-----
|
||||
// 0100 | 1000
|
||||
//
|
||||
display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000001);
|
||||
display.display();
|
||||
delay(200);
|
||||
display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000011);
|
||||
display.display();
|
||||
delay(200);
|
||||
display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000111);
|
||||
display.display();
|
||||
delay(200);
|
||||
display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00001111);
|
||||
display.display();
|
||||
}
|
||||
|
||||
void printBuffer(void) {
|
||||
// Initialize the log buffer
|
||||
// allocate memory to store 8 lines of text and 30 chars per line.
|
||||
display.setLogBuffer(5, 30);
|
||||
|
||||
// Some test data
|
||||
const char* test[] = {
|
||||
"Hello",
|
||||
"World" ,
|
||||
"----",
|
||||
"Show off",
|
||||
"how",
|
||||
"the log buffer",
|
||||
"is",
|
||||
"working.",
|
||||
"Even",
|
||||
"scrolling is",
|
||||
"working"
|
||||
};
|
||||
|
||||
for (uint8_t i = 0; i < 11; i++) {
|
||||
display.clear();
|
||||
// Print to the screen
|
||||
display.println(test[i]);
|
||||
// Draw it to the internal screen buffer
|
||||
display.drawLogBuffer(0, 0);
|
||||
// Display it on the screen
|
||||
display.display();
|
||||
delay(500);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
display.init();
|
||||
|
||||
// display.flipScreenVertically();
|
||||
|
||||
display.setContrast(255);
|
||||
|
||||
drawLines();
|
||||
delay(1000);
|
||||
display.clear();
|
||||
|
||||
drawRect();
|
||||
delay(1000);
|
||||
display.clear();
|
||||
|
||||
fillRect();
|
||||
delay(1000);
|
||||
display.clear();
|
||||
|
||||
drawCircle();
|
||||
delay(1000);
|
||||
display.clear();
|
||||
|
||||
printBuffer();
|
||||
delay(1000);
|
||||
display.clear();
|
||||
}
|
||||
|
||||
void loop() { }
|
@ -0,0 +1,127 @@
|
||||
/**
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
Copyright (c) 2018 by Fabrice Weinberg
|
||||
|
||||
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.
|
||||
|
||||
ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
Please support us by buying our products (and not the clones) from
|
||||
https://thingpulse.com
|
||||
|
||||
*/
|
||||
|
||||
#if defined(ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#elif defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include <WiFiUdp.h>
|
||||
#endif
|
||||
|
||||
#include <ArduinoOTA.h>
|
||||
|
||||
const char *ssid = "[Your SSID]";
|
||||
const char *password = "[Your Password]";
|
||||
|
||||
|
||||
// Include the correct display library
|
||||
// For a connection via I2C using Wire include
|
||||
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
|
||||
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
|
||||
// For a connection via I2C using brzo_i2c (must be installed) include
|
||||
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Brzo.h"
|
||||
// #include "SH1106Brzo.h"
|
||||
// For a connection via SPI include
|
||||
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Spi.h"
|
||||
// #include "SH1106SPi.h"
|
||||
|
||||
// Use the corresponding display class:
|
||||
|
||||
// Initialize the OLED display using SPI
|
||||
// D5 -> CLK
|
||||
// D7 -> MOSI (DOUT)
|
||||
// D0 -> RES
|
||||
// D2 -> DC
|
||||
// D8 -> CS
|
||||
// SSD1306Spi display(D0, D2, D8);
|
||||
// or
|
||||
// SH1106Spi display(D0, D2);
|
||||
|
||||
// Initialize the OLED display using brzo_i2c
|
||||
// D3 -> SDA
|
||||
// D5 -> SCL
|
||||
// SSD1306Brzo display(0x3c, D3, D5);
|
||||
// or
|
||||
// SH1106Brzo display(0x3c, D3, D5);
|
||||
|
||||
// Initialize the OLED display using Wire library
|
||||
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL - SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h
|
||||
// SH1106Wire display(0x3c, SDA, SCL);
|
||||
|
||||
|
||||
void setup() {
|
||||
WiFi.begin ( ssid, password );
|
||||
|
||||
// Wait for connection
|
||||
while ( WiFi.status() != WL_CONNECTED ) {
|
||||
delay ( 10 );
|
||||
}
|
||||
|
||||
display.init();
|
||||
display.flipScreenVertically();
|
||||
display.setContrast(255);
|
||||
|
||||
ArduinoOTA.begin();
|
||||
ArduinoOTA.onStart([]() {
|
||||
display.clear();
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
|
||||
display.drawString(display.getWidth() / 2, display.getHeight() / 2 - 10, "OTA Update");
|
||||
display.display();
|
||||
});
|
||||
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
display.drawProgressBar(4, 32, 120, 8, progress / (total / 100) );
|
||||
display.display();
|
||||
});
|
||||
|
||||
ArduinoOTA.onEnd([]() {
|
||||
display.clear();
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
|
||||
display.drawString(display.getWidth() / 2, display.getHeight() / 2, "Restart");
|
||||
display.display();
|
||||
});
|
||||
|
||||
// Align text vertical/horizontal center
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.drawString(display.getWidth() / 2, display.getHeight() / 2, "Ready for OTA:\n" + WiFi.localIP().toString());
|
||||
display.display();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
ArduinoOTA.handle();
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
/**
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2022 by Stefan Seyfried
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Include the correct display library
|
||||
// For a connection via I2C using Wire include
|
||||
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
|
||||
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
|
||||
// For a connection via I2C using brzo_i2c (must be installed) include
|
||||
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Brzo.h"
|
||||
// #include "SH1106Brzo.h"
|
||||
// For a connection via SPI include
|
||||
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Spi.h"
|
||||
// #include "SH1106Spi.h"
|
||||
|
||||
// Use the corresponding display class:
|
||||
|
||||
// Initialize the OLED display using SPI
|
||||
// D5 -> CLK
|
||||
// D7 -> MOSI (DOUT)
|
||||
// D0 -> RES
|
||||
// D2 -> DC
|
||||
// D8 -> CS
|
||||
// SSD1306Spi display(D0, D2, D8);
|
||||
// or
|
||||
// SH1106Spi display(D0, D2);
|
||||
|
||||
// Initialize the OLED display using brzo_i2c
|
||||
// D3 -> SDA
|
||||
// D5 -> SCL
|
||||
// SSD1306Brzo display(0x3c, D3, D5);
|
||||
// or
|
||||
// SH1106Brzo display(0x3c, D3, D5);
|
||||
|
||||
// Initialize the OLED display using Wire library
|
||||
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL - SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h
|
||||
// SH1106Wire display(0x3c, SDA, SCL);
|
||||
|
||||
// UTF-8 sprinkled within, because it tests special conditions in the char-counting code
|
||||
const String loremipsum = "Lorem ipsum dolor sit ämet, "
|
||||
"consetetur sadipscing elitr, sed diam nonümy eirmöd "
|
||||
"tempor invidunt ut labore et dolore mägnä aliquyam erat, "
|
||||
"sed diam voluptua. At vero eos et accusam et justo duo "
|
||||
"dolores et ea rebum. Stet clita kasd gubergren, no sea "
|
||||
"takimata sanctus est Lorem ipsum dolor sit amet. "
|
||||
"äöü-ÄÖÜ/߀é/çØ.";
|
||||
|
||||
void setup() {
|
||||
display.init();
|
||||
display.setContrast(255);
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.display();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
static uint16_t start_at = 0;
|
||||
display.clear();
|
||||
uint16_t firstline = display.drawStringMaxWidth(0, 0, 128, loremipsum.substring(start_at));
|
||||
display.display();
|
||||
if (firstline != 0) {
|
||||
start_at += firstline;
|
||||
} else {
|
||||
start_at = 0;
|
||||
delay(1000); // additional pause before going back to start
|
||||
}
|
||||
delay(1000);
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
/**
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
Copyright (c) 2018 by Fabrice Weinberg
|
||||
|
||||
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.
|
||||
|
||||
ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
Please support us by buying our products (and not the clones) from
|
||||
https://thingpulse.com
|
||||
|
||||
*/
|
||||
|
||||
// Include the correct display library
|
||||
|
||||
// For a connection via I2C using the Arduino Wire include:
|
||||
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
#include "SSD1306Wire.h" // legacy: #include "SSD1306.h"
|
||||
// OR #include "SH1106Wire.h" // legacy: #include "SH1106.h"
|
||||
|
||||
// For a connection via I2C using brzo_i2c (must be installed) include:
|
||||
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Brzo.h"
|
||||
// OR #include "SH1106Brzo.h"
|
||||
|
||||
// For a connection via SPI include:
|
||||
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Spi.h"
|
||||
// OR #include "SH1106SPi.h"
|
||||
|
||||
|
||||
// Optionally include custom images
|
||||
#include "images.h"
|
||||
|
||||
|
||||
// Initialize the OLED display using Arduino Wire:
|
||||
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL - SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h
|
||||
// SSD1306Wire display(0x3c, D3, D5); // ADDRESS, SDA, SCL - If not, they can be specified manually.
|
||||
// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32); // ADDRESS, SDA, SCL, OLEDDISPLAY_GEOMETRY - Extra param required for 128x32 displays.
|
||||
// SH1106Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||
|
||||
// Initialize the OLED display using brzo_i2c:
|
||||
// SSD1306Brzo display(0x3c, D3, D5); // ADDRESS, SDA, SCL
|
||||
// or
|
||||
// SH1106Brzo display(0x3c, D3, D5); // ADDRESS, SDA, SCL
|
||||
|
||||
// Initialize the OLED display using SPI:
|
||||
// D5 -> CLK
|
||||
// D7 -> MOSI (DOUT)
|
||||
// D0 -> RES
|
||||
// D2 -> DC
|
||||
// D8 -> CS
|
||||
// SSD1306Spi display(D0, D2, D8); // RES, DC, CS
|
||||
// or
|
||||
// SH1106Spi display(D0, D2); // RES, DC
|
||||
|
||||
|
||||
#define DEMO_DURATION 3000
|
||||
typedef void (*Demo)(void);
|
||||
|
||||
int demoMode = 0;
|
||||
int counter = 1;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
|
||||
// Initialising the UI will init the display too.
|
||||
display.init();
|
||||
|
||||
display.flipScreenVertically();
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
|
||||
}
|
||||
|
||||
void drawFontFaceDemo() {
|
||||
// Font Demo1
|
||||
// create more fonts at http://oleddisplay.squix.ch/
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.drawString(0, 0, "Hello world");
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.drawString(0, 10, "Hello world");
|
||||
display.setFont(ArialMT_Plain_24);
|
||||
display.drawString(0, 26, "Hello world");
|
||||
}
|
||||
|
||||
void drawTextFlowDemo() {
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.drawStringMaxWidth(0, 0, 128,
|
||||
"Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore." );
|
||||
}
|
||||
|
||||
void drawTextAlignmentDemo() {
|
||||
// Text alignment demo
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
|
||||
// The coordinates define the left starting point of the text
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.drawString(0, 10, "Left aligned (0,10)");
|
||||
|
||||
// The coordinates define the center of the text
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display.drawString(64, 22, "Center aligned (64,22)");
|
||||
|
||||
// The coordinates define the right end of the text
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display.drawString(128, 33, "Right aligned (128,33)");
|
||||
}
|
||||
|
||||
void drawRectDemo() {
|
||||
// Draw a pixel at given position
|
||||
for (int i = 0; i < 10; i++) {
|
||||
display.setPixel(i, i);
|
||||
display.setPixel(10 - i, i);
|
||||
}
|
||||
display.drawRect(12, 12, 20, 20);
|
||||
|
||||
// Fill the rectangle
|
||||
display.fillRect(14, 14, 17, 17);
|
||||
|
||||
// Draw a line horizontally
|
||||
display.drawHorizontalLine(0, 40, 20);
|
||||
|
||||
// Draw a line horizontally
|
||||
display.drawVerticalLine(40, 0, 20);
|
||||
}
|
||||
|
||||
void drawCircleDemo() {
|
||||
for (int i = 1; i < 8; i++) {
|
||||
display.setColor(WHITE);
|
||||
display.drawCircle(32, 32, i * 3);
|
||||
if (i % 2 == 0) {
|
||||
display.setColor(BLACK);
|
||||
}
|
||||
display.fillCircle(96, 32, 32 - i * 3);
|
||||
}
|
||||
}
|
||||
|
||||
void drawProgressBarDemo() {
|
||||
int progress = (counter / 5) % 100;
|
||||
// draw the progress bar
|
||||
display.drawProgressBar(0, 32, 120, 10, progress);
|
||||
|
||||
// draw the percentage as String
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display.drawString(64, 15, String(progress) + "%");
|
||||
}
|
||||
|
||||
void drawImageDemo() {
|
||||
// see http://blog.squix.org/2015/05/esp8266-nodemcu-how-to-create-xbm.html
|
||||
// on how to create xbm files
|
||||
display.drawXbm(34, 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
|
||||
}
|
||||
|
||||
Demo demos[] = {drawFontFaceDemo, drawTextFlowDemo, drawTextAlignmentDemo, drawRectDemo, drawCircleDemo, drawProgressBarDemo, drawImageDemo};
|
||||
int demoLength = (sizeof(demos) / sizeof(Demo));
|
||||
long timeSinceLastModeSwitch = 0;
|
||||
|
||||
void loop() {
|
||||
// clear the display
|
||||
display.clear();
|
||||
// draw the current demo method
|
||||
demos[demoMode]();
|
||||
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display.drawString(128, 54, String(millis()));
|
||||
// write the buffer to the display
|
||||
display.display();
|
||||
|
||||
if (millis() - timeSinceLastModeSwitch > DEMO_DURATION) {
|
||||
demoMode = (demoMode + 1) % demoLength;
|
||||
timeSinceLastModeSwitch = millis();
|
||||
}
|
||||
counter++;
|
||||
delay(10);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
#define WiFi_Logo_width 60
|
||||
#define WiFi_Logo_height 36
|
||||
const uint8_t WiFi_Logo_bits[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
|
||||
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,
|
||||
0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,
|
||||
0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,
|
||||
0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,
|
||||
0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,
|
||||
0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,
|
||||
0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,
|
||||
0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,
|
||||
0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,
|
||||
0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
|
||||
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
@ -0,0 +1,75 @@
|
||||
/**
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
|
||||
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.
|
||||
|
||||
ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
Please support us by buying our products (and not the clones) from
|
||||
https://thingpulse.com
|
||||
|
||||
*/
|
||||
|
||||
// Include the correct display library
|
||||
// For a connection via I2C using Wire include
|
||||
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
|
||||
#include "images.h"
|
||||
|
||||
// Initialize the OLED display using Wire library
|
||||
SSD1306Wire display(0x3c, 0, 14);
|
||||
SSD1306Wire display2(0x3c, 5, 4);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
|
||||
// Initialising the UI will init the display too.
|
||||
display.init();
|
||||
display2.init();
|
||||
|
||||
// This will make sure that multiple instances of a display driver
|
||||
// running on different ports will work together transparently
|
||||
display.setI2cAutoInit(true);
|
||||
display2.setI2cAutoInit(true);
|
||||
|
||||
display.flipScreenVertically();
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
|
||||
display2.flipScreenVertically();
|
||||
display2.setFont(ArialMT_Plain_10);
|
||||
display2.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
display.clear();
|
||||
display.drawString(0, 0, "Hello world: " + String(millis()));
|
||||
display.display();
|
||||
|
||||
display2.clear();
|
||||
display2.drawString(0, 0, "Hello world: " + String(millis()));
|
||||
display2.display();
|
||||
|
||||
delay(10);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
#define WiFi_Logo_width 60
|
||||
#define WiFi_Logo_height 36
|
||||
const uint8_t WiFi_Logo_bits[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
|
||||
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,
|
||||
0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,
|
||||
0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,
|
||||
0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,
|
||||
0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,
|
||||
0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,
|
||||
0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,
|
||||
0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,
|
||||
0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,
|
||||
0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
|
||||
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
@ -0,0 +1,194 @@
|
||||
/**
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
|
||||
Copyright (c) 2018 by Fabrice Weinberg
|
||||
|
||||
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.
|
||||
|
||||
ThingPulse invests considerable time and money to develop these open source libraries.
|
||||
Please support us by buying our products (and not the clones) from
|
||||
https://thingpulse.com
|
||||
|
||||
*/
|
||||
|
||||
// Include the correct display library
|
||||
// For a connection via I2C using Wire include
|
||||
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
|
||||
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
|
||||
// For a connection via I2C using brzo_i2c (must be installed) include
|
||||
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Brzo.h"
|
||||
// #include "SH1106Brzo.h"
|
||||
// For a connection via SPI include
|
||||
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
|
||||
// #include "SSD1306Spi.h"
|
||||
// #include "SH1106SPi.h"
|
||||
|
||||
// Include the UI lib
|
||||
#include "OLEDDisplayUi.h"
|
||||
|
||||
// Include custom images
|
||||
|
||||
#include "images.h"
|
||||
|
||||
// Use the corresponding display class:
|
||||
|
||||
// Initialize the OLED display using SPI
|
||||
// D5 -> CLK
|
||||
// D7 -> MOSI (DOUT)
|
||||
// D0 -> RES
|
||||
// D2 -> DC
|
||||
// D8 -> CS
|
||||
// SSD1306Spi display(D0, D2, D8);
|
||||
// or
|
||||
// SH1106Spi display(D0, D2);
|
||||
|
||||
// Initialize the OLED display using brzo_i2c
|
||||
// D3 -> SDA
|
||||
// D5 -> SCL
|
||||
// SSD1306Brzo display(0x3c, D3, D5);
|
||||
// or
|
||||
// SH1106Brzo display(0x3c, D3, D5);
|
||||
|
||||
// Initialize the OLED display using Wire library
|
||||
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL - SDA and SCL usually populate automatically based on your board's pins_arduino.h e.g. https://github.com/esp8266/Arduino/blob/master/variants/nodemcu/pins_arduino.h
|
||||
// SH1106Wire display(0x3c, SDA, SCL);
|
||||
|
||||
OLEDDisplayUi ui ( &display );
|
||||
|
||||
void msOverlay(OLEDDisplay *display, OLEDDisplayUiState* state) {
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
display->drawString(128, 0, String(millis()));
|
||||
}
|
||||
|
||||
void drawFrame1(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
|
||||
// draw an xbm image.
|
||||
// Please note that everything that should be transitioned
|
||||
// needs to be drawn relative to x and y
|
||||
|
||||
display->drawXbm(x + 34, y + 14, WiFi_Logo_width, WiFi_Logo_height, WiFi_Logo_bits);
|
||||
}
|
||||
|
||||
void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
|
||||
// Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file
|
||||
// Besides the default fonts there will be a program to convert TrueType fonts into this format
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
display->drawString(0 + x, 10 + y, "Arial 10");
|
||||
|
||||
display->setFont(ArialMT_Plain_16);
|
||||
display->drawString(0 + x, 20 + y, "Arial 16");
|
||||
|
||||
display->setFont(ArialMT_Plain_24);
|
||||
display->drawString(0 + x, 34 + y, "Arial 24");
|
||||
}
|
||||
|
||||
void drawFrame3(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
|
||||
// Text alignment demo
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
|
||||
// The coordinates define the left starting point of the text
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->drawString(0 + x, 11 + y, "Left aligned (0,10)");
|
||||
|
||||
// The coordinates define the center of the text
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->drawString(64 + x, 22 + y, "Center aligned (64,22)");
|
||||
|
||||
// The coordinates define the right end of the text
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display->drawString(128 + x, 33 + y, "Right aligned (128,33)");
|
||||
}
|
||||
|
||||
void drawFrame4(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
|
||||
// Demo for drawStringMaxWidth:
|
||||
// with the third parameter you can define the width after which words will be wrapped.
|
||||
// Currently only spaces and "-" are allowed for wrapping
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
display->drawStringMaxWidth(0 + x, 10 + y, 128, "Lorem ipsum\n dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore.");
|
||||
}
|
||||
|
||||
void drawFrame5(OLEDDisplay *display, OLEDDisplayUiState* state, int16_t x, int16_t y) {
|
||||
|
||||
}
|
||||
|
||||
// This array keeps function pointers to all frames
|
||||
// frames are the single views that slide in
|
||||
FrameCallback frames[] = { drawFrame1, drawFrame2, drawFrame3, drawFrame4, drawFrame5 };
|
||||
|
||||
// how many frames are there?
|
||||
int frameCount = 5;
|
||||
|
||||
// Overlays are statically drawn on top of a frame eg. a clock
|
||||
OverlayCallback overlays[] = { msOverlay };
|
||||
int overlaysCount = 1;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
// The ESP is capable of rendering 60fps in 80Mhz mode
|
||||
// but that won't give you much time for anything else
|
||||
// run it in 160Mhz mode or just set it to 30 fps
|
||||
ui.setTargetFPS(60);
|
||||
|
||||
// Customize the active and inactive symbol
|
||||
ui.setActiveSymbol(activeSymbol);
|
||||
ui.setInactiveSymbol(inactiveSymbol);
|
||||
|
||||
// You can change this to
|
||||
// TOP, LEFT, BOTTOM, RIGHT
|
||||
ui.setIndicatorPosition(BOTTOM);
|
||||
|
||||
// Defines where the first frame is located in the bar.
|
||||
ui.setIndicatorDirection(LEFT_RIGHT);
|
||||
|
||||
// You can change the transition that is used
|
||||
// SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN
|
||||
ui.setFrameAnimation(SLIDE_LEFT);
|
||||
|
||||
// Add frames
|
||||
ui.setFrames(frames, frameCount);
|
||||
|
||||
// Add overlays
|
||||
ui.setOverlays(overlays, overlaysCount);
|
||||
|
||||
// Initialising the UI will init the display too.
|
||||
ui.init();
|
||||
|
||||
display.flipScreenVertically();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
int remainingTimeBudget = ui.update();
|
||||
|
||||
if (remainingTimeBudget > 0) {
|
||||
// You can do some work here
|
||||
// Don't do stuff if you are below your
|
||||
// time budget.
|
||||
delay(remainingTimeBudget);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
#define WiFi_Logo_width 60
|
||||
#define WiFi_Logo_height 36
|
||||
const uint8_t WiFi_Logo_bits[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
|
||||
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x03, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0x07, 0xC0, 0x83, 0x01, 0x80, 0xFF, 0xFF, 0xFF,
|
||||
0x01, 0x00, 0x07, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x0C, 0x00,
|
||||
0xC0, 0xFF, 0xFF, 0x7C, 0x00, 0x60, 0x0C, 0x00, 0xC0, 0x31, 0x46, 0x7C,
|
||||
0xFC, 0x77, 0x08, 0x00, 0xE0, 0x23, 0xC6, 0x3C, 0xFC, 0x67, 0x18, 0x00,
|
||||
0xE0, 0x23, 0xE4, 0x3F, 0x1C, 0x00, 0x18, 0x00, 0xE0, 0x23, 0x60, 0x3C,
|
||||
0x1C, 0x70, 0x18, 0x00, 0xE0, 0x03, 0x60, 0x3C, 0x1C, 0x70, 0x18, 0x00,
|
||||
0xE0, 0x07, 0x60, 0x3C, 0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C,
|
||||
0xFC, 0x73, 0x18, 0x00, 0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00,
|
||||
0xE0, 0x87, 0x70, 0x3C, 0x1C, 0x70, 0x18, 0x00, 0xE0, 0x8F, 0x71, 0x3C,
|
||||
0x1C, 0x70, 0x18, 0x00, 0xC0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x08, 0x00,
|
||||
0xC0, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x0C, 0x00, 0x80, 0xFF, 0xFF, 0x1F,
|
||||
0x00, 0x00, 0x06, 0x00, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0x07, 0x00,
|
||||
0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0xFF,
|
||||
0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF,
|
||||
0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
const uint8_t activeSymbol[] PROGMEM = {
|
||||
B00000000,
|
||||
B00000000,
|
||||
B00011000,
|
||||
B00100100,
|
||||
B01000010,
|
||||
B01000010,
|
||||
B00100100,
|
||||
B00011000
|
||||
};
|
||||
|
||||
const uint8_t inactiveSymbol[] PROGMEM = {
|
||||
B00000000,
|
||||
B00000000,
|
||||
B00000000,
|
||||
B00000000,
|
||||
B00011000,
|
||||
B00011000,
|
||||
B00000000,
|
||||
B00000000
|
||||
};
|
@ -0,0 +1,100 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map List
|
||||
#######################################
|
||||
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
INVERSE LITERAL1
|
||||
|
||||
TEXT_ALIGN_LEFT LITERAL1
|
||||
TEXT_ALIGN_RIGHT LITERAL1
|
||||
TEXT_ALIGN_CENTER LITERAL1
|
||||
TEXT_ALIGN_CENTER_BOTH LITERAL1
|
||||
|
||||
GEOMETRY_128_64 LITERAL1
|
||||
GEOMETRY_128_32 LITERAL1
|
||||
GEOMETRY_RAWMODE LITERAL1
|
||||
|
||||
ArialMT_Plain_10 LITERAL1
|
||||
ArialMT_Plain_16 LITERAL1
|
||||
ArialMT_Plain_24 LITERAL1
|
||||
|
||||
SLIDE_UP LITERAL1
|
||||
SLIDE_DOWN LITERAL1
|
||||
SLIDE_LEFT LITERAL1
|
||||
SLIDE_RIGHT LITERAL1
|
||||
|
||||
TOP LITERAL1
|
||||
RIGHT LITERAL1
|
||||
BOTTOM LITERAL1
|
||||
LEFT LITERAL1
|
||||
|
||||
LEFT_RIGHT LITERAL1
|
||||
RIGHT_LEFT LITERAL1
|
||||
|
||||
IN_TRANSITION LITERAL1
|
||||
FIXED LITERAL1
|
||||
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
OLEDDisplay KEYWORD1
|
||||
OLEDDisplayUi KEYWORD1
|
||||
|
||||
SH1106Wire KEYWORD1
|
||||
SH1106Brzo KEYWORD1
|
||||
SH1106Spi KEYWORD1
|
||||
|
||||
SSD1306Wire KEYWORD1
|
||||
SSD1306Brzo KEYWORD1
|
||||
SSD1306I2C KEYWORD1
|
||||
SSD1306Spi KEYWORD1
|
||||
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
allocateBuffer KEYWORD2
|
||||
init KEYWORD2
|
||||
resetDisplay KEYWORD2
|
||||
setColor KEYWORD2
|
||||
getColor KEYWORD2
|
||||
setPixel KEYWORD2
|
||||
setPixelColor KEYWORD2
|
||||
clearPixel KEYWORD2
|
||||
drawLine KEYWORD2
|
||||
drawRect KEYWORD2
|
||||
fillRect KEYWORD2
|
||||
drawCircle KEYWORD2
|
||||
drawCircleQuads KEYWORD2
|
||||
fillCircle KEYWORD2
|
||||
fillRing KEYWORD2
|
||||
drawHorizontalLine KEYWORD2
|
||||
drawVerticalLine KEYWORD2
|
||||
drawProgressBar KEYWORD2
|
||||
drawFastImage KEYWORD2
|
||||
drawXbm KEYWORD2
|
||||
drawIco16x16 KEYWORD2
|
||||
drawString KEYWORD2
|
||||
drawStringMaxWidth KEYWORD2
|
||||
getStringWidth KEYWORD2
|
||||
setTextAlignment KEYWORD2
|
||||
setFont KEYWORD2
|
||||
setFontTableLookupFunction KEYWORD2
|
||||
displayOn KEYWORD2
|
||||
displayOff KEYWORD2
|
||||
invertDisplay KEYWORD2
|
||||
normalDisplay KEYWORD2
|
||||
setContrast KEYWORD2
|
||||
setBrightness KEYWORD2
|
||||
resetOrientation KEYWORD2
|
||||
flipScreenVertically KEYWORD2
|
||||
mirrorScreen KEYWORD2
|
||||
display KEYWORD2
|
||||
setLogBuffer KEYWORD2
|
||||
drawLogBuffer KEYWORD2
|
||||
getWidth KEYWORD2
|
||||
getHeight KEYWORD2
|
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "ESP8266 and ESP32 OLED driver for SSD1306 displays",
|
||||
"version": "4.3.0",
|
||||
"keywords": "ssd1306, oled, display, i2c",
|
||||
"description": "I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS",
|
||||
"license": "MIT",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/ThingPulse/esp8266-oled-ssd1306"
|
||||
},
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
"name": "Daniel Eichhorn, ThingPulse",
|
||||
"email": "squix78@gmail.com",
|
||||
"url": "https://thingpulse.com"
|
||||
},
|
||||
{
|
||||
"name": "Fabrice Weinberg",
|
||||
"email": "fabrice@weinberg.me"
|
||||
}
|
||||
],
|
||||
"frameworks": "arduino",
|
||||
"platforms": [
|
||||
"espressif8266",
|
||||
"espressif32",
|
||||
"nordicnrf52"
|
||||
]
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
name=ESP8266 and ESP32 OLED driver for SSD1306 displays
|
||||
version=4.3.0
|
||||
author=ThingPulse, Fabrice Weinberg
|
||||
maintainer=ThingPulse <info@thingpulse.com>
|
||||
sentence=I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS
|
||||
paragraph=The following geometries are currently supported: 128x64, 128x32, 64x48. The init sequence was inspired by Adafruit's library for the same display.
|
||||
category=Display
|
||||
url=https://github.com/ThingPulse/esp8266-oled-ssd1306
|
||||
architectures=esp8266,esp32
|
||||
license=MIT
|
@ -0,0 +1,24 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 by Daniel Eichhorn
|
||||
Copyright (c) 2016 by Fabrice Weinberg
|
||||
|
||||
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.
|
||||
|
||||
See more at http://blog.squix.ch
|
@ -0,0 +1,19 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; http://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:d1_mini]
|
||||
platform = espressif8266
|
||||
board = d1_mini
|
||||
framework = arduino
|
||||
upload_speed = 921600
|
||||
board_build.f_cpu = 160000000L
|
||||
upload_port = /dev/cu.SLAB_USBtoUART
|
||||
monitor_port = /dev/cu.SLAB_USBtoUART
|
||||
lib_deps =
|
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 26 KiB |