Update examples

This commit is contained in:
lewisxhe 2020-11-24 17:03:49 +08:00
commit 617f77cca4
283 changed files with 33265 additions and 232 deletions

1
.gitignore vendored
View file

@ -8,3 +8,4 @@ test
.gitignore
.travis.yml
lib
src

View file

@ -1,10 +1,52 @@
TTGO-T-Beam
=====================
<h1 align = "center">🌟LilyGo LoRa Series🌟</h1>
![](image/product.jpg)
## **English | [中文](./README_CN.MD)**
<h3 align = "left">Quick start:</h3>
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 dont know the version, please ask customer service, or Check the silkscreen on the board
6. Upload
<h3 align = "left">Product 📷:</h3>
| 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) |
<h3 align = "left">Application :</h3>
- [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)
<h3 align = "left">Datasheet :</h3>
- [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]()
<h3 align = "left">Schematic :</h3>
- [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)
<h3 align = "left">PinOut :</h3>
## 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
<h3 align = "left">Power Control Channel :</h3>
| 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)

77
README_CN.MD Normal file
View file

@ -0,0 +1,77 @@
<h1 align = "center">🌟LilyGo LoRa Series🌟</h1>
## **[English](./README.MD) | 中文**
<h3 align = "left">快速开始:</h3>
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. 上传
<h3 align = "left">Product 📷:</h3>
| 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) |
<h3 align = "left">Application :</h3>
- [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)
<h3 align = "left">Datasheet :</h3>
- [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]()
<h3 align = "left">Schematic :</h3>
- [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)
<h3 align = "left">PinOut :</h3>
| 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 |
<h3 align = "left">Power Control Channel :</h3>
| Modules | T_BEAM_V10/V1.1 | T_BEAM_V07 |
| ------- | --------------- | ---------- |
| GPS | LDO3 | No supoort |
| LORA | LDO2 | No supoort |
| OLED | DCDC1 | No supoort |

Binary file not shown.

Binary file not shown.

View file

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

Binary file not shown.

Binary file not shown.

View file

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

Binary file not shown.

Binary file not shown.

View file

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -3,7 +3,7 @@
* Created by Lewis he
* */
#include "board_def.h"
#include "utilities.h"
#include <WiFi.h>
#include <Wire.h>
#include "axp20x.h"

View file

@ -0,0 +1,37 @@
#include <LoRa.h>
#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());
}
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -0,0 +1,34 @@
#include <LoRa.h>
#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);
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

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

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <MicroNMEA.h> //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);
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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);
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <TinyGPS++.h>
#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();
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <TinyGPS++.h>
#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();
}
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <Wire.h> // 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);
}

View file

@ -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,
};

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <Wire.h> // 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);
}
}

View file

@ -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
};

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <RadioLib.h>
#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;
}
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <RadioLib.h>
#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;
}
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <RadioLib.h>
#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;
}
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <RadioLib.h>
#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);
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <RadioLib.h>
#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;
}
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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 <RadioLib.h>
#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);
}

View file

@ -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 <SPI.h>
#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.h>
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();
}

View file

@ -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*/

View file

@ -1,48 +0,0 @@
#include "board_def.h"
#include "SPI.h"
#include <Wire.h>
#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());
}
}

View file

@ -0,0 +1 @@
{"type": "library", "name": "AXP202X_Library", "version": "1.1.2", "spec": {"owner": "lewisxhe", "id": 6657, "name": "AXP202X_Library", "requirements": null, "url": null}}

View file

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

View file

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

View file

@ -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 <Wire.h>
#include <axp20x.h>
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);
}

View file

@ -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 <Wire.h>
#include <axp20x.h>
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);
}

View file

@ -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 <Wire.h>
#include <axp20x.h>
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();
}
}

View file

@ -0,0 +1,44 @@
#include <Wire.h>
#include <axp20x.h>
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()
{
}

View file

@ -0,0 +1,115 @@
#include <Wire.h>
#include <axp20x.h>
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();
}
}
}

View file

@ -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 <Wire.h>
#include <axp20x.h>
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();
}
}

View file

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

View file

@ -0,0 +1,9 @@
name=AXP202X_Library
version=1.1.2
author=Lewis He
maintainer=Lewis He <lewishe@outlook.com>
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

21
libdeps/Button2/LICENSE Normal file
View file

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

44
libdeps/Button2/README.md Normal file
View file

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

View file

@ -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)");
}
/////////////////////////////////////////////////////////////////

View file

@ -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(")");
}
/////////////////////////////////////////////////////////////////

View file

@ -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");
}
}
/////////////////////////////////////////////////////////////////

View file

@ -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");
}
/////////////////////////////////////////////////////////////////

View file

@ -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");
}
/////////////////////////////////////////////////////////////////

View file

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

View file

@ -0,0 +1,10 @@
name=Button2
version=1.0.0
author=Lennart Hennigs
maintainer=Lennart Hennigs <mail@lennarthennigs.de>
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

View file

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

View file

@ -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"
}

View file

@ -0,0 +1,4 @@
set(COMPONENT_ADD_INCLUDEDIRS src)
set(COMPONENT_PRIV_REQUIRES arduino-esp32)
set(COMPONENT_SRCDIRS src)
register_component()

View file

@ -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
<table><tr><td><img src="https://thingpulse.com/assets/ThingPulse-open-source-prime.png" width="150">
</td><td>This is a ThingPulse <em>prime</em> project. See our <a href="https://thingpulse.com/about/open-source-commitment/">open-source commitment declaration</a> for what this means.</td></tr></table>
## Credits
This library has initially been written by Daniel Eichhorn ([@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 <Wire.h>
#include "SSD1306Wire.h"
// for 128x64 displays:
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
// for 128x32 displays:
// SSD1306Wire display(0x3c, SDA, SCL, GEOMETRY_128_32); // ADDRESS, SDA, SCL, GEOMETRY_128_32 (or 128_64)
```
for a SH1106:
```C++
#include <Wire.h>
#include "SH1106Wire.h"
SH1106Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
```
### I2C with brzo_i2c
```C++
#include <brzo_i2c.h>
#include "SSD1306Brzo.h"
SSD1306Brzo display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
```
or for the SH1106:
```C++
#include <brzo_i2c.h>
#include "SH1106Brzo.h"
SH1106Brzo display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
```
### SPI
```C++
#include <SPI.h>
#include "SSD1306Spi.h"
SSD1306Spi display(D0, D2, D8); // RES, DC, CS
```
or for the SH1106:
```C++
#include <SPI.h>
#include "SH1106Spi.h"
SH1106Spi display(D0, D2); // RES, DC
```
## API
### Display Control
```C++
// Initialize the display
void init();
// Free the memory used by the display
void end();
// Cycle through the initialization
void resetDisplay(void);
// Connect again to the display through I2C
void reconnect(void);
// Turn the display on
void displayOn(void);
// Turn the display offs
void displayOff(void);
// Clear the local pixel buffer
void clear(void);
// Write the buffer to the display memory
void display(void);
// Inverted display mode
void invertDisplay(void);
// Normal display mode
void normalDisplay(void);
// Set display contrast
// really low brightness & contrast: contrast = 10, precharge = 5, comdetect = 0
// normal brightness & contrast: contrast = 100
void setContrast(uint8_t contrast, uint8_t precharge = 241, uint8_t comdetect = 64);
// Convenience method to access
void setBrightness(uint8_t);
// Turn the display upside down
void flipScreenVertically();
// Draw the screen mirrored
void mirrorScreen();
```
## Pixel drawing
```C++
/* Drawing functions */
// Sets the color of all pixel operations
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?

View file

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

View file

@ -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);
```

View file

@ -0,0 +1,3 @@
COMPONENT_ADD_INCLUDEDIRS := src
COMPONENT_SRCDIRS := src
CXXFLAGS += -Wno-ignored-qualifiers

View file

@ -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 <TimeLib.h>
// Include the correct display library
// For a connection via I2C using Wire include
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
// For a connection via I2C using brzo_i2c (must be installed) include
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Brzo.h"
// #include "SH1106Brzo.h"
// For a connection via SPI include
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Spi.h"
// #include "SH1106SPi.h"
// Include the UI lib
#include "OLEDDisplayUi.h"
// Include custom images
#include "images.h"
// Use the corresponding display class:
// Initialize the OLED display using SPI
// D5 -> CLK
// D7 -> MOSI (DOUT)
// D0 -> RES
// D2 -> DC
// D8 -> CS
// SSD1306Spi display(D0, D2, D8);
// or
// SH1106Spi display(D0, D2);
// Initialize the OLED display using brzo_i2c
// D3 -> SDA
// D5 -> SCL
// SSD1306Brzo display(0x3c, D3, D5);
// or
// SH1106Brzo display(0x3c, D3, D5);
// Initialize the OLED display using Wire library
SSD1306Wire display(0x3c, 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);
}
}

View file

@ -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
};

View file

@ -0,0 +1,233 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
* Copyright (c) 2018 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* ThingPulse invests considerable time and money to develop these open source libraries.
* Please support us by buying our products (and not the clones) from
* https://thingpulse.com
*
*/
// Include the correct display library
// For a connection via I2C using Wire include
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
// For a connection via I2C using brzo_i2c (must be installed) include
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Brzo.h"
// #include "SH1106Brzo.h"
// For a connection via SPI include
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Spi.h"
// #include "SH1106SPi.h"
// Use the corresponding display class:
// Initialize the OLED display using SPI
// D5 -> CLK
// D7 -> MOSI (DOUT)
// D0 -> RES
// D2 -> DC
// D8 -> CS
// SSD1306Spi display(D0, D2, D8);
// or
// SH1106Spi display(D0, D2);
// Initialize the OLED display using brzo_i2c
// D3 -> SDA
// D5 -> SCL
// SSD1306Brzo display(0x3c, D3, D5);
// or
// SH1106Brzo display(0x3c, D3, D5);
// Initialize the OLED display using Wire library
SSD1306Wire display(0x3c, D3, D5);
// SH1106 display(0x3c, D3, D5);
// Adapted from Adafruit_SSD1306
void drawLines() {
for (int16_t i=0; i<display.getWidth(); i+=4) {
display.drawLine(0, 0, i, display.getHeight()-1);
display.display();
delay(10);
}
for (int16_t i=0; i<display.getHeight(); i+=4) {
display.drawLine(0, 0, display.getWidth()-1, i);
display.display();
delay(10);
}
delay(250);
display.clear();
for (int16_t i=0; i<display.getWidth(); i+=4) {
display.drawLine(0, display.getHeight()-1, i, 0);
display.display();
delay(10);
}
for (int16_t i=display.getHeight()-1; i>=0; i-=4) {
display.drawLine(0, display.getHeight()-1, display.getWidth()-1, i);
display.display();
delay(10);
}
delay(250);
display.clear();
for (int16_t i=display.getWidth()-1; i>=0; i-=4) {
display.drawLine(display.getWidth()-1, display.getHeight()-1, i, 0);
display.display();
delay(10);
}
for (int16_t i=display.getHeight()-1; i>=0; i-=4) {
display.drawLine(display.getWidth()-1, display.getHeight()-1, 0, i);
display.display();
delay(10);
}
delay(250);
display.clear();
for (int16_t i=0; i<display.getHeight(); i+=4) {
display.drawLine(display.getWidth()-1, 0, 0, i);
display.display();
delay(10);
}
for (int16_t i=0; i<display.getWidth(); i+=4) {
display.drawLine(display.getWidth()-1, 0, i, display.getHeight()-1);
display.display();
delay(10);
}
delay(250);
}
// Adapted from Adafruit_SSD1306
void drawRect(void) {
for (int16_t i=0; i<display.getHeight()/2; i+=2) {
display.drawRect(i, i, display.getWidth()-2*i, display.getHeight()-2*i);
display.display();
delay(10);
}
}
// Adapted from Adafruit_SSD1306
void fillRect(void) {
uint8_t color = 1;
for (int16_t i=0; i<display.getHeight()/2; i+=3) {
display.setColor((color % 2 == 0) ? BLACK : WHITE); // alternate colors
display.fillRect(i, i, display.getWidth() - i*2, display.getHeight() - i*2);
display.display();
delay(10);
color++;
}
// Reset back to WHITE
display.setColor(WHITE);
}
// Adapted from Adafruit_SSD1306
void drawCircle(void) {
for (int16_t i=0; i<display.getHeight(); i+=2) {
display.drawCircle(display.getWidth()/2, display.getHeight()/2, i);
display.display();
delay(10);
}
delay(1000);
display.clear();
// This will draw the part of the circel in quadrant 1
// Quadrants are numberd like this:
// 0010 | 0001
// ------|-----
// 0100 | 1000
//
display.drawCircleQuads(display.getWidth()/2, display.getHeight()/2, display.getHeight()/4, 0b00000001);
display.display();
delay(200);
display.drawCircleQuads(display.getWidth()/2, display.getHeight()/2, display.getHeight()/4, 0b00000011);
display.display();
delay(200);
display.drawCircleQuads(display.getWidth()/2, display.getHeight()/2, display.getHeight()/4, 0b00000111);
display.display();
delay(200);
display.drawCircleQuads(display.getWidth()/2, display.getHeight()/2, display.getHeight()/4, 0b00001111);
display.display();
}
void printBuffer(void) {
// Initialize the log buffer
// allocate memory to store 8 lines of text and 30 chars per line.
display.setLogBuffer(5, 30);
// Some test data
const char* test[] = {
"Hello",
"World" ,
"----",
"Show off",
"how",
"the log buffer",
"is",
"working.",
"Even",
"scrolling is",
"working"
};
for (uint8_t i = 0; i < 11; i++) {
display.clear();
// Print to the screen
display.println(test[i]);
// Draw it to the internal screen buffer
display.drawLogBuffer(0, 0);
// Display it on the screen
display.display();
delay(500);
}
}
void setup() {
display.init();
// display.flipScreenVertically();
display.setContrast(255);
drawLines();
delay(1000);
display.clear();
drawRect();
delay(1000);
display.clear();
fillRect();
delay(1000);
display.clear();
drawCircle();
delay(1000);
display.clear();
printBuffer();
delay(1000);
display.clear();
}
void loop() { }

View file

@ -0,0 +1,123 @@
/**
* 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
*
*/
// WiFi includes
#include <ESP8266WiFi.h>
// OTA Includes
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
const char *ssid = "[Your SSID]";
const char *password = "[Your Password]";
// Include the correct display library
// For a connection via I2C using Wire include
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
// For a connection via I2C using brzo_i2c (must be installed) include
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Brzo.h"
// #include "SH1106Brzo.h"
// For a connection via SPI include
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Spi.h"
// #include "SH1106SPi.h"
// Use the corresponding display class:
// Initialize the OLED display using SPI
// D5 -> CLK
// D7 -> MOSI (DOUT)
// D0 -> RES
// D2 -> DC
// D8 -> CS
// SSD1306Spi display(D0, D2, D8);
// or
// SH1106Spi display(D0, D2);
// Initialize the OLED display using brzo_i2c
// D3 -> SDA
// D5 -> SCL
// SSD1306Brzo display(0x3c, D3, D5);
// or
// SH1106Brzo display(0x3c, D3, D5);
// Initialize the OLED display using Wire library
SSD1306Wire display(0x3c, 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();
}

View file

@ -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 <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy: #include "SSD1306.h"
// OR #include "SH1106Wire.h" // legacy: #include "SH1106.h"
// For a connection via I2C using brzo_i2c (must be installed) include:
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Brzo.h"
// OR #include "SH1106Brzo.h"
// For a connection via SPI include:
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Spi.h"
// OR #include "SH1106SPi.h"
// Optionally include custom images
#include "images.h"
// Initialize the OLED display using Arduino Wire:
SSD1306Wire display(0x3c, SDA, SCL); // ADDRESS, SDA, SCL - SDA and SCL usually populate automatically based on your board's pins_arduino.h
// 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);
}

View file

@ -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,
};

View file

@ -0,0 +1,75 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* ThingPulse invests considerable time and money to develop these open source libraries.
* Please support us by buying our products (and not the clones) from
* https://thingpulse.com
*
*/
// Include the correct display library
// For a connection via I2C using Wire include
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
#include "images.h"
// Initialize the OLED display using Wire library
SSD1306Wire display(0x3c, 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);
}

View file

@ -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,
};

View file

@ -0,0 +1,194 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2018 by ThingPulse, Daniel Eichhorn
* Copyright (c) 2018 by Fabrice Weinberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* ThingPulse invests considerable time and money to develop these open source libraries.
* Please support us by buying our products (and not the clones) from
* https://thingpulse.com
*
*/
// Include the correct display library
// For a connection via I2C using Wire include
#include <Wire.h> // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
// or #include "SH1106Wire.h", legacy include: `#include "SH1106.h"`
// For a connection via I2C using brzo_i2c (must be installed) include
// #include <brzo_i2c.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Brzo.h"
// #include "SH1106Brzo.h"
// For a connection via SPI include
// #include <SPI.h> // Only needed for Arduino 1.6.5 and earlier
// #include "SSD1306Spi.h"
// #include "SH1106SPi.h"
// Include the UI lib
#include "OLEDDisplayUi.h"
// Include custom images
#include "images.h"
// Use the corresponding display class:
// Initialize the OLED display using SPI
// D5 -> CLK
// D7 -> MOSI (DOUT)
// D0 -> RES
// D2 -> DC
// D8 -> CS
// SSD1306Spi display(D0, D2, D8);
// or
// SH1106Spi display(D0, D2);
// Initialize the OLED display using brzo_i2c
// D3 -> SDA
// D5 -> SCL
// SSD1306Brzo display(0x3c, D3, D5);
// or
// SH1106Brzo display(0x3c, D3, D5);
// Initialize the OLED display using Wire library
SSD1306Wire display(0x3c, 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);
}
}

View file

@ -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
};

View file

@ -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"
]
}

View file

@ -0,0 +1,9 @@
name=ESP8266 and ESP32 OLED driver for SSD1306 displays
version=4.1.0
author=ThingPulse, Fabrice Weinberg
maintainer=ThingPulse <info@thingpulse.com>
sentence=I2C display driver for SSD1306 OLED displays connected to ESP8266, ESP32, Mbed-OS
paragraph=The following geometries are currently supported: 128x64, 128x32, 64x48. The init sequence was inspired by Adafruit's library for the same display.
category=Display
url=https://github.com/ThingPulse/esp8266-oled-ssd1306
architectures=esp8266,esp32

View file

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

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