Merge pull request #131 from timmbogner/release_2023_01

Upcoming Release
pull/151/head
Timm Bogner 1 year ago committed by GitHub
commit 8edef7fdd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,69 +4,73 @@
##### <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. The system establishes a series of low-power, low-cost access points and repeaters that provide light-weight ESP-NOW and LoRa coverage to remote devices. The system can be used to exchange sensor readings or control messages in situations where it would be too difficult or energy-consuming to provide full WiFi/LoRaWAN coverage. While it was designed with farming in mind, FDRS can also be useful in a home, classroom, or research setting.
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 alse 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.
Devices are classified into two types: **Gateways** and **User Nodes**. Gateways comprise the infrastructure of the network, moving data in pre-determined directions to provide coverage to all devices. User nodes allow the user to exchange data with the gateways. 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
- To install FDRS, download the project folder by clicking the “Clone or download” button and then clicking “Download ZIP”. You should then move it to your Arduino 'libraries' folder to complete the installation.
- After installing, edit the 'src/fdrs_globals.h' file with your WiFi credentials and other global parameters.
- To begin, flash an ESP device with the **1_UART_Gateway.ino** example, and another with the **ESPNOW_Sensor.ino** example. The mocked-up sensor readings will be received by the gateway and relayed to the serial port, where it may be monitored via a terminal.
- If you would like to use MQTT, you can connect a second ESP 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'.
**Libraries Required:**
- [ArduinoJson](https://arduinojson.org/)
- [RadioLib](https://github.com/jgromes/RadioLib) for LoRa
- [PubSubClient](https://github.com/knolleary/pubsubclient/) for MQTT
Install the libraries that you need:
- [ArduinoJson](https://arduinojson.org/) (mandatory)
- [LoRa library](https://github.com/sandeepmistry/arduino-LoRa) by sandeepmistry (required if using LoRa)
- [PubSubClient](https://github.com/knolleary/pubsubclient/) (required for MQTT Gateways)
- [ArduinoUniqueID](https://github.com/ricaun/ArduinoUniqueID) (required for LoRa nodes)
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 a 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.
## User nodes
## 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** registers with a gateway to begin receiving data from it, then subscribes to the specific READING_ID(s) that it will listen for data from. When data arrives from an ID the device is subscribed to, a callback function is activated containing the data. Currently this is available only on ESP-NOW devices.
- 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 ESP32/8266 devices that can perform a variety of functions. These include collecting, distributing, and relaying data; as well providing a cohesive interface between various wired and wireless protocols. They are generally arranged in a line or star topology, with the gateway closest to the front-end being assigned an address of 0x00.
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 backets coming *from* the front-end out to any controller nodes that are registered/listening.
In its most basic 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 infers that these are sensor readings and passes them downstream towards the front-end. The gateway will send packets originating from the front end to registered peers and repeat them to the next gateway upstream, if applicable.
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 downsteam 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 the point where the user interacts with FDRS. This could be anything from a microcontroller communicating through UART and displaying data on a screen, to your favorite server/database platform logging the data via MQTT.
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 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.
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
A few things that I intend to add are:
- Internal timekeeping is the big feature-addition on the horizon. I would like to add a way for FDRS gateways to keep track of time via NTP (on WiFi) or an RTC module, and seamlessly distribute the current time amongst its neighbors automatically. All gateways could then be queried by remote nodes for the current time. Get your T-Watch ready!
- More sensor and controller sketches! If you have designed any open source hardware for ESP32 or 8266, please contact me and I will provide support for your device in this repo.
- Support for several new devices and protocols: ethernet, nRF24L01, 4G LTE, and the E5 LoRa module from Seeed Studio.
- Channel Activity Detection (CAD) and some improvements for LoRa, including controller capabilities.
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 heasitate to contact me at timmbogner@gmail.com or open a discussion here on Github.
**...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/)
[**Random Nerd Tutorials**](https://randomnerdtutorials.com/) was also an indispensable source of ESP knowledge. If you are a beginner and trying to learn more about microcontrollers, I highly reccomend starting there.
Development of this project would not have been possible without the support of my former employer, **Sola Gratia Farm** of **Urbana, IL, USA**. Sola Gratia is a community-based farm dedicated to growing high-quality produce and sharing it with those in need. Thank you.
It is a great honor to have been [featured on **Hackaday**](https://hackaday.com/2022/07/02/farm-data-relay-system/) and [hackster.io!]
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 reccomend starting there.
#
![Basic - UART](extras/basic-UART.png)

@ -2,11 +2,11 @@
//
// GATEWAY 2.000
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
//
#include "fdrs_gateway_config.h"
#include <fdrs_functions.h>
#include <fdrs_gateway.h>
void setup() {
beginFDRS();

@ -1,101 +1,70 @@
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000 Configuration
// GATEWAY CONFIGURATION
#include <fdrs_globals.h>
//Addresses
#define UNIT_MAC 0x00 // The address of this gateway
#define FDRS_DEBUG //Enable USB-Serial debugging
#define DEBUG_CONFIG // Displays full config info on startup
#define UNIT_MAC 0x00 // The address of this gateway
// Actions -- Define what happens when a packet arrives at each interface:
// Current function options are: sendESPNOW(MAC), sendSerial(), sendMQTT(),
// bufferLoRa(interface), bufferESPNOW(interface), bufferSerial(), and bufferMQTT().
#define ESPNOWG_ACT
#define SERIAL_ACT sendMQTT();
#define MQTT_ACT sendSerial();
#define LORAG_ACT
// Protocols -- Define which protocols the gateway will use.
// Warning: ESP-NOW and WiFi should not be used simultaneously.
#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 //Used only for MQTT gateway
// Neighbor addresses
#define ESPNOW_NEIGHBOR_1 0x0E // ESPNOW1 Address
#define ESPNOW_NEIGHBOR_2 0x0F // ESPNOW2 Address
#define LORA_NEIGHBOR_1 0x0E // LoRa1 Address
#define LORA_NEIGHBOR_2 0x0F // LoRa2 Address
#define USE_WIFI // Will cause errors if used with ESP-NOW. Use a serial link instead!
//#define USE_ETHERNET
// Neighbor Actions
#define ESPNOW1_ACT
// 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 LORA1_ACT
#define LORA2_ACT
//Pins for UART data interface (ESP32 only)
// LoRa Configuration
#define RADIOLIB_MODULE 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 USE_SX126X
//#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_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
// UART data interface pins (if available)
#define RXD2 14
#define TXD2 15
//Logging settings -- Logging will occur when MQTT is disconnected
//#define USE_SD_LOG //Enable SD-card logging
//#define USE_FS_LOG //Enable filesystem (flash) logging
#define LOGBUF_DELAY 10000 // Log Buffer Delay - in milliseconds
#define SD_SS 0 //SD card CS pin (Use different pins for LoRa and SD)
#define SD_FILENAME "fdrs_log.csv"
#define FS_FILENAME "fdrs_log.csv"
// SPI Configuration -- Needed only on Boards with multiple SPI interfaces like the ESP32
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
// LoRa Configuration -- Needed only if using LoRa
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define LORA_BAND 915E6 // LoRa Frequency Band
#define LORA_SF 7 // LoRa Spreading Factor
#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
// Buffer Delays - in milliseconds - Uncomment to enable any buffer
//#define ESPNOW1_DELAY 0
//#define ESPNOW2_DELAY 0
//#define ESPNOWG_DELAY 0
//#define SERIAL_DELAY 0
//#define MQTT_DELAY 0
//#define LORAG_DELAY 1000
//#define LORA1_DELAY 1000
//#define LORA2_DELAY 1000
#define PEER_TIMEOUT 300000
// FastLED -- Not yet fully implemented
//#define USE_LED
#define LED_PIN 32
#define NUM_LEDS 4
// WiFi and MQTT Credentials -- Needed for MQTT only if "fdrs_globals.h" is not included
// 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"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"
#define TOPIC_COMMAND "fdrs/command"

@ -6,7 +6,7 @@
//
#include "fdrs_gateway_config.h"
#include <fdrs_functions.h>
#include <fdrs_gateway.h>
void setup() {
beginFDRS();

@ -1,100 +1,70 @@
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000 Configuration
// GATEWAY CONFIGURATION
#include <fdrs_globals.h>
#define FDRS_DEBUG //Enable USB-Serial debugging
#define DEBUG_CONFIG // Displays full config info on startup
//Addresses
#define UNIT_MAC 0x01 // The address of this gateway
#define UNIT_MAC 0x01 // The address of this gateway
// Actions -- Define what happens when a packet arrives at each interface:
// Current function options are: sendESPNOW(MAC), sendSerial(), sendMQTT(),
// bufferLoRa(interface), bufferESPNOW(interface), bufferSerial(), and bufferMQTT().
#define ESPNOWG_ACT sendSerial();
#define SERIAL_ACT sendESPNOW(0x02); bufferLoRa(1); sendESPNOWpeers();
#define MQTT_ACT
#define LORAG_ACT sendSerial();
// Protocols -- Define which protocols the gateway will use.
// Warning: ESP-NOW and WiFi should not be used simultaneously.
#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 //Used only for MQTT gateway
//#define USE_WIFI // Will cause errors if used with ESP-NOW. Use a serial link instead!
//#define USE_ETHERNET
// Neighboring gateway addresses
#define ESPNOW_NEIGHBOR_1 0x0E // ESPNOW1 Address
#define ESPNOW_NEIGHBOR_2 0x0F // ESPNOW2 Address
#define LORA_NEIGHBOR_1 0x02 // LoRa1 Address
#define LORA_NEIGHBOR_2 0x0F // LoRa2 Address
// Neighbor Actions
#define ESPNOW1_ACT
#define ESPNOW2_ACT
#define LORA1_ACT sendSerial();
#define LORA2_ACT
//Pins for UART data interface (ESP32 only)
// 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_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
//#define USE_SX126X
//#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_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
// UART data interface pins (if available)
#define RXD2 14
#define TXD2 15
//Logging settings -- Logging will occur when MQTT is disconnected
//#define USE_SD_LOG //Enable SD-card logging
//#define USE_FS_LOG //Enable filesystem (flash) logging
#define LOGBUF_DELAY 10000 // Log Buffer Delay - in milliseconds
#define SD_SS 0 //SD card CS pin (Use different pins for LoRa and SD)
#define SD_FILENAME "fdrs_log.csv"
#define FS_FILENAME "fdrs_log.csv"
// SPI Configuration -- Needed only on boards with multiple SPI interfaces like the ESP32
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
// LoRa Configuration -- Needed only if using LoRa
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define LORA_BAND 915E6 // LoRa Frequency Band
#define LORA_SF 7 // LoRa Spreading Factor
#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
// Buffer Delays - in milliseconds - Uncomment to enable any buffer
//#define ESPNOW1_DELAY 0
//#define ESPNOW2_DELAY 0
//#define ESPNOWG_DELAY 0
//#define SERIAL_DELAY 0
//#define MQTT_DELAY 0
//#define LORAG_DELAY 1000
//#define LORA1_DELAY 500
//#define LORA2_DELAY 1000
#define PEER_TIMEOUT 300000
// FastLED -- Not yet fully implemented
//#define USE_LED
#define LED_PIN 32
#define NUM_LEDS 4
// WiFi and MQTT Credentials -- Needed for MQTT only if "fdrs_globals.h" is not included
// 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"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"
#define TOPIC_COMMAND "fdrs/command"

@ -6,7 +6,7 @@
//
#include "fdrs_gateway_config.h"
#include <fdrs_functions.h>
#include <fdrs_gateway.h>
void setup() {
beginFDRS();

@ -1,102 +1,70 @@
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000 Configuration
// GATEWAY CONFIGURATION
#include <fdrs_globals.h>
//Addresses
#define UNIT_MAC 0x02 // The address of this gateway
#define FDRS_DEBUG //Enable USB-Serial debugging
#define DEBUG_CONFIG // Displays full config info on startup
#define UNIT_MAC 0x02 // The address of this gateway
// Actions -- Define what happens when a packet arrives at each interface:
// Current function options are: sendESPNOW(MAC), sendSerial(), sendMQTT(),
// bufferLoRa(interface), bufferESPNOW(interface), bufferSerial(), and bufferMQTT().
#define ESPNOWG_ACT sendESPNOW(0x01);
#define SERIAL_ACT
#define MQTT_ACT
#define LORAG_ACT
// Protocols -- Define which protocols the gateway will use.
// Warning: ESP-NOW and WiFi should not be used simultaneously.
#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 //Used only for MQTT gateway
//#define USE_WIFI // Will cause errors if used with ESP-NOW. Use a serial link instead!
//#define USE_ETHERNET
// Neighbor addresses
#define ESPNOW_NEIGHBOR_1 0x01 // ESPNOW1 Address
#define ESPNOW_NEIGHBOR_2 0x0F // ESPNOW2 Address
#define LORA_NEIGHBOR_1 0x0E // LoRa1 Address
#define LORA_NEIGHBOR_2 0x0F // LoRa2 Address
// Neighbor Actions
#define ESPNOW1_ACT sendSerial(); // This would display packets arriving *from* the front-end.
#define ESPNOW2_ACT
#define LORA1_ACT
// 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
//Pins for UART data interface (ESP32 only)
// LoRa Configuration
#define RADIOLIB_MODULE 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 USE_SX126X
//#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_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
// UART data interface pins (if available)
#define RXD2 14
#define TXD2 15
//Logging settings -- Logging will occur when MQTT is disconnected
//#define USE_SD_LOG //Enable SD-card logging
//#define USE_FS_LOG //Enable filesystem (flash) logging
#define LOGBUF_DELAY 10000 // Log Buffer Delay - in milliseconds
#define SD_SS 0 //SD card CS pin (Use different pins for LoRa and SD)
#define SD_FILENAME "fdrs_log.csv"
#define FS_FILENAME "fdrs_log.csv"
// SPI Configuration -- Needed only on Boards with multiple SPI interfaces like the ESP32
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
// LoRa Configuration -- Needed only if using LoRa
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define LORA_BAND 915E6 // LoRa Frequency Band
#define LORA_SF 7 // LoRa Spreading Factor
#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm.
// Buffer Delays - in milliseconds - Uncomment to enable any buffer
//#define ESPNOW1_DELAY 0
//#define ESPNOW2_DELAY 0
//#define ESPNOWG_DELAY 0
//#define SERIAL_DELAY 0
//#define MQTT_DELAY 0
//#define LORAG_DELAY 1000
//#define LORA1_DELAY 1000
//#define LORA2_DELAY 1000
#define PEER_TIMEOUT 300000
// FastLED -- Not yet fully implemented
//#define USE_LED
#define LED_PIN 32
#define NUM_LEDS 4
// WiFi and MQTT Credentials -- Needed for MQTT only if "fdrs_globals.h" is not included
// 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"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"
#define TOPIC_COMMAND "fdrs/command"

@ -6,7 +6,7 @@
//
#include "fdrs_gateway_config.h"
#include <fdrs_functions.h>
#include <fdrs_gateway.h>
void setup() {
beginFDRS();

@ -1,100 +1,70 @@
// FARM DATA RELAY SYSTEM
//
// GATEWAY 2.000 Configuration
// GATEWAY CONFIGURATION
#include <fdrs_globals.h>
#define FDRS_DEBUG //Enable USB-Serial debugging
#define DEBUG_CONFIG // Displays full config info on startup
//Addresses
#define UNIT_MAC 0x03 // The address of this gateway
#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
// Actions -- Define what happens when a packet arrives at each interface:
// Current function options are: sendESPNOW(MAC), sendSerial(), sendMQTT(),
// bufferLoRa(interface), bufferESPNOW(interface), bufferSerial(), and bufferMQTT().
#define ESPNOWG_ACT bufferLoRa(1);
#define SERIAL_ACT
#define MQTT_ACT
#define LORAG_ACT bufferLoRa(1);
// Protocols -- Define which protocols the gateway will use.
// Warning: ESP-NOW and WiFi should not be used simultaneously.
#define USE_ESPNOW
// Interfaces
//#define USE_ESPNOW
#define USE_LORA
//#define USE_WIFI //Used only for MQTT gateway
// Neighbor addresses
#define ESPNOW_NEIGHBOR_1 0x0E // ESPNOW1 Address
#define ESPNOW_NEIGHBOR_2 0x0F // ESPNOW2 Address
#define LORA_NEIGHBOR_1 0x01 // LoRa1 Address
#define LORA_NEIGHBOR_2 0x0F // LoRa2 Address
// Neighbor Actions
#define ESPNOW1_ACT
//#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 sendSerial(); // This would display packets arriving *from* the front-end.
#define LORA2_ACT
//Pins for UART data interface (ESP32 only)
#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_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
//#define USE_SX126X
//#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_SDA 4
#define OLED_SCL 15
#define OLED_RST 16
// UART data interface pins (if available)
#define RXD2 14
#define TXD2 15
//Logging settings -- Logging will occur when MQTT is disconnected
//#define USE_SD_LOG //Enable SD-card logging
//#define USE_FS_LOG //Enable filesystem (flash) logging
#define LOGBUF_DELAY 10000 // Log Buffer Delay - in milliseconds
#define SD_SS 0 //SD card CS pin (Use different pins for LoRa and SD)
#define SD_FILENAME "fdrs_log.csv"
#define FS_FILENAME "fdrs_log.csv"
// SPI Configuration -- Needed only on Boards with multiple SPI interfaces like the ESP32
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//#define USE_LR // Use ESP-NOW LR mode (ESP32 only)
// LoRa Configuration -- Needed only if using LoRa
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
#define LORA_BAND 915E6 // LoRa Frequency Band
#define LORA_SF 7 // LoRa Spreading Factor
#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm.
// Buffer Delays - in milliseconds - Uncomment to enable any buffer
//#define ESPNOW1_DELAY 0
//#define ESPNOW2_DELAY 0
//#define ESPNOWG_DELAY 0
//#define SERIAL_DELAY 0
//#define MQTT_DELAY 0
//#define LORAG_DELAY 1000
#define LORA1_DELAY 5000
//#define LORA2_DELAY 1000
#define PEER_TIMEOUT 300000
// FastLED -- Not yet fully implemented
//#define USE_LED
#define LED_PIN 32
#define NUM_LEDS 4
// WiFi and MQTT Credentials -- Needed for MQTT only if "fdrs_globals.h" is not included
// 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"
// MQTT Topics
#define TOPIC_DATA "fdrs/data"
#define TOPIC_STATUS "fdrs/status"
#define TOPIC_COMMAND "fdrs/command"

@ -28,7 +28,7 @@
#define NUM_LEDS 24 // Number of physical LEDs.
#include <FastLED.h>
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
CRGB rgb_color = CRGB::Black;

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm
//#define LORA_ACK // Request LoRa acknowledgment. Increases battery usage.
//#define LORA_ACK_TIMEOUT 400 // LoRa ACK timeout in ms. (Minimum = 200)
//#define LORA_RETRIES 2 // LoRa ACK retries [0 - 3]

@ -5,7 +5,7 @@
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
//
//
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#define

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm
//#define LORA_ACK // Request LoRa acknowledgment. Increases battery usage.
//#define LORA_ACK_TIMEOUT 400 // LoRa ACK timeout in ms. (Minimum = 200)
//#define LORA_RETRIES 2 // LoRa ACK retries [0 - 3]

@ -6,7 +6,7 @@
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
//
//
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#include <TFT_eSPI.h>

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm
//#define LORA_ACK // Request LoRa acknowledgment. Increases battery usage.
//#define LORA_ACK_TIMEOUT 400 // LoRa ACK timeout in ms. (Minimum = 200)
//#define LORA_RETRIES 2 // LoRa ACK retries [0 - 3]

@ -2,30 +2,28 @@
//
// ESP-NOW Sensor Example
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// 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_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
void fdrs_recv_cb(DataReading theData) {
void fdrs_recv_cb(DataReading theData)
{
DBG("ID: " + String(theData.id));
DBG("Type: " + String(theData.t));
DBG("Data: " + String(theData.d));
}
void setup() {
void setup()
{
beginFDRS();
//pingFDRS(1000);
addFDRS(1000, fdrs_recv_cb);
pingFDRS(1000);
addFDRS(fdrs_recv_cb);
subscribeFDRS(READING_ID);
}
void loop() {
// data1 = readHum();
// loadFDRS(data1, HUMIDITY_T);
// data2 = readTemp();
// loadFDRS(data2, TEMP_T);
// sendFDRS();
// sleepFDRS(10); //Sleep time in seconds
void loop()
{
loopFDRS();
}

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm
//#define LORA_ACK // Request LoRa acknowledgment. Increases battery usage.
//#define LORA_ACK_TIMEOUT 400 // LoRa ACK timeout in ms. (Minimum = 200)
//#define LORA_RETRIES 2 // LoRa ACK retries [0 - 3]

@ -2,11 +2,11 @@
//
// ESP-NOW Sensor Example
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// 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_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
float data1;

@ -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.

@ -1,34 +0,0 @@
// 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
#define DEBUG_CONFIG // Displays full config info on startup
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm
//#define LORA_ACK // Request LoRa acknowledgment. Increases battery usage.
//#define LORA_ACK_TIMEOUT 400 // LoRa ACK timeout in ms. (Minimum = 200)
//#define LORA_RETRIES 2 // LoRa ACK retries [0 - 3]

@ -5,7 +5,7 @@
// Sends ESP-NOW packets at approximately 60Hz.
//
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
void setup() {

@ -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.

@ -1,34 +0,0 @@
// 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
//#define DEBUG_CONFIG // Displays full config info on startup
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm
//#define LORA_ACK // Request LoRa acknowledgment. Increases battery usage.
//#define LORA_ACK_TIMEOUT 400 // LoRa ACK timeout in ms. (Minimum = 200)
//#define LORA_RETRIES 2 // LoRa ACK retries [0 - 3]

@ -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,70 @@
// 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_TXPWR 17 // LoRa TX power in dBm (: +2dBm - +17dBm (for SX1276-7) +20dBm (for SX1278))
//#define USE_SX126X
//#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_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,22 @@
// 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 //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.

@ -2,11 +2,11 @@
//
// LoRa Sensor Example
//
// Developed by Timm Bogner (timmbogner@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
// An example of how to send data via LoRa using FDRS.
//
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
float data1;

@ -0,0 +1,29 @@
// 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 //Tested on SX1276
//#define USE_SX126X
#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.
//#define CUSTOM_SPI
#define LORA_SPI_SCK 5
#define LORA_SPI_MISO 19
#define LORA_SPI_MOSI 27

@ -1,34 +0,0 @@
// 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
#define DEBUG_CONFIG // Displays full config info on startup
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm
#define LORA_ACK // Request LoRa acknowledgment. Increases battery usage.

@ -4,7 +4,7 @@
//
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <Adafruit_AHTX0.h>
#include <fdrs_node.h>

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -2,9 +2,9 @@
//
// BME280 SENSOR MODULE
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <Adafruit_BME280.h>
#include <fdrs_node.h>

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -5,7 +5,7 @@
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
// Connect sensor SDA and SCL pins to those of the ESP.
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <Adafruit_BMP280.h>
#include <fdrs_node.h>

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -2,11 +2,11 @@
//
// CAPACITIVE SOIL MOISTURE SENSOR MODULE
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
// Connect sensor to the analog pin of the ESP (A0).
//
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
void setup() {
Serial.begin(115200);

@ -0,0 +1,21 @@
// 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 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.

@ -1,33 +0,0 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#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 DEEP_SLEEP
#define POWER_CTRL 14
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -3,7 +3,7 @@
// Modified by Timm Bogner for Farm Data Relay System -- Untested because I don't have a DHT sensor onhand.
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#include "DHT.h"

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -5,7 +5,7 @@
#define ONE_WIRE_BUS 13 //Pin that the DS18B20 is connected to
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#include <OneWire.h>
#include <DallasTemperature.h>

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -7,7 +7,7 @@
// https://www.printables.com/model/176752-gypson-water-sensor
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>

@ -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.

@ -1,33 +0,0 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -6,7 +6,7 @@
// Reads in GPS data from serial and sends latitude, longitude and altitude to a gateway.
//
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#define SERIAL1_RX 34 // TX pin of GPS sensor

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -9,7 +9,7 @@
#define DEBUG
#define CREDENTIALS
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#include <RTClib.h>
RTC_DS3231 rtc;

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -14,7 +14,7 @@
#define USER_BUTTON 35
#define DS18B20_PIN 21
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
#include <BH1750.h>
#include <Adafruit_BME280.h>

@ -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.

@ -1,33 +0,0 @@
// 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 4
#define FDRS_DEBUG
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -5,7 +5,7 @@
// https://github.com/gadjet/Multifunction-ESP8266-Sensor-board
//
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <Adafruit_AHT10.h>
#include <fdrs_node.h>

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -2,9 +2,9 @@
//
// MLX90614 INFRARED TEMPERATURE SENSOR MODULE
//
// Developed by Timm Bogner (bogner1@gmail.com) for Sola Gratia Farm in Urbana, Illinois, USA.
// Developed by Timm Bogner (timmbogner@gmail.com) in Urbana, Illinois, USA.
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <Adafruit_MLX90614.h>
#include <fdrs_node.h>

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -6,7 +6,7 @@
// If you are using the sensor for air monitoring, change SOIL_T to HUMIDITY_T.
//
#include "DFRobot_SHT20.h"
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
DFRobot_SHT20 sht20(&Wire, SHT20_I2C_ADDR);

@ -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.

@ -1,34 +0,0 @@
// FARM DATA RELAY SYSTEM
//
// Sensor Configuration
#include <fdrs_globals.h>
#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
#define DEBUG_CONFIG // Displays full config info on startup
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm
//#define LORA_ACK // Request LoRa acknowledgment. Increases battery usage.
//#define LORA_ACK_TIMEOUT 400 // LoRa ACK timeout in ms. (Minimum = 200)
//#define LORA_RETRIES 2 // LoRa ACK retries [0 - 3]

@ -2,7 +2,7 @@
#include <Adafruit_Sensor.h>
#include <Adafruit_TSL2561_U.h>
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 12345);

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -6,7 +6,7 @@
#define REED_PIN 2
#include "fdrs_sensor_config.h"
#include "fdrs_node_config.h"
#include <fdrs_node.h>
unsigned int theCount = 0;

@ -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.

@ -1,33 +0,0 @@
// 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
//SPI Configuration -- Needed only on chipsets with multiple SPI interfaces (ESP32)
#define SPI_SCK 5
#define SPI_MISO 19
#define SPI_MOSI 27
//LoRa Configuration
#define LORA_SS 18
#define LORA_RST 14
#define LORA_DIO0 26
//433E6 for Asia
//866E6 for Europe
//915E6 for North America
//#define LORA_BAND 915E6 // LoRa Frequency Band
//#define LORA_SF 7 // LoRa Spreading Factor
//#define LORA_TXPWR 17 // LoRa TX power in dBm (+2dBm - +20dBm), default is +17dBm. Lower power = less battery use
//#define LORA_ACK // Uncomment to enable request for LoRa ACKs at cost of increased battery usage
//#define LORA_ACK_TIMEOUT 400 // ms timeout waiting for LoRa ACKs (if enabled). Wouldn't go less than 200ms
//#define LORA_RETRIES 2 // [0 - 3] When ACK enabled, number of sensor node tx retries when ACK not received or invalid CRC

@ -1,74 +1,193 @@
# 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 "Actions" section of the configuration file.
## Actions
Actions define how the gateway reacts to a packet received via each data source. An action may consist of one or multiple commands separated by (and terminated with) semicolons.
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.
The following commands re-send data instantaneously: ```sendESPNOW(MAC)```, ```sendESPNOWpeers()```, ```sendSerial()```, and ```sendMQTT()```.
A basic FDRS gateway's sketch file (.ino) will look like this:
These commands send data to buffers to be released at an interval: ```bufferLoRa(interface)```, ```bufferESPNOW(interface)```, ```bufferSerial()```, and ```bufferMQTT()```.
``` cpp
#include "fdrs_gateway_config.h"
#include <fdrs_gateway.h>
In this example, the gateway is set to take any ESP-NOW packet it receives and send it first over the serial port, then re-transmit it via ESP-NOW to another gateway with the address 0x01:
```
#define ESPNOWG_ACT sendSerial(); sendESPNOW(0x01);
```
## Options
### ```#define UNIT_MAC (0xNN)```
The UNIT_MAC is the ESP-NOW and LoRa address of the gateway. This is the address that nodes or other gateways will use to pass data to this device.
### ```#define FDRS_DEBUG```
This definition enables debug messages to be sent over the serial port. If disabled, the USB serial port is still used to echo data being sent via the sendSerial() command.
### ```#define DEBUG_CONFIG```
This displays a readout of the device's configuration on start-up.
void setup() {
beginFDRS();
}
Thanks to [@gulpman](https://github.com/gulpman) for this feature!
### ```#define RXD2 (pin)``` and ```TXD2 (pin)```
These are the pins for inter-device serial communication. The single ESP8266 serial interface is not configurable, and thus these options only apply to ESP32 boards.
void loop() {
loopFDRS();
}
```
### ```#define USE_ESPNOW```
## 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.
USE_ESPNOW and USE_WIFI must not be activated at the same time!
### ```#define USE_LORA```
Enables LoRa. Make sure that you set the LoRa module configuration parameters in the lines below.
#### ```#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.
LORA_BAND and LORA_SF (spreading factor) can also be configured in 'fdrs_globals.h' if enabled.
### ```#define USE_WIFI```
Enables WiFi. Used only on the MQTT gateway.
## 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.
SSID, password, and MQTT credentials are also configurable in 'fdrs_globals.h'.
### ```#define USE_SD_LOG```
Enables SD-card logging. Used only on the MQTT gateway if sending the MQTT message fails. Make sure to set the correct SD_SS (chip select) pin in the lines below.
Logging is done in the following CSV Format: ```timestamp,reading_id,type,value```
Thanks to [@thefeiter](https://github.com/thefeiter) for this feature!
**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 DIO1 on SX127x chips and DIO1 on SX126x chips.
#### ```#define LORA_TXPWR n```
LoRa TX power in dBm.
#### ```#define USE_SX126X```
Enable this if using the SX126x series of LoRa chips.
#
**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.
#### ```#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.
## 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.
### ```#define USE_LED```
This option initializes FastLED! I haven't developed this very much, perhaps you have ideas?
Calling ```scheduleFDRS(function, interval);``` after initializing FDRS will schedule ```function()``` to be called every ```interval``` milliseconds.
## Neighbors
### Routing
In addition to reacting to packets from general (unknown) ESP-NOW and LoRa devices, the gateway can also listen for traffic originating from a specific device address (MAC) and react differently than it would to general traffic. This can be used to 'propel' packets upstream or downstream and allows the user to define different paths for data originating from either direction. The user can define up to two neighbor addresses each for the ESP-NOW and LoRa interfaces (ESPNOW1 & ESPNOW2 and LORA1 & LORA2).
### Buffers
Each neighbor also has a send buffer associated with it. Buffers are enabled by uncommenting their corresponding DELAY macro (ex: ```#define LORAG_DELAY 1000```). When enabled, the gateway will automatically send the buffer contents at the interval specified.
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.
While ESP-NOW is quick enough to handle a lot of traffic in real-time, LoRa is much slower. For this reason, you must send LoRa data to a buffer. Since buffers are mandatory, a LoRa repeater always needs to be configured using a neighbor.
#### ```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.
Buffers can hold a maximum of 256 DataReadings.
**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();
}
```
#
![Basic](Basic_Setup.png)
![Advanced](Advanced_Setup.png)
![Basic LoRa](Basic_LoRa_Setup.png)
![Advanced LoRa](Advanced_Setup_LoRa.png)
![Advanced LoRa](Advanced_Setup_LoRa.png)

@ -1,124 +1,145 @@
# FDRS User Node
A node is a device that sends and receives data from a nearby gateway. A node can be a sensor, controller, or both.
# 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.
*NOTE: Controller node functionality is currently restricted to the *ESP-NOW protocol*. LoRa gateways can still transport data bi-directionally, but you will need to use ESP-NOW to register a controller node with a gateway.*
# Commands
### ``` beginFDRS();```
## Usage
#### ```beginFDRS();```
Initializes FDRS, powers up the sensor array, and begins ESP-NOW and/or LoRa.
## Sensor Commands
### ```loadFDRS(float d, uint8_t t);```
Loads some data into the current packet. 'd' is a float and 't' is a byte used to represent the sensor type. Type definitions can be found below. Please feel free to contact me if you'd like to add a new sensor type.
### ```bool sendFDRS();```
#### ```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(int sleep_time)```
If available and enabled, the device enters deep-sleep. If ```#DEEP_SLEEP``` is disabled, the device will use a delay instead. ```sleep_time``` is entered in seconds.
## Controller Commands
### ```addFDRS(int timeout, void callback);```
Adds the device to the gateway's peer registry. This enables the device to receive transmissions from the gateway. ```timeout``` is in milliseconds. ```callback``` should be the name of the function that will recieve all incoming transmissions. The ESP-NOW Controller example demonstrates functionality.
### ```subscribeFDRS(uint16_t sub_id)```
#### ```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)```
#### ```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 usage:
## Basic Examples:
### Sensor
Sensor nodes load a packet with data, then send the packet to the gateway that they are addressed to.
```
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();
  beginFDRS(); // Start the system
pingFDRS(2000); // Send ping and wait 2000ms for response
}
void loop() {
  loadFDRS(21.0, TEMP_T);
  sendFDRS();
  sleepFDRS(10);  //Sleep time in seconds
  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
Controller nodes register with the gateway they are addressed to, then receive data from it.
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) {
  //Quickly handle incoming data
DBG("ID: " + String(theData.id));
DBG("Type: " + String(theData.t));
DBG("Data: " + String(theData.d));
}
void setup() {
  beginFDRS();
  //pingFDRS(1000);
  addFDRS(1000, fdrs_recv_cb);
  subscribeFDRS(READING_ID);
  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 READING_ID  n```
The identifier of this individual device. Should be a 16 bit integer value (0 - 65535). Controllers are not necessarily tied to this parameter, and can be subscribed to up to 256 different IDs. Sensors will likely be treated similarly in the future, allowing the user to send sensor readings under multiple IDs.
### ```#define GTWY_MAC  0xnn```
The UNIT_MAC of the gateway that this device will communicate with.
### ```#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 DEBUG_CONFIG```
This displays a readout of the device's configuration on start-up.
Thanks to [@gulpman](https://github.com/gulpman) for this feature!
### ```#define USE_ESPNOW```
#### ```#define USE_ESPNOW```
Enables/disables ESP-NOW.
### ```#define USE_LORA```
#### ```#define USE_LORA```
Enables/disables LoRa.
### ```#define LORA_ACK```
#### ```#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 DEEP_SLEEP```
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 (pin)```
#### ```#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.
## Callback function
The callback function is executed when data arrives with an ID that the controller is subscribed to, interrupting all other tasks. Inside of this function, the user has access to the incoming DataReading.
This function should **ONLY** contain the code needed to save the data to a more permanent location. *Interpretation or display of the data should occur outside of the callback function*. Some light serial debug messages are okay.
Intermediate users may also like to know that if the controller is subscribed to multiple IDs, the callback may be called multiple times before returning to the loop().
#
### 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 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
## Under the Hood
```
typedef struct __attribute__((packed)) DataReading {
  float d;

@ -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 @@
[![Build Status](https://github.com/ThingPulse/esp8266-oled-ssd1306/actions/workflows/main.yml/badge.svg)](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.
[![ThingPulse ESP8266 WeatherStation Classic Kit](https://github.com/ThingPulse/esp8266-weather-station/blob/master/resources/ThingPulse-ESP8266-Weather-Station.jpeg?raw=true)](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.
![FontTool](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/FontTool.png)
## 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
![DemoFrame1](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame1.jpg)
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
![DemoFrame2](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame2.jpg)
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
![DemoFrame3](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame3.jpg)
This frame demonstrates the text alignment. The coordinates in the frame show relative to which position the texts have been rendered.
### Frame 4
![DemoFrame4](https://github.com/squix78/esp8266-oled-ssd1306/raw/master/resources/DemoFrame4.jpg)
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
![SPIVersion](https://github.com/neptune2/esp8266-oled-ssd1306/raw/master/resources/SPI_version.jpg)
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

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save