diff --git a/.gitignore b/.gitignore index e8d6686..57f00e2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ test .gitignore .travis.yml -lib \ No newline at end of file +lib +src \ No newline at end of file diff --git a/README.MD b/README.MD index 68f008a..161efe4 100644 --- a/README.MD +++ b/README.MD @@ -1,10 +1,52 @@ -TTGO-T-Beam -===================== +

🌟LilyGo LoRa Series🌟

-![](image/product.jpg) +## **English | [中文](./README_CN.MD)** + + +

Quick start:

+ +1. Copy all folders in the `libdeps` directory to the `~/Arduino/libraries` directory, and put them in `"Documents/Arduino/libraries"` for Windons users +2. Open the corresponding example +3. Choose `TTGO T-Beam` for the board +4. Select the port of the board in the port +5. The default version is 1.0/1.1. If the purchased version is v0.7, please comment out `T_BEAM_V10` in the example `utilities.h`, and uncomment `T_BEAM_V07`, if you don’t know the version, please ask customer service, or Check the silkscreen on the board +6. Upload + + +

Product 📷:

+ +| Product | Product Link | +| :-----------------------: | :---------------------------------------------------------------: | +| [T-Beam SX1278/SX1276 ]() | [Product link](https://pt.aliexpress.com/item/32967228739.html) | +| [T-Beam SX1262]() | [Product link](https://pt.aliexpress.com/item/4001287221970.html) | + + + +

Application :

+ +- [T-Beam SoftRF](https://github.com/lyusupov/SoftRF) +- [T-Beam Paxcounter](https://github.com/cyberman54/ESP32-Paxcounter) +- [T-Beam Meshtastic](https://github.com/meshtastic/Meshtastic-device) + +

Datasheet :

+ +- [AXP192](http://www.x-powers.com/en.php/Info/product_detail/article_id/29) +- [SX1262 LoRa](https://www.semtech.com/products/wireless-rf/lora-transceivers/sx1262) +- [SX1278 LoRa](https://www.semtech.com/products/wireless-rf/lora-transceivers/sx1278) +- [SX1276 LoRa](https://www.semtech.com/products/wireless-rf/lora-transceivers/sx1276) +- [GSP NEO-6/NEO-8](https://www.u-blox.com/en/product/neo-6-series) +- [GPS Air530]() + +

Schematic :

+ +- [TBeam_V0.7 Schematic](schematic/LilyGo_TBeam_V0.7.pdf) +- [TBeam_V1.0 Schematic](schematic/LilyGo_TBeam_V1.0.pdf) +- [TBeam_V1.1 Schematic](schematic/LilyGo_TBeam_V1.1.pdf) + + +

PinOut :

-## PinOut | Pins | T_BEAM(AXP192) | T_BEAM_V07 | | ----------- | -------------- | ---------- | | LORA_SCK | 5 | 5 | @@ -22,7 +64,9 @@ TTGO-T-Beam | PMU_IRQ | 35 | N/A | | USER BUTTON | 36 | N/A | -## Power Control Channel + +

Power Control Channel :

+ | Modules | T_BEAM_V10/V1.1 | T_BEAM_V07 | | ------- | --------------- | ---------- | | GPS | LDO3 | No supoort | @@ -30,25 +74,5 @@ TTGO-T-Beam | OLED | DCDC1 | No supoort | -### Button Map - -| USB | BTN1 | BTN2 | BTN3 | -| --- | --------------- | ----------- | ----- | -| N/A | axp192 powerkey | user button | reset | -## Button Function: -- Click button 2 will cycle the user function, the default start to enable GPS positioning, the second click will be set to lora send, the third click will be set to lora receive, long press for two seconds and then release, will enter deep sleep - -## About OLED: -- The boot will scan the I2C device. If the OLED is found, all log information will be displayed in the OLED. If not, it will be printed on the serial port. - -## How to use -- For dependencies on other files please see `platformio.ini` -- Regarding the board, you can modify the board version and lora frequency in `board_def.h` -- If you use the Arduino IDE for compilation, please store `board_def.h` and `LilyGO-T-Beam.ino` in the same directory, and the directory folder name must be the same as ino - -## Deepsleep -- Regarding deep sleep, except for DCDC3, power off all channels of AXP192, the current consumption is about 580μA - -![](image/deepsleep.jpg) diff --git a/README_CN.MD b/README_CN.MD new file mode 100644 index 0000000..3ceb4b2 --- /dev/null +++ b/README_CN.MD @@ -0,0 +1,77 @@ +

🌟LilyGo LoRa Series🌟

+ +## **[English](./README.MD) | 中文** + +

快速开始:

+ +1. 将 `libdeps` 目录中所有文件夹复制到`~/Arduino/libraries`目录内,Windons用户放在 `"我的文档/Arduino/libraries"` +2. 打开对应的示例 +3. 板子选择`TTGO T-Beam` +4. 在端口中选择板子的端口 +5. 默认版本为1.0/1.1,如果购买的版本是v0.7,请在示例`utilities.h`中 注释掉 `T_BEAM_V10` ,并且取消`T_BEAM_V07`的注释,不清楚版本,请询问客服,或者查看板子上的丝印 +6. 上传 + + +

Product 📷:

+ +| Product | Product Link | +| :-----------------------: | :---------------------------------------------------------------: | +| [T-Beam SX1278/SX1276 ]() | [Product link](https://pt.aliexpress.com/item/32967228739.html) | +| [T-Beam SX1262]() | [Product link](https://pt.aliexpress.com/item/4001287221970.html) | + + + +

Application :

+ +- [T-Beam SoftRF](https://github.com/lyusupov/SoftRF) +- [T-Beam Paxcounter](https://github.com/cyberman54/ESP32-Paxcounter) +- [T-Beam Meshtastic](https://github.com/meshtastic/Meshtastic-device) + +

Datasheet :

+ +- [AXP192](http://www.x-powers.com/en.php/Info/product_detail/article_id/29) +- [SX1262 LoRa](https://www.semtech.com/products/wireless-rf/lora-transceivers/sx1262) +- [SX1278 LoRa](https://www.semtech.com/products/wireless-rf/lora-transceivers/sx1278) +- [SX1276 LoRa](https://www.semtech.com/products/wireless-rf/lora-transceivers/sx1276) +- [GSP NEO-6/NEO-8](https://www.u-blox.com/en/product/neo-6-series) +- [GPS Air530]() + +

Schematic :

+ +- [TBeam_V0.7 Schematic](schematic/LilyGo_TBeam_V0.7.pdf) +- [TBeam_V1.0 Schematic](schematic/LilyGo_TBeam_V1.0.pdf) +- [TBeam_V1.1 Schematic](schematic/LilyGo_TBeam_V1.1.pdf) + + +

PinOut :

+ + +| Pins | T_BEAM(AXP192) | T_BEAM_V07 | +| ----------- | -------------- | ---------- | +| LORA_SCK | 5 | 5 | +| LORA_MISO | 19 | 19 | +| LORA_MOSI | 27 | 27 | +| LORA_SS | 18 | 18 | +| LORA_DIO0 | 26 | 26 | +| LORA_DIO1 | 33 | 33 | +| LORA_DIO2 | 32 | 32 | +| LORA_RST | 23 | 23 | +| GPS_RX_PIN | 34 | 12 | +| GPS_TX_PIN | 12 | 15 | +| I2C_SDA | 21 | 21 | +| I2C_SCL | 22 | 22 | +| PMU_IRQ | 35 | N/A | +| USER BUTTON | 36 | N/A | + + +

Power Control Channel :

+ +| Modules | T_BEAM_V10/V1.1 | T_BEAM_V07 | +| ------- | --------------- | ---------- | +| GPS | LDO3 | No supoort | +| LORA | LDO2 | No supoort | +| OLED | DCDC1 | No supoort | + + + + diff --git a/TBEAM_20200803.zip b/TBEAM_20200803.zip deleted file mode 100644 index 88bd00c..0000000 Binary files a/TBEAM_20200803.zip and /dev/null differ diff --git a/bin/433/TBeam_433.bin b/bin/433/TBeam_433.bin deleted file mode 100644 index 1fc2e32..0000000 Binary files a/bin/433/TBeam_433.bin and /dev/null differ diff --git a/bin/433/TBeam_433.txt b/bin/433/TBeam_433.txt deleted file mode 100644 index 9b1988d..0000000 --- a/bin/433/TBeam_433.txt +++ /dev/null @@ -1,8 +0,0 @@ -Ŀļ:D:\TTGO-Series\TTGO-T-Beam\bin\433\TBeam_433.bin С:0x000515F0 -ִС: - - ļ С ƫ ǿƲ - 1 D:\TTGO-Series\TTGO-T-Beam\bin\boot_app0.bin 0x00002000 0x0000E000 - 2 D:\TTGO-Series\TTGO-T-Beam\bin\bootloader_dio_80m.bin 0x00003D30 0x00001000 - 3 D:\TTGO-Series\TTGO-T-Beam\bin\433\TTGO-T-Beam.ino.bin 0x000415F0 0x00010000 - 4 D:\TTGO-Series\TTGO-T-Beam\bin\433\TTGO-T-Beam.ino.partitions.bin 0x00000C00 0x00008000 diff --git a/bin/433/TTGO-T-Beam.ino.bin b/bin/433/TTGO-T-Beam.ino.bin deleted file mode 100644 index acbe3bf..0000000 Binary files a/bin/433/TTGO-T-Beam.ino.bin and /dev/null differ diff --git a/bin/433/TTGO-T-Beam.ino.partitions.bin b/bin/433/TTGO-T-Beam.ino.partitions.bin deleted file mode 100644 index 6326adc..0000000 Binary files a/bin/433/TTGO-T-Beam.ino.partitions.bin and /dev/null differ diff --git a/bin/868/TBeam_868.bin b/bin/868/TBeam_868.bin deleted file mode 100644 index 3f0efda..0000000 Binary files a/bin/868/TBeam_868.bin and /dev/null differ diff --git a/bin/868/TBeam_868.txt b/bin/868/TBeam_868.txt deleted file mode 100644 index 66e4c5c..0000000 --- a/bin/868/TBeam_868.txt +++ /dev/null @@ -1,8 +0,0 @@ -Ŀļ:D:\TTGO-Series\TTGO-T-Beam\bin\868\TBeam_868.bin С:0x000515F0 -ִС: - - ļ С ƫ ǿƲ - 1 D:\TTGO-Series\TTGO-T-Beam\bin\boot_app0.bin 0x00002000 0x0000E000 - 2 D:\TTGO-Series\TTGO-T-Beam\bin\bootloader_dio_80m.bin 0x00003D30 0x00001000 - 3 D:\TTGO-Series\TTGO-T-Beam\bin\868\TTGO-T-Beam.ino.bin 0x000415F0 0x00010000 - 4 D:\TTGO-Series\TTGO-T-Beam\bin\868\TTGO-T-Beam.ino.partitions.bin 0x00000C00 0x00008000 diff --git a/bin/868/TTGO-T-Beam.ino.bin b/bin/868/TTGO-T-Beam.ino.bin deleted file mode 100644 index d3d2b4f..0000000 Binary files a/bin/868/TTGO-T-Beam.ino.bin and /dev/null differ diff --git a/bin/868/TTGO-T-Beam.ino.partitions.bin b/bin/868/TTGO-T-Beam.ino.partitions.bin deleted file mode 100644 index 6326adc..0000000 Binary files a/bin/868/TTGO-T-Beam.ino.partitions.bin and /dev/null differ diff --git a/bin/915/TBeam_915.bin b/bin/915/TBeam_915.bin deleted file mode 100644 index bf788f2..0000000 Binary files a/bin/915/TBeam_915.bin and /dev/null differ diff --git a/bin/915/TBeam_915.txt b/bin/915/TBeam_915.txt deleted file mode 100644 index 72520e7..0000000 --- a/bin/915/TBeam_915.txt +++ /dev/null @@ -1,8 +0,0 @@ -Ŀļ:D:\TTGO-Series\TTGO-T-Beam\bin\915\TBeam_915.bin С:0x000515F0 -ִС: - - ļ С ƫ ǿƲ - 1 D:\TTGO-Series\TTGO-T-Beam\bin\boot_app0.bin 0x00002000 0x0000E000 - 2 D:\TTGO-Series\TTGO-T-Beam\bin\bootloader_dio_80m.bin 0x00003D30 0x00001000 - 3 D:\TTGO-Series\TTGO-T-Beam\bin\915\TTGO-T-Beam.ino.bin 0x000415F0 0x00010000 - 4 D:\TTGO-Series\TTGO-T-Beam\bin\915\TTGO-T-Beam.ino.partitions.bin 0x00000C00 0x00008000 diff --git a/bin/915/TTGO-T-Beam.ino.bin b/bin/915/TTGO-T-Beam.ino.bin deleted file mode 100644 index 70ee202..0000000 Binary files a/bin/915/TTGO-T-Beam.ino.bin and /dev/null differ diff --git a/bin/915/TTGO-T-Beam.ino.partitions.bin b/bin/915/TTGO-T-Beam.ino.partitions.bin deleted file mode 100644 index 6326adc..0000000 Binary files a/bin/915/TTGO-T-Beam.ino.partitions.bin and /dev/null differ diff --git a/bin/boot_app0.bin b/bin/boot_app0.bin deleted file mode 100644 index 13562ca..0000000 Binary files a/bin/boot_app0.bin and /dev/null differ diff --git a/bin/bootloader_dio_80m.bin b/bin/bootloader_dio_80m.bin deleted file mode 100644 index d0d0a8b..0000000 Binary files a/bin/bootloader_dio_80m.bin and /dev/null differ diff --git a/examples/AllFunction/AllFunction.ino b/examples/AllFunction/AllFunction.ino index d80210d..9878910 100644 --- a/examples/AllFunction/AllFunction.ino +++ b/examples/AllFunction/AllFunction.ino @@ -3,7 +3,7 @@ * Created by Lewis he * */ -#include "board_def.h" +#include "utilities.h" #include #include #include "axp20x.h" diff --git a/examples/AllFunction/board_def.h b/examples/AllFunction/utilities.h similarity index 100% rename from examples/AllFunction/board_def.h rename to examples/AllFunction/utilities.h diff --git a/examples/ArduinoLoRa/LoRaReceiver/LoRaReceiver.ino b/examples/ArduinoLoRa/LoRaReceiver/LoRaReceiver.ino new file mode 100644 index 0000000..ba58b41 --- /dev/null +++ b/examples/ArduinoLoRa/LoRaReceiver/LoRaReceiver.ino @@ -0,0 +1,37 @@ + +#include +#include "utilities.h" + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + Serial.println("LoRa Receiver"); + + LoRa.setPins(RADIO_CS_PIN, RADIO_RST_PIN, RADIO_DI0_PIN); + if (!LoRa.begin(868E6)) { + Serial.println("Starting LoRa failed!"); + while (1); + } +} + +void loop() +{ + // try to parse packet + int packetSize = LoRa.parsePacket(); + if (packetSize) { + // received a packet + Serial.print("Received packet '"); + + // read packet + while (LoRa.available()) { + Serial.print((char)LoRa.read()); + } + + // print RSSI of packet + Serial.print("' with RSSI "); + Serial.println(LoRa.packetRssi()); + } +} diff --git a/examples/ArduinoLoRa/LoRaReceiver/utilities.h b/examples/ArduinoLoRa/LoRaReceiver/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/ArduinoLoRa/LoRaReceiver/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/ArduinoLoRa/LoRaSender/LoRaSender.ino b/examples/ArduinoLoRa/LoRaSender/LoRaSender.ino new file mode 100644 index 0000000..a5925da --- /dev/null +++ b/examples/ArduinoLoRa/LoRaSender/LoRaSender.ino @@ -0,0 +1,34 @@ +#include +#include "utilities.h" + +int counter = 0; + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + Serial.println("LoRa Sender"); + LoRa.setPins(RADIO_CS_PIN, RADIO_RST_PIN, RADIO_DI0_PIN); + if (!LoRa.begin(868E6)) { + Serial.println("Starting LoRa failed!"); + while (1); + } +} + +void loop() +{ + Serial.print("Sending packet: "); + Serial.println(counter); + + // send packet + LoRa.beginPacket(); + LoRa.print("hello "); + LoRa.print(counter); + LoRa.endPacket(); + + counter++; + + delay(5000); +} diff --git a/examples/ArduinoLoRa/LoRaSender/utilities.h b/examples/ArduinoLoRa/LoRaSender/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/ArduinoLoRa/LoRaSender/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/GPS/Example1_BasicNMEARead/Example1_BasicNMEARead.ino b/examples/GPS/Example1_BasicNMEARead/Example1_BasicNMEARead.ino new file mode 100644 index 0000000..6aed298 --- /dev/null +++ b/examples/GPS/Example1_BasicNMEARead/Example1_BasicNMEARead.ino @@ -0,0 +1,36 @@ +/* + Read NMEA sentences over Serial using Ublox module SAM-M8Q, NEO-M8P, ZED-F9P, etc + This example reads the NMEA setences from the Ublox module over Serial and outputs + them to the serial port + Base on SparkFun_Ublox_Arduino_Library //https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library +*/ +#include "SparkFun_Ublox_Arduino_Library.h" +#include "utilities.h" + +SFE_UBLOX_GPS myGPS; + +void setup() +{ + initBoard(); + + // When the power is turned on, a delay is required. + delay(1500); + + Serial.println("SparkFun Ublox Example"); + myGPS.enableDebugging(); + + if (myGPS.begin(Serial1) == false) { + Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing.")); + while (1); + } + + //This will pipe all NMEA sentences to the serial port so we can see them + myGPS.setNMEAOutputPort(Serial); +} + +void loop() +{ + myGPS.checkUblox(); //See if new data is available. Process bytes as they come in. + + delay(250); //Don't pound too hard on the I2C bus +} diff --git a/examples/GPS/Example1_BasicNMEARead/utilities.h b/examples/GPS/Example1_BasicNMEARead/utilities.h new file mode 100644 index 0000000..4bfe3ef --- /dev/null +++ b/examples/GPS/Example1_BasicNMEARead/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN, RADIO_CS_PIN); + initPMU(); +} + + diff --git a/examples/GPS/Example2_NMEAParsing/Example2_NMEAParsing.ino b/examples/GPS/Example2_NMEAParsing/Example2_NMEAParsing.ino new file mode 100644 index 0000000..1a26239 --- /dev/null +++ b/examples/GPS/Example2_NMEAParsing/Example2_NMEAParsing.ino @@ -0,0 +1,60 @@ +/* + Read NMEA sentences over sERIAL using Ublox module SAM-M8Q, NEO-M8P, etc + Base on SparkFun_Ublox_Arduino_Library //https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library +*/ + +#include "SparkFun_Ublox_Arduino_Library.h" +#include "utilities.h" + +SFE_UBLOX_GPS myGPS; + +#include //https://github.com/stevemarple/MicroNMEA + +char nmeaBuffer[100]; +MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer)); + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + Serial.println("SparkFun Ublox Example"); + + if (myGPS.begin(Serial1) == false) { + Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing.")); + while (1); + } +} + +void loop() +{ + myGPS.checkUblox(); //See if new data is available. Process bytes as they come in. + + if (nmea.isValid() == true) { + long latitude_mdeg = nmea.getLatitude(); + long longitude_mdeg = nmea.getLongitude(); + + Serial.print("Latitude (deg): "); + Serial.println(latitude_mdeg / 1000000., 6); + Serial.print("Longitude (deg): "); + Serial.println(longitude_mdeg / 1000000., 6); + } else { + Serial.print("No Fix - "); + Serial.print("Num. satellites: "); + Serial.println(nmea.getNumSatellites()); + } + + delay(250); //Don't pound too hard on the I2C bus +} + +//This function gets called from the SparkFun Ublox Arduino Library +//As each NMEA character comes in you can specify what to do with it +//Useful for passing to other libraries like tinyGPS, MicroNMEA, or even +//a buffer, radio, etc. +void SFE_UBLOX_GPS::processNMEA(char incoming) +{ + //Take the incoming char from the Ublox I2C port and pass it on to the MicroNMEA lib + //for sentence cracking + nmea.process(incoming); +} diff --git a/examples/GPS/Example2_NMEAParsing/utilities.h b/examples/GPS/Example2_NMEAParsing/utilities.h new file mode 100644 index 0000000..4bfe3ef --- /dev/null +++ b/examples/GPS/Example2_NMEAParsing/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN, RADIO_CS_PIN); + initPMU(); +} + + diff --git a/examples/GPS/Example3_FactoryDefaultsviaSerial/Example3_FactoryDefaultsviaSerial.ino b/examples/GPS/Example3_FactoryDefaultsviaSerial/Example3_FactoryDefaultsviaSerial.ino new file mode 100644 index 0000000..18b7243 --- /dev/null +++ b/examples/GPS/Example3_FactoryDefaultsviaSerial/Example3_FactoryDefaultsviaSerial.ino @@ -0,0 +1,83 @@ +/* + Test baud rate changes on serial, factory reset, and hard reset. + Base on SparkFun_Ublox_Arduino_Library //https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library +*/ + +#include "SparkFun_Ublox_Arduino_Library.h" +#include "utilities.h" + +SFE_UBLOX_GPS myGPS; +int state = 0; // steps through auto-baud, reset, etc states + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + Serial.println("SparkFun Ublox Example"); +} + +void loop() +{ + Serial.print("===== STATE "); + Serial.println(state); + switch (state) { + case 0: // auto-baud connection, then switch to 38400 and save config + do { + Serial.println("GPS: trying 38400 baud"); + Serial1.begin(38400, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + if (myGPS.begin(Serial1)) break; + + delay(100); + Serial.println("GPS: trying 9600 baud"); + Serial1.begin(9600, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + + if (myGPS.begin(Serial1)) { + Serial.println("GPS: connected at 9600 baud, switching to 38400"); + myGPS.setSerialRate(38400); + delay(100); + } else { + delay(2000); //Wait a bit before trying again to limit the Serial output flood + } + } while (1); + myGPS.setUART1Output(COM_TYPE_UBX); //Set the UART port to output UBX only + myGPS.saveConfiguration(); //Save the current settings to flash and BBR + Serial.println("GPS serial connected, saved config"); + state++; + break; + case 1: // hardReset, expect to see GPS back at 38400 baud + Serial.println("Issuing hardReset (cold start)"); + myGPS.hardReset(); + delay(1000); + Serial1.begin(38400, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + + if (myGPS.begin(Serial1)) { + Serial.println("Success."); + state++; + } else { + Serial.println("*** GPS did not respond at 38400 baud, starting over."); + state = 0; + } + break; + case 2: // factoryReset, expect to see GPS back at 9600 baud + Serial.println("Issuing factoryReset"); + myGPS.factoryReset(); + delay(2000); // takes more than one second... a loop to resync would be best + Serial1.begin(9600, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + if (myGPS.begin(Serial1)) { + Serial.println("Success."); + state++; + } else { + Serial.println("*** GPS did not come back at 9600 baud, starting over."); + state = 0; + } + break; + case 3: // print version info + state = 0; + Serial.println("Reset Done"); + while (1) { + delay(10000); + } + } + delay(1000); +} diff --git a/examples/GPS/Example3_FactoryDefaultsviaSerial/utilities.h b/examples/GPS/Example3_FactoryDefaultsviaSerial/utilities.h new file mode 100644 index 0000000..4bfe3ef --- /dev/null +++ b/examples/GPS/Example3_FactoryDefaultsviaSerial/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN, RADIO_CS_PIN); + initPMU(); +} + + diff --git a/examples/GPS/TinyGPS_Example/TinyGPS_Example.ino b/examples/GPS/TinyGPS_Example/TinyGPS_Example.ino new file mode 100644 index 0000000..245f3be --- /dev/null +++ b/examples/GPS/TinyGPS_Example/TinyGPS_Example.ino @@ -0,0 +1,80 @@ +/* + This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object. + Base on TinyGPSPlus //https://github.com/mikalhart/TinyGPSPlus +*/ + +#include +#include "utilities.h" + +TinyGPSPlus gps; + +void displayInfo(); + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + Serial.println(F("DeviceExample.ino")); + Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module")); + Serial.print(F("Testing TinyGPS++ library v. ")); + Serial.println(TinyGPSPlus::libraryVersion()); + Serial.println(F("by Mikal Hart")); + Serial.println(); +} + +void loop() +{ + // This sketch displays information every time a new sentence is correctly encoded. + while (Serial1.available() > 0) + if (gps.encode(Serial1.read())) + displayInfo(); + + if (millis() > 5000 && gps.charsProcessed() < 10) { + Serial.println(F("No GPS detected: check wiring.")); + while (true); + } +} + +void displayInfo() +{ + Serial.print(F("Location: ")); + if (gps.location.isValid()) { + Serial.print(gps.location.lat(), 6); + Serial.print(F(",")); + Serial.print(gps.location.lng(), 6); + } else { + Serial.print(F("INVALID")); + } + + Serial.print(F(" Date/Time: ")); + if (gps.date.isValid()) { + Serial.print(gps.date.month()); + Serial.print(F("/")); + Serial.print(gps.date.day()); + Serial.print(F("/")); + Serial.print(gps.date.year()); + } else { + Serial.print(F("INVALID")); + } + + Serial.print(F(" ")); + if (gps.time.isValid()) { + if (gps.time.hour() < 10) Serial.print(F("0")); + Serial.print(gps.time.hour()); + Serial.print(F(":")); + if (gps.time.minute() < 10) Serial.print(F("0")); + Serial.print(gps.time.minute()); + Serial.print(F(":")); + if (gps.time.second() < 10) Serial.print(F("0")); + Serial.print(gps.time.second()); + Serial.print(F(".")); + if (gps.time.centisecond() < 10) Serial.print(F("0")); + Serial.print(gps.time.centisecond()); + } else { + Serial.print(F("INVALID")); + } + + Serial.println(); +} diff --git a/examples/GPS/TinyGPS_Example/utilities.h b/examples/GPS/TinyGPS_Example/utilities.h new file mode 100644 index 0000000..4bfe3ef --- /dev/null +++ b/examples/GPS/TinyGPS_Example/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN, RADIO_CS_PIN); + initPMU(); +} + + diff --git a/examples/GPS/TinyGPS_KitchenSink/TinyGPS_KitchenSink.ino b/examples/GPS/TinyGPS_KitchenSink/TinyGPS_KitchenSink.ino new file mode 100644 index 0000000..077815a --- /dev/null +++ b/examples/GPS/TinyGPS_KitchenSink/TinyGPS_KitchenSink.ino @@ -0,0 +1,179 @@ +/* + This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object. + Base on TinyGPSPlus //https://github.com/mikalhart/TinyGPSPlus +*/ + +#include +#include "utilities.h" + +TinyGPSPlus gps; + +// For stats that happen every 5 seconds +unsigned long last = 0UL; + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + Serial.println(F("DeviceExample.ino")); + Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module")); + Serial.print(F("Testing TinyGPS++ library v. ")); + Serial.println(TinyGPSPlus::libraryVersion()); + Serial.println(F("by Mikal Hart")); + Serial.println(); +} + +void loop() +{ + // This sketch displays information every time a new sentence is correctly encoded. + while (Serial1.available() > 0) + gps.encode(Serial1.read()); + + + if (gps.location.isUpdated()) { + Serial.print(F("LOCATION Fix Age=")); + Serial.print(gps.location.age()); + Serial.print(F("ms Raw Lat=")); + Serial.print(gps.location.rawLat().negative ? "-" : "+"); + Serial.print(gps.location.rawLat().deg); + Serial.print("[+"); + Serial.print(gps.location.rawLat().billionths); + Serial.print(F(" billionths], Raw Long=")); + Serial.print(gps.location.rawLng().negative ? "-" : "+"); + Serial.print(gps.location.rawLng().deg); + Serial.print("[+"); + Serial.print(gps.location.rawLng().billionths); + Serial.print(F(" billionths], Lat=")); + Serial.print(gps.location.lat(), 6); + Serial.print(F(" Long=")); + Serial.println(gps.location.lng(), 6); + } + + else if (gps.date.isUpdated()) { + Serial.print(F("DATE Fix Age=")); + Serial.print(gps.date.age()); + Serial.print(F("ms Raw=")); + Serial.print(gps.date.value()); + Serial.print(F(" Year=")); + Serial.print(gps.date.year()); + Serial.print(F(" Month=")); + Serial.print(gps.date.month()); + Serial.print(F(" Day=")); + Serial.println(gps.date.day()); + } + + else if (gps.time.isUpdated()) { + Serial.print(F("TIME Fix Age=")); + Serial.print(gps.time.age()); + Serial.print(F("ms Raw=")); + Serial.print(gps.time.value()); + Serial.print(F(" Hour=")); + Serial.print(gps.time.hour()); + Serial.print(F(" Minute=")); + Serial.print(gps.time.minute()); + Serial.print(F(" Second=")); + Serial.print(gps.time.second()); + Serial.print(F(" Hundredths=")); + Serial.println(gps.time.centisecond()); + } + + else if (gps.speed.isUpdated()) { + Serial.print(F("SPEED Fix Age=")); + Serial.print(gps.speed.age()); + Serial.print(F("ms Raw=")); + Serial.print(gps.speed.value()); + Serial.print(F(" Knots=")); + Serial.print(gps.speed.knots()); + Serial.print(F(" MPH=")); + Serial.print(gps.speed.mph()); + Serial.print(F(" m/s=")); + Serial.print(gps.speed.mps()); + Serial.print(F(" km/h=")); + Serial.println(gps.speed.kmph()); + } + + else if (gps.course.isUpdated()) { + Serial.print(F("COURSE Fix Age=")); + Serial.print(gps.course.age()); + Serial.print(F("ms Raw=")); + Serial.print(gps.course.value()); + Serial.print(F(" Deg=")); + Serial.println(gps.course.deg()); + } + + else if (gps.altitude.isUpdated()) { + Serial.print(F("ALTITUDE Fix Age=")); + Serial.print(gps.altitude.age()); + Serial.print(F("ms Raw=")); + Serial.print(gps.altitude.value()); + Serial.print(F(" Meters=")); + Serial.print(gps.altitude.meters()); + Serial.print(F(" Miles=")); + Serial.print(gps.altitude.miles()); + Serial.print(F(" KM=")); + Serial.print(gps.altitude.kilometers()); + Serial.print(F(" Feet=")); + Serial.println(gps.altitude.feet()); + } + + else if (gps.satellites.isUpdated()) { + Serial.print(F("SATELLITES Fix Age=")); + Serial.print(gps.satellites.age()); + Serial.print(F("ms Value=")); + Serial.println(gps.satellites.value()); + } + + else if (gps.hdop.isUpdated()) { + Serial.print(F("HDOP Fix Age=")); + Serial.print(gps.hdop.age()); + Serial.print(F("ms raw=")); + Serial.print(gps.hdop.value()); + Serial.print(F(" hdop=")); + Serial.println(gps.hdop.hdop()); + } + + else if (millis() - last > 5000) { + Serial.println(); + if (gps.location.isValid()) { + static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002; + double distanceToLondon = + TinyGPSPlus::distanceBetween( + gps.location.lat(), + gps.location.lng(), + LONDON_LAT, + LONDON_LON); + double courseToLondon = + TinyGPSPlus::courseTo( + gps.location.lat(), + gps.location.lng(), + LONDON_LAT, + LONDON_LON); + + Serial.print(F("LONDON Distance=")); + Serial.print(distanceToLondon / 1000, 6); + Serial.print(F(" km Course-to=")); + Serial.print(courseToLondon, 6); + Serial.print(F(" degrees [")); + Serial.print(TinyGPSPlus::cardinal(courseToLondon)); + Serial.println(F("]")); + } + + Serial.print(F("DIAGS Chars=")); + Serial.print(gps.charsProcessed()); + Serial.print(F(" Sentences-with-Fix=")); + Serial.print(gps.sentencesWithFix()); + Serial.print(F(" Failed-checksum=")); + Serial.print(gps.failedChecksum()); + Serial.print(F(" Passed-checksum=")); + Serial.println(gps.passedChecksum()); + + if (gps.charsProcessed() < 10) + Serial.println(F("WARNING: No GPS data. Check wiring.")); + + last = millis(); + Serial.println(); + } +} + diff --git a/examples/GPS/TinyGPS_KitchenSink/utilities.h b/examples/GPS/TinyGPS_KitchenSink/utilities.h new file mode 100644 index 0000000..4bfe3ef --- /dev/null +++ b/examples/GPS/TinyGPS_KitchenSink/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN, RADIO_CS_PIN); + initPMU(); +} + + diff --git a/examples/OLED/SSD1306SimpleDemo/SSD1306SimpleDemo.ino b/examples/OLED/SSD1306SimpleDemo/SSD1306SimpleDemo.ino new file mode 100644 index 0000000..62107f2 --- /dev/null +++ b/examples/OLED/SSD1306SimpleDemo/SSD1306SimpleDemo.ino @@ -0,0 +1,173 @@ +/** + * 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 // Only needed for Arduino 1.6.5 and earlier +#include "SSD1306Wire.h" // legacy: #include "SSD1306.h" +// Optionally include custom images +#include "images.h" +#include "utilities.h" + + +SSD1306Wire display(0x3c, I2C_SDA, I2C_SCL); + + +#define DEMO_DURATION 3000 +typedef void (*Demo)(void); + +int demoMode = 0; +int counter = 1; + +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 setup() +{ + initBoard(); + delay(1500); + + // Initialising the UI will init the display too. + display.init(); + + display.flipScreenVertically(); + display.setFont(ArialMT_Plain_10); +} + +void loop() +{ + // clear the display + display.clear(); + // draw the current demo method + demos[demoMode](); + + display.setTextAlignment(TEXT_ALIGN_RIGHT); + display.drawString(10, 128, String(millis())); + // write the buffer to the display + display.display(); + + if (millis() - timeSinceLastModeSwitch > DEMO_DURATION) { + demoMode = (demoMode + 1) % demoLength; + timeSinceLastModeSwitch = millis(); + } + counter++; + delay(10); +} diff --git a/examples/OLED/SSD1306SimpleDemo/images.h b/examples/OLED/SSD1306SimpleDemo/images.h new file mode 100644 index 0000000..5041799 --- /dev/null +++ b/examples/OLED/SSD1306SimpleDemo/images.h @@ -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, + }; diff --git a/examples/OLED/SSD1306SimpleDemo/utilities.h b/examples/OLED/SSD1306SimpleDemo/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/OLED/SSD1306SimpleDemo/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/OLED/SSD1306UiDemo/SSD1306UiDemo.ino b/examples/OLED/SSD1306UiDemo/SSD1306UiDemo.ino new file mode 100644 index 0000000..b2f9619 --- /dev/null +++ b/examples/OLED/SSD1306UiDemo/SSD1306UiDemo.ino @@ -0,0 +1,166 @@ +/** + * 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 // Only needed for Arduino 1.6.5 and earlier +#include "SSD1306Wire.h" // legacy: #include "SSD1306.h" +#include "images.h" +#include "utilities.h" +#include "OLEDDisplayUi.h" + +SSD1306Wire display(0x3c, I2C_SDA, I2C_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() +{ + initBoard(); + delay(1500); + + // 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); + } +} diff --git a/examples/OLED/SSD1306UiDemo/images.h b/examples/OLED/SSD1306UiDemo/images.h new file mode 100644 index 0000000..7ad3c0d --- /dev/null +++ b/examples/OLED/SSD1306UiDemo/images.h @@ -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 +}; diff --git a/examples/OLED/SSD1306UiDemo/utilities.h b/examples/OLED/SSD1306UiDemo/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/OLED/SSD1306UiDemo/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/SX1262/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino b/examples/SX1262/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino new file mode 100644 index 0000000..8d7dfca --- /dev/null +++ b/examples/SX1262/SX126x_Receive_Interrupt/SX126x_Receive_Interrupt.ino @@ -0,0 +1,149 @@ +/* + RadioLib SX1276 Transmit Example + + This example transmits packets using SX1276 LoRa radio module. + Each packet contains up to 256 bytes of data, in the form of: + - Arduino String + - null-terminated char array (C-string) + - arbitrary binary data (byte array) + + Other modules from SX127x/RFM9x family can also be used. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + + +#include +#include "utilities.h" + +SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + + +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// disable interrupt when it's not needed +volatile bool enableInterrupt = true; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) +{ + // check if the interrupt is enabled + if (!enableInterrupt) { + return; + } + + // we got a packet, set the flag + receivedFlag = true; +} + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + + // initialize SX1262 with default settings + Serial.print(F("[SX1262] Initializing ... ")); + int state = radio.begin(); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set the function that will be called + // when new packet is received + radio.setDio1Action(setFlag); + + // start listening for LoRa packets + Serial.print(F("[SX1262] Starting to listen ... ")); + state = radio.startReceive(); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // if needed, 'listen' mode can be disabled by calling + // any of the following methods: + // + // radio.standby() + // radio.sleep() + // radio.transmit(); + // radio.receive(); + // radio.readData(); + // radio.scanChannel(); +} + + +void loop() +{ + // check if the flag is set + if (receivedFlag) { + // disable the interrupt service routine while + // processing the data + enableInterrupt = false; + + // reset flag + receivedFlag = false; + + // you can read received data as an Arduino String + String str; + int state = radio.readData(str); + + // you can also read received data as byte array + /* + byte byteArr[8]; + int state = radio.readData(byteArr, 8); + */ + + if (state == ERR_NONE) { + // packet was successfully received + Serial.println(F("[SX1262] Received packet!")); + + // print data of the packet + Serial.print(F("[SX1262] Data:\t\t")); + Serial.println(str); + + // print RSSI (Received Signal Strength Indicator) + Serial.print(F("[SX1262] RSSI:\t\t")); + Serial.print(radio.getRSSI()); + Serial.println(F(" dBm")); + + // print SNR (Signal-to-Noise Ratio) + Serial.print(F("[SX1262] SNR:\t\t")); + Serial.print(radio.getSNR()); + Serial.println(F(" dB")); + + } else if (state == ERR_CRC_MISMATCH) { + // packet was received, but is malformed + Serial.println(F("CRC error!")); + + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + + } + + // put module back to listen mode + radio.startReceive(); + + // we're ready to receive more packets, + // enable interrupt service routine + enableInterrupt = true; + } +} diff --git a/examples/SX1262/SX126x_Receive_Interrupt/utilities.h b/examples/SX1262/SX126x_Receive_Interrupt/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/SX1262/SX126x_Receive_Interrupt/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/SX1262/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino b/examples/SX1262/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino new file mode 100644 index 0000000..01c1ca1 --- /dev/null +++ b/examples/SX1262/SX126x_Transmit_Interrupt/SX126x_Transmit_Interrupt.ino @@ -0,0 +1,138 @@ +/* + RadioLib SX1276 Transmit Example + + This example transmits packets using SX1276 LoRa radio module. + Each packet contains up to 256 bytes of data, in the form of: + - Arduino String + - null-terminated char array (C-string) + - arbitrary binary data (byte array) + + Other modules from SX127x/RFM9x family can also be used. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + + +#include +#include "utilities.h" + +SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +// or using RadioShield +// https://github.com/jgromes/RadioShield +//SX1262 radio = RadioShield.ModuleA; + +// save transmission state between loops +int transmissionState = ERR_NONE; +// flag to indicate that a packet was sent +volatile bool transmittedFlag = false; + +// disable interrupt when it's not needed +volatile bool enableInterrupt = true; + +// this function is called when a complete packet +// is transmitted by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) +{ + // check if the interrupt is enabled + if (!enableInterrupt) { + return; + } + + // we sent a packet, set the flag + transmittedFlag = true; +} + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + + // initialize SX1262 with default settings + Serial.print(F("[SX1262] Initializing ... ")); + int state = radio.begin(); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // set the function that will be called + // when packet transmission is finished + radio.setDio1Action(setFlag); + + // start transmitting the first packet + Serial.print(F("[SX1262] Sending first packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + transmissionState = radio.startTransmit("Hello World!"); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + state = radio.startTransmit(byteArr, 8); + */ +} + + +void loop() +{ + // check if the previous transmission finished + if (transmittedFlag) { + // disable the interrupt service routine while + // processing the data + enableInterrupt = false; + + // reset flag + transmittedFlag = false; + + if (transmissionState == ERR_NONE) { + // packet was successfully sent + Serial.println(F("transmission finished!")); + + // NOTE: when using interrupt-driven transmit method, + // it is not possible to automatically measure + // transmission data rate using getDataRate() + + } else { + Serial.print(F("failed, code ")); + Serial.println(transmissionState); + + } + + // wait a second before transmitting again + delay(1000); + + // send another one + Serial.print(F("[SX1262] Sending another packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + transmissionState = radio.startTransmit("Hello World!"); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + int state = radio.startTransmit(byteArr, 8); + */ + + // we're ready to send more packets, + // enable interrupt service routine + enableInterrupt = true; + } +} + + diff --git a/examples/SX1262/SX126x_Transmit_Interrupt/utilities.h b/examples/SX1262/SX126x_Transmit_Interrupt/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/SX1262/SX126x_Transmit_Interrupt/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/SX1276/SX1276_Receive_Interrupt/SX1276_Receive_Interrupt.ino b/examples/SX1276/SX1276_Receive_Interrupt/SX1276_Receive_Interrupt.ino new file mode 100644 index 0000000..b0611df --- /dev/null +++ b/examples/SX1276/SX1276_Receive_Interrupt/SX1276_Receive_Interrupt.ino @@ -0,0 +1,154 @@ +/* + RadioLib SX127x Receive Example + + This example listens for LoRa transmissions using SX127x Lora modules. + To successfully receive data, the following settings have to be the same + on both transmitter and receiver: + - carrier frequency + - bandwidth + - spreading factor + - coding rate + - sync word + - preamble length + + Other modules from SX127x/RFM9x family can also be used. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +#include +#include "utilities.h" + +SX1276 radio = new Module(RADIO_CS_PIN, RADIO_DI0_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// disable interrupt when it's not needed +volatile bool enableInterrupt = true; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) +{ + // check if the interrupt is enabled + if (!enableInterrupt) { + return; + } + + // we got a packet, set the flag + receivedFlag = true; +} + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + // initialize SX1276 with default settings + Serial.print(F("[SX1276] Initializing ... ")); + int state = radio.begin(868.0); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + // set the function that will be called + // when new packet is received + radio.setDio0Action(setFlag); + + // start listening for LoRa packets + Serial.print(F("[SX1276] Starting to listen ... ")); + state = radio.startReceive(); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // if needed, 'listen' mode can be disabled by calling + // any of the following methods: + // + // radio.standby() + // radio.sleep() + // radio.transmit(); + // radio.receive(); + // radio.readData(); + // radio.scanChannel(); +} + + +void loop() +{ + // check if the flag is set + if (receivedFlag) { + // disable the interrupt service routine while + // processing the data + enableInterrupt = false; + + // reset flag + receivedFlag = false; + + // you can read received data as an Arduino String + String str; + int state = radio.readData(str); + + // you can also read received data as byte array + /* + byte byteArr[8]; + int state = radio.readData(byteArr, 8); + */ + + if (state == ERR_NONE) { + // packet was successfully received + Serial.println(F("[SX1276] Received packet!")); + + // print data of the packet + Serial.print(F("[SX1276] Data:\t\t")); + Serial.println(str); + + // print RSSI (Received Signal Strength Indicator) + Serial.print(F("[SX1276] RSSI:\t\t")); + Serial.print(radio.getRSSI()); + Serial.println(F(" dBm")); + + // print SNR (Signal-to-Noise Ratio) + Serial.print(F("[SX1276] SNR:\t\t")); + Serial.print(radio.getSNR()); + Serial.println(F(" dB")); + + // print frequency error + Serial.print(F("[SX1276] Frequency error:\t")); + Serial.print(radio.getFrequencyError()); + Serial.println(F(" Hz")); + + } else if (state == ERR_CRC_MISMATCH) { + // packet was received, but is malformed + Serial.println(F("[SX1276] CRC error!")); + + } else { + // some other error occurred + Serial.print(F("[SX1276] Failed, code ")); + Serial.println(state); + } + + // put module back to listen mode + radio.startReceive(); + + // we're ready to receive more packets, + // enable interrupt service routine + enableInterrupt = true; + } +} + diff --git a/examples/SX1276/SX1276_Receive_Interrupt/utilities.h b/examples/SX1276/SX1276_Receive_Interrupt/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/SX1276/SX1276_Receive_Interrupt/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/SX1276/SX1276_Transmit_Interrupt/SX1276_Transmit_Interrupt.ino b/examples/SX1276/SX1276_Transmit_Interrupt/SX1276_Transmit_Interrupt.ino new file mode 100644 index 0000000..668cc61 --- /dev/null +++ b/examples/SX1276/SX1276_Transmit_Interrupt/SX1276_Transmit_Interrupt.ino @@ -0,0 +1,89 @@ +/* + RadioLib SX1276 Transmit Example + + This example transmits packets using SX1276 LoRa radio module. + Each packet contains up to 256 bytes of data, in the form of: + - Arduino String + - null-terminated char array (C-string) + - arbitrary binary data (byte array) + + Other modules from SX127x/RFM9x family can also be used. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + + +#include +#include "utilities.h" + +SX1276 radio = new Module(RADIO_CS_PIN, RADIO_DI0_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + // initialize SX1276 with default settings + Serial.print(F("[SX1276] Initializing ... ")); + int state = radio.begin(868.0); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } +} + + +void loop() +{ + Serial.print(F("[SX1276] Transmitting packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + // NOTE: transmit() is a blocking method! + // See example SX127x_Transmit_Interrupt for details + // on non-blocking transmission method. + int state = radio.transmit("Hello World!"); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; + int state = radio.transmit(byteArr, 8); + */ + + if (state == ERR_NONE) { + // the packet was successfully transmitted + Serial.println(F(" success!")); + + // print measured data rate + Serial.print(F("[SX1276] Datarate:\t")); + Serial.print(radio.getDataRate()); + Serial.println(F(" bps")); + + } else if (state == ERR_PACKET_TOO_LONG) { + // the supplied packet was longer than 256 bytes + Serial.println(F("too long!")); + + } else if (state == ERR_TX_TIMEOUT) { + // timeout occurred while transmitting packet + Serial.println(F("timeout!")); + + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + + } + + // wait for a second before transmitting again + delay(1000); +} + + diff --git a/examples/SX1276/SX1276_Transmit_Interrupt/utilities.h b/examples/SX1276/SX1276_Transmit_Interrupt/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/SX1276/SX1276_Transmit_Interrupt/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/SX1278/SX1276_Receive/SX1278_Receive.ino b/examples/SX1278/SX1276_Receive/SX1278_Receive.ino new file mode 100644 index 0000000..6a8f693 --- /dev/null +++ b/examples/SX1278/SX1276_Receive/SX1278_Receive.ino @@ -0,0 +1,154 @@ +/* + RadioLib SX127x Receive Example + + This example listens for LoRa transmissions using SX127x Lora modules. + To successfully receive data, the following settings have to be the same + on both transmitter and receiver: + - carrier frequency + - bandwidth + - spreading factor + - coding rate + - sync word + - preamble length + + Other modules from SX127x/RFM9x family can also be used. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +#include +#include "utilities.h" + +SX1278 radio = new Module(RADIO_CS_PIN, RADIO_DI0_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +// flag to indicate that a packet was received +volatile bool receivedFlag = false; + +// disable interrupt when it's not needed +volatile bool enableInterrupt = true; + +// this function is called when a complete packet +// is received by the module +// IMPORTANT: this function MUST be 'void' type +// and MUST NOT have any arguments! +void setFlag(void) +{ + // check if the interrupt is enabled + if (!enableInterrupt) { + return; + } + + // we got a packet, set the flag + receivedFlag = true; +} + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + // initialize SX1278 with default settings + Serial.print(F("[SX1278] Initializing ... ")); + int state = radio.begin(433.0); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + // set the function that will be called + // when new packet is received + radio.setDio0Action(setFlag); + + // start listening for LoRa packets + Serial.print(F("[SX1278] Starting to listen ... ")); + state = radio.startReceive(); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // if needed, 'listen' mode can be disabled by calling + // any of the following methods: + // + // radio.standby() + // radio.sleep() + // radio.transmit(); + // radio.receive(); + // radio.readData(); + // radio.scanChannel(); +} + + +void loop() +{ + // check if the flag is set + if (receivedFlag) { + // disable the interrupt service routine while + // processing the data + enableInterrupt = false; + + // reset flag + receivedFlag = false; + + // you can read received data as an Arduino String + String str; + int state = radio.readData(str); + + // you can also read received data as byte array + /* + byte byteArr[8]; + int state = radio.readData(byteArr, 8); + */ + + if (state == ERR_NONE) { + // packet was successfully received + Serial.println(F("[SX1278] Received packet!")); + + // print data of the packet + Serial.print(F("[SX1278] Data:\t\t")); + Serial.println(str); + + // print RSSI (Received Signal Strength Indicator) + Serial.print(F("[SX1278] RSSI:\t\t")); + Serial.print(radio.getRSSI()); + Serial.println(F(" dBm")); + + // print SNR (Signal-to-Noise Ratio) + Serial.print(F("[SX1278] SNR:\t\t")); + Serial.print(radio.getSNR()); + Serial.println(F(" dB")); + + // print frequency error + Serial.print(F("[SX1278] Frequency error:\t")); + Serial.print(radio.getFrequencyError()); + Serial.println(F(" Hz")); + + } else if (state == ERR_CRC_MISMATCH) { + // packet was received, but is malformed + Serial.println(F("[SX1278] CRC error!")); + + } else { + // some other error occurred + Serial.print(F("[SX1278] Failed, code ")); + Serial.println(state); + } + + // put module back to listen mode + radio.startReceive(); + + // we're ready to receive more packets, + // enable interrupt service routine + enableInterrupt = true; + } +} + diff --git a/examples/SX1278/SX1276_Receive/utilities.h b/examples/SX1278/SX1276_Receive/utilities.h new file mode 100644 index 0000000..59f91f0 --- /dev/null +++ b/examples/SX1278/SX1276_Receive/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +// #define T_BEAM_V07 +#define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/SX1278/SX1276_Transmit/SX1276_Transmit.ino b/examples/SX1278/SX1276_Transmit/SX1276_Transmit.ino new file mode 100644 index 0000000..32d6d8e --- /dev/null +++ b/examples/SX1278/SX1276_Transmit/SX1276_Transmit.ino @@ -0,0 +1,89 @@ +/* + RadioLib SX1278 Transmit Example + + This example transmits packets using SX1278 LoRa radio module. + Each packet contains up to 256 bytes of data, in the form of: + - Arduino String + - null-terminated char array (C-string) + - arbitrary binary data (byte array) + + Other modules from SX127x/RFM9x family can also be used. + + For default module settings, see the wiki page + https://github.com/jgromes/RadioLib/wiki/Default-configuration#sx127xrfm9x---lora-modem + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + + +#include +#include "utilities.h" + +SX1278 radio = new Module(RADIO_CS_PIN, RADIO_DI0_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN); + +void setup() +{ + initBoard(); + // When the power is turned on, a delay is required. + delay(1500); + + // initialize SX1278 with default settings + Serial.print(F("[SX1278] Initializing ... ")); + int state = radio.begin(433.0); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } +} + + +void loop() +{ + Serial.print(F("[SX1278] Transmitting packet ... ")); + + // you can transmit C-string or Arduino string up to + // 256 characters long + // NOTE: transmit() is a blocking method! + // See example SX127x_Transmit_Interrupt for details + // on non-blocking transmission method. + int state = radio.transmit("Hello World!"); + + // you can also transmit byte array up to 256 bytes long + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; + int state = radio.transmit(byteArr, 8); + */ + + if (state == ERR_NONE) { + // the packet was successfully transmitted + Serial.println(F(" success!")); + + // print measured data rate + Serial.print(F("[SX1278] Datarate:\t")); + Serial.print(radio.getDataRate()); + Serial.println(F(" bps")); + + } else if (state == ERR_PACKET_TOO_LONG) { + // the supplied packet was longer than 256 bytes + Serial.println(F("too long!")); + + } else if (state == ERR_TX_TIMEOUT) { + // timeout occurred while transmitting packet + Serial.println(F("timeout!")); + + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + + } + + // wait for a second before transmitting again + delay(1000); +} + + diff --git a/examples/SX1278/SX1276_Transmit/utilities.h b/examples/SX1278/SX1276_Transmit/utilities.h new file mode 100644 index 0000000..2dfba28 --- /dev/null +++ b/examples/SX1278/SX1276_Transmit/utilities.h @@ -0,0 +1,98 @@ +/* +* This factory is just to test LilyGo T-Beam series hardware +* Created by Lewis he +* */ + +#define T_BEAM_V07 +// #define T_BEAM_V10 //same v1.1 version + + +#include + +#if defined(T_BEAM_V07) +#define GPS_RX_PIN 12 +#define GPS_TX_PIN 15 +#define BUTTON_PIN 39 +#define BUTTON_PIN_MASK GPIO_SEL_39 +#elif defined(T_BEAM_V10) +#define GPS_RX_PIN 34 +#define GPS_TX_PIN 12 +#define BUTTON_PIN 38 +#define BUTTON_PIN_MASK GPIO_SEL_38 +#endif + +#define I2C_SDA 21 +#define I2C_SCL 22 +#define PMU_IRQ 35 + +#define RADIO_SCLK_PIN 5 +#define RADIO_MISO_PIN 19 +#define RADIO_MOSI_PIN 27 +#define RADIO_CS_PIN 18 +#define RADIO_DI0_PIN 26 +#define RADIO_RST_PIN 23 +#define RADIO_DIO1_PIN 33 +#define RADIO_BUSY_PIN 32 + +#define GPS_BAND_RATE 9600 + +#ifdef T_BEAM_V10 +#include +AXP20X_Class PMU; + +bool initPMU() +{ + Wire.begin(I2C_SDA, I2C_SCL); + + if (PMU.begin(Wire, AXP192_SLAVE_ADDRESS) == AXP_FAIL) { + return false; + } + /* + * The charging indicator can be turned on or off + * * * */ + // PMU.setChgLEDMode(LED_BLINK_4HZ); + + /* + * The default ESP32 power supply has been turned on, + * no need to set, please do not set it, if it is turned off, + * it will not be able to program + * + * PMU.setDCDC1Voltage(3300); + * PMU.setPowerOutPut(AXP192_DCDC1, AXP202_ON); + * + * * * */ + + /* + * Turn off unused power sources to save power + * **/ + PMU.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + PMU.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + + /* + * Set the power of LoRa and GPS module to 3.3V + **/ + PMU.setLDO2Voltage(3300); //LoRa VDD + PMU.setLDO3Voltage(3300); //GPS VDD + + PMU.setPowerOutPut(AXP192_LDO2, AXP202_ON); + PMU.setPowerOutPut(AXP192_LDO3, AXP202_ON); + + return true; +} + +#else +#define initPMU() +#endif + +void initBoard() +{ + Serial.begin(115200); + Serial.println("initBoard"); + Serial1.begin(GPS_BAND_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); + SPI.begin(RADIO_SCLK_PIN, RADIO_MISO_PIN, RADIO_MOSI_PIN); + initPMU(); +} + + diff --git a/examples/gps/board_def.h b/examples/gps/board_def.h deleted file mode 100644 index 860d7d2..0000000 --- a/examples/gps/board_def.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -* This factory is just to test LilyGo T-Beam series hardware -* Created by Lewis he -* */ -#ifndef BOARD_DEF_H -#define BOARD_DEF_H - -// #define T_BEAM_V07 -#define T_BEAM_V10 //same v1.1 version - -#if defined(T_BEAM_V07) -#define GPS_RX_PIN 12 -#define GPS_TX_PIN 15 -#define BUTTON_PIN 39 -#define BUTTON_PIN_MASK GPIO_SEL_39 -#elif defined(T_BEAM_V10) -#define GPS_RX_PIN 34 -#define GPS_TX_PIN 12 -#define BUTTON_PIN 38 -#define BUTTON_PIN_MASK GPIO_SEL_38 -#endif - -#define I2C_SDA 21 -#define I2C_SCL 22 -#define PMU_IRQ 35 - -#endif /*BOARD_DEF_H*/ \ No newline at end of file diff --git a/examples/gps/gps.ino b/examples/gps/gps.ino deleted file mode 100644 index 4c17e06..0000000 --- a/examples/gps/gps.ino +++ /dev/null @@ -1,48 +0,0 @@ -#include "board_def.h" -#include "SPI.h" -#include -#include "axp20x.h" - -#define SerialGPS Serial1 - -AXP20X_Class axp; - -bool findPower = false; - -void setup() -{ - Serial.begin(115200); - - Wire.begin(I2C_SDA, I2C_SCL); - - SerialGPS.begin(9600, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); - - findPower = !axp.begin(Wire, AXP192_SLAVE_ADDRESS); - if (findPower) { - // ! DC1 is the power supply of ESP32, do not control it - // axp.setDCDC1Voltage(3300); //esp32 core VDD 3v3 - // axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); - - //Setting LDO2 and LOD3 3300mV - axp.setLDO2Voltage(3300); //LORA VDD 3v3 - axp.setLDO3Voltage(3300); //GPS VDD 3v3 - - //Enable LDO2 , It controls the lora power - axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); - //Enable LDO3, It controls the GPS power - axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); - - //Idle the power supply, turn it off - axp.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); - axp.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); - } else { - Serial.println("AXP192 not found"); - } -} - -void loop() -{ - while (SerialGPS.available()) { - Serial.write(SerialGPS.read()); - } -} diff --git a/libdeps/AXP202X_Library/.piopm b/libdeps/AXP202X_Library/.piopm new file mode 100644 index 0000000..fba640f --- /dev/null +++ b/libdeps/AXP202X_Library/.piopm @@ -0,0 +1 @@ +{"type": "library", "name": "AXP202X_Library", "version": "1.1.2", "spec": {"owner": "lewisxhe", "id": 6657, "name": "AXP202X_Library", "requirements": null, "url": null}} \ No newline at end of file diff --git a/libdeps/AXP202X_Library/LICENSE b/libdeps/AXP202X_Library/LICENSE new file mode 100644 index 0000000..0b0f6fd --- /dev/null +++ b/libdeps/AXP202X_Library/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 lewis he + +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. diff --git a/libdeps/AXP202X_Library/README.md b/libdeps/AXP202X_Library/README.md new file mode 100644 index 0000000..896b6be --- /dev/null +++ b/libdeps/AXP202X_Library/README.md @@ -0,0 +1,21 @@ +AXP202X_Library +===================================== +- axp192 partial support, the function is not fully tested, please refer to the manual +- The `setPowerOutPut` function has forced DCDC3 to be turned on and cannot be controlled because T-Watch uses DCDC3 as the esp32 to power the main chip. If it is turned off, the hardware cannot be programmed. + + +TTGO invests time and resources to provide this open source code, please support TTGO and open source hardware by purchasing products from TTGO! + +Written by Lewis He for TTGO. MIT license, all text above must be included in any redistribution + +## Chip resource table +| CHIP | AXP173 | AXP192 | AXP202 | +| -------- | ---------------- | ---------------- | ---------------- | +| DC1 | 0v7~3v5 /1200mA | 0v7~3v5 /1200mA | X | +| DC2 | 0v7~2v275/1600mA | 0v7~2v275/1600mA | 0v7~2v275/1600mA | +| DC3 | X | 0v7~3v5 /700mA | 0v7~3v5 /1200mA | +| LDO1 | 3v3 /30mA | 3v3 /30mA | 3v3 /30mA | +| LDO2 | 1v8~3v3 /200mA | 1v8~3v3 /200mA | 1v8~3v3 /200mA | +| LDO3 | 1v8~3v3 /200mA | 1v8~3v3 /200mA | 0v7~3v3 /200mA | +| LDO4 | 0v7~3v5 /500mA | X | 1v8~3v3 /200mA | +| LDO5/IO0 | X | 1v8~3v3 /50mA | 1v8~3v3 /50mA | diff --git a/libdeps/AXP202X_Library/examples/axp202_gpio_input/axp202_gpio_input.ino b/libdeps/AXP202X_Library/examples/axp202_gpio_input/axp202_gpio_input.ino new file mode 100644 index 0000000..35f5318 --- /dev/null +++ b/libdeps/AXP202X_Library/examples/axp202_gpio_input/axp202_gpio_input.ino @@ -0,0 +1,66 @@ +/* +MIT License + +Copyright (c) 2019 lewis he + +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 +#include + +AXP20X_Class axp; + +const uint8_t i2c_sda = 21; +const uint8_t i2c_scl = 22; + +void setup() +{ + Serial.begin(115200); + Wire.begin(i2c_sda, i2c_scl); + + int ret = axp.begin(Wire); + + if (ret == AXP_FAIL) { + Serial.println("AXP Power begin failed"); + while (1); + } + //! AXP202 GPIO has no internal pull-up or pull-down. + //! For stability, external pull-up or pull-down resistors are required. + ret = axp.setGPIOMode(AXP_GPIO_0, AXP_IO_INPUT_MODE); + Serial.printf("AXP_GPIO_0 %d\n", ret); + ret = axp.setGPIOMode(AXP_GPIO_1, AXP_IO_INPUT_MODE); + Serial.printf("AXP_GPIO_1 %d\n", ret); + ret = axp.setGPIOMode(AXP_GPIO_2, AXP_IO_INPUT_MODE); + Serial.printf("AXP_GPIO_2 %d\n", ret); + ret = axp.setGPIOMode(AXP_GPIO_3, AXP_IO_INPUT_MODE); + Serial.printf("AXP_GPIO_3 %d\n", ret); + +} + +void loop() +{ + Serial.printf("GPIO: [0]:%d [1]:%d [2]:%d [3]:%d\n", + axp.gpioRead(AXP_GPIO_0), + axp.gpioRead(AXP_GPIO_1), + axp.gpioRead(AXP_GPIO_2), + axp.gpioRead(AXP_GPIO_3) + ); + delay(1000); +} + diff --git a/libdeps/AXP202X_Library/examples/axp202_gpio_output/axp202_gpio_output.ino b/libdeps/AXP202X_Library/examples/axp202_gpio_output/axp202_gpio_output.ino new file mode 100644 index 0000000..d39d9b0 --- /dev/null +++ b/libdeps/AXP202X_Library/examples/axp202_gpio_output/axp202_gpio_output.ino @@ -0,0 +1,63 @@ +/* +MIT License + +Copyright (c) 2019 lewis he + +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 +#include + +AXP20X_Class axp; + +const uint8_t i2c_sda = 21; +const uint8_t i2c_scl = 22; + +void setup() +{ + Serial.begin(115200); + Wire.begin(i2c_sda, i2c_scl); + + int ret = axp.begin(Wire); + + if (ret == AXP_FAIL) { + Serial.println("AXP Power begin failed"); + while (1); + } + + axp.setGPIOMode(AXP_GPIO_0, AXP_IO_OUTPUT_HIGH_MODE); + axp.setGPIOMode(AXP_GPIO_1, AXP_IO_OUTPUT_HIGH_MODE); + + //! GPIO2, GPIO3 is only allowed to be configured to output low + axp.gpioWrite(AXP_GPIO_2, LOW); + axp.gpioWrite(AXP_GPIO_3, LOW); + +} + +void loop() +{ + //! GPIO0, GPIO1 allows output high and low + axp.gpioWrite(AXP_GPIO_0, HIGH); + axp.gpioWrite(AXP_GPIO_1, HIGH); + delay(1000); + axp.gpioWrite(AXP_GPIO_0, LOW); + axp.gpioWrite(AXP_GPIO_1, LOW); + delay(1000); +} + diff --git a/libdeps/AXP202X_Library/examples/axp202_timer/axp202_timer.ino b/libdeps/AXP202X_Library/examples/axp202_timer/axp202_timer.ino new file mode 100644 index 0000000..b32e60e --- /dev/null +++ b/libdeps/AXP202X_Library/examples/axp202_timer/axp202_timer.ino @@ -0,0 +1,87 @@ +/* +MIT License + +Copyright (c) 2019 lewis he + +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 +#include + + +AXP20X_Class axp; +bool axpIrq = 0; +uint8_t second = 0; +uint32_t timer = 0; + +const uint8_t i2c_sda = 21; +const uint8_t i2c_scl = 22; +const uint8_t axp_irq_pin = 35; + +void setup() +{ + Serial.begin(115200); + Wire.begin(i2c_sda, i2c_scl); + + int ret = axp.begin(Wire); + + if (ret == AXP_FAIL) { + Serial.println("AXP Power begin failed"); + while (1); + } + + //! enable timer irq and pek key press irq channel + axp.enableIRQ(AXP202_TIMER_TIMEOUT_IRQ | AXP202_PEK_SHORTPRESS_IRQ, true); + + //! attachInterrupt to gpio 35 + pinMode(axp_irq_pin, INPUT); + attachInterrupt(axp_irq_pin, [] { + axpIrq = 1; + }, FALLING); + axp.clearIRQ(); + + axp.setTimer(1); + +} + + +void loop() +{ + if (millis() - timer > 1000) { + second++; + Serial.printf("%u second\n", second); + timer = millis(); + } + if (axpIrq) { + axpIrq = 0; + axp.readIRQ(); + if (axp.isPEKShortPressIRQ()) { + Serial.printf("AXP202 PEK key Click\n"); + } + if (axp.isTimerTimeoutIRQ()) { + Serial.printf("AXP202 timer timeout\n"); + axp.clearTimerStatus(); + while (1) { + delay(100); + } + } + axp.clearIRQ(); + } +} + diff --git a/libdeps/AXP202X_Library/examples/axp_charge_cur/axp_charge_cur.ino b/libdeps/AXP202X_Library/examples/axp_charge_cur/axp_charge_cur.ino new file mode 100644 index 0000000..1474c4e --- /dev/null +++ b/libdeps/AXP202X_Library/examples/axp_charge_cur/axp_charge_cur.ino @@ -0,0 +1,44 @@ +#include +#include + +AXP20X_Class axp; + +const uint8_t i2c_sda = 21; +const uint8_t i2c_scl = 22; + +void setup() +{ + Serial.begin(115200); + + delay(3000); + + Wire.begin(i2c_sda, i2c_scl); + + int ret = axp.begin(Wire); + if (ret == AXP_FAIL) { + Serial.println("AXP Power begin failed"); + while (1); + } + int cur = axp.getChargeControlCur(); + Serial.printf("Current charge control current = %d mA \n", cur); + + + //axp202 allows maximum charging current of 1800mA, minimum 300mA + axp.setChargeControlCur(500); + Serial.printf("Set charge control current 500 mA \n"); + + //When the chip is axp192 / 173, the allowed values are 0 ~ 15, + //corresponding to the axp1xx_charge_current_t enumeration + // axp.setChargeControlCur(AXP1XX_CHARGE_CUR_550MA); + // Serial.printf("Set charge control current 550 mA \n"); + + cur = axp.getChargeControlCur(); + Serial.printf("Current charge control current = %d mA \n", cur); + + +} + +void loop() +{ +} + diff --git a/libdeps/AXP202X_Library/examples/axp_sleep_mode/axp_sleep_mode.ino b/libdeps/AXP202X_Library/examples/axp_sleep_mode/axp_sleep_mode.ino new file mode 100644 index 0000000..9d4e29c --- /dev/null +++ b/libdeps/AXP202X_Library/examples/axp_sleep_mode/axp_sleep_mode.ino @@ -0,0 +1,115 @@ +#include +#include + +AXP20X_Class axp; + +const uint8_t i2c_sda = 21; +const uint8_t i2c_scl = 22; +const uint8_t irq_pin = 35; + +bool pmu_irq = false; + + +void sleepPMU() +{ + int ret; + // PEK or GPIO edge wake-up function enable setting in Sleep mode + do { + // In order to ensure that it is set correctly, + // the loop waits for it to return the correct return value + Serial.println("Set PMU in sleep mode"); + ret = axp.setSleep(); + delay(500); + } while (ret != AXP_PASS) ; + + // Turn off all power channels, only use PEK or AXP GPIO to wake up + + // After setting AXP202/AXP192 to sleep, + // it will start to record the status of the power channel that was turned off after setting, + // it will restore the previously set state after PEK button or GPIO wake up + + + // Turn off all AXP192 power channels + ret = axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); + Serial.printf("Set Power AXP192_LDO2:%s\n", ret == AXP_PASS ? "OK" : "FAIL"); + + ret = axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); + Serial.printf("Set Power AXP192_LDO3:%s\n", ret == AXP_PASS ? "OK" : "FAIL"); + + ret = axp.setPowerOutPut(AXP192_DCDC1, AXP202_OFF); + Serial.printf("Set Power AXP192_DCDC1:%s\n", ret == AXP_PASS ? "OK" : "FAIL"); + + ret = axp.setPowerOutPut(AXP192_DCDC2, AXP202_OFF); + Serial.printf("Set Power AXP192_DCDC2:%s\n", ret == AXP_PASS ? "OK" : "FAIL"); + + ret = axp.setPowerOutPut(AXP192_EXTEN, AXP202_OFF); + Serial.printf("Set Power AXP192_EXTEN:%s\n", ret == AXP_PASS ? "OK" : "FAIL"); + + Serial.flush(); + delay(1000); + + // Tbeam v1.0 uses DC3 as the MCU power channel, turning it off as the last + ret = axp.setPowerOutPut(AXP192_DCDC3, AXP202_OFF); + Serial.printf("Set Power AXP192_DCDC3:%s\n", ret == AXP_PASS ? "OK" : "FAIL"); + + // Turn off all AXP202 power channels + // axp.setPowerOutPut(AXP202_LDO2, AXP202_OFF); + // axp.setPowerOutPut(AXP202_LDO3, AXP202_OFF); + // axp.setPowerOutPut(AXP202_LDO4, AXP202_OFF); + // axp.setPowerOutPut(AXP202_DCDC2, AXP202_OFF); + // axp.setPowerOutPut(AXP202_DCDC3, AXP202_OFF); + // axp.setPowerOutPut(AXP202_EXTEN, AXP202_OFF); + + + // If you set the power supply to sleep mode and you turn off the power supply of the MCU, + // you will not be able to use the wake-up mode provided by the MCU. + // If you do not turn off the power of the MCU, you can continue to use it +} + +void setup() +{ + Serial.begin(115200); + + delay(3000); + + Wire.begin(i2c_sda, i2c_scl); + + + // Test with AXP192 ,TBeam v1.0 board + int ret = axp.begin(Wire, AXP192_SLAVE_ADDRESS); + if (ret == AXP_FAIL) { + Serial.println("AXP Power begin failed"); + while (1); + } + + // Register the PMU interrupt pin, it will be triggered on the falling edge + pinMode(irq_pin, INPUT); + attachInterrupt(irq_pin, [] { + pmu_irq = true; + }, FALLING); + + // Before using IRQ, remember to clear the IRQ status register + axp.clearIRQ(); + + // Turn on the key to press the interrupt function + axp.enableIRQ(AXP202_PEK_SHORTPRESS_IRQ, true); + + + Serial.println("Wait for the PEK button to be pressed"); +} + +void loop() +{ + if ( pmu_irq) { + pmu_irq = false; + axp.readIRQ(); + // When the PEK button is pressed briefly, the PMU is set to sleep + if (axp.isPEKShortPressIRQ()) { + // Clear all interrupt status before going to sleep + axp.clearIRQ(); + // Set PMU to sleep + sleepPMU(); + } + } +} + diff --git a/libdeps/AXP202X_Library/examples/base/base.ino b/libdeps/AXP202X_Library/examples/base/base.ino new file mode 100644 index 0000000..d3f506a --- /dev/null +++ b/libdeps/AXP202X_Library/examples/base/base.ino @@ -0,0 +1,139 @@ +/* +MIT License + +Copyright (c) 2019 lewis he + +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 +#include + + +AXP20X_Class axp; +bool axpIrq = 0; + +const uint8_t i2c_sda = 21; +const uint8_t i2c_scl = 22; +const uint8_t axp_irq_pin = 35; + + +uint8_t readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) +{ + uint8_t ret = 0; + Wire.beginTransmission(addr); + Wire.write(reg); + Wire.endTransmission(false); + uint8_t cnt = Wire.requestFrom(addr, (uint8_t)len, (uint8_t)1); + if (!cnt) { + ret = 0xFF; + } + uint16_t index = 0; + while (Wire.available()) { + if (index > len)return 0xFF; + data[index++] = Wire.read(); + } + return ret; +} + +uint8_t writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len) +{ + uint8_t ret = 0; + Wire.beginTransmission(addr); + Wire.write(reg); + for (uint16_t i = 0; i < len; i++) { + Wire.write(data[i]); + } + ret = Wire.endTransmission(); + return ret ? ret : 0xFF; +} + +void setup() +{ + Serial.begin(115200); + Wire.begin(i2c_sda, i2c_scl); + + //! Use the Wire port + // int ret = axp.begin(Wire); + + //! Use custom I2C to return processing + int ret = axp.begin(readBytes, writeBytes); + + if (ret == AXP_FAIL) { + Serial.println("AXP Power begin failed"); + while (1); + } + + //! enable all irq channel + axp.enableIRQ(0xFFFFFFFF, true); + + //! attachInterrupt to gpio 35 + pinMode(axp_irq_pin, INPUT_PULLUP); + attachInterrupt(axp_irq_pin, [] { + axpIrq = 1; + }, FALLING); + axp.clearIRQ(); + + axp.setPowerOutPut(AXP202_DCDC3, AXP202_ON); + axp.setPowerOutPut(AXP202_EXTEN, AXP202_ON); + axp.setPowerOutPut(AXP202_LDO2, AXP202_ON); + axp.setPowerOutPut(AXP202_LDO4, AXP202_ON); + axp.setPowerOutPut(AXP202_DCDC2, AXP202_ON); + axp.setLDO4Voltage(AXP202_LDO4_1800MV); + axp.setLDO3Voltage(3500); + axp.setPowerOutPut(AXP202_LDO3, AXP202_ON); + + Serial.print("DC2:"); + Serial.print(axp.isDCDC2Enable() ? String(axp.getDCDC2Voltage()) + " mv" : "DISABLE"); + Serial.print(" "); + + Serial.print("DC3:"); + Serial.print(axp.isDCDC3Enable() ? String(axp.getDCDC3Voltage()) + " mv" : "DISABLE"); + Serial.print(" "); + + Serial.print("LDO2:"); + Serial.print(axp.isLDO2Enable() ? String(axp.getLDO2Voltage()) + " mv" : "DISABLE"); + Serial.print(" "); + + Serial.print("LDO3:"); + Serial.print(axp.isLDO3Enable() ? String(axp.getLDO3Voltage()) + " mv" : "DISABLE"); + Serial.print(" "); + + Serial.print("LDO4:"); + Serial.print(axp.isLDO4Enable() ? "ENABLE" : "DISABLE"); + Serial.print(" "); + + Serial.print("Exten:"); + Serial.print(axp.isExtenEnable() ? "ENABLE" : "DISABLE"); + Serial.print("\r\n"); + +} + + +void loop() +{ + if (axpIrq) { + axpIrq = 0; + axp.readIRQ(); + if (axp.isPEKShortPressIRQ()) { + Serial.printf("AXP202 PEK key Click\n"); + } + axp.clearIRQ(); + } +} + diff --git a/libdeps/AXP202X_Library/keywords.txt b/libdeps/AXP202X_Library/keywords.txt new file mode 100644 index 0000000..fee5b25 --- /dev/null +++ b/libdeps/AXP202X_Library/keywords.txt @@ -0,0 +1,176 @@ +####################################### +# Syntax Coloring Map For X-Power AXP20X Library By lewis He +# github:https://github.com/lewisxhe +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +AXP20X_Class KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +isChargeing KEYWORD2 +isLDO2Enable KEYWORD2 +isLDO3Enable KEYWORD2 +isLDO4Enable KEYWORD2 +isDCDC3Enable KEYWORD2 +isDCDC2Enable KEYWORD2 +isChargeingEnable KEYWORD2 +isAcinOverVoltageIRQ KEYWORD2 +isAcinPlugInIRQ KEYWORD2 +isAcinRemoveIRQ KEYWORD2 +isVbusOverVoltageIRQ KEYWORD2 +isVbusPlugInIRQ KEYWORD2 +isVbusRemoveIRQ KEYWORD2 +isVbusLowVHOLDIRQ KEYWORD2 +isBattPlugInIRQ KEYWORD2 +isBattRemoveIRQ KEYWORD2 +isBattEnterActivateIRQ KEYWORD2 +isBattExitActivateIRQ KEYWORD2 +isChargingIRQ KEYWORD2 +isChargingDoneIRQ KEYWORD2 +isBattTempLowIRQ KEYWORD2 +isBattTempHighIRQ KEYWORD2 +isPEKShortPressIRQ KEYWORD2 +isPEKLongtPressIRQ KEYWORD2 +getAcinVoltage KEYWORD2 +getAcinCurrent KEYWORD2 +getVbusVoltage KEYWORD2 +getVbusCurrent KEYWORD2 +getTemp KEYWORD2 +getTSTemp KEYWORD2 +getGPIO0Voltage KEYWORD2 +getGPIO1Voltage KEYWORD2 +getBattInpower KEYWORD2 +getBattVoltage KEYWORD2 +getBattChargeCurrent KEYWORD2 +getBattDischargeCurrent KEYWORD2 +getSysIPSOUTVoltage KEYWORD2 +getBattChargeCoulomb KEYWORD2 +getBattDischargeCoulomb KEYWORD2 +getSettingChargeCurrent KEYWORD2 +setChargingTargetVoltage KEYWORD2 +enableChargeing KEYWORD2 +adc1Enable KEYWORD2 +adc2Enable KEYWORD2 +setStartupTime KEYWORD2 +setlongPressTime KEYWORD2 +setShutdownTime KEYWORD2 +setTimeOutShutdown KEYWORD2 +enableIRQ KEYWORD2 +readIRQ KEYWORD2 +clearIRQ KEYWORD2 +setDCDC2Voltage KEYWORD2 +setDCDC3Voltage KEYWORD2 +setLDO2Voltage KEYWORD2 +setLDO3Voltage KEYWORD2 +setLDO4Voltage KEYWORD2 +getBattPercentage KEYWORD2 +setTScurrent KEYWORD2 +setTSfunction KEYWORD2 +setTSmode KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + + +####################################### +# Constants (LITERAL1) +####################################### +AXP202_LDO4_1250MV LITERAL1 +AXP202_LDO4_1300MV LITERAL1 +AXP202_LDO4_1400MV LITERAL1 +AXP202_LDO4_1500MV LITERAL1 +AXP202_LDO4_1600MV LITERAL1 +AXP202_LDO4_1700MV LITERAL1 +AXP202_LDO4_1800MV LITERAL1 +AXP202_LDO4_1900MV LITERAL1 +AXP202_LDO4_2000MV LITERAL1 +AXP202_LDO4_2500MV LITERAL1 +AXP202_LDO4_2700MV LITERAL1 +AXP202_LDO4_2800MV LITERAL1 +AXP202_LDO4_3000MV LITERAL1 +AXP202_LDO4_3100MV LITERAL1 +AXP202_LDO4_3200MV LITERAL1 +AXP202_LDO4_3300MV LITERAL1 + +AXP202_VBUS_VHOLD_LOW_IRQ LITERAL1 +AXP202_VBUS_REMOVED_IRQ LITERAL1 +AXP202_VBUS_CONNECT_IRQ LITERAL1 +AXP202_VBUS_OVER_VOL_IRQ LITERAL1 +AXP202_ACIN_REMOVED_IRQ LITERAL1 +AXP202_ACIN_CONNECT_IRQ LITERAL1 +AXP202_ACIN_OVER_VOL_IRQ LITERAL1 +AXP202_BATT_LOW_TEMP_IRQ LITERAL1 +AXP202_BATT_OVER_TEMP_IRQ LITERAL1 +AXP202_CHARGING_FINISHED_IRQ LITERAL1 +AXP202_CHARGING_IRQ LITERAL1 +AXP202_BATT_EXIT_ACTIVATE_IRQ LITERAL1 +AXP202_BATT_ACTIVATE_IRQ LITERAL1 +AXP202_BATT_REMOVED_IRQ LITERAL1 +AXP202_BATT_CONNECT_IRQ LITERAL1 +AXP202_PEK_LONGPRESS_IRQ LITERAL1 +AXP202_PEL_SHORTPRESS_IRQ LITERAL1 +AXP202_LDO3_LOW_VOL_IRQ LITERAL1 +AXP202_DC3_LOW_VOL_IRQ LITERAL1 +AXP202_DC2_LOW_VOL_IRQ LITERAL1 +AXP202_CHARGE_LOW_CUR_IRQ LITERAL1 +AXP202_CHIP_TEMP_HIGH_IRQ LITERAL1 +AXP202_APS_LOW_VOL_LEVEL2_IRQ LITERAL1 +APX202_APS_LOW_VOL_LEVEL1_IRQ LITERAL1 +AXP202_VBUS_SESSION_END_IRQ LITERAL1 +AXP202_VBUS_SESSION_AB_IRQ LITERAL1 +AXP202_VBUS_INVALID_IRQ LITERAL1 +AXP202_VBUS_VAILD_IRQ LITERAL1 +AXP202_NOE_OFF_IRQ LITERAL1 +AXP202_NOE_ON_IRQ LITERAL1 + +AXP202_TEMP_MONITORING_ADC2 LITERAL1 +AXP202_GPIO1_FUNC_ADC2 LITERAL1 +AXP202_GPIO0_FUNC_ADC2 LITERAL1 + +AXP202_BATT_VOL_ADC1 LITERAL1 +AXP202_BATT_CUR_ADC1 LITERAL1 +AXP202_ACIN_VOL_ADC1 LITERAL1 +AXP202_ACIN_CUR_ADC1 LITERAL1 +AXP202_VBUS_VOL_ADC1 LITERAL1 +AXP202_VBUS_CUR_ADC1 LITERAL1 +AXP202_APS_VOL_ADC1 LITERAL1 +AXP202_TS_PIN_ADC1 LITERAL1 + +AXP202_TARGET_VOL_4_1V LITERAL1 +AXP202_TARGET_VOL_4_15V LITERAL1 +AXP202_TARGET_VOL_4_2V LITERAL1 +AXP202_TARGET_VOL_4_36V LITERAL1 +AXP202_STARTUP_TIME_128MS LITERAL1 +AXP202_STARTUP_TIME_3S LITERAL1 +AXP202_STARTUP_TIME_1S LITERAL1 +AXP202_STARTUP_TIME_2S LITERAL1 +AXP202_STARTUP_TIME LITERAL1 +AXP202_LONGPRESS_TIME LITERAL1 +AXP202_SHUTDOWN_EXCEEDS_TIME LITERAL1 +AXP202_PWROK_SIGNAL_DELAY LITERAL1 +AXP202_SHUTDOWN_TIME LITERAL1 + +AXP_TS_PIN_CURRENT_20UA LITERAL1 +AXP_TS_PIN_CURRENT_40UA LITERAL1 +AXP_TS_PIN_CURRENT_60UA LITERAL1 +AXP_TS_PIN_CURRENT_80UA LITERAL1 +AXP_TS_PIN_FUNCTION_BATT LITERAL1 +AXP_TS_PIN_FUNCTION_ADC LITERAL1 +AXP_TS_PIN_MODE_DISABLE LITERAL1 +AXP_TS_PIN_MODE_CHARGING LITERAL1 +AXP_TS_PIN_MODE_SAMPLING LITERAL1 +AXP_TS_PIN_MODE_ENABLE LITERAL1 + +AXP202_EXTEN LITERAL1 +AXP202_DCDC3 LITERAL1 +AXP202_LDO2 LITERAL1 +AXP202_LDO4 LITERAL1 +AXP202_DCDC2 LITERAL1 +AXP202_LDO3 LITERAL1 diff --git a/libdeps/AXP202X_Library/library.properties b/libdeps/AXP202X_Library/library.properties new file mode 100644 index 0000000..9216335 --- /dev/null +++ b/libdeps/AXP202X_Library/library.properties @@ -0,0 +1,9 @@ +name=AXP202X_Library +version=1.1.2 +author=Lewis He +maintainer=Lewis He +sentence=Arduino library for X-Power AXP202 chip +paragraph=Arduino library for X-Power AXP202 chip. Tested with ESP32 +category=Communication +url=https://github.com/lewisxhe/AXP202X_Library +architectures=esp32 diff --git a/libdeps/Button2/LICENSE b/libdeps/Button2/LICENSE new file mode 100644 index 0000000..53754be --- /dev/null +++ b/libdeps/Button2/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 LennartHennigs + +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. diff --git a/libdeps/Button2/README.md b/libdeps/Button2/README.md new file mode 100644 index 0000000..61a2837 --- /dev/null +++ b/libdeps/Button2/README.md @@ -0,0 +1,44 @@ +Button2 +====== + +* Author: Lennart Hennigs (https://www.lennarthennigs.de) +* Copyright (C) 2017 Lennart Hennigs. +* Released under the MIT license. + +Arduino Library to simplify working with buttons. + + +Description +----------- +It allows you to use callback functions to track single, double, triple and long clicks. It also takes care of debouncing. It will reduce and simplify your source code significantly. Tested with Arduino and ESP8266. + +Installation +------------ +Open the Arduino IDE choose "Sketch > Include Library" and search for "Button2". +Or download the ZIP archive (https://github.com/lennarthennigs/Button2/zipball/master), and choose "Sketch > Include Library > Add .ZIP Library..." and select the downloaded file. + + +License +------- + +MIT License + +Copyright (c) 2017 Lennart Hennigs + +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. diff --git a/libdeps/Button2/examples/LongpressHandler/LongpressHandler.ino b/libdeps/Button2/examples/LongpressHandler/LongpressHandler.ino new file mode 100644 index 0000000..f63b6e9 --- /dev/null +++ b/libdeps/Button2/examples/LongpressHandler/LongpressHandler.ino @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h"; + +///////////////////////////////////////////////////////////////// + +#define BUTTON_A_PIN 2 + +///////////////////////////////////////////////////////////////// + +Button2 buttonA = Button2(BUTTON_A_PIN); + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nLongpress Handler Demo"); + + buttonA.setLongClickHandler(longpress); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + buttonA.loop(); +} + +///////////////////////////////////////////////////////////////// + +void longpress(Button2& btn) { + unsigned int time = btn.wasPressedFor(); + Serial.print("You clicked "); + if (time > 1500) { + Serial.print("a really really long time."); + } else if (time > 1000) { + Serial.print("a really long time."); + } else if (time > 500) { + Serial.print("a long time."); + } else { + Serial.print("long."); + } + Serial.print(" ("); + Serial.print(time); + Serial.println(" ms)"); +} + +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/libdeps/Button2/examples/MultiHandler/MultiHandler.ino b/libdeps/Button2/examples/MultiHandler/MultiHandler.ino new file mode 100644 index 0000000..a5b698e --- /dev/null +++ b/libdeps/Button2/examples/MultiHandler/MultiHandler.ino @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h"; + +///////////////////////////////////////////////////////////////// + +#define BUTTON_A_PIN 2 + +///////////////////////////////////////////////////////////////// + +Button2 buttonA = Button2(BUTTON_A_PIN); + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nMulti Handler Demo"); + + buttonA.setClickHandler(handler); + buttonA.setLongClickHandler(handler); + buttonA.setDoubleClickHandler(handler); + buttonA.setTripleClickHandler(handler); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + buttonA.loop(); +} + +///////////////////////////////////////////////////////////////// + +void handler(Button2& btn) { + switch (btn.getClickType()) { + case SINGLE_CLICK: + break; + case DOUBLE_CLICK: + Serial.print("double "); + break; + case TRIPLE_CLICK: + Serial.print("triple "); + break; + case LONG_CLICK: + Serial.print("long"); + break; + } + Serial.print("click"); + Serial.print(" ("); + Serial.print(btn.getNumberOfClicks()); + Serial.println(")"); +} +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/libdeps/Button2/examples/MultipleButtons/MultipleButtons.ino b/libdeps/Button2/examples/MultipleButtons/MultipleButtons.ino new file mode 100644 index 0000000..ce25d16 --- /dev/null +++ b/libdeps/Button2/examples/MultipleButtons/MultipleButtons.ino @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h"; + +///////////////////////////////////////////////////////////////// + +#define BUTTON_A_PIN 2 +#define BUTTON_B_PIN 0 + +///////////////////////////////////////////////////////////////// + +Button2 buttonA = Button2(BUTTON_A_PIN); +Button2 buttonB = Button2(BUTTON_B_PIN); + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nMultiple Buttons Demo"); + + buttonA.setClickHandler(click); + buttonB.setClickHandler(click); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + buttonA.loop(); + buttonB.loop(); +} + +///////////////////////////////////////////////////////////////// + +void click(Button2& btn) { + if (btn == buttonA) { + Serial.println("A clicked"); + } else if (btn == buttonB) { + Serial.println("B clicked"); + } +} + +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/libdeps/Button2/examples/SingleButton/SingleButton.ino b/libdeps/Button2/examples/SingleButton/SingleButton.ino new file mode 100644 index 0000000..fd09cdd --- /dev/null +++ b/libdeps/Button2/examples/SingleButton/SingleButton.ino @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h"; + +///////////////////////////////////////////////////////////////// + +#define BUTTON_A_PIN 2 + +///////////////////////////////////////////////////////////////// + +Button2 buttonA = Button2(BUTTON_A_PIN); + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nButton Demo"); + + // buttonA.setChangedHandler(changed); + // buttonA.setPressedHandler(pressed); + buttonA.setReleasedHandler(released); + + // buttonA.setTapHandler(tap); + buttonA.setClickHandler(click); + buttonA.setLongClickHandler(longClick); + buttonA.setDoubleClickHandler(doubleClick); + buttonA.setTripleClickHandler(tripleClick); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + button.loop(); +} + +///////////////////////////////////////////////////////////////// + +void pressed(Button2& btn) { + Serial.println("pressed"); +} +void released(Button2& btn) { + Serial.print("released: "); + Serial.println(btn.wasPressedFor()); +} +void changed(Button2& btn) { + Serial.println("changed"); +} +void click(Button2& btn) { + Serial.println("click\n"); +} +void longClick(Button2& btn) { + Serial.println("long click\n"); +} +void doubleClick(Button2& btn) { + Serial.println("double click\n"); +} +void tripleClick(Button2& btn) { + Serial.println("triple click\n"); +} +void tap(Button2& btn) { + Serial.println("tap"); +} +///////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/libdeps/Button2/examples/SingleButtonSimple/SingleButtonSimple.ino b/libdeps/Button2/examples/SingleButtonSimple/SingleButtonSimple.ino new file mode 100644 index 0000000..ccdee84 --- /dev/null +++ b/libdeps/Button2/examples/SingleButtonSimple/SingleButtonSimple.ino @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////// + +#include "Button2.h"; + +///////////////////////////////////////////////////////////////// + +#define BUTTON_A_PIN 2 + +///////////////////////////////////////////////////////////////// + +Button2 buttonA = Button2(BUTTON_A_PIN); + +///////////////////////////////////////////////////////////////// + +void setup() { + Serial.begin(9600); + delay(50); + Serial.println("\n\nButton Demo"); + + buttonA.setChangedHandler(changed); + //buttonA.setPressedHandler(pressed); + //buttonA.setReleasedHandler(released); + + // captures any type of click, longpress or shortpress + buttonA.setTapHandler(tap); +} + +///////////////////////////////////////////////////////////////// + +void loop() { + buttonA.loop(); +} + +///////////////////////////////////////////////////////////////// + +void pressed(Button2& btn) { + Serial.println("pressed"); +} +void released(Button2& btn) { + Serial.print("released: "); + Serial.println(btn.wasPressedFor()); +} +void changed(Button2& btn) { + Serial.println("changed"); +} +void tap(Button2& btn) { + Serial.println("tap"); +} +///////////////////////////////////////////////////////////////// + diff --git a/libdeps/Button2/keywords.txt b/libdeps/Button2/keywords.txt new file mode 100644 index 0000000..e41de13 --- /dev/null +++ b/libdeps/Button2/keywords.txt @@ -0,0 +1,22 @@ +Button2 KEYWORD1 +setDebounceTime KEYWORD2 +setChangedHandler KEYWORD2 +setPressedHandler KEYWORD2 +setReleasedHandler KEYWORD2 +setClickHandler KEYWORD2 +setTapHandler KEYWORD2 +setLongClickHandler KEYWORD2 +setDoubleClickHandler KEYWORD2 +setTripleClickHandler KEYWORD2 +wasPressedFor KEYWORD2 +isPressed KEYWORD2 +getNumberOfClicks KEYWORD2 +getClickType KEYWORD2 +loop KEYWORD2 +DEBOUNCE_MS LITERAL1 +LONGCLICK_MS LITERAL1 +DOUBLECLICK_MS LITERAL1 +SINGLE_CLICK LITERAL1 +DOUBLE_CLICK LITERAL1 +TRIPLE_CLICK LITERAL1 +LONG_CLICK LITERAL1 \ No newline at end of file diff --git a/libdeps/Button2/library.properties b/libdeps/Button2/library.properties new file mode 100644 index 0000000..726180d --- /dev/null +++ b/libdeps/Button2/library.properties @@ -0,0 +1,10 @@ +name=Button2 +version=1.0.0 +author=Lennart Hennigs +maintainer=Lennart Hennigs +sentence=Arduino Library to simplify working with buttons. +paragraph=It allows you to use callback functions to track single, double, triple and long clicks. It also takes care of debouncing. It will reduce and simplify your souce code significantly. Tested with Arduino and ESP8266. +category=Communication +url=https://github.com/LennartHennigs/Button2 +architectures=* +includes=ButtonCallback.h diff --git a/libdeps/ESP8266_SSD1306/.github/stale.yml b/libdeps/ESP8266_SSD1306/.github/stale.yml new file mode 100644 index 0000000..9bcd4eb --- /dev/null +++ b/libdeps/ESP8266_SSD1306/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 180 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 14 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/libdeps/ESP8266_SSD1306/.library.json b/libdeps/ESP8266_SSD1306/.library.json new file mode 100644 index 0000000..7c89870 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/.library.json @@ -0,0 +1,37 @@ +{ + "name": "ESP8266_SSD1306", + "repository": { + "url": "https://github.com/ThingPulse/esp8266-oled-ssd1306", + "type": "git" + }, + "platforms": [ + "espressif32", + "espressif8266" + ], + "frameworks": [ + "arduino" + ], + "version": "4.1.0", + "authors": [ + { + "maintainer": false, + "name": "Daniel Eichhorn, ThingPulse", + "url": "https://thingpulse.com", + "email": "squix78@gmail.com" + }, + { + "url": null, + "maintainer": false, + "email": "fabrice@weinberg.me", + "name": "Fabrice Weinberg" + } + ], + "keywords": [ + "oled", + "i2c", + "display", + "ssd1306" + ], + "id": 562, + "description": "I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS" +} \ No newline at end of file diff --git a/libdeps/ESP8266_SSD1306/CMakeLists.txt b/libdeps/ESP8266_SSD1306/CMakeLists.txt new file mode 100644 index 0000000..705d9a0 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_ADD_INCLUDEDIRS src) +set(COMPONENT_PRIV_REQUIRES arduino-esp32) +set(COMPONENT_SRCDIRS src) +register_component() diff --git a/libdeps/ESP8266_SSD1306/README.md b/libdeps/ESP8266_SSD1306/README.md new file mode 100644 index 0000000..f6fb177 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/README.md @@ -0,0 +1,419 @@ +[![Build Status](https://travis-ci.org/ThingPulse/esp8266-oled-ssd1306.svg?branch=master)](https://travis-ci.org/ThingPulse/esp8266-oled-ssd1306) + +# ThingPulse OLED SSD1306 (ESP8266/ESP32/Mbed-OS) + +> We just released version 4.0.0. Please have a look at our [upgrade guide](UPGRADE-4.0.md) + +This is a driver for SSD1306 128x64 and 128x32 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. + +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. Just execute the following command: +``` +platformio lib install 562 +``` + +## Service level promise + +
+This is a ThingPulse prime project. See our open-source commitment declaration for what this means.
+ +## Credits + +This library has initially been written by Daniel Eichhorn ([@squix78](https://github.com/squix78)). Many thanks go to Fabrice Weinberg ([@FWeinb](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 ([@helmut64](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 +#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 a SH1106: +```C++ +#include +#include "SH1106Wire.h" + +SH1106Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL +``` + +### I2C with brzo_i2c + +```C++ +#include +#include "SSD1306Brzo.h" + +SSD1306Brzo display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL +``` +or for the SH1106: +```C++ +#include +#include "SH1106Brzo.h" + +SH1106Brzo display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL +``` + +### SPI + +```C++ +#include +#include "SSD1306Spi.h" + +SSD1306Spi display(D0, D2, D8); // RES, DC, CS +``` +or for the SH1106: +```C++ +#include +#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 +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 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 char* xbm); +``` + +## Text operations + +``` C++ +void drawString(int16_t x, int16_t y, 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 +void drawStringMaxWidth(int16_t x, int16_t y, int16_t maxLineWidth, String text); + +// Returns the width of the const char* with the current +// font settings +uint16_t getStringWidth(const char* text, uint16_t length); + +// Convencience method for the const char version +uint16_t getStringWidth(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 Ui elements called, `Frames` and `Overlays`. A `Frame` is used to provide +information the default behaviour is to display a `Frame` for a defined time and than move to the next. The library also provides an `Indicator` that will be updated accordingly. An `Overlay` on the other hand is a pieces of information (e.g. a clock) that is displayed always 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 char* symbol); + +/** + * Set the symbol to indicate an inactive frame in the indicator bar. + */ +void setInactiveSymbol(const char* 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); + +// Manuell Controll +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 xbm image + * How to draw a 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) + * Yours? diff --git a/libdeps/ESP8266_SSD1306/UPGRADE-3.0.md b/libdeps/ESP8266_SSD1306/UPGRADE-3.0.md new file mode 100644 index 0000000..e7a315b --- /dev/null +++ b/libdeps/ESP8266_SSD1306/UPGRADE-3.0.md @@ -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. diff --git a/libdeps/ESP8266_SSD1306/UPGRADE-4.0.md b/libdeps/ESP8266_SSD1306/UPGRADE-4.0.md new file mode 100644 index 0000000..4b17693 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/UPGRADE-4.0.md @@ -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); + ``` diff --git a/libdeps/ESP8266_SSD1306/component.mk b/libdeps/ESP8266_SSD1306/component.mk new file mode 100644 index 0000000..23a01a0 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/component.mk @@ -0,0 +1,3 @@ +COMPONENT_ADD_INCLUDEDIRS := src +COMPONENT_SRCDIRS := src +CXXFLAGS += -Wno-ignored-qualifiers diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306ClockDemo/SSD1306ClockDemo.ino b/libdeps/ESP8266_SSD1306/examples/SSD1306ClockDemo/SSD1306ClockDemo.ino new file mode 100644 index 0000000..63102cf --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306ClockDemo/SSD1306ClockDemo.ino @@ -0,0 +1,214 @@ +/** + * 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 + +// Include the correct display library +// For a connection via I2C using Wire include +#include // 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 // Only needed for Arduino 1.6.5 and earlier +// #include "SSD1306Brzo.h" +// #include "SH1106Brzo.h" +// For a connection via SPI include +// #include // 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, D3, D5); +// SH1106 display(0x3c, D3, D5); + +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(9600); + 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); + + } + + +} diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306ClockDemo/images.h b/libdeps/ESP8266_SSD1306/examples/SSD1306ClockDemo/images.h new file mode 100644 index 0000000..1889188 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306ClockDemo/images.h @@ -0,0 +1,21 @@ +const unsigned char activeSymbol[] PROGMEM = { + B00000000, + B00000000, + B00011000, + B00100100, + B01000010, + B01000010, + B00100100, + B00011000 +}; + +const unsigned char inactiveSymbol[] PROGMEM = { + B00000000, + B00000000, + B00000000, + B00000000, + B00011000, + B00011000, + B00000000, + B00000000 +}; diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino b/libdeps/ESP8266_SSD1306/examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino new file mode 100644 index 0000000..43bd974 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306DrawingDemo/SSD1306DrawingDemo.ino @@ -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 // 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 // Only needed for Arduino 1.6.5 and earlier + // #include "SSD1306Brzo.h" + // #include "SH1106Brzo.h" + // For a connection via SPI include + // #include // 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, D3, D5); + // SH1106 display(0x3c, D3, D5); + +// Adapted from Adafruit_SSD1306 +void drawLines() { + for (int16_t i=0; 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 + + // OTA Includes + #include + #include + + const char *ssid = "[Your SSID]"; + const char *password = "[Your Password]"; + + +// Include the correct display library +// For a connection via I2C using Wire include +#include // 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 // Only needed for Arduino 1.6.5 and earlier +// #include "SSD1306Brzo.h" +// #include "SH1106Brzo.h" +// For a connection via SPI include +// #include // 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, D3, D5); +// SH1106 display(0x3c, D3, D5); + + +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(); +} diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino b/libdeps/ESP8266_SSD1306/examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino new file mode 100644 index 0000000..8d715e4 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306SimpleDemo/SSD1306SimpleDemo.ino @@ -0,0 +1,197 @@ +/** + * 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 // 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 // Only needed for Arduino 1.6.5 and earlier +// #include "SSD1306Brzo.h" +// OR #include "SH1106Brzo.h" + +// For a connection via SPI include: +// #include // 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 +// 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. +// SH1106 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.setTextAlignment(TEXT_ALIGN_RIGHT); + display.drawString(10, 128, String(millis())); + // write the buffer to the display + display.display(); + + if (millis() - timeSinceLastModeSwitch > DEMO_DURATION) { + demoMode = (demoMode + 1) % demoLength; + timeSinceLastModeSwitch = millis(); + } + counter++; + delay(10); +} diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306SimpleDemo/images.h b/libdeps/ESP8266_SSD1306/examples/SSD1306SimpleDemo/images.h new file mode 100644 index 0000000..5041799 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306SimpleDemo/images.h @@ -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, + }; diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306TwoScreenDemo/SSD1306TwoScreenDemo.ino b/libdeps/ESP8266_SSD1306/examples/SSD1306TwoScreenDemo/SSD1306TwoScreenDemo.ino new file mode 100644 index 0000000..b9595d8 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306TwoScreenDemo/SSD1306TwoScreenDemo.ino @@ -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 // 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, D3, D5); +SSD1306Wire display2(0x3c, D1, D2); + +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); +} diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306TwoScreenDemo/images.h b/libdeps/ESP8266_SSD1306/examples/SSD1306TwoScreenDemo/images.h new file mode 100644 index 0000000..5041799 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306TwoScreenDemo/images.h @@ -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, + }; diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306UiDemo/SSD1306UiDemo.ino b/libdeps/ESP8266_SSD1306/examples/SSD1306UiDemo/SSD1306UiDemo.ino new file mode 100644 index 0000000..72c836b --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306UiDemo/SSD1306UiDemo.ino @@ -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 // 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 // Only needed for Arduino 1.6.5 and earlier + // #include "SSD1306Brzo.h" + // #include "SH1106Brzo.h" + // For a connection via SPI include + // #include // 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, D3, D5); +// SH1106Wire display(0x3c, D3, D5); + +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); + } +} diff --git a/libdeps/ESP8266_SSD1306/examples/SSD1306UiDemo/images.h b/libdeps/ESP8266_SSD1306/examples/SSD1306UiDemo/images.h new file mode 100644 index 0000000..2489d1e --- /dev/null +++ b/libdeps/ESP8266_SSD1306/examples/SSD1306UiDemo/images.h @@ -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 +}; diff --git a/libdeps/ESP8266_SSD1306/library.json b/libdeps/ESP8266_SSD1306/library.json new file mode 100644 index 0000000..f3409a2 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/library.json @@ -0,0 +1,28 @@ +{ + "name": "ESP8266_SSD1306", + "version": "4.1.0", + "keywords": "ssd1306, oled, display, i2c", + "description": "I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS", + "repository": + { + "type": "git", + "url": "https://github.com/ThingPulse/esp8266-oled-ssd1306" + }, + "authors": + [ + { + "name": "Daniel Eichhorn, ThingPulse", + "email": "squix78@gmail.com", + "url": "https://thingpulse.com" + }, + { + "name": "Fabrice Weinberg", + "email": "fabrice@weinberg.me" + } + ], + "frameworks": "arduino", + "platforms": [ + "espressif8266", + "espressif32" + ] +} diff --git a/libdeps/ESP8266_SSD1306/library.properties b/libdeps/ESP8266_SSD1306/library.properties new file mode 100644 index 0000000..a62c352 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/library.properties @@ -0,0 +1,9 @@ +name=ESP8266 and ESP32 OLED driver for SSD1306 displays +version=4.1.0 +author=ThingPulse, Fabrice Weinberg +maintainer=ThingPulse +sentence=I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS +paragraph=The following geometries are currently supported: 128x64, 128x32, 64x48. The init sequence was inspired by Adafruit's library for the same display. +category=Display +url=https://github.com/ThingPulse/esp8266-oled-ssd1306 +architectures=esp8266,esp32 diff --git a/libdeps/ESP8266_SSD1306/license b/libdeps/ESP8266_SSD1306/license new file mode 100644 index 0000000..706c10f --- /dev/null +++ b/libdeps/ESP8266_SSD1306/license @@ -0,0 +1,24 @@ +The MIT License (MIT) + +Copyright (c) 2016 by Daniel Eichhorn +Copyright (c) 2016 by Fabrice Weinberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +See more at http://blog.squix.ch diff --git a/libdeps/ESP8266_SSD1306/resources/DemoFrame1.jpg b/libdeps/ESP8266_SSD1306/resources/DemoFrame1.jpg new file mode 100644 index 0000000..536b570 Binary files /dev/null and b/libdeps/ESP8266_SSD1306/resources/DemoFrame1.jpg differ diff --git a/libdeps/ESP8266_SSD1306/resources/DemoFrame2.jpg b/libdeps/ESP8266_SSD1306/resources/DemoFrame2.jpg new file mode 100644 index 0000000..8dccbcd Binary files /dev/null and b/libdeps/ESP8266_SSD1306/resources/DemoFrame2.jpg differ diff --git a/libdeps/ESP8266_SSD1306/resources/DemoFrame3.jpg b/libdeps/ESP8266_SSD1306/resources/DemoFrame3.jpg new file mode 100644 index 0000000..49e07ab Binary files /dev/null and b/libdeps/ESP8266_SSD1306/resources/DemoFrame3.jpg differ diff --git a/libdeps/ESP8266_SSD1306/resources/DemoFrame4.jpg b/libdeps/ESP8266_SSD1306/resources/DemoFrame4.jpg new file mode 100644 index 0000000..99cbe1b Binary files /dev/null and b/libdeps/ESP8266_SSD1306/resources/DemoFrame4.jpg differ diff --git a/libdeps/ESP8266_SSD1306/resources/FontTool.png b/libdeps/ESP8266_SSD1306/resources/FontTool.png new file mode 100644 index 0000000..c7bb222 Binary files /dev/null and b/libdeps/ESP8266_SSD1306/resources/FontTool.png differ diff --git a/libdeps/ESP8266_SSD1306/resources/SPI_version.jpg b/libdeps/ESP8266_SSD1306/resources/SPI_version.jpg new file mode 100644 index 0000000..115c9f3 Binary files /dev/null and b/libdeps/ESP8266_SSD1306/resources/SPI_version.jpg differ diff --git a/libdeps/ESP8266_SSD1306/resources/glyphEditor.html b/libdeps/ESP8266_SSD1306/resources/glyphEditor.html new file mode 100644 index 0000000..f253a80 --- /dev/null +++ b/libdeps/ESP8266_SSD1306/resources/glyphEditor.html @@ -0,0 +1,633 @@ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +
Font array name: +
First char code:
Width:
Height:
+
+
+
+
+

+ +
+
+ +
+
+
+
+ + + diff --git a/libdeps/ESP8266_SSD1306/resources/glyphEditor.png b/libdeps/ESP8266_SSD1306/resources/glyphEditor.png new file mode 100644 index 0000000..800efc5 Binary files /dev/null and b/libdeps/ESP8266_SSD1306/resources/glyphEditor.png differ diff --git a/libdeps/ESP8266_SSD1306/resources/xbmPreview.png b/libdeps/ESP8266_SSD1306/resources/xbmPreview.png new file mode 100644 index 0000000..70ea3a5 Binary files /dev/null and b/libdeps/ESP8266_SSD1306/resources/xbmPreview.png differ diff --git a/libdeps/LoRa/.library.json b/libdeps/LoRa/.library.json new file mode 100644 index 0000000..de5b24e --- /dev/null +++ b/libdeps/LoRa/.library.json @@ -0,0 +1,53 @@ +{ + "description": "An Arduino library for sending and receiving data using LoRa radios.", + "repository": { + "url": "https://github.com/sandeepmistry/arduino-LoRa", + "type": "git" + }, + "platforms": [ + "atmelavr", + "atmelsam", + "espressif32", + "espressif8266", + "gd32v", + "infineonxmc", + "intel_arc32", + "kendryte210", + "microchippic32", + "nordicnrf51", + "nordicnrf52", + "ststm32", + "ststm8", + "teensy", + "timsp430" + ], + "export": { + "exclude": [ + "extras", + "docs", + "tests", + "test", + "*.doxyfile", + "*.pdf" + ], + "include": null + }, + "authors": [ + { + "maintainer": true, + "name": "Sandeep Mistry", + "url": null, + "email": "sandeep.mistry@gmail.com" + } + ], + "keywords": [ + "communication" + ], + "id": 1167, + "name": "LoRa", + "frameworks": [ + "arduino" + ], + "version": "0.7.0", + "homepage": null +} \ No newline at end of file diff --git a/libdeps/LoRa/API.md b/libdeps/LoRa/API.md new file mode 100644 index 0000000..ded3b9c --- /dev/null +++ b/libdeps/LoRa/API.md @@ -0,0 +1,355 @@ +# LoRa API + +## Include Library + +```arduino +#include +``` + +## Setup + +### Begin + +Initialize the library with the specified frequency. + +```arduino +LoRa.begin(frequency); +``` + * `frequency` - frequency in Hz (`433E6`, `866E6`, `915E6`) + +Returns `1` on success, `0` on failure. + +### Set pins + +Override the default `NSS`, `NRESET`, and `DIO0` pins used by the library. **Must** be called before `LoRa.begin()`. + +```arduino +LoRa.setPins(ss, reset, dio0); +``` + * `ss` - new slave select pin to use, defaults to `10` + * `reset` - new reset pin to use, defaults to `9` + * `dio0` - new DIO0 pin to use, defaults to `2`. **Must** be interrupt capable via [attachInterrupt(...)](https://www.arduino.cc/en/Reference/AttachInterrupt). + +This call is optional and only needs to be used if you need to change the default pins used. + +#### No MCU controlled reset pin + +To save further pins one could connect the reset pin of the MCU with reset pin of the radio thus resetting only during startup. + +* `reset` - set to `-1` to omit this pin + +### Set SPI interface + +Override the default SPI interface used by the library. **Must** be called before `LoRa.begin()`. + +```arduino +LoRa.setSPI(spi); +``` + * `spi` - new SPI interface to use, defaults to `SPI` + +This call is optional and only needs to be used if you need to change the default SPI interface used, in the case your Arduino (or compatible) board has more than one SPI interface present. + +### Set SPI Frequency + +Override the default SPI frequency of 10 MHz used by the library. **Must** be called before `LoRa.begin()`. + +```arduino +LoRa.setSPIFrequency(frequency); +``` + * `frequency` - new SPI frequency to use, defaults to `8E6` + +This call is optional and only needs to be used if you need to change the default SPI frequency used. Some logic level converters cannot support high speeds such as 8 MHz, so a lower SPI frequency can be selected with `LoRa.setSPIFrequency(frequency)`. + +### End + +Stop the library + +```arduino +LoRa.end() +``` + +## Sending data + +### Begin packet + +Start the sequence of sending a packet. + +```arduino +LoRa.beginPacket(); + +LoRa.beginPacket(implicitHeader); +``` + + * `implicitHeader` - (optional) `true` enables implicit header mode, `false` enables explicit header mode (default) + +Returns `1` if radio is ready to transmit, `0` if busy or on failure. + +### Writing + +Write data to the packet. Each packet can contain up to 255 bytes. + +```arduino +LoRa.write(byte); + +LoRa.write(buffer, length); +``` +* `byte` - single byte to write to packet + +or + +* `buffer` - data to write to packet +* `length` - size of data to write + +Returns the number of bytes written. + +**Note:** Other Arduino `Print` API's can also be used to write data into the packet + +### End packet + +End the sequence of sending a packet. + +```arduino +LoRa.endPacket(); + +LoRa.endPacket(async); +``` + * `async` - (optional) `true` enables non-blocking mode, `false` waits for transmission to be completed (default) + +Returns `1` on success, `0` on failure. + +## Receiving data + +### Parsing packet + +Check if a packet has been received. + +```arduino +int packetSize = LoRa.parsePacket(); + +int packetSize = LoRa.parsePacket(size); +``` + + * `size` - (optional) if `> 0` implicit header mode is enabled with the expected a packet of `size` bytes, default mode is explicit header mode + + +Returns the packet size in bytes or `0` if no packet was received. + +### Continuous receive mode + +**WARNING**: Not supported on the Arduino MKR WAN 1300 board! + +#### Register callback + +Register a callback function for when a packet is received. + +```arduino +LoRa.onReceive(onReceive); + +void onReceive(int packetSize) { + // ... +} +``` + + * `onReceive` - function to call when a packet is received. + +#### Receive mode + +Puts the radio in continuous receive mode. + +```arduino +LoRa.receive(); + +LoRa.receive(int size); +``` + + * `size` - (optional) if `> 0` implicit header mode is enabled with the expected a packet of `size` bytes, default mode is explicit header mode + +The `onReceive` callback will be called when a packet is received. + +### Packet RSSI + +```arduino +int rssi = LoRa.packetRssi(); +``` + +Returns the RSSI of the received packet. + +### Packet SNR + +```arduino +float snr = LoRa.packetSnr(); +``` + +Returns the estimated SNR of the received packet in dB. + +### Packet Frequency Error + +```arduino +long freqErr = LoRa.packetFrequencyError(); +``` + +Returns the frequency error of the received packet in Hz. The frequency error is the frequency offset between the receiver centre frequency and that of an incoming LoRa signal. + +### Available + +```arduino +int availableBytes = LoRa.available() +``` + +Returns number of bytes available for reading. + +### Peeking + +Peek at the next byte in the packet. + +```arduino +byte b = LoRa.peek(); +``` + +Returns the next byte in the packet or `-1` if no bytes are available. + +### Reading + +Read the next byte from the packet. + +```arduino +byte b = LoRa.read(); +``` + +Returns the next byte in the packet or `-1` if no bytes are available. + +**Note:** Other Arduino [`Stream` API's](https://www.arduino.cc/en/Reference/Stream) can also be used to read data from the packet + +## Other radio modes + +### Idle mode + +Put the radio in idle (standby) mode. + +```arduino +LoRa.idle(); +``` + +### Sleep mode + +Put the radio in sleep mode. + +```arduino +LoRa.sleep(); +``` + +## Radio parameters + +### TX Power + +Change the TX power of the radio. + +```arduino +LoRa.setTxPower(txPower); + +LoRa.setTxPower(txPower, outputPin); +``` + * `txPower` - TX power in dB, defaults to `17` + * `outputPin` - (optional) PA output pin, supported values are `PA_OUTPUT_RFO_PIN` and `PA_OUTPUT_PA_BOOST_PIN`, defaults to `PA_OUTPUT_PA_BOOST_PIN`. + +Supported values are `2` to `20` for `PA_OUTPUT_PA_BOOST_PIN`, and `0` to `14` for `PA_OUTPUT_RFO_PIN`. + +Most modules have the PA output pin connected to PA BOOST, + +### Frequency + +Change the frequency of the radio. + +```arduino +LoRa.setFrequency(frequency); +``` + * `frequency` - frequency in Hz (`433E6`, `866E6`, `915E6`) + +### Spreading Factor + +Change the spreading factor of the radio. + +```arduino +LoRa.setSpreadingFactor(spreadingFactor); +``` + * `spreadingFactor` - spreading factor, defaults to `7` + +Supported values are between `6` and `12`. If a spreading factor of `6` is set, implicit header mode must be used to transmit and receive packets. + +### Signal Bandwidth + +Change the signal bandwidth of the radio. + +```arduino +LoRa.setSignalBandwidth(signalBandwidth); +``` + + * `signalBandwidth` - signal bandwidth in Hz, defaults to `125E3`. + +Supported values are `7.8E3`, `10.4E3`, `15.6E3`, `20.8E3`, `31.25E3`, `41.7E3`, `62.5E3`, `125E3`, and `250E3`. + +### Coding Rate + +Change the coding rate of the radio. + +```arduino +LoRa.setCodingRate4(codingRateDenominator); +``` + + * `codingRateDenominator` - denominator of the coding rate, defaults to `5` + +Supported values are between `5` and `8`, these correspond to coding rates of `4/5` and `4/8`. The coding rate numerator is fixed at `4`. + +### Preamble Length + +Change the preamble length of the radio. + +```arduino +LoRa.setPreambleLength(preambleLength); +``` + + * `preambleLength` - preamble length in symbols, defaults to `8` + +Supported values are between `6` and `65535`. + +### Sync Word + +Change the sync word of the radio. + +```arduino +LoRa.setSyncWord(syncWord); +``` + + * `syncWord` - byte value to use as the sync word, defaults to `0x12` + +### CRC + +Enable or disable CRC usage, by default a CRC is not used. + +```arduino +LoRa.enableCrc(); + +LoRa.disableCrc(); +``` + +### Invert IQ Signals + +Enable or disable Invert the LoRa I and Q signals, by default a invertIQ is not used. + +```arduino +LoRa.enableInvertIQ(); + +LoRa.disableInvertIQ(); +``` + +## Other functions + +### Random + +Generate a random byte, based on the Wideband RSSI measurement. + +``` +byte b = LoRa.random(); +``` + +Returns random byte. diff --git a/libdeps/LoRa/LICENSE b/libdeps/LoRa/LICENSE new file mode 100644 index 0000000..1e85b95 --- /dev/null +++ b/libdeps/LoRa/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Sandeep Mistry + +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. diff --git a/libdeps/LoRa/README.md b/libdeps/LoRa/README.md new file mode 100644 index 0000000..c89956a --- /dev/null +++ b/libdeps/LoRa/README.md @@ -0,0 +1,91 @@ +# Arduino LoRa + +[![Build Status](https://travis-ci.org/sandeepmistry/arduino-LoRa.svg?branch=master)](https://travis-ci.org/sandeepmistry/arduino-LoRa) + +An [Arduino](https://arduino.cc/) library for sending and receiving data using [LoRa](https://www.lora-alliance.org/) radios. + +## Compatible Hardware + + * [Semtech SX1276/77/78/79](http://www.semtech.com/apps/product.php?pn=SX1276) based boards including: + * [Dragino Lora Shield](http://www.dragino.com/products/module/item/102-lora-shield.html) + * [HopeRF](http://www.hoperf.com/rf_transceiver/lora/) [RFM95W](http://www.hoperf.com/rf_transceiver/lora/RFM95W.html), [RFM96W](http://www.hoperf.com/rf_transceiver/lora/RFM96W.html), and [RFM98W](http://www.hoperf.com/rf_transceiver/lora/RFM98W.html) + * [Modtronix](http://modtronix.com/) [inAir4](http://modtronix.com/inair4.html), [inAir9](http://modtronix.com/inair9.html), and [inAir9B](http://modtronix.com/inair9b.html) + * [Arduino MKR WAN 1300](https://store.arduino.cc/usa/mkr-wan-1300) + * **NOTE:** Requires firmware v1.1.6 or later on the on-board Murata module. Please use the [MKRWANFWUpdate_standalone example](https://github.com/arduino-libraries/MKRWAN/blob/master/examples/MKRWANFWUpdate_standalone/MKRWANFWUpdate_standalone.ino) from latest [MKRWAN library](https://github.com/arduino-libraries/MKRWAN) release to update the firmware. + * **WARNING**: [LoRa.onReceive(...)](https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md#register-callback) and [LoRa.recieve()](https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md#receive-mode) is not compatible with this board! + +### Semtech SX1276/77/78/79 wiring + +| Semtech SX1276/77/78/79 | Arduino | +| :---------------------: | :------:| +| VCC | 3.3V | +| GND | GND | +| SCK | SCK | +| MISO | MISO | +| MOSI | MOSI | +| NSS | 10 | +| NRESET | 9 | +| DIO0 | 2 | + + +`NSS`, `NRESET`, and `DIO0` pins can be changed by using `LoRa.setPins(ss, reset, dio0)`. `DIO0` pin is optional, it is only needed for receive callback mode. If `DIO0` pin is used, it **must** be interrupt capable via [`attachInterrupt(...)`](https://www.arduino.cc/en/Reference/AttachInterrupt). + +**NOTES**: + * Some boards (like the Arduino Nano), cannot supply enough current for the SX127x in TX mode. This will cause lockups when sending, be sure to use an external 3.3V supply that can provide at least 120mA's when using these boards. + * If your Arduino board operates at 5V, like the Arduino Uno, Leonardo or Mega, you will need to use a level converter for the wiring to the Semtech SX127x module. Most Semtech SX127x breakout boards do not have logic level converters built-in. + +## Installation + +### Using the Arduino IDE Library Manager + +1. Choose `Sketch` -> `Include Library` -> `Manage Libraries...` +2. Type `LoRa` into the search box. +3. Click the row to select the library. +4. Click the `Install` button to install the library. + +### Using Git + +```sh +cd ~/Documents/Arduino/libraries/ +git clone https://github.com/sandeepmistry/arduino-LoRa LoRa +``` + +## API + +See [API.md](API.md). + +## Examples + +See [examples](examples) folder. + +## FAQ + +**1) Initilizating the LoRa radio is failing** + +Please check the wiring you are using matches what's listed in [Semtech SX1276/77/78/79 wiring](#semtech-sx1276777879-wiring). You can also use `LoRa.setPins(ss, reset, dio0)` to change the default pins used. Some logic level converters cannot operate at 8 MHz, you can call `LoRa.setSPIFrequency(frequency)` to lower the SPI frequency used by the library. Both API's must be called before `LoRa.begin(...)`. + +**2) Can other radios see the packets I'm sending?** + +Yes, any LoRa radio that are configured with the same radio parameters and in range can see the packets you send. + +**3) Is the data I'm sending encrypted?** + +No, all data is sent unencrypted. If want your packet data to be encrypted, you must encrypt it before passing it into this library, followed by decrypting on the receiving end. + +**4) How does this library differ from LoRaWAN libraries?** + +This library exposes the LoRa radio directly, and allows you to send data to any radios in range with same radio parameters. All data is broadcasted and there is no addressing. LoRaWAN builds on top of LoRA, but adds addressing, encryption, and additional layers. It also requires a LoRaWAN gateway and LoRaWAN network and application server. + +**5) Does this library honor duty cycles?** + +No, you have to manage it by your self. + +**6) Which frequencies can I use?** + +You can use [this table](https://www.thethingsnetwork.org/wiki/LoRaWAN/Frequencies/By-Country) to lookup the available frequencies by your country. The selectable frequency also depends on your hardware. You can lookup the data sheet or ask your supplier. + +Please also notice the frequency dependent duty cycles for legal reasons! + +## License + +This libary is [licensed](LICENSE) under the [MIT Licence](https://en.wikipedia.org/wiki/MIT_License). diff --git a/libdeps/LoRa/examples/LoRaDumpRegisters/LoRaDumpRegisters.ino b/libdeps/LoRa/examples/LoRaDumpRegisters/LoRaDumpRegisters.ino new file mode 100644 index 0000000..5a23d2e --- /dev/null +++ b/libdeps/LoRa/examples/LoRaDumpRegisters/LoRaDumpRegisters.ino @@ -0,0 +1,30 @@ +/* + LoRa register dump + + This examples shows how to inspect and output the LoRa radio's + registers on the Serial interface +*/ +#include // include libraries +#include + +void setup() { + Serial.begin(9600); // initialize serial + while (!Serial); + + Serial.println("LoRa Dump Registers"); + + // override the default CS, reset, and IRQ pins (optional) + // LoRa.setPins(7, 6, 1); // set CS, reset, IRQ pin + + if (!LoRa.begin(915E6)) { // initialize ratio at 915 MHz + Serial.println("LoRa init failed. Check your connections."); + while (true); // if failed, do nothing + } + + LoRa.dumpRegisters(Serial); +} + + +void loop() { +} + diff --git a/libdeps/LoRa/examples/LoRaDuplex/LoRaDuplex.ino b/libdeps/LoRa/examples/LoRaDuplex/LoRaDuplex.ino new file mode 100644 index 0000000..c914254 --- /dev/null +++ b/libdeps/LoRa/examples/LoRaDuplex/LoRaDuplex.ino @@ -0,0 +1,106 @@ +/* + LoRa Duplex communication + + Sends a message every half second, and polls continually + for new incoming messages. Implements a one-byte addressing scheme, + with 0xFF as the broadcast address. + + Uses readString() from Stream class to read payload. The Stream class' + timeout may affect other functuons, like the radio's callback. For an + + created 28 April 2017 + by Tom Igoe +*/ +#include // include libraries +#include + +const int csPin = 7; // LoRa radio chip select +const int resetPin = 6; // LoRa radio reset +const int irqPin = 1; // change for your board; must be a hardware interrupt pin + +String outgoing; // outgoing message + +byte msgCount = 0; // count of outgoing messages +byte localAddress = 0xBB; // address of this device +byte destination = 0xFF; // destination to send to +long lastSendTime = 0; // last send time +int interval = 2000; // interval between sends + +void setup() { + Serial.begin(9600); // initialize serial + while (!Serial); + + Serial.println("LoRa Duplex"); + + // override the default CS, reset, and IRQ pins (optional) + LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin + + if (!LoRa.begin(915E6)) { // initialize ratio at 915 MHz + Serial.println("LoRa init failed. Check your connections."); + while (true); // if failed, do nothing + } + + Serial.println("LoRa init succeeded."); +} + +void loop() { + if (millis() - lastSendTime > interval) { + String message = "HeLoRa World!"; // send a message + sendMessage(message); + Serial.println("Sending " + message); + lastSendTime = millis(); // timestamp the message + interval = random(2000) + 1000; // 2-3 seconds + } + + // parse for a packet, and call onReceive with the result: + onReceive(LoRa.parsePacket()); +} + +void sendMessage(String outgoing) { + LoRa.beginPacket(); // start packet + LoRa.write(destination); // add destination address + LoRa.write(localAddress); // add sender address + LoRa.write(msgCount); // add message ID + LoRa.write(outgoing.length()); // add payload length + LoRa.print(outgoing); // add payload + LoRa.endPacket(); // finish packet and send it + msgCount++; // increment message ID +} + +void onReceive(int packetSize) { + if (packetSize == 0) return; // if there's no packet, return + + // read packet header bytes: + int recipient = LoRa.read(); // recipient address + byte sender = LoRa.read(); // sender address + byte incomingMsgId = LoRa.read(); // incoming msg ID + byte incomingLength = LoRa.read(); // incoming msg length + + String incoming = ""; + + while (LoRa.available()) { + incoming += (char)LoRa.read(); + } + + if (incomingLength != incoming.length()) { // check length for error + Serial.println("error: message length does not match length"); + return; // skip rest of function + } + + // if the recipient isn't this device or broadcast, + if (recipient != localAddress && recipient != 0xFF) { + Serial.println("This message is not for me."); + return; // skip rest of function + } + + // if message is for this device, or broadcast, print details: + Serial.println("Received from: 0x" + String(sender, HEX)); + Serial.println("Sent to: 0x" + String(recipient, HEX)); + Serial.println("Message ID: " + String(incomingMsgId)); + Serial.println("Message length: " + String(incomingLength)); + Serial.println("Message: " + incoming); + Serial.println("RSSI: " + String(LoRa.packetRssi())); + Serial.println("Snr: " + String(LoRa.packetSnr())); + Serial.println(); +} + diff --git a/libdeps/LoRa/examples/LoRaDuplexCallback/LoRaDuplexCallback.ino b/libdeps/LoRa/examples/LoRaDuplexCallback/LoRaDuplexCallback.ino new file mode 100644 index 0000000..0511f3e --- /dev/null +++ b/libdeps/LoRa/examples/LoRaDuplexCallback/LoRaDuplexCallback.ino @@ -0,0 +1,110 @@ +/* + LoRa Duplex communication wth callback + + Sends a message every half second, and uses callback + for new incoming messages. Implements a one-byte addressing scheme, + with 0xFF as the broadcast address. + + Note: while sending, LoRa radio is not listening for incoming messages. + Note2: when using the callback method, you can't use any of the Stream + functions that rely on the timeout, such as readString, parseInt(), etc. + + created 28 April 2017 + by Tom Igoe +*/ +#include // include libraries +#include + +#ifdef ARDUINO_SAMD_MKRWAN1300 +#error "This example is not compatible with the Arduino MKR WAN 1300 board!" +#endif + +const int csPin = 7; // LoRa radio chip select +const int resetPin = 6; // LoRa radio reset +const int irqPin = 1; // change for your board; must be a hardware interrupt pin + +String outgoing; // outgoing message +byte msgCount = 0; // count of outgoing messages +byte localAddress = 0xBB; // address of this device +byte destination = 0xFF; // destination to send to +long lastSendTime = 0; // last send time +int interval = 2000; // interval between sends + +void setup() { + Serial.begin(9600); // initialize serial + while (!Serial); + + Serial.println("LoRa Duplex with callback"); + + // override the default CS, reset, and IRQ pins (optional) + LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin + + if (!LoRa.begin(915E6)) { // initialize ratio at 915 MHz + Serial.println("LoRa init failed. Check your connections."); + while (true); // if failed, do nothing + } + + LoRa.onReceive(onReceive); + LoRa.receive(); + Serial.println("LoRa init succeeded."); +} + +void loop() { + if (millis() - lastSendTime > interval) { + String message = "HeLoRa World!"; // send a message + sendMessage(message); + Serial.println("Sending " + message); + lastSendTime = millis(); // timestamp the message + interval = random(2000) + 1000; // 2-3 seconds + LoRa.receive(); // go back into receive mode + } +} + +void sendMessage(String outgoing) { + LoRa.beginPacket(); // start packet + LoRa.write(destination); // add destination address + LoRa.write(localAddress); // add sender address + LoRa.write(msgCount); // add message ID + LoRa.write(outgoing.length()); // add payload length + LoRa.print(outgoing); // add payload + LoRa.endPacket(); // finish packet and send it + msgCount++; // increment message ID +} + +void onReceive(int packetSize) { + if (packetSize == 0) return; // if there's no packet, return + + // read packet header bytes: + int recipient = LoRa.read(); // recipient address + byte sender = LoRa.read(); // sender address + byte incomingMsgId = LoRa.read(); // incoming msg ID + byte incomingLength = LoRa.read(); // incoming msg length + + String incoming = ""; // payload of packet + + while (LoRa.available()) { // can't use readString() in callback, so + incoming += (char)LoRa.read(); // add bytes one by one + } + + if (incomingLength != incoming.length()) { // check length for error + Serial.println("error: message length does not match length"); + return; // skip rest of function + } + + // if the recipient isn't this device or broadcast, + if (recipient != localAddress && recipient != 0xFF) { + Serial.println("This message is not for me."); + return; // skip rest of function + } + + // if message is for this device, or broadcast, print details: + Serial.println("Received from: 0x" + String(sender, HEX)); + Serial.println("Sent to: 0x" + String(recipient, HEX)); + Serial.println("Message ID: " + String(incomingMsgId)); + Serial.println("Message length: " + String(incomingLength)); + Serial.println("Message: " + incoming); + Serial.println("RSSI: " + String(LoRa.packetRssi())); + Serial.println("Snr: " + String(LoRa.packetSnr())); + Serial.println(); +} + diff --git a/libdeps/LoRa/examples/LoRaReceiver/LoRaReceiver.ino b/libdeps/LoRa/examples/LoRaReceiver/LoRaReceiver.ino new file mode 100644 index 0000000..51cff48 --- /dev/null +++ b/libdeps/LoRa/examples/LoRaReceiver/LoRaReceiver.ino @@ -0,0 +1,34 @@ +#include +#include + +void setup() +{ + Serial.begin(9600); + while (!Serial); + + Serial.println("LoRa Receiver"); + + if (!LoRa.begin(915E6)) { + Serial.println("Starting LoRa failed!"); + while (1); + } +} + +void loop() +{ + // try to parse packet + int packetSize = LoRa.parsePacket(); + if (packetSize) { + // received a packet + Serial.print("Received packet '"); + + // read packet + while (LoRa.available()) { + Serial.print((char)LoRa.read()); + } + + // print RSSI of packet + Serial.print("' with RSSI "); + Serial.println(LoRa.packetRssi()); + } +} diff --git a/libdeps/LoRa/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino b/libdeps/LoRa/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino new file mode 100644 index 0000000..e227e23 --- /dev/null +++ b/libdeps/LoRa/examples/LoRaReceiverCallback/LoRaReceiverCallback.ino @@ -0,0 +1,43 @@ +#include +#include + +#ifdef ARDUINO_SAMD_MKRWAN1300 +#error "This example is not compatible with the Arduino MKR WAN 1300 board!" +#endif + +void setup() { + Serial.begin(9600); + while (!Serial); + + Serial.println("LoRa Receiver Callback"); + + if (!LoRa.begin(915E6)) { + Serial.println("Starting LoRa failed!"); + while (1); + } + + // register the receive callback + LoRa.onReceive(onReceive); + + // put the radio into receive mode + LoRa.receive(); +} + +void loop() { + // do nothing +} + +void onReceive(int packetSize) { + // received a packet + Serial.print("Received packet '"); + + // read packet + for (int i = 0; i < packetSize; i++) { + Serial.print((char)LoRa.read()); + } + + // print RSSI of packet + Serial.print("' with RSSI "); + Serial.println(LoRa.packetRssi()); +} + diff --git a/libdeps/LoRa/examples/LoRaSender/LoRaSender.ino b/libdeps/LoRa/examples/LoRaSender/LoRaSender.ino new file mode 100644 index 0000000..a252ee5 --- /dev/null +++ b/libdeps/LoRa/examples/LoRaSender/LoRaSender.ino @@ -0,0 +1,31 @@ +#include +#include + +int counter = 0; + +void setup() { + Serial.begin(9600); + while (!Serial); + + Serial.println("LoRa Sender"); + + if (!LoRa.begin(915E6)) { + Serial.println("Starting LoRa failed!"); + while (1); + } +} + +void loop() { + Serial.print("Sending packet: "); + Serial.println(counter); + + // send packet + LoRa.beginPacket(); + LoRa.print("hello "); + LoRa.print(counter); + LoRa.endPacket(); + + counter++; + + delay(5000); +} diff --git a/libdeps/LoRa/examples/LoRaSenderNonBlocking/LoRaSenderNonBlocking.ino b/libdeps/LoRa/examples/LoRaSenderNonBlocking/LoRaSenderNonBlocking.ino new file mode 100644 index 0000000..0f39077 --- /dev/null +++ b/libdeps/LoRa/examples/LoRaSenderNonBlocking/LoRaSenderNonBlocking.ino @@ -0,0 +1,35 @@ +#include +#include + +int counter = 0; + +void setup() { + Serial.begin(9600); + while (!Serial); + + Serial.println("LoRa Sender non-blocking"); + + if (!LoRa.begin(915E6)) { + Serial.println("Starting LoRa failed!"); + while (1); + } +} + +void loop() { + // wait until the radio is ready to send a packet + while (LoRa.beginPacket() == 0) { + Serial.print("waiting for radio ... "); + delay(100); + } + + Serial.print("Sending packet non-blocking: "); + Serial.println(counter); + + // send in async / non-blocking mode + LoRa.beginPacket(); + LoRa.print("hello "); + LoRa.print(counter); + LoRa.endPacket(true); // true = async / non-blocking mode + + counter++; +} diff --git a/libdeps/LoRa/examples/LoRaSetSpread/LoRaSetSpread.ino b/libdeps/LoRa/examples/LoRaSetSpread/LoRaSetSpread.ino new file mode 100644 index 0000000..99d0e8d --- /dev/null +++ b/libdeps/LoRa/examples/LoRaSetSpread/LoRaSetSpread.ino @@ -0,0 +1,87 @@ +/* + LoRa Duplex communication with Spreading Factor + + Sends a message every half second, and polls continually + for new incoming messages. Sets the LoRa radio's spreading factor. + + Spreading factor affects how far apart the radio's transmissions + are, across the available bandwidth. Radios with different spreading + factors will not receive each other's transmissions. This is one way you + can filter out radios you want to ignore, without making an addressing scheme. + + Spreading factor affects reliability of transmission at high rates, however, + so avoid a hugh spreading factor when you're sending continually. + + See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf + for more on Spreading Factor. + + created 28 April 2017 + by Tom Igoe +*/ +#include // include libraries +#include + +const int csPin = 7; // LoRa radio chip select +const int resetPin = 6; // LoRa radio reset +const int irqPin = 1; // change for your board; must be a hardware interrupt pin + +byte msgCount = 0; // count of outgoing messages +int interval = 2000; // interval between sends +long lastSendTime = 0; // time of last packet send + +void setup() { + Serial.begin(9600); // initialize serial + while (!Serial); + + Serial.println("LoRa Duplex - Set spreading factor"); + + // override the default CS, reset, and IRQ pins (optional) + LoRa.setPins(csPin, resetPin, irqPin); // set CS, reset, IRQ pin + + if (!LoRa.begin(915E6)) { // initialize ratio at 915 MHz + Serial.println("LoRa init failed. Check your connections."); + while (true); // if failed, do nothing + } + + LoRa.setSpreadingFactor(8); // ranges from 6-12,default 7 see API docs + Serial.println("LoRa init succeeded."); +} + +void loop() { + if (millis() - lastSendTime > interval) { + String message = "HeLoRa World! "; // send a message + message += msgCount; + sendMessage(message); + Serial.println("Sending " + message); + lastSendTime = millis(); // timestamp the message + interval = random(2000) + 1000; // 2-3 seconds + msgCount++; + } + + // parse for a packet, and call onReceive with the result: + onReceive(LoRa.parsePacket()); +} + +void sendMessage(String outgoing) { + LoRa.beginPacket(); // start packet + LoRa.print(outgoing); // add payload + LoRa.endPacket(); // finish packet and send it + msgCount++; // increment message ID +} + +void onReceive(int packetSize) { + if (packetSize == 0) return; // if there's no packet, return + + // read packet header bytes: + String incoming = ""; + + while (LoRa.available()) { + incoming += (char)LoRa.read(); + } + + Serial.println("Message: " + incoming); + Serial.println("RSSI: " + String(LoRa.packetRssi())); + Serial.println("Snr: " + String(LoRa.packetSnr())); + Serial.println(); +} + diff --git a/libdeps/LoRa/examples/LoRaSetSyncWord/LoRaSetSyncWord.ino b/libdeps/LoRa/examples/LoRaSetSyncWord/LoRaSetSyncWord.ino new file mode 100644 index 0000000..69af87d --- /dev/null +++ b/libdeps/LoRa/examples/LoRaSetSyncWord/LoRaSetSyncWord.ino @@ -0,0 +1,82 @@ +/* + LoRa Duplex communication with Sync Word + + Sends a message every half second, and polls continually + for new incoming messages. Sets the LoRa radio's Sync Word. + + Spreading factor is basically the radio's network ID. Radios with different + Sync Words will not receive each other's transmissions. This is one way you + can filter out radios you want to ignore, without making an addressing scheme. + + See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf + for more on Sync Word. + + created 28 April 2017 + by Tom Igoe +*/ +#include // include libraries +#include +const int csPin = 7; // LoRa radio chip select +const int resetPin = 6; // LoRa radio reset +const int irqPin = 1; // change for your board; must be a hardware interrupt pin + +byte msgCount = 0; // count of outgoing messages +int interval = 2000; // interval between sends +long lastSendTime = 0; // time of last packet send + +void setup() { + Serial.begin(9600); // initialize serial + while (!Serial); + + Serial.println("LoRa Duplex - Set sync word"); + + // override the default CS, reset, and IRQ pins (optional) + LoRa.setPins(csPin, resetPin, irqPin);// set CS, reset, IRQ pin + + if (!LoRa.begin(915E6)) { // initialize ratio at 915 MHz + Serial.println("LoRa init failed. Check your connections."); + while (true); // if failed, do nothing + } + + LoRa.setSyncWord(0xF3); // ranges from 0-0xFF, default 0x34, see API docs + Serial.println("LoRa init succeeded."); +} + +void loop() { + if (millis() - lastSendTime > interval) { + String message = "HeLoRa World! "; // send a message + message += msgCount; + sendMessage(message); + Serial.println("Sending " + message); + lastSendTime = millis(); // timestamp the message + interval = random(2000) + 1000; // 2-3 seconds + msgCount++; + } + + // parse for a packet, and call onReceive with the result: + onReceive(LoRa.parsePacket()); +} + +void sendMessage(String outgoing) { + LoRa.beginPacket(); // start packet + LoRa.print(outgoing); // add payload + LoRa.endPacket(); // finish packet and send it + msgCount++; // increment message ID +} + +void onReceive(int packetSize) { + if (packetSize == 0) return; // if there's no packet, return + + // read packet header bytes: + String incoming = ""; + + while (LoRa.available()) { + incoming += (char)LoRa.read(); + } + + Serial.println("Message: " + incoming); + Serial.println("RSSI: " + String(LoRa.packetRssi())); + Serial.println("Snr: " + String(LoRa.packetSnr())); + Serial.println(); +} + diff --git a/libdeps/LoRa/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino b/libdeps/LoRa/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino new file mode 100644 index 0000000..745bf1f --- /dev/null +++ b/libdeps/LoRa/examples/LoRaSimpleGateway/LoRaSimpleGateway.ino @@ -0,0 +1,113 @@ +/* + LoRa Simple Gateway/Node Exemple + + This code uses InvertIQ function to create a simple Gateway/Node logic. + + Gateway - Sends messages with enableInvertIQ() + - Receives messages with disableInvertIQ() + + Node - Sends messages with disableInvertIQ() + - Receives messages with enableInvertIQ() + + With this arrangement a Gateway never receive messages from another Gateway + and a Node never receive message from another Node. + Only Gateway to Node and vice versa. + + This code receives messages and sends a message every second. + + InvertIQ function basically invert the LoRa I and Q signals. + + See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf + for more on InvertIQ register 0x33. + + created 05 August 2018 + by Luiz H. Cassettari +*/ + +#include // include libraries +#include + +const long frequency = 915E6; // LoRa Frequency + +const int csPin = 10; // LoRa radio chip select +const int resetPin = 9; // LoRa radio reset +const int irqPin = 2; // change for your board; must be a hardware interrupt pin + +void setup() { + Serial.begin(9600); // initialize serial + while (!Serial); + + LoRa.setPins(csPin, resetPin, irqPin); + + if (!LoRa.begin(frequency)) { + Serial.println("LoRa init failed. Check your connections."); + while (true); // if failed, do nothing + } + + Serial.println("LoRa init succeeded."); + Serial.println(); + Serial.println("LoRa Simple Gateway"); + Serial.println("Only receive messages from nodes"); + Serial.println("Tx: invertIQ enable"); + Serial.println("Rx: invertIQ disable"); + Serial.println(); + + LoRa.onReceive(onReceive); + LoRa_rxMode(); +} + +void loop() { + if (runEvery(5000)) { // repeat every 5000 millis + + String message = "HeLoRa World! "; + message += "I'm a Gateway! "; + message += millis(); + + LoRa_sendMessage(message); // send a message + + Serial.println("Send Message!"); + } +} + +void LoRa_rxMode(){ + LoRa.disableInvertIQ(); // normal mode + LoRa.receive(); // set receive mode +} + +void LoRa_txMode(){ + LoRa.idle(); // set standby mode + LoRa.enableInvertIQ(); // active invert I and Q signals +} + +void LoRa_sendMessage(String message) { + LoRa_txMode(); // set tx mode + LoRa.beginPacket(); // start packet + LoRa.print(message); // add payload + LoRa.endPacket(); // finish packet and send it + LoRa_rxMode(); // set rx mode +} + +void onReceive(int packetSize) { + String message = ""; + + while (LoRa.available()) { + message += (char)LoRa.read(); + } + + Serial.print("Gateway Receive: "); + Serial.println(message); + +} + +boolean runEvery(unsigned long interval) +{ + static unsigned long previousMillis = 0; + unsigned long currentMillis = millis(); + if (currentMillis - previousMillis >= interval) + { + previousMillis = currentMillis; + return true; + } + return false; +} + diff --git a/libdeps/LoRa/examples/LoRaSimpleNode/LoRaSimpleNode.ino b/libdeps/LoRa/examples/LoRaSimpleNode/LoRaSimpleNode.ino new file mode 100644 index 0000000..a6cb0c0 --- /dev/null +++ b/libdeps/LoRa/examples/LoRaSimpleNode/LoRaSimpleNode.ino @@ -0,0 +1,113 @@ +/* + LoRa Simple Gateway/Node Exemple + + This code uses InvertIQ function to create a simple Gateway/Node logic. + + Gateway - Sends messages with enableInvertIQ() + - Receives messages with disableInvertIQ() + + Node - Sends messages with disableInvertIQ() + - Receives messages with enableInvertIQ() + + With this arrangement a Gateway never receive messages from another Gateway + and a Node never receive message from another Node. + Only Gateway to Node and vice versa. + + This code receives messages and sends a message every second. + + InvertIQ function basically invert the LoRa I and Q signals. + + See the Semtech datasheet, http://www.semtech.com/images/datasheet/sx1276.pdf + for more on InvertIQ register 0x33. + + created 05 August 2018 + by Luiz H. Cassettari +*/ + +#include // include libraries +#include + +const long frequency = 915E6; // LoRa Frequency + +const int csPin = 10; // LoRa radio chip select +const int resetPin = 9; // LoRa radio reset +const int irqPin = 2; // change for your board; must be a hardware interrupt pin + +void setup() { + Serial.begin(9600); // initialize serial + while (!Serial); + + LoRa.setPins(csPin, resetPin, irqPin); + + if (!LoRa.begin(frequency)) { + Serial.println("LoRa init failed. Check your connections."); + while (true); // if failed, do nothing + } + + Serial.println("LoRa init succeeded."); + Serial.println(); + Serial.println("LoRa Simple Node"); + Serial.println("Only receive messages from gateways"); + Serial.println("Tx: invertIQ disable"); + Serial.println("Rx: invertIQ enable"); + Serial.println(); + + LoRa.onReceive(onReceive); + LoRa_rxMode(); +} + +void loop() { + if (runEvery(1000)) { // repeat every 1000 millis + + String message = "HeLoRa World! "; + message += "I'm a Node! "; + message += millis(); + + LoRa_sendMessage(message); // send a message + + Serial.println("Send Message!"); + } +} + +void LoRa_rxMode(){ + LoRa.enableInvertIQ(); // active invert I and Q signals + LoRa.receive(); // set receive mode +} + +void LoRa_txMode(){ + LoRa.idle(); // set standby mode + LoRa.disableInvertIQ(); // normal mode +} + +void LoRa_sendMessage(String message) { + LoRa_txMode(); // set tx mode + LoRa.beginPacket(); // start packet + LoRa.print(message); // add payload + LoRa.endPacket(); // finish packet and send it + LoRa_rxMode(); // set rx mode +} + +void onReceive(int packetSize) { + String message = ""; + + while (LoRa.available()) { + message += (char)LoRa.read(); + } + + Serial.print("Node Receive: "); + Serial.println(message); + +} + +boolean runEvery(unsigned long interval) +{ + static unsigned long previousMillis = 0; + unsigned long currentMillis = millis(); + if (currentMillis - previousMillis >= interval) + { + previousMillis = currentMillis; + return true; + } + return false; +} + diff --git a/libdeps/LoRa/issue_template.md b/libdeps/LoRa/issue_template.md new file mode 100644 index 0000000..3fa6d74 --- /dev/null +++ b/libdeps/LoRa/issue_template.md @@ -0,0 +1,3 @@ +Are you receiving `Starting LoRa failed` while using the demo code? + +PLEASE see the [FAQ #1](https://github.com/sandeepmistry/arduino-LoRa#faq) about using [setPins](https://github.com/sandeepmistry/arduino-LoRa/blob/master/API.md#set-pins) **BEFORE** submitting an issue. diff --git a/libdeps/LoRa/keywords.txt b/libdeps/LoRa/keywords.txt new file mode 100644 index 0000000..2cf0351 --- /dev/null +++ b/libdeps/LoRa/keywords.txt @@ -0,0 +1,60 @@ +####################################### +# Syntax Coloring Map For LoRa +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +LoRa KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +end KEYWORD2 + +beginPacket KEYWORD2 +endPacket KEYWORD2 + +parsePacket KEYWORD2 +packetRssi KEYWORD2 +packetSnr KEYWORD2 +packetFrequencyError KEYWORD2 + +write KEYWORD2 + +available KEYWORD2 +read KEYWORD2 +peek KEYWORD2 +flush KEYWORD2 + +onReceive KEYWORD2 +receive KEYWORD2 +idle KEYWORD2 +sleep KEYWORD2 + +setTxPower KEYWORD2 +setFrequency KEYWORD2 +setSpreadingFactor KEYWORD2 +setSignalBandwidth KEYWORD2 +setCodingRate4 KEYWORD2 +setPreambleLength KEYWORD2 +setSyncWord KEYWORD2 +enableCrc KEYWORD2 +disableCrc KEYWORD2 +enableInvertIQ KEYWORD2 +disableInvertIQ KEYWORD2 + +random KEYWORD2 +setPins KEYWORD2 +setSPIFrequency KEYWORD2 +dumpRegisters KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +PA_OUTPUT_RFO_PIN LITERAL1 +PA_OUTPUT_PA_BOOST_PIN LITERAL1 diff --git a/libdeps/LoRa/library.properties b/libdeps/LoRa/library.properties new file mode 100644 index 0000000..db6d845 --- /dev/null +++ b/libdeps/LoRa/library.properties @@ -0,0 +1,10 @@ +name=LoRa +version=0.7.0 +author=Sandeep Mistry +maintainer=Sandeep Mistry +sentence=An Arduino library for sending and receiving data using LoRa radios. +paragraph=Supports Semtech SX1276/77/78/79 based boards/shields. +category=Communication +url=https://github.com/sandeepmistry/arduino-LoRa +architectures=* +includes=LoRa.h diff --git a/libdeps/MicroNMEA/.bumpversion.cfg b/libdeps/MicroNMEA/.bumpversion.cfg new file mode 100644 index 0000000..7742d8d --- /dev/null +++ b/libdeps/MicroNMEA/.bumpversion.cfg @@ -0,0 +1,9 @@ +[bumpversion] +current_version = 2.0.3 +commit = True +tag = True + +[bumpversion:file:library.properties] + +[bumpversion:file:src/MicroNMEA.h] + diff --git a/libdeps/MicroNMEA/LICENSE b/libdeps/MicroNMEA/LICENSE new file mode 100644 index 0000000..5f2dd7f --- /dev/null +++ b/libdeps/MicroNMEA/LICENSE @@ -0,0 +1,505 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +(This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.) + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random + Hacker. + + {signature of Ty Coon}, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + diff --git a/libdeps/MicroNMEA/README.rst b/libdeps/MicroNMEA/README.rst new file mode 100644 index 0000000..4d2f103 --- /dev/null +++ b/libdeps/MicroNMEA/README.rst @@ -0,0 +1,145 @@ +MicroNMEA +========= + +MicroNMEA is a compact Arduino library to parse a subset of NMEA +sentences, which can originate from either GPS or GNSS receivers. Only +two types of messages are parsed, ``$GPGGA`` (and its GNSS +versions ``$GNGGA``, ``$GLGGA``, and ``$GAGGA``) and ``$GPRMC`` (and +its GNSS versions ``$GNRMC``, ``$GLRMC``, and ``$GARMC``). From these +two NMEA sentences MicroNMEA can output date, time, latitude, +longitude, altitude, number of satellites used, horizontal dilution of +precision (HDOP), course and speed. When other NMEA sentences are +detected they can be passed to an optional callback function for +decoding or logging. Checksum failures can be indicated with another +optional callback function. + +NMEA sentences can easily be sent to an output stream with the +``sendSentence()`` function which computes and appends the checksum, +as well as the correct ```` terminators. + +License +------- + +The MicroNMEA library is released under the GNU Lesser General Public License, version 2.1. +http://www.gnu.org/licenses/lgpl-2.1.html + +Initialization and basic usage +------------------------------ + +A ``MicroNMEA`` object must be defined with a pointer to a buffer and the buffer length:: + + char buffer[85]; + MicroNMEA nmea(buffer, sizeof(buffer)); + +This approach enables the user to size the buffer appropriately according to use without requiring ``malloc()``; for instance the buffer size can be increased if the temporal and spatial resolution reported have been increased by some properietary NMEA command. + +Output data from the GPS/GNSS device must be passed to the library for processing:: + + while (gps.available()) { + char c = gps.read(); + if (nmea.process(c)) { + // Complete NMEA command read and processed, do something + ... + } + } + +In the code fragment above ``gps`` is the output stream of the GPS/GNSS device. + +Retrieving information from MicroNMEA +------------------------------------- +Location, date, time and various status information can be requested using the appropriate member functions which are described below. To obtain all of the information listed below MicroNMEA must process both ``GxGGA`` and ``GxRMC`` sentences:: + + char getNavSystem() const + +Returns a single character indicating the navigation system in use: + ++--------+-----------------------------------------------------------------+ +| ``P`` | Navigation results based only on GPS satellites. | ++--------+-----------------------------------------------------------------+ +| ``L`` | Navigation results based only on GLONASS satellites. | ++--------+-----------------------------------------------------------------+ +| ``A`` | Navigation results based only on Galileo satellites. | ++--------+-----------------------------------------------------------------+ +| ``N`` | GNSS, navigation results from multiple satellite constellations.| ++--------+-----------------------------------------------------------------+ +| ``\0`` | No valid fix | ++--------+-----------------------------------------------------------------+ + +:: + + uint8_t getHDOP(void) const + +Horizontal dilution of precision in tenths (i.e., divide by 10 to get true HDOP). :: + + bool isValid(void) const + +Validity of latest fix. :: + + long getLatitude(void) const + +Latitude in millionths of a degree, North is positive. :: + + long getLlongitude(void) const + +Longitude in millionths of a degree, East is positive. :: + + bool getAltitude(long &alt) const + +Altitude in millimetres, returns true if the altitude was obtained from a valid fix. :: + + uint16_t getYear(void) const + uint8_t getMonth(void) const + uint8_t getDay(void) const + uint8_t getHour(void) const + uint8_t getMinute(void) const + uint8_t getSecond(void) const + uint8_t getHundredths(void) const + +Date and time. :: + + long getCourse(void) const + +Course over ground, in thousandths of a degree. :: + + long getSpeed(void) const + +Speed over ground, in thousandths of a knot. :: + + void clear(void) + +Clear all stored values. ``isValid()`` will return false. Year, month and day will all be zero. Hour, minute and second time will be set to 99. Speed, course and altitude will be set to ``LONG_MIN``; the altitude validity flag will be false. Latitude and longitude will be set to 999 degrees. + +Callback and associated functions +--------------------------------- + +:: + + void setBadChecksumHandler(void (*handler)(MicroNMEA& nmea)) + +``setBadChecksumHandler()`` enables MicroNMEA to call a function when a bad NMEA checksum is detected. The callback function should accept a single parameter (a ``MicroNMEA`` object passed by reference) and return ``void``. :: + + void setUnknownSentenceHandler(void (*handler)(MicroNMEA& nmea)) + +``setUnknownSentenceHandler()`` enables MicroNMEA to call a function when a valid but unknown NMEA command is +received. The callback function should accept a single parameter (a ``MicroNMEA`` object passed by reference) and return ``void``. :: + + const char* getSentence(void) const + +Return the current NMEA sentence. Useful when using callback functions. :: + + char getTalkerID(void) const + +Return the talker ID from the last processed NMEA sentence. The meaning is the same as the return value from ``getNavSystem()``. If ``$GxGSV`` messages are received then talker ID could be from any of the GNSS constellations. :: + + const char* getMessageID(void) const + +Return the message ID from the last processed NMEA sentence, e.g, ``RMC``, ``GGA``. Useful when using callback functions. + + +Contributors +------------ + +- Steve Marple +- Christopher Liebman + + diff --git a/libdeps/MicroNMEA/examples/X_NUCLEO_GNSS1A1_MicroNMEA_I2C/X_NUCLEO_GNSS1A1_MicroNMEA_I2C.ino b/libdeps/MicroNMEA/examples/X_NUCLEO_GNSS1A1_MicroNMEA_I2C/X_NUCLEO_GNSS1A1_MicroNMEA_I2C.ino new file mode 100644 index 0000000..405ee60 --- /dev/null +++ b/libdeps/MicroNMEA/examples/X_NUCLEO_GNSS1A1_MicroNMEA_I2C/X_NUCLEO_GNSS1A1_MicroNMEA_I2C.ino @@ -0,0 +1,257 @@ +/** + ****************************************************************************** + * @file X_NUCLEO_GNSS1A1_MicroNMEA_I2C.ino + * @author AST + * @version V1.0.0 + * @date January 2018 + * @brief Arduino test application for the STMicrolectronics X-NUCLEO-GNSS1A1 + * GNSS module expansion board based on TeseoLIV3F. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +//NOTE: In order for this example to work, the jumper J4 on the device should +// be moved to J8 +//NOTE: This example is compatible with the Arduino Uno board + +#include +#include + +//I2C communication parameters +#define DEFAULT_DEVICE_ADDRESS 0x3A +#define DEFAULT_DEVICE_PORT 0xFF +#define I2C_DELAY 1 + +#define RESET_PIN 7 + +#ifdef ARDUINO_SAM_DUE +#define DEV_I2C Wire1 +#endif + +#ifdef ARDUINO_ARCH_STM32 +#define DEV_I2C Wire +#endif + +#ifdef ARDUINO_ARCH_AVR +#define DEV_I2C Wire +#endif + +// Refer to Stream devices by use +HardwareSerial& console = Serial; +TwoWire& gps = DEV_I2C; + +//I2C read data structures +char buff[32]; +int idx = 0; + +//MicroNMEA library structures +char nmeaBuffer[100]; +MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer)); + + +bool ledState = LOW; +volatile bool ppsTriggered = false; + + +void ppsHandler(void); + + +void ppsHandler(void) +{ + ppsTriggered = true; +} + + +void gpsHardwareReset() +{ + //reset the device + digitalWrite(RESET_PIN, LOW); + delay(50); + digitalWrite(RESET_PIN, HIGH); + + //wait for reset to apply + delay(2000); + +} + +//Read 32 bytes from I2C +void readI2C(char *inBuff) +{ + gps.beginTransmission(DEFAULT_DEVICE_ADDRESS); + gps.write((uint8_t) DEFAULT_DEVICE_PORT); + gps.endTransmission(false); + gps.requestFrom((uint8_t)DEFAULT_DEVICE_ADDRESS, (uint8_t) 32); + int i = 0; + while (gps.available()) + { + inBuff[i]= gps.read(); + i++; + } +} + +//Send a NMEA command via I2C +void sendCommand(char *cmd) +{ + gps.beginTransmission(DEFAULT_DEVICE_ADDRESS); + gps.write((uint8_t) DEFAULT_DEVICE_PORT); + MicroNMEA::sendSentence(gps, cmd); + gps.endTransmission(true); +} + +void setup(void) +{ + console.begin(115200); // console + gps.begin(); // gps + + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, ledState); + + //Start the module + pinMode(RESET_PIN, OUTPUT); + digitalWrite(RESET_PIN, HIGH); + console.println("Resetting GPS module ..."); + gpsHardwareReset(); + console.println("... done"); + + // Change the echoing messages to the ones recognized by the MicroNMEA library + sendCommand("$PSTMSETPAR,1231,0x00000042"); + sendCommand("$PSTMSAVEPAR"); + + //Reset the device so that the changes could take plaace + sendCommand("$PSTMSRR"); + + delay(4000); + + //Reinitialize I2C after the reset + gps.begin(); + + //clear i2c buffer + char c; + idx = 0; + memset(buff, 0, 32); + do + { + if (idx == 0) + { + readI2C(buff); + delay(I2C_DELAY); + } + c = buff[idx]; + idx++; + idx %= 32; + } + while ((uint8_t) c != 0xFF); + + pinMode(2, INPUT); + attachInterrupt(digitalPinToInterrupt(2), ppsHandler, RISING); +} + +void loop(void) +{ + //If a message is recieved print all the informations + if (ppsTriggered) + { + ppsTriggered = false; + ledState = !ledState; + digitalWrite(LED_BUILTIN, ledState); + + // Output GPS information from previous second + console.print("Valid fix: "); + console.println(nmea.isValid() ? "yes" : "no"); + + console.print("Nav. system: "); + if (nmea.getNavSystem()) + console.println(nmea.getNavSystem()); + else + console.println("none"); + + console.print("Num. satellites: "); + console.println(nmea.getNumSatellites()); + + console.print("HDOP: "); + console.println(nmea.getHDOP()/10., 1); + + console.print("Date/time: "); + console.print(nmea.getYear()); + console.print('-'); + console.print(int(nmea.getMonth())); + console.print('-'); + console.print(int(nmea.getDay())); + console.print('T'); + console.print(int(nmea.getHour())); + console.print(':'); + console.print(int(nmea.getMinute())); + console.print(':'); + console.println(int(nmea.getSecond())); + + long latitude_mdeg = nmea.getLatitude(); + long longitude_mdeg = nmea.getLongitude(); + console.print("Latitude (deg): "); + console.println(latitude_mdeg / 1000000., 6); + + console.print("Longitude (deg): "); + console.println(longitude_mdeg / 1000000., 6); + + long alt; + console.print("Altitude (m): "); + if (nmea.getAltitude(alt)) + console.println(alt / 1000., 3); + else + console.println("not available"); + + console.print("Speed: "); + console.println(nmea.getSpeed() / 1000., 3); + console.print("Course: "); + console.println(nmea.getCourse() / 1000., 3); + console.println("-----------------------"); + nmea.clear(); + } + + //While the message isn't complete + while (!ppsTriggered ) + { + char c ; + if (idx == 0) + { + readI2C(buff); + delay(I2C_DELAY); + } + //Fetch the character one by one + c = buff[idx]; + idx++; + idx %= 32; + //If we have a valid character pass it to the library + if ((uint8_t) c != 0xFF) + { + console.print(c); + nmea.process(c); + } + } + +} diff --git a/libdeps/MicroNMEA/examples/X_NUCLEO_GNSS1A1_MicroNMEA_UART/X_NUCLEO_GNSS1A1_MicroNMEA_UART.ino b/libdeps/MicroNMEA/examples/X_NUCLEO_GNSS1A1_MicroNMEA_UART/X_NUCLEO_GNSS1A1_MicroNMEA_UART.ino new file mode 100644 index 0000000..a29c436 --- /dev/null +++ b/libdeps/MicroNMEA/examples/X_NUCLEO_GNSS1A1_MicroNMEA_UART/X_NUCLEO_GNSS1A1_MicroNMEA_UART.ino @@ -0,0 +1,191 @@ +/** + ****************************************************************************** + * @file X_NUCLEO_GNSS1A1_MicroNMEA_UART.ino + * @author AST + * @version V1.0.0 + * @date January 2018 + * @brief Arduino test application for the STMicrolectronics X-NUCLEO-GNSS1A1 + * GNSS module expansion board based on TeseoLIV3F. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2019 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +//NOTE: for compatibility with the Arduino Due some additional cabling needs to be performed: +// pin D8 should be connected to pin D18 and pin D2 should be connected to pin D19 + +#include + +//Define Serial1 for STM32 Nucleo boards +#ifdef ARDUINO_ARCH_STM32 +HardwareSerial Serial1(PA10, PA9); +#endif + +#define RESET_PIN 7 + +// Refer to serial devices by use +HardwareSerial& console = Serial; +HardwareSerial& gps = Serial1; + +//MicroNMEA library structures +char nmeaBuffer[100]; +MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer)); + +bool ledState = LOW; +volatile bool ppsTriggered = false; + +void ppsHandler(void); + + +void ppsHandler(void) +{ + ppsTriggered = true; +} + + +void gpsHardwareReset() +{ + // Empty input buffer + while (gps.available()) + gps.read(); + + //reset the device + digitalWrite(RESET_PIN, LOW); + delay(50); + digitalWrite(RESET_PIN, HIGH); + + //wait for reset to apply + delay(2000); + +} + +void setup(void) +{ + console.begin(115200); // console + gps.begin(9600); // gps + + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, ledState); + + //Start the module + pinMode(RESET_PIN, OUTPUT); + digitalWrite(RESET_PIN, HIGH); + console.println("Resetting GPS module ..."); + gpsHardwareReset(); + console.println("... done"); + + // Change the echoing messages to the ones recognized by the MicroNMEA library + MicroNMEA::sendSentence(gps, "$PSTMSETPAR,1201,0x00000042"); + MicroNMEA::sendSentence(gps, "$PSTMSAVEPAR"); + + //Reset the device so that the changes could take plaace + MicroNMEA::sendSentence(gps, "$PSTMSRR"); + + delay(4000); + + //clear serial buffer + while (gps.available()) + gps.read(); + + pinMode(6, INPUT); + attachInterrupt(digitalPinToInterrupt(6), ppsHandler, RISING); +} + +void loop(void) +{ + //If a message is recieved print all the informations + if (ppsTriggered) + { + ppsTriggered = false; + ledState = !ledState; + digitalWrite(LED_BUILTIN, ledState); + + // Output GPS information from previous second + console.print("Valid fix: "); + console.println(nmea.isValid() ? "yes" : "no"); + + console.print("Nav. system: "); + if (nmea.getNavSystem()) + console.println(nmea.getNavSystem()); + else + console.println("none"); + + console.print("Num. satellites: "); + console.println(nmea.getNumSatellites()); + + console.print("HDOP: "); + console.println(nmea.getHDOP()/10., 1); + + console.print("Date/time: "); + console.print(nmea.getYear()); + console.print('-'); + console.print(int(nmea.getMonth())); + console.print('-'); + console.print(int(nmea.getDay())); + console.print('T'); + console.print(int(nmea.getHour())); + console.print(':'); + console.print(int(nmea.getMinute())); + console.print(':'); + console.println(int(nmea.getSecond())); + + long latitude_mdeg = nmea.getLatitude(); + long longitude_mdeg = nmea.getLongitude(); + console.print("Latitude (deg): "); + console.println(latitude_mdeg / 1000000., 6); + + console.print("Longitude (deg): "); + console.println(longitude_mdeg / 1000000., 6); + + long alt; + console.print("Altitude (m): "); + if (nmea.getAltitude(alt)) + console.println(alt / 1000., 3); + else + console.println("not available"); + + console.print("Speed: "); + console.println(nmea.getSpeed() / 1000., 3); + console.print("Course: "); + console.println(nmea.getCourse() / 1000., 3); + + console.println("-----------------------"); + nmea.clear(); + } + + //While the message isn't complete + while (!ppsTriggered && gps.available()) + { + //Fetch the character one by one + char c = gps.read(); + console.print(c); + //Pass the character to the library + nmea.process(c); + } + +} diff --git a/libdeps/MicroNMEA/examples/demo/demo.ino b/libdeps/MicroNMEA/examples/demo/demo.ino new file mode 100644 index 0000000..25706fc --- /dev/null +++ b/libdeps/MicroNMEA/examples/demo/demo.ino @@ -0,0 +1,159 @@ +#include + +// To display free memory include the MemoryFree library, see +// https://github.com/maniacbug/MemoryFree and uncomment the line +// below +//#include + +// Refer to serial devices by use +HardwareSerial& console = Serial; +HardwareSerial& gps = Serial1; + +char nmeaBuffer[100]; +MicroNMEA nmea(nmeaBuffer, sizeof(nmeaBuffer)); +bool ledState = LOW; +volatile bool ppsTriggered = false; + +void ppsHandler(void); + + +void ppsHandler(void) +{ + ppsTriggered = true; +} + +void printUnknownSentence(const MicroNMEA& nmea) +{ + console.println(); + console.print("Unknown sentence: "); + console.println(nmea.getSentence()); +} + +void gpsHardwareReset() +{ + // Empty input buffer + while (gps.available()) + gps.read(); + + digitalWrite(A0, LOW); + delay(50); + digitalWrite(A0, HIGH); + + // Reset is complete when the first valid message is received + while (1) { + while (gps.available()) { + char c = gps.read(); + if (nmea.process(c)) + return; + + } + } +} + +void setup(void) +{ + console.begin(115200); // console + gps.begin(115200); // gps + + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, ledState); + + nmea.setUnknownSentenceHandler(printUnknownSentence); + + pinMode(A0, OUTPUT); + digitalWrite(A0, HIGH); + console.println("Resetting GPS module ..."); + gpsHardwareReset(); + console.println("... done"); + + // Clear the list of messages which are sent. + MicroNMEA::sendSentence(gps, "$PORZB"); + + // Send only RMC and GGA messages. + MicroNMEA::sendSentence(gps, "$PORZB,RMC,1,GGA,1"); + + // Disable compatability mode (NV08C-CSM proprietary message) and + // adjust precision of time and position fields + MicroNMEA::sendSentence(gps, "$PNVGNME,2,9,1"); + // MicroNMEA::sendSentence(gps, "$PONME,2,4,1,0"); + +#ifdef ARDUINO_AVR_CALUNIUM + pinMode(6, INPUT); + attachInterrupt(2, ppsHandler, RISING); +#else +#error Please configure interrupt handler code for alternative board. +#endif + +} + +void loop(void) +{ + if (ppsTriggered) { + ppsTriggered = false; + ledState = !ledState; + digitalWrite(LED_BUILTIN, ledState); + + // Output GPS information from previous second + console.print("Valid fix: "); + console.println(nmea.isValid() ? "yes" : "no"); + + console.print("Nav. system: "); + if (nmea.getNavSystem()) + console.println(nmea.getNavSystem()); + else + console.println("none"); + + console.print("Num. satellites: "); + console.println(nmea.getNumSatellites()); + + console.print("HDOP: "); + console.println(nmea.getHDOP()/10., 1); + + console.print("Date/time: "); + console.print(nmea.getYear()); + console.print('-'); + console.print(int(nmea.getMonth())); + console.print('-'); + console.print(int(nmea.getDay())); + console.print('T'); + console.print(int(nmea.getHour())); + console.print(':'); + console.print(int(nmea.getMinute())); + console.print(':'); + console.println(int(nmea.getSecond())); + + long latitude_mdeg = nmea.getLatitude(); + long longitude_mdeg = nmea.getLongitude(); + console.print("Latitude (deg): "); + console.println(latitude_mdeg / 1000000., 6); + + console.print("Longitude (deg): "); + console.println(longitude_mdeg / 1000000., 6); + + long alt; + console.print("Altitude (m): "); + if (nmea.getAltitude(alt)) + console.println(alt / 1000., 3); + else + console.println("not available"); + + console.print("Speed: "); + console.println(nmea.getSpeed() / 1000., 3); + console.print("Course: "); + console.println(nmea.getCourse() / 1000., 3); + +#ifdef MEMORY_FREE_H + console.print("freeMemory()="); + console.println(freeMemory()); +#endif + console.println("-----------------------"); + nmea.clear(); + } + + while (!ppsTriggered && gps.available()) { + char c = gps.read(); + console.print(c); + nmea.process(c); + } + +} diff --git a/libdeps/MicroNMEA/keywords.txt b/libdeps/MicroNMEA/keywords.txt new file mode 100644 index 0000000..c3bf729 --- /dev/null +++ b/libdeps/MicroNMEA/keywords.txt @@ -0,0 +1,48 @@ +####################################### +# Syntax Coloring Map For MicroNMEA +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### +MicroNMEA KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +skipField KEYWORD2 +parseUnsignedInt KEYWORD2 +parseFloat KEYWORD2 +parseDegreeMinute KEYWORD2 +parseToComma KEYWORD2 +parseField KEYWORD2 +generateChecksum KEYWORD2 +testChecksum KEYWORD2 +sendSentence KEYWORD2 +clear KEYWORD2 +getNavSystem KEYWORD2 +getNumSatellites KEYWORD2 +getHDOP KEYWORD2 +isValid KEYWORD2 +getLatitude KEYWORD2 +getLongitude KEYWORD2 +getAltitude KEYWORD2 +getYear KEYWORD2 +getMonth KEYWORD2 +getDay KEYWORD2 +getHour KEYWORD2 +getMinute KEYWORD2 +getSecond KEYWORD2 +getHundredths KEYWORD2 +getSpeed KEYWORD2 +getCourse KEYWORD2 +process KEYWORD2 +setBadChecksumHandler KEYWORD2 +setUnknownSentenceHandler KEYWORD2 +getSentence KEYWORD2 +getTalkerID KEYWORD2 +getMessageID KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libdeps/MicroNMEA/library.properties b/libdeps/MicroNMEA/library.properties new file mode 100644 index 0000000..ef23d36 --- /dev/null +++ b/libdeps/MicroNMEA/library.properties @@ -0,0 +1,9 @@ +name=MicroNMEA +version=2.0.3 +author=Steve Marple +maintainer=Steve Marple +sentence=Compact Arduino library to parse NMEA sentences. +paragraph=MicroNMEA is a compact Arduino library to parse a subset of NMEA sentences, which can originate from either GPS or GNSS receivers. Only two types of messages are parsed, $GPGGA (and its GNSS versions $GNGGA, $GLGGA, and $GAGGA) and $GPRMC (and its GNSS versions $GNRMC, $GLRMC, and $GARMC). From these two NMEA sentences MicroNMEA can output date, time, latitude, longitude, altitude, number of satellites used, horizontal dilution of precision (HDOP), course and speed. When other NMEA sentences are detected they can be passed to an optional callback function for decoding or logging. Checksum failures can be indicated with another optional callback function. GNU LGPL v2.1. +category=Timing +url=https://github.com/stevemarple/MicroNMEA +architectures=* diff --git a/libdeps/RadioLib/.piopm b/libdeps/RadioLib/.piopm new file mode 100644 index 0000000..02cf96b --- /dev/null +++ b/libdeps/RadioLib/.piopm @@ -0,0 +1 @@ +{"type": "library", "name": "RadioLib", "version": "4.0.6", "spec": {"owner": "jgromes", "id": 5795, "name": "RadioLib", "requirements": null, "url": null}} \ No newline at end of file diff --git a/libdeps/RadioLib/CODE_OF_CONDUCT.md b/libdeps/RadioLib/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..1a32eac --- /dev/null +++ b/libdeps/RadioLib/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Code of Conduct + +Don't be an a*shole. diff --git a/libdeps/RadioLib/CONTRIBUTING.md b/libdeps/RadioLib/CONTRIBUTING.md new file mode 100644 index 0000000..563d444 --- /dev/null +++ b/libdeps/RadioLib/CONTRIBUTING.md @@ -0,0 +1,110 @@ +# Contributing to RadioLib + +First of all, thank you very much for taking the time to contribute! All feedback and ideas are greatly appreciated. +To keep this library organized, please follow these rules. + +## Issues + +The following rules guide submission of new issues. These rules are in place mainly so that the issue author can get help as quickly as possible. + +1. **Questions are welcome, spam is not.** +Any issues without description will be considered spam and as such will be **CLOSED** and **LOCKED** immediately! +2. **This repository has issue templates.** +To report bugs or suggest new features, use the provided issue templates. Use the default issue only if the templates do not fit your issue type. +3. **Be as clear as possible when creating issues.** +Issues with generic titles (e.g. "not working", "lora", etc.) will be **CLOSED** until the title is fixed, since the title is supposed to categorize the issue. The same applies for issues with very little information and extensive grammatical or formatting errors that make it difficult to find out what is the actual issue. +4. **Issues deserve some attention too.** +Issues that are left for 2 weeks without response by the original author when asked for further information will be closed due to inactivity. This is to keep track of important issues, the author is encouraged to reopen the issue at a later date. + +## Code style guidelines + +I like pretty code! Or at least, I like *consistent* code style. When creating pull requests, please follow these style guidelines, they're in place to keep high code readability. + +1. **Bracket style** +This library uses the following style of bracket indentation (1TBS, or "javascript" style): + +```c++ +if (foo) { + bar(); +} else { + baz(); +} +``` + +2. **Tabs** +Use 2 space characters for tabs. + +3. **Single-line comments** +Comments can be very useful - and they can become the bane of readability. Every single-line comment should start at new line, have one space between comment delimiter `//` and the start of the comment itself. The comment should also start with a lower-case letter. + +```c++ +// this function does something +foo("bar"); + +// here it does something else +foo(12345); +``` + +4. **Split code into blocks** +It is very easy to write code that machine can read. It is much harder to write one that humans can read. That's why it's a great idea to split code into blocks - even if the block is just a single line! + +```c++ +// build a temporary buffer (first block) +uint8_t* data = new uint8_t[len + 1]; +if(!data) { + return(ERR_MEMORY_ALLOCATION_FAILED); +} + +// read the received data (second block) +state = readData(data, len); + +// add null terminator (third block) +data[len] = 0; +``` + +5. **Doxygen** +If you're adding a new method, make sure to add appropriate Doxygen comments, so that the documentation is always complete. + +6. **Keywords** +This is an Arduino library, so it needs to comply with the Arduino library specification. To add a new keyword to the Arduino IDE syntax highlighting, add it to the keywords.txt file. **Use true tabs in keywords.txt! No spaces there!** + +7. **Dynamic memory** +Sometimes, RadioLib might be used in critical applications where dynamic memory allocation using `new` or `malloc` might cause issues. For such cases, RadioLib provides the option to compile using only static arrays. This means that every dynamically allocated array must have a sufficiently large static counterpart. Naturally, all dynamically allocated memory must be properly de-allocated using `delete` or `free`. + +```c++ +// build a temporary buffer +#ifdef RADIOLIB_STATIC_ONLY + uint8_t data[RADIOLIB_STATIC_ARRAY_SIZE + 1]; +#else + uint8_t* data = new uint8_t[length + 1]; + if(!data) { + return(ERR_MEMORY_ALLOCATION_FAILED); + } +#endif + +// read the received data +readData(data, length); + +// deallocate temporary buffer +#ifndef RADIOLIB_STATIC_ONLY + delete[] data; +#endif +``` + +8. **God Mode** +During development, it can be useful to have access to the low level drivers, such as the SPI commands. These are incredibly powerful, since they will basically let user do anything he wants with the module, outside of the normal level of sanity checks. As such, they are normally protected using C++ access modifiers `private` or `protected`. God mode disables this protection, and so any newly implemented `class` must contain the appropriate macro check: + +```c++ +class Module { + void publicMethod(); + +#ifndef RADIOLIB_GODMODE + private: +#endif + + void privateMethod(); +}; +``` + +9. **No Arduino Strings** +Arduino `String` class should never be used internally in the library. The only allowed occurence of Arduino `String` is in public API methods, and only at the top-most layer. diff --git a/libdeps/RadioLib/Doxyfile b/libdeps/RadioLib/Doxyfile new file mode 100644 index 0000000..3c1d2d1 --- /dev/null +++ b/libdeps/RadioLib/Doxyfile @@ -0,0 +1,2565 @@ +# Doxyfile 1.8.15 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = RadioLib + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Universal wireless communication library for Arduino" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = docs + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is +# Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files +# were built. This is equivalent to specifying the "-p" option to a clang tool, +# such as clang-check. These options will then be passed to the parser. +# Note: The availability of this option depends on whether or not doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /