Compare commits

...
Sign in to create a new pull request.

20 commits

Author SHA1 Message Date
lewisxhe
16bc3e2b42 Update RadioLib 2026-04-20 18:00:37 +08:00
lewisxhe
a8257c0cb2 Added mag example 2026-04-20 17:59:07 +08:00
lewisxhe
026b4b8a97 factory: Simplify testing methods 2026-04-20 14:39:04 +08:00
lewisxhe
8456c77e74 Add magnetometer calibrate https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/issues/298 2026-04-20 11:16:22 +08:00
lewisxhe
2565cc61c7 Add t-beam-1w battery shell https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/issues/297 2026-04-20 09:58:15 +08:00
lewisxhe
a2be16de05 add factory firmware support t-beam-1w-lr1121 and lr2021 2026-04-17 17:29:40 +08:00
lewisxhe
0658572eee Update docs 2026-04-17 17:23:05 +08:00
lewisxhe
811f6064d7 Update RadioLib 2026-04-17 10:15:48 +08:00
lewisxhe
54315bae97 fix doc https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/issues/296 2026-04-16 09:16:27 +08:00
lewisxhe
ef126883e9 Update README 2026-04-15 13:58:11 +08:00
lewisxhe
e34f7425b5 Update docs 2026-04-10 16:32:32 +08:00
lewisxhe
cc84e2435e Update docs 2026-04-10 16:27:43 +08:00
lewisxhe
d04e9c4c66 update docs 2026-04-08 14:55:11 +08:00
lewisxhe
7624e98d89 Update sensor examples 2026-04-08 14:52:34 +08:00
lewisxhe
84d258883b Update LoRaBoards 2026-04-08 14:47:17 +08:00
lewisxhe
904e3f64d7 Update ini 2026-04-08 14:46:04 +08:00
lewisxhe
9da7269831 Update t-beam-supreme factory firmware 2026-04-08 14:44:09 +08:00
lewisxhe
412151c70b Add t-beam-supreme qmc6309 mag sensor support 2026-04-08 14:43:42 +08:00
lewisxhe
3a2ae5c2a8 Update sensorlib 2026-04-08 14:29:36 +08:00
lewisxhe
4fdc6077b7 Update SensorLib 2026-04-08 09:28:20 +08:00
769 changed files with 394826 additions and 37336 deletions

View file

@ -11,13 +11,14 @@
- ⚠️ If using the PA version, please carefully read the PA power setting limits on the corresponding page. Incorrect output power settings may damage the PA.
- ⚠️ 如果使用PA版本请仔细阅读对应页面的PA功率设置限制错误的设置输出功率很有可能会损坏PA
### `1` Get Started
- 🔧 **[T-Beam Quick Start](./docs/en/t_beam/t_beam_hw.md)**
- 🔧 **[T-Beam Supreme Quick Start](./docs/en/t_beam_supreme/t_beam_supreme_hw.md)**
- 🔧 **[T-Beam BPF Quick Start](./docs/en/t_beam_bpf/t_beam_bpf_hw.md)**
- 🔧 **[T-Beam 1W Quick Start](./docs/en/t_beam_1w/t_beam_1w_hw.md)**
- 🔧 **[T-Beam 1W SX1262 Quick Start](./docs/en/t_beam_1w_sx1262/t_beam_1w_sx1262.md)**
- 🔧 **[T-Beam 1W LR1121 Quick Start](./docs/en/t_beam_1w_lr1121/t_beam_1w_lr1121.md)**
- 🔧 **[T-Beam 1W LR2021 Quick Start](./docs/en/t_beam_1w_lr2021/t_beam_1w_lr2021.md)**
- 🔧 **[LoRa32 V1.3 Quick Start](./docs/en/t3_v13_sx1276/t3_v13_sx1276.md)**
- 🔧 **[LoRa32 V1.6.1 Quick Start](./docs/en/t3_v161_sx1276/t3_v161_sx1276_hw.md)**
- 🔧 **[LoRa32 TCXO Quick Start](./docs/en/t3_tcxo_sx1276/t3_tcxo_sx1276_hw.md)**

Binary file not shown.

View file

@ -20,7 +20,7 @@
[1]: https://www.lilygo.cc/products/t-lora-c6 "T-Lora C6"
### PlatformIO Quick Start
<!-- ### PlatformIO Quick Start
1. Install [Visual Studio Code](https://code.visualstudio.com/) and [Python](https://www.python.org/)
2. Search for the `PlatformIO` plugin in the `Visual Studio Code` extension and install it.
@ -34,7 +34,9 @@
10. Connect the board to the computer USB-C , Micro-USB is used for module firmware upgrade
11. Click (→) to upload firmware
12. Click (plug symbol) to monitor serial output
13. If it cannot be written, or the USB device keeps flashing, please check the **FAQ** below
13. If it cannot be written, or the USB device keeps flashing, please check the **FAQ** below -->
### PlatformIO Not support ESP32C6
### Arduino IDE quick start

View file

@ -12,6 +12,7 @@
1. This version does not have BMS, please use a lithium-ion battery with battery protection function
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module
3. The T3-S3 V1.2 and T3-S3 V1.3 use the same pins; the only difference is the charging circuit.
### Product
@ -103,6 +104,7 @@
| On Board LED | 37 | ❌ |
* You can use GPIO10,21 by removing the two resistors in the figure below. Otherwise, the GPIO is connected to DIO8,DIO7 of Radio by default.
* SDA(18) and SCL(17) are not brought out and cannot be accessed. They can only be used as other GPIOs through QWIIC or header pins. During initialization, use explicit initialization `Wire.begin(sda,scl);` Any unused GPIO can be used as SDA and SCL.
| T3 V1.2 | T3 V1.3 |
| ------------------------------------------------ | ------------------------------------------------ |
@ -171,12 +173,16 @@
| ---------------------------------------------- | ---------------------------------------------- |
| ![T3-S3](../../static/T3S3-WIFI-IPEX-V1.2.png) | ![T3-S3](../../static/T3S3-WIFI-IPEX-V1.3.png) |
## LoRa-IPEX
## LoRa Ant
* The following figure shows how to switch the onboard LoRa SMA antenna to IPEX
* For instructions on how to configure LoRa antenna control, please refer to the [example](https://github.com/Xinyuan-LilyGO/LilyGo-LoRa-Series/blob/d04e9c4c66516ad918c7fafbd63b477822066ec8/examples/T3S3Factory/T3S3Factory.ino#L562)
* LR1121 The 2.4G antenna interface is located on the LoRa module and cannot be changed.
* LoRa 2.4G and Sub1G antennas are independent and cannot be shared.
* The following figure shows how to switch the onboard LoRa-Sub1G SMA antenna to IPEX
![LORA-IPEX](./images/LORA-IPEX.png)
### LR1121 RF Block Diagram
![RF Block Diagram](./images/LR1121.png)

View file

@ -12,6 +12,7 @@
1. This version does not have BMS, please use a lithium-ion battery with battery protection function
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module
3. The T3-S3 V1.2 and T3-S3 V1.3 use the same pins; the only difference is the charging circuit.
### Product
@ -100,6 +101,7 @@
| On Board LED | 37 | ❌ |
* You can use GPIO10,21 by removing the two resistors in the figure below. Otherwise, the GPIO is connected to DIO8,DIO7 of Radio by default.
* SDA(18) and SCL(17) are not brought out and cannot be accessed. They can only be used as other GPIOs through QWIIC or header pins. During initialization, use explicit initialization `Wire.begin(sda,scl);` Any unused GPIO can be used as SDA and SCL.
| T3 V1.2 | T3 V1.3 |
| ------------------------------------------------ | ------------------------------------------------ |

View file

@ -12,6 +12,7 @@
1. This version does not have BMS, please use a lithium-ion battery with battery protection function
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module
3. The T3-S3 V1.2 and T3-S3 V1.3 use the same pins; the only difference is the charging circuit.
### Product
@ -103,6 +104,7 @@
| On Board LED | 37 | ❌ |
* You can use GPIO10,21 by removing the two resistors in the figure below. Otherwise, the GPIO is connected to DIO3,DIO4 of Radio by default.
* SDA(18) and SCL(17) are not brought out and cannot be accessed. They can only be used as other GPIOs through QWIIC or header pins. During initialization, use explicit initialization `Wire.begin(sda,scl);` Any unused GPIO can be used as SDA and SCL.
| T3 V1.2 | T3 V1.3 |
| ------------------------------------------------ | ------------------------------------------------ |

View file

@ -12,6 +12,7 @@
1. This version does not have BMS, please use a lithium-ion battery with battery protection function
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module
3. The T3-S3 V1.2 and T3-S3 V1.3 use the same pins; the only difference is the charging circuit.
### Product
@ -107,6 +108,7 @@
| On Board LED | 37 | ❌ |
* You can use GPIO10,21 by removing the two resistors in the figure below. Otherwise, the GPIO is connected to DIO3,DIO4 of Radio by default.
* SDA(18) and SCL(17) are not brought out and cannot be accessed. They can only be used as other GPIOs through QWIIC or header pins. During initialization, use explicit initialization `Wire.begin(sda,scl);` Any unused GPIO can be used as SDA and SCL.
| T3 V1.2 | T3 V1.3 |
| ------------------------------------------------ | ------------------------------------------------ |

View file

@ -12,6 +12,7 @@
1. This version does not have BMS, please use a lithium-ion battery with battery protection function
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module
3. The T3-S3 V1.2 and T3-S3 V1.3 use the same pins; the only difference is the charging circuit.
### Product
@ -107,6 +108,7 @@
| On Board LED | 37 | ❌ |
* You can use GPIO10,21 by removing the two resistors in the figure below. Otherwise, the GPIO is connected to DIO3,DIO4 of Radio by default.
* SDA(18) and SCL(17) are not brought out and cannot be accessed. They can only be used as other GPIOs through QWIIC or header pins. During initialization, use explicit initialization `Wire.begin(sda,scl);` Any unused GPIO can be used as SDA and SCL.
| T3 V1.2 | T3 V1.3 |
| ------------------------------------------------ | ------------------------------------------------ |

View file

@ -12,6 +12,7 @@
1. This version does not have BMS, please use a lithium-ion battery with battery protection function
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module
3. The T3-S3 V1.2 and T3-S3 V1.3 use the same pins; the only difference is the charging circuit.
### Product
@ -102,6 +103,8 @@
| Battery ADC | 1 | ❌ |
| On Board LED | 37 | ❌ |
* SDA(18) and SCL(17) are not brought out and cannot be accessed. They can only be used as other GPIOs through QWIIC or header pins. During initialization, use explicit initialization `Wire.begin(sda,scl);` Any unused GPIO can be used as SDA and SCL.
### 🧑🏼‍🔧 I2C Devices Address
| Devices | 7-Bit Address | Share Bus |

View file

@ -12,6 +12,7 @@
1. This version does not have BMS, please use a lithium-ion battery with battery protection function
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module
3. The T3-S3 V1.2 and T3-S3 V1.3 use the same pins; the only difference is the charging circuit.
### Product
@ -105,6 +106,7 @@
| On Board LED | 37 | ❌ |
* QWIIC IO10/IO21 GPIOs are already connected to the Radio TX/RX Pin and cannot be used.
* SDA(18) and SCL(17) are not brought out and cannot be accessed. They can only be used as other GPIOs through QWIIC or header pins. During initialization, use explicit initialization `Wire.begin(sda,scl);` Any unused GPIO can be used as SDA and SCL.
### 🧑🏼‍🔧 I2C Devices Address

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

View file

@ -0,0 +1,176 @@
<div align="center" markdown="1">
<img src="../../../.github/LilyGo_logo.png" alt="LilyGo logo" width="100"/>
</div>
<h1 align = "center">🌟LilyGo T-Beam-1W-LR1121</h1>
## Overview
* This page introduces the hardware parameters related to `LilyGo T-Beam-1W-LR1121`
### Notes on use
1. This board will not charge the external 7.4V battery, it is only powered by the battery.
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module.
3. Please note that the GPIO with * added to the external pin header GPIO name is already connected to the internal module and cannot be used
4. This RF module provides a maximum power output of 30dBm on this board
## PlatformIO Quick Start
1. Install [Visual Studio Code](https://code.visualstudio.com/) and [Python](https://www.python.org/)
2. Search for the `PlatformIO` plugin in the `Visual Studio Code` extension and install it.
3. After the installation is complete, you need to restart `Visual Studio Code`
4. After restarting `Visual Studio Code`, select `File` in the upper left corner of `Visual Studio Code` -> `Open Folder` -> select the `LilyGo-LoRa-Series` directory
5. Wait for the installation of third-party dependent libraries to complete
6. Click on the `platformio.ini` file, and in the `platformio` column
7. Select the board name you want to use in `default_envs` and uncomment it.
8. Uncomment one of the lines `src_dir = xxxx` to make sure only one line works , Please note the example comments, indicating what works and what does not.
9. Click the (✔) symbol in the lower left corner to compile
10. Connect the board to the computer USB-C , Micro-USB is used for module firmware upgrade
11. Click (→) to upload firmware
12. Click (plug symbol) to monitor serial output
13. If it cannot be written, or the USB device keeps flashing, please check the **FAQ** below
## Arduino IDE quick start
1. Install [Arduino IDE](https://www.arduino.cc/en/software)
2. Install [Arduino ESP32](https://docs.espressif.com/projects/arduino-esp32/en/latest/)
3. Copy all folders in the `lib` directory to the `Sketchbook location` directory. How to find the location of your own libraries, [please see here](https://support.arduino.cc/hc/en-us/articles/4415103213714-Find-sketches-libraries-board-cores-and-other-files-on-your-computer)
* Windows: `C:\Users\{username}\Documents\Arduino`
* macOS: `/Users/{username}/Documents/Arduino`
* Linux: `/home/{username}/Arduino`
4. Open the corresponding example
* Open the downloaded `LilyGo-LoRa-Series`
* Open `examples`
* Select the sample file and open the file ending with `ino`
5. On Arduino Select the corresponding board in the IDE tool project and click on the corresponding option in the list below to select
| Name | Value |
| ------------------------------------ | ---------------------------------------------------- |
| Board | **ESP32S3 Dev Module** |
| Port | Your port |
| USB CDC On Boot | Enable |
| CPU Frequency | 240MHZ(WiFi) |
| Core Debug Level | None |
| USB DFU On Boot | Disable |
| Erase All Flash Before Sketch Upload | Disable |
| Flash Mode | QIO 80Mhz |
| Flash Size | **16MB(128Mb)** |
| Arduino Runs On | Core1 |
| USB Firmware MSC On Boot | Disable |
| Partition Scheme | **Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)** |
| PSRAM | **QSPI PSRAM** |
| Upload Speed | 921600 |
| Programmer | **Esptool** |
6. Please uncomment the `utilities.h` file of each sketch according to your board model e.g `T_BEAM_1W_LR1121`, otherwise the compilation will report an error.
7. Upload sketch
### 📍 Pins Map
| Name | GPIO NUM | Free |
| ----------------------- | ------------------------------ | ---- |
| Uart1 TX | 43(External QWIIC Socket) | ✅️ |
| Uart1 RX | 44(External QWIIC Socket) | ✅️ |
| SDA | 8 (External QWIIC Socket same) | ❌ |
| SCL | 9 (External QWIIC Socket same) | ❌ |
| SPI MOSI | 11 | ❌ |
| SPI MISO | 12 | ❌ |
| SPI SCK | 13 | ❌ |
| SD CS | 10 | ❌ |
| SD MOSI | Share with SPI bus | ❌ |
| SD MISO | Share with SPI bus | ❌ |
| SD SCK | Share with SPI bus | ❌ |
| GNSS(**L76K**) TX | 6 | ❌ |
| GNSS(**L76K**) RX | 5 | ❌ |
| GNSS(**L76K**) PPS | 7 | ❌ |
| GNSS(**L76K**) Wake-up | 16 | ❌ |
| LoRa(**LR1121**) SCK | Share with SPI bus | ❌ |
| LoRa(**LR1121**) MISO | Share with SPI bus | ❌ |
| LoRa(**LR1121**) MOSI | Share with SPI bus | ❌ |
| LoRa(**LR1121**) RESET | 3 | ❌ |
| LoRa(**LR1121**) DIO10 | 1 | ❌ |
| LoRa(**LR1121**) DIO11 | 21 | ❌ |
| LoRa(**LR1121**) CS | 15 | ❌ |
| LoRa(**LR1121**) LDO EN | 40 | ❌ |
| LoRa(**LR1121**) BUSY | 38 | ❌ |
| Button1 (BOOT) | 0 | ❌ |
| Button2 | 17 | ❌ |
| On Board LED | 18 | ❌ |
| NTC ADC | 14 | ❌ |
| Battery ADC | 4 | ❌ |
| Fan control | 41 | ❌ |
> \[!IMPORTANT]
>
> LDO EN pin is control pin inside the module:
>
> 1. High level turns on the Radio
> 2. Low level turns off the Radio
>
### 🧑🏼‍🔧 I2C Devices Address
| Devices | 7-Bit Address | Share Bus |
| ------------------- | ------------- | --------- |
| OLED Display SH1106 | 0x3C | ✅️ |
### ⚡ Electrical parameters
| Features | Details |
| -------------------- | ------- |
| 🔗USB-C Input Voltage | 3.9V-6V |
| ⚡Charge Function | ❌ |
| 🔋Battery Voltage | 7.4V |
> \[!IMPORTANT]
>
> The battery used must have a discharge capacity of 2A or greater; otherwise, it may trigger battery protection during high-power transmission.
>
### Button Description
| Channel | Peripherals |
| ------- | ------------------------------ |
| IO17 | Customizable buttons |
| BOOT | Boot mode button, customizable |
| RST | Reset button |
### LED Description
* IO18 LED
1. Connect to GPIO18, you can turn the LED on or off by writing high or low level.
* PPS LED
1. This LED cannot be turned off and is connected to the GPS PPS Pin. This LED flashes to indicate that the PPS pulse has arrived.
* USB LED
1. LED On means the USB cable is connected,LED off means the USB cable is disconnected
### RF parameters
| Features | 868MHz |
| ------------------------- | ----------------------- |
| RF Module | LR1121 TCXO (XY16E8P33) |
| Frequency range | 840~930MHz |
| Transfer rate(FSK) | 0.6 ~ 300 kbps |
| Transfer rate(LoRa) Sub1G | 0.091 ~ 62.5 kbps |
| Transfer rate(LoRa) 2.4G | 0.476 ~ 101.5 kbps |
| Modulation | FSK, MSK, GMSK, LoRa |
### RF Block Diagram
![RF Block Diagram](./images/XY16EXP33.png)
### VCC=+5V, 840MHz~930MHz module output power dBm and current
![currnetA](./images/currnetA.png)
### VCC=+5V, 2400MHz~2500MHz module output power dBm and current
![currnetB](./images/currnetB.png)
### Resource
* [Schematic](../../../schematic/T-Beam_1W_V1.1.pdf)

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

View file

@ -0,0 +1,208 @@
<div align="center" markdown="1">
<img src="../../../.github/LilyGo_logo.png" alt="LilyGo logo" width="100"/>
</div>
<h1 align = "center">🌟LilyGo T-Beam-1W-LR2021</h1>
## Overview
* This page introduces the hardware parameters related to `LilyGo T-Beam-1W-LR2021`
### Notes on use
1. This board will not charge the external 7.4V battery, it is only powered by the battery.
2. Please be sure to connect the antenna before transmitting, otherwise it is easy to damage the RF module.
3. Please note that the GPIO with * added to the external pin header GPIO name is already connected to the internal module and cannot be used
4. This RF module provides a maximum power output of 30dBm on this board
## PlatformIO Quick Start
1. Install [Visual Studio Code](https://code.visualstudio.com/) and [Python](https://www.python.org/)
2. Search for the `PlatformIO` plugin in the `Visual Studio Code` extension and install it.
3. After the installation is complete, you need to restart `Visual Studio Code`
4. After restarting `Visual Studio Code`, select `File` in the upper left corner of `Visual Studio Code` -> `Open Folder` -> select the `LilyGo-LoRa-Series` directory
5. Wait for the installation of third-party dependent libraries to complete
6. Click on the `platformio.ini` file, and in the `platformio` column
7. Select the board name you want to use in `default_envs` and uncomment it.
8. Uncomment one of the lines `src_dir = xxxx` to make sure only one line works , Please note the example comments, indicating what works and what does not.
9. Click the (✔) symbol in the lower left corner to compile
10. Connect the board to the computer USB-C , Micro-USB is used for module firmware upgrade
11. Click (→) to upload firmware
12. Click (plug symbol) to monitor serial output
13. If it cannot be written, or the USB device keeps flashing, please check the **FAQ** below
## Arduino IDE quick start
1. Install [Arduino IDE](https://www.arduino.cc/en/software)
2. Install [Arduino ESP32](https://docs.espressif.com/projects/arduino-esp32/en/latest/)
3. Copy all folders in the `lib` directory to the `Sketchbook location` directory. How to find the location of your own libraries, [please see here](https://support.arduino.cc/hc/en-us/articles/4415103213714-Find-sketches-libraries-board-cores-and-other-files-on-your-computer)
* Windows: `C:\Users\{username}\Documents\Arduino`
* macOS: `/Users/{username}/Documents/Arduino`
* Linux: `/home/{username}/Arduino`
4. Open the corresponding example
* Open the downloaded `LilyGo-LoRa-Series`
* Open `examples`
* Select the sample file and open the file ending with `ino`
5. On Arduino Select the corresponding board in the IDE tool project and click on the corresponding option in the list below to select
| Name | Value |
| ------------------------------------ | ---------------------------------------------------- |
| Board | **ESP32S3 Dev Module** |
| Port | Your port |
| USB CDC On Boot | Enable |
| CPU Frequency | 240MHZ(WiFi) |
| Core Debug Level | None |
| USB DFU On Boot | Disable |
| Erase All Flash Before Sketch Upload | Disable |
| Flash Mode | QIO 80Mhz |
| Flash Size | **16MB(128Mb)** |
| Arduino Runs On | Core1 |
| USB Firmware MSC On Boot | Disable |
| Partition Scheme | **Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS)** |
| PSRAM | **QSPI PSRAM** |
| Upload Speed | 921600 |
| Programmer | **Esptool** |
6. Please uncomment the `utilities.h` file of each sketch according to your board model e.g `T_BEAM_1W_LR2021`, otherwise the compilation will report an error.
7. Upload sketch
### 📍 Pins Map
| Name | GPIO NUM | Free |
| ----------------------- | ------------------------------ | ---- |
| Uart1 TX | 43(External QWIIC Socket) | ✅️ |
| Uart1 RX | 44(External QWIIC Socket) | ✅️ |
| SDA | 8 (External QWIIC Socket same) | ❌ |
| SCL | 9 (External QWIIC Socket same) | ❌ |
| SPI MOSI | 11 | ❌ |
| SPI MISO | 12 | ❌ |
| SPI SCK | 13 | ❌ |
| SD CS | 10 | ❌ |
| SD MOSI | Share with SPI bus | ❌ |
| SD MISO | Share with SPI bus | ❌ |
| SD SCK | Share with SPI bus | ❌ |
| GNSS(**L76K**) TX | 6 | ❌ |
| GNSS(**L76K**) RX | 5 | ❌ |
| GNSS(**L76K**) PPS | 7 | ❌ |
| GNSS(**L76K**) Wake-up | 16 | ❌ |
| LoRa(**LR2021**) SCK | Share with SPI bus | ❌ |
| LoRa(**LR2021**) MISO | Share with SPI bus | ❌ |
| LoRa(**LR2021**) MOSI | Share with SPI bus | ❌ |
| LoRa(**LR2021**) RESET | 3 | ❌ |
| LoRa(**LR2021**) DIO10 | 1 | ❌ |
| LoRa(**LR2021**) DIO11 | 21 | ❌ |
| LoRa(**LR2021**) CS | 15 | ❌ |
| LoRa(**LR2021**) LDO EN | 40 | ❌ |
| LoRa(**LR2021**) BUSY | 38 | ❌ |
| Button1 (BOOT) | 0 | ❌ |
| Button2 | 17 | ❌ |
| On Board LED | 18 | ❌ |
| NTC ADC | 14 | ❌ |
| Battery ADC | 4 | ❌ |
| Fan control | 41 | ❌ |
> \[!IMPORTANT]
>
> LDO EN pin is control pin inside the module:
>
> 1. High level turns on the Radio
> 2. Low level turns off the Radio
>
### 🧑🏼‍🔧 I2C Devices Address
| Devices | 7-Bit Address | Share Bus |
| ------------------- | ------------- | --------- |
| OLED Display SH1106 | 0x3C | ✅️ |
### ⚡ Electrical parameters
| Features | Details |
| -------------------- | ------- |
| 🔗USB-C Input Voltage | 3.9V-6V |
| ⚡Charge Function | ❌ |
| 🔋Battery Voltage | 7.4V |
> \[!IMPORTANT]
>
> The battery used must have a discharge capacity of 2A or greater; otherwise, it may trigger battery protection during high-power transmission.
>
### Button Description
| Channel | Peripherals |
| ------- | ------------------------------ |
| IO17 | Customizable buttons |
| BOOT | Boot mode button, customizable |
| RST | Reset button |
### LED Description
* IO18 LED
1. Connect to GPIO18, you can turn the LED on or off by writing high or low level.
* PPS LED
1. This LED cannot be turned off and is connected to the GPS PPS Pin. This LED flashes to indicate that the PPS pulse has arrived.
* USB LED
1. LED On means the USB cable is connected,LED off means the USB cable is disconnected
### RF parameters
| Features | LR2021 (XY16E3AXP33) |
| ------------------------- | ----------------------------- |
| RF Module | LR2021 TCXO |
| Frequency range | 840 ~ 930MHz |
| Transfer rate(FSK) | 0.5 ~ 2000 kbps |
| Transfer rate(LoRa Sub1G) | 0.091 ~ 62.5kbps |
| Transfer rate(FSK 2.4G) | 0.476 ~ 101.5 Kbps |
| Transfer rate(FLRC) | 0.13 ~ 2.6 Mbps |
| Modulation | FSK, MSK, LoRa ,FLRC |
### RadioLib RF Setting
```c
static const uint32_t pa_version_rf_switch_dio_pins[] = {
RADIOLIB_LR2021_DIO5, RADIOLIB_LR2021_DIO6, RADIOLIB_LR2021_DIO7, RADIOLIB_LR2021_DIO8, RADIOLIB_NC
};
static const Module::RfSwitchMode_t low_sub1g_switch_table[] = {
// mode DIO5 DIO6 DIO7 DIO8
{ LR2021::MODE_STBY, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_TX, { LOW, LOW, LOW, HIGH} }, // Sub1G DIO8 SET HIGH
{ LR2021::MODE_RX, { LOW, LOW, LOW, LOW} }, // Sub1G ALL DIO SET LOW
{ LR2021::MODE_RX_HF, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_TX_HF, { LOW, LOW, LOW, LOW} },
END_OF_MODE_TABLE,
};
static const Module::RfSwitchMode_t high_2g4_switch_table[] = {
// mode DIO5 DIO6 DIO7 DIO8
{ LR2021::MODE_STBY, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_TX, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_RX, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_RX_HF, { LOW, HIGH, LOW, LOW} }, //2.4G RX DIO6 SET HIGH
{ LR2021::MODE_TX_HF, { LOW, LOW, HIGH, LOW} }, //2.4G TX DIO7 SET HIGH
END_OF_MODE_TABLE,
};
```
### RF Block Diagram
![RF Block Diagram](./images/XY16E3AXP33.png)
### VCC=+5V, 840MHz~930MHz module output power dBm and current
![currnetA](./images/currentA.png)
### VCC=+5V, 2400MHz~2500MHz module output power dBm and current
![currnetB](./images/currentB.png)
### Resource
* [Schematic](../../../schematic/T-Beam_1W_V1.1.pdf)

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 116 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 68 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Before After
Before After

View file

@ -141,10 +141,6 @@
| BOOT | Boot mode button, customizable |
| RST | Reset button |
* The PWR button is connected to the PMU
1. In shutdown mode, press the PWR button to turn on the power supply
2. In power-on mode, press the PWR button for 6 seconds (default time) to turn off the power supply
### LED Description
* IO18 LED

View file

@ -79,52 +79,55 @@
### 📍 Pins Map
| Name | GPIO NUM | Free |
| ------------------------------------- | -------------------------- | ---- |
| Uart1 TX | 43(External QWIIC Socket) | ✅️ |
| Uart1 RX | 44(External QWIIC Socket) | ✅️ |
| SDA | 17 | ❌ |
| SCL | 18 | ❌ |
| OLED(**SH1106**) SDA | Share with I2C bus | ❌ |
| OLED(**SH1106**) SCL | Share with I2C bus | ❌ |
| RTC(**PCF8563**) SDA | Share with **PMU** I2C bus | ❌ |
| RTC(**PCF8563**) SCL | Share with **PMU** I2C bus | ❌ |
| MAG Sensor(**QMC6310U/QMC6310N**) SDA | Share with I2C bus | ❌ |
| MAG Sensor(**QMC6310U/QMC6310N**) SCL | Share with I2C bus | ❌ |
| RTC(**PCF8563**) Interrupt | 14 | ❌ |
| IMU Sensor(**QMI8658**) Interrupt | 33 | ❌ |
| IMU Sensor(**QMI8658**) MISO | Share with SPI bus | ❌ |
| IMU Sensor(**QMI8658**) MOSI | Share with SPI bus | ❌ |
| IMU Sensor(**QMI8658**) SCK | Share with SPI bus | ❌ |
| IMU Sensor(**QMI8658**) CS | 34 | ❌ |
| SPI MOSI | 35 | ❌ |
| SPI MISO | 37 | ❌ |
| SPI SCK | 36 | ❌ |
| SD CS | 47 | ❌ |
| SD MOSI | Share with SPI bus | ❌ |
| SD MISO | Share with SPI bus | ❌ |
| SD SCK | Share with SPI bus | ❌ |
| GNSS(**L76K or Ublox M10**) TX | 8 | ❌ |
| GNSS(**L76K or Ublox M10**) RX | 9 | ❌ |
| GNSS(**L76K or Ublox M10**) PPS | 6 | ❌ |
| GNSS(**L76K**) Wake-up | 7 | ❌ |
| LoRa(**SX1262 or LR1121**) SCK | 12 | ❌ |
| LoRa(**SX1262 or LR1121**) MISO | 13 | ❌ |
| LoRa(**SX1262 or LR1121**) MOSI | 11 | ❌ |
| LoRa(**SX1262 or LR1121**) RESET | 5 | ❌ |
| LoRa(**SX1262 or LR1121**) DIO1/DIO9 | 1 | ❌ |
| LoRa(**SX1262 or LR1121**) BUSY | 4 | ❌ |
| LoRa(**SX1262 or LR1121**) CS | 10 | ❌ |
| Button1 (BOOT) | 0 | ❌ |
| PMU (**AXP2101**) IRQ | 40 | ❌ |
| PMU (**AXP2101**) SDA | 42 | ❌ |
| PMU (**AXP2101**) SCL | 41 | ❌ |
| Name | GPIO NUM | Free |
| -------------------------------------------- | -------------------------- | ---- |
| Uart1 TX | 43(External QWIIC Socket) | ✅️ |
| Uart1 RX | 44(External QWIIC Socket) | ✅️ |
| SDA | 17 | ❌ |
| SCL | 18 | ❌ |
| OLED(**SH1106**) SDA | Share with I2C bus | ❌ |
| OLED(**SH1106**) SCL | Share with I2C bus | ❌ |
| RTC(**PCF8563**) SDA | Share with **PMU** I2C bus | ❌ |
| RTC(**PCF8563**) SCL | Share with **PMU** I2C bus | ❌ |
| MAG Sensor(**QMC6310U/QMC6310N/QC6309**) SDA | Share with I2C bus | ❌ |
| MAG Sensor(**QMC6310U/QMC6310N/QC6309**) SCL | Share with I2C bus | ❌ |
| RTC(**PCF8563**) Interrupt | 14 | ❌ |
| IMU Sensor(**QMI8658**) Interrupt | 33 | ❌ |
| IMU Sensor(**QMI8658**) MISO | Share with SPI bus | ❌ |
| IMU Sensor(**QMI8658**) MOSI | Share with SPI bus | ❌ |
| IMU Sensor(**QMI8658**) SCK | Share with SPI bus | ❌ |
| IMU Sensor(**QMI8658**) CS | 34 | ❌ |
| SPI MOSI | 35 | ❌ |
| SPI MISO | 37 | ❌ |
| SPI SCK | 36 | ❌ |
| SD CS | 47 | ❌ |
| SD MOSI | Share with SPI bus | ❌ |
| SD MISO | Share with SPI bus | ❌ |
| SD SCK | Share with SPI bus | ❌ |
| GNSS(**L76K or Ublox M10**) TX | 8 | ❌ |
| GNSS(**L76K or Ublox M10**) RX | 9 | ❌ |
| GNSS(**L76K or Ublox M10**) PPS | 6 | ❌ |
| GNSS(**L76K**) Wake-up | 7 | ❌ |
| LoRa(**SX1262 or LR1121**) SCK | 12 | ❌ |
| LoRa(**SX1262 or LR1121**) MISO | 13 | ❌ |
| LoRa(**SX1262 or LR1121**) MOSI | 11 | ❌ |
| LoRa(**SX1262 or LR1121**) RESET | 5 | ❌ |
| LoRa(**SX1262 or LR1121**) DIO1/DIO9 | 1 | ❌ |
| LoRa(**SX1262 or LR1121**) BUSY | 4 | ❌ |
| LoRa(**SX1262 or LR1121**) CS | 10 | ❌ |
| Button1 (BOOT) | 0 | ❌ |
| PMU (**AXP2101**) IRQ | 40 | ❌ |
| PMU (**AXP2101**) SDA | 42 | ❌ |
| PMU (**AXP2101**) SCL | 41 | ❌ |
> \[!IMPORTANT]
>
> 1. GNSS Wake-up is only available in L76K version
>
> 2. Radio has its own SPI bus, and other peripheral SPI devices share the SPI bus.
>
> 3. T-BeamSupreme has three magnetometer versions: QMC6310N, QMC6310U, and QMC6309, each with a different device address.
>
### 🧑🏼‍🔧 I2C Devices Address
@ -132,6 +135,7 @@
| --------------------------------------- | ------------- | -------------- |
| OLED Display (**SH1106**) | 0x3C/0x3D | ✅️ (I2C Bus 0) |
| MAG Sensor(**QMC6310U OR QMC6310N**) | 0x1C/0x3C | ✅️ (I2C Bus 0) |
| MAG Sensor(**QMC6309**) | 0x7C | ✅️ (I2C Bus 0) |
| Temperature/humidity Sensor(**BME280**) | 0x77 | ✅️ (I2C Bus 0) |
| RTC (**PCF8563**) | 0x51 | ❌ (I2C Bus 1) |
| Power Manager (**AXP2101**) | 0x34 | ❌ (I2C Bus 1) |
@ -144,6 +148,7 @@
>
> The QMC6310U and QMC6310N use different device addresses: QMC6310U (0x1C) and QMC6310N (0x3C).
> The SH1106 uses either device address 0x3C or 0x3D. If using the QMC6310U version, the device address is 0x3C; if using the QMC6310N version, the device address is 0x3D.
> The screen device address using the QMC6309 magnetic sensor is 0x3C, the same as the QMC6310U.
>
### BME280 Address

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -4,11 +4,19 @@
* @license MIT
* @copyright Copyright (c) 2024 Shenzhen Xin Yuan Electronic Technology Co., Ltd
* @date 2024-12-18
* @note This example is for T-beam V1.2, T-Beam-BPF, T-Beam SUPREME factory examples
* @note This example is for T-beam V1.2, T-Beam-BPF, T-Beam SUPREME factory examples
* @note This example is for T-beam V1.2, T-Beam-BPF, T-Beam SUPREME factory examples
* @note This example is for T-beam V1.2, T-Beam-BPF, T-Beam SUPREME factory examples
*/
* @note This example is for T-beam V1.2, T-Beam-BPF,T-Beam-1W-xxxx, T-Beam SUPREME factory examples
* @note This example is for T-beam V1.2, T-Beam-BPF,T-Beam-1W-xxxx, T-Beam SUPREME factory examples
* @note This example is for T-beam V1.2, T-Beam-BPF,T-Beam-1W-xxxx, T-Beam SUPREME factory examples
* @note This example is for T-beam V1.2, T-Beam-BPF,T-Beam-1W-xxxx, T-Beam SUPREME factory examples
*
* | Board | B1 | B2 |
* | ---------------- | ----------- | ------------ |
* | T-Bema Supreme | Boot button | Power button |
* | T-Bema 1W SX1262 | Boot button | IO17 |
* | T-Bema 1W LR1121 | Boot button | IO17 |
* | T-Bema 1W LR2021 | Boot button | IO17 |
* | | | |
**/
#include <Arduino.h>
#include <Wire.h>
@ -42,9 +50,10 @@
#include <Adafruit_BME280.h>
#include <SensorQMI8658.hpp>
#include <SensorQMC6310.hpp>
#include <SensorQMC6309.hpp>
#include <SensorPCF8563.hpp>
SensorQMC6310 qmc;
MagnetometerBase *magnetometer = nullptr;
SensorQMI8658 qmi;
SensorPCF8563 rtc;
Adafruit_BME280 bme;
@ -77,64 +86,44 @@ static void beginSensor();
#if defined(USING_SX1276)
#ifdef T_BEAM_S3_BPF
// BPF Freq range : 144Mhz ~ 148MHz
#define CONFIG_RADIO_FREQ 144.0
#else /*T_BEAM_S3_BPF*/
#define CONFIG_RADIO_FREQ 868.0
#endif /*T_BEAM_S3_BPF*/
#define CONFIG_RADIO_OUTPUT_POWER 17
#define CONFIG_RADIO_BW 125.0
int txPowerLevel = CONFIG_RADIO_SUB1G_OUTPUT_POWER;
SX1276 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO1_PIN);
#elif defined(USING_SX1278)
#ifdef T_BEAM_S3_BPF
// BPF Freq range : 144Mhz ~ 148MHz
#define CONFIG_RADIO_FREQ 144.0
#else
#define CONFIG_RADIO_FREQ 433.0
#endif /*T_BEAM_S3_BPF*/
#define CONFIG_RADIO_OUTPUT_POWER 17
#define CONFIG_RADIO_BW 125.0
int txPowerLevel = CONFIG_RADIO_SUB1G_OUTPUT_POWER;
SX1278 radio = new Module(RADIO_CS_PIN, RADIO_DIO0_PIN, RADIO_RST_PIN, RADIO_DIO1_PIN);
#elif defined(USING_SX1262)
#ifndef CONFIG_RADIO_FREQ
#define CONFIG_RADIO_FREQ 868.0
#endif
#define CONFIG_RADIO_OUTPUT_POWER 22
#define CONFIG_RADIO_BW 125.0
int txPowerLevel = CONFIG_RADIO_SUB1G_OUTPUT_POWER;
SX1262 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
#elif defined(USING_SX1280)
#define CONFIG_RADIO_FREQ 2400.0
#define CONFIG_RADIO_OUTPUT_POWER 13
#define CONFIG_RADIO_BW 203.125
int txPowerLevel = CONFIG_RADIO_2G4_OUTPUT_POWER;
SX1280 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
#elif defined(USING_SX1280PA)
#define CONFIG_RADIO_FREQ 2400.0
#define CONFIG_RADIO_OUTPUT_POWER 3 // PA Version power range : -18 ~ 3dBm
#define CONFIG_RADIO_BW 203.125
int txPowerLevel = CONFIG_RADIO_2G4_OUTPUT_POWER; // PA Version power range : -18 ~ 3dBm
SX1280 radio = new Module(RADIO_CS_PIN, RADIO_DIO1_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
#elif defined(USING_LR1121)
// The maximum power of LR1121 2.4G band can only be set to 13 dBm
#define CONFIG_RADIO_FREQ 2450.0
#define CONFIG_RADIO_OUTPUT_POWER 13
#define CONFIG_RADIO_BW 125.0
// int txPowerLevel = CONFIG_RADIO_2G4_OUTPUT_POWER;
// The maximum power of LR1121 Sub 1G band can only be set to 22 dBm
// #define CONFIG_RADIO_FREQ 868.0
// #define CONFIG_RADIO_OUTPUT_POWER 22
// #define CONFIG_RADIO_BW 125.0
int txPowerLevel = CONFIG_RADIO_SUB1G_OUTPUT_POWER;
LR1121 radio = new Module(RADIO_CS_PIN, RADIO_DIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
#elif defined(USING_LR2021)
int txPowerLevel = CONFIG_RADIO_SUB1G_OUTPUT_POWER;
LR2021 radio = new Module(RADIO_CS_PIN, RADIO_IRQ_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
LR1121 radio = new Module(RADIO_CS_PIN, RADIO_DIO9_PIN, RADIO_RST_PIN, RADIO_BUSY_PIN);
#endif /*Radio option*/
@ -144,6 +133,65 @@ LR1121 radio = new Module(RADIO_CS_PIN, RADIO_DIO9_PIN, RADIO_RST_PIN, RADIO_BUS
#endif
#if defined(T_BEAM_1W_LR1121)
// LR1121 Version PA RF switch table
static const uint32_t pa_version_rf_switch_dio_pins[] = {
RADIOLIB_LR11X0_DIO5, RADIOLIB_LR11X0_DIO6, RADIOLIB_LR11X0_DIO7, RADIOLIB_LR11X0_DIO8, RADIOLIB_NC
};
static const Module::RfSwitchMode_t low_sub1g_switch_table[] = {
// mode DIO5 DIO6 DIO7 DIO8
{ LR11x0::MODE_STBY, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_TX, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_RX, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_TX_HP, { LOW, LOW, LOW, HIGH} }, //Sub1G DIO8 SET HIGH
{ LR11x0::MODE_TX_HF, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_GNSS, { LOW, LOW, LOW, HIGH} },
{ LR11x0::MODE_WIFI, { LOW, LOW, LOW, HIGH} },
END_OF_MODE_TABLE,
};
static const Module::RfSwitchMode_t high_2g4_switch_table[] = {
// mode DIO5 DIO6 DIO7 DIO8
{ LR11x0::MODE_STBY, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_TX, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_RX, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_TX_HP, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_TX_HF, { LOW, LOW, HIGH, LOW} }, //2.4G TX DIO7 SET HIGH
{ LR11x0::MODE_GNSS, { LOW, LOW, LOW, LOW} },
{ LR11x0::MODE_WIFI, { LOW, HIGH, LOW, LOW} }, //2.4G RX DIO6 SET HIGH
END_OF_MODE_TABLE,
};
#elif defined(T_BEAM_1W_LR2021)
// LR1121 Version PA RF switch table
static const uint32_t pa_version_rf_switch_dio_pins[] = {
RADIOLIB_LR2021_DIO5, RADIOLIB_LR2021_DIO6, RADIOLIB_LR2021_DIO7, RADIOLIB_LR2021_DIO8, RADIOLIB_NC
};
static const Module::RfSwitchMode_t low_sub1g_switch_table[] = {
// mode DIO5 DIO6 DIO7 DIO8
{ LR2021::MODE_STBY, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_TX, { LOW, LOW, LOW, HIGH} }, // Sub1G DIO8 SET HIGH
{ LR2021::MODE_RX, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_RX_HF, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_TX_HF, { LOW, LOW, LOW, LOW} },
END_OF_MODE_TABLE,
};
static const Module::RfSwitchMode_t high_2g4_switch_table[] = {
//2.4G RX DIO6 SET HIGH
// mode DIO5 DIO6 DIO7 DIO8
{ LR2021::MODE_STBY, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_TX, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_RX, { LOW, LOW, LOW, LOW} },
{ LR2021::MODE_RX_HF, { HIGH, LOW, LOW, LOW} },
{ LR2021::MODE_TX_HF, { LOW, LOW, HIGH, LOW} }, //2.4G TX DIO7 SET HIGH
END_OF_MODE_TABLE,
};
#endif /*T_BEAM_1W_LR1121 | T_BEAM_1W_LR2021*/
enum TransmissionDirection {
TRANSMISSION,
RECEIVE,
@ -164,6 +212,33 @@ uint32_t gps_use_second = 0;
uint32_t gps_start_ms = 0;
extern uint8_t display_address;
static uint8_t freq_index = 0;
static const float factory_freq[] = {
#ifdef T_BEAM_S3_BPF
144.0, 148.0
#else
433.0, 470.0,
850.0, 868.0,
915.0, 920.0, 923.0,
#if defined(USING_LR1121) || defined(USING_LR2021)
2400, 2450
#endif
#endif
};
static const char *freq_table[] = {
#ifdef T_BEAM_S3_BPF
"144.0MHz", "148.0MHz"
#endif
"433MHz", "470MHz",
"850MHz", "868MHz",
"915MHz", "920MHz", "923MHz",
#if defined(USING_LR1121) || defined(USING_LR2021)
"2400MHz", "2450MHz"
#endif
};
static float current_freq = CONFIG_RADIO_FREQ;
FrameCallback frames[] = {
hwProbe,
radioTx,
@ -197,6 +272,8 @@ AceButton button2;
#endif /*BUTTON2_PIN*/
String macStr;
volatile bool freqSelectDone = false;
volatile bool freqSelectMode = false;
void setFlag(void)
{
@ -217,7 +294,10 @@ void sleepDevice()
radio.sleep();
display->clear();
display->drawString(60, 28, "Sleep");
display->setFont(Roboto_Mono_Medium_12);
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(64, 28, "DEVICE ENTER SLEEP");
display->display();
delay(2000);
display->displayOff();
@ -385,7 +465,9 @@ void sleepDevice()
* | T-BeamV 1.2 OLED | ~ 450 uA |
* | T-BeamV 1.2 | ~ 440 uA |
* | T-Beam BPF V1.2 | ~ 350 uA |
* | T-Beam 2W v1.0 | ~ 442 uA |
* | T-Beam 1W SX1262 | ~ 442 uA |
* | T-Beam 1W LR1121 | ~ 450 uA |
* | T-Beam 1W LR2021 | ~ 450 uA |
* | T-BeamS3 Supreme | ~ 1.45mA |
*
*/
@ -436,20 +518,22 @@ void handleMenu()
#ifdef RADIO_CTRL
Serial.println("Turn off LAN,Trun on PA, Enter Tx mode.");
/*
* 2W and BPF LoRa LAN Control ,set Low turn off LAN , TX Mode
* T-Beam 1W SX1262 Version and T-Beam BPF LoRa LAN Control ,set Low turn off LAN , TX Mode
* */
digitalWrite(RADIO_CTRL, LOW);
#endif /*RADIO_CTRL*/
#ifdef RADIO_TX_CW
radio.transmitDirect();
{
int16_t state = radio.transmitDirect();
Serial.printf("transmitDirect:%d\n", state);
}
#else /*RADIO_TX_CW*/
Serial.println("Start transmit");
transmissionDirection = TRANSMISSION;
transmissionState = radio.transmit((uint8_t *)&transmissionCounter, 4);
if (transmissionState != RADIOLIB_ERR_NONE) {
Serial.print(F("[Radio] transmit packet failed! err:"));
Serial.println(transmissionState);
Serial.printf("[Radio] transmit packet failed! err: %d\n", transmissionState);
}
#endif /*RADIO_TX_CW*/
break;
@ -458,7 +542,7 @@ void handleMenu()
#ifdef RADIO_CTRL
Serial.println("Turn on LAN, Enter Rx mode.");
/*
* 2W and BPF LoRa LAN Control ,set HIGH turn on LAN ,RX Mode
* T-Beam 1W SX1262 Version and T-Beam BPF LoRa LAN Control ,set HIGH turn on LAN ,RX Mode
* */
digitalWrite(RADIO_CTRL, HIGH);
#endif /*RADIO_CTRL*/
@ -466,7 +550,7 @@ void handleMenu()
transmissionDirection = RECEIVE;
transmissionState = radio.startReceive();
if (transmissionState != RADIOLIB_ERR_NONE) {
Serial.println(F("[Radio] Received packet failed!"));
Serial.printf("[Radio] Received packet failed! err: %d\n", transmissionState);
}
break;
@ -474,7 +558,7 @@ void handleMenu()
#ifdef RADIO_CTRL
Serial.println("Turn on LAN, Enter Rx mode.");
/*
* 2W and BPF LoRa LAN Control ,set HIGH turn on LAN ,RX Mode
* T-Beam 1W SX1262 Version and T-Beam BPF LoRa LAN Control ,set HIGH turn on LAN ,RX Mode
* */
digitalWrite(RADIO_CTRL, HIGH);
#endif /*RADIO_CTRL*/
@ -488,30 +572,42 @@ void prevButtonHandleEvent(AceButton *button, uint8_t eventType, uint8_t butto
{
switch (eventType) {
case AceButton::kEventClicked:
Serial.printf("prevButtonHandleEvent currentFrames:%d frames_count:%d\n", currentFrames, max_frames);
if (freqSelectMode) {
freq_index = (freq_index + 1) % (sizeof(freq_table) / sizeof(freq_table[0]));
} else {
Serial.printf("prevButtonHandleEvent currentFrames:%d frames_count:%d\n", currentFrames, max_frames);
#ifdef BUTTON2_PIN
currentFrames = ((currentFrames + 1) >= max_frames) ? currentFrames : currentFrames + 1;
currentFrames = ((currentFrames + 1) >= max_frames) ? currentFrames : currentFrames + 1;
#else /*BUTTON2_PIN*/
currentFrames++;
currentFrames %= max_frames;
currentFrames++;
currentFrames %= max_frames;
#endif /*BUTTON2_PIN*/
handleMenu();
handleMenu();
}
break;
case AceButton::kEventLongPressed:
sleepDevice();
if (!freqSelectMode) {
sleepDevice();
}
break;
default:
break;
}
}
#ifdef BUTTON2_PIN
void nextButtonHandleEvent(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType) {
case AceButton::kEventClicked:
Serial.printf("nextButtonHandleEvent currentFrames:%d frames_count:%d\n", currentFrames, max_frames);
currentFrames = ((currentFrames - 1) < 0) ? currentFrames : currentFrames - 1;
handleMenu();
if (freqSelectMode) {
int tableSize = sizeof(freq_table) / sizeof(freq_table[0]);
freq_index = (freq_index - 1 < 0) ? (tableSize - 1) : freq_index - 1;
} else {
Serial.printf("nextButtonHandleEvent currentFrames:%d frames_count:%d\n", currentFrames, max_frames);
currentFrames = ((currentFrames - 1) < 0) ? currentFrames : currentFrames - 1;
handleMenu();
}
break;
case AceButton::kEventLongPressed:
Serial.println("Long pressed!");
@ -519,9 +615,14 @@ void nextButtonHandleEvent(AceButton *button, uint8_t eventType, uint8_t butto
Serial.println("Long pressed! ,on/off FAN");
digitalWrite(FAN_CTRL, 1 - digitalRead(FAN_CTRL));
#endif /*FAN_CTRL*/
if (freqSelectMode) {
freqSelectDone = true;
}
break;
}
}
#endif /*BUTTON2_PIN*/
void timeavailable(struct timeval *t)
{
@ -565,7 +666,7 @@ void setup()
Serial.println(info.wifi_sta_disconnected.reason);
}, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
setupBoards(true);
setupBoards(false);
setupBLE();
@ -659,7 +760,43 @@ void setup()
Serial.printf("[%s]:", RADIO_TYPE_STR);
Serial.println(F(" Selected"));
#if defined(RADIO_TX_CW) && !defined(USING_LR1121)
/***********************
* Frequency Selection
***********************/
freqSelectMode = true;
freqSelectDone = false;
freq_index = 0;
display->clear();
display->setFont(Roboto_Mono_Medium_12);
display->setTextAlignment(TEXT_ALIGN_CENTER);
while (!freqSelectDone) {
display->clear();
display->drawString(64, 10, "Select Frequency");
display->drawLine(0, 28, 128, 28);
display->drawString(64, 32, freq_table[freq_index]);
display->drawString(64, 48, "B1:Up B2:Down L:OK");
display->display();
button.check();
#ifdef BUTTON2_PIN
button2.check();
#endif
#ifdef HAS_PMU
loopPMU(power_key_pressed, power_key_long_pressed);
#endif
delay(50);
}
freqSelectMode = false;
current_freq = factory_freq[freq_index];
Serial.printf("Selected frequency: %s\n", freq_table[freq_index]);
#if defined(USING_LR2021)
radio.irqDioNum = RADIO_DIO_NUM;
#endif
#if defined(RADIO_TX_CW) && !defined(USING_LR1121) && !defined(USING_LR2021)
Serial.print("Begin Radio FSK ");
int state = radio.beginFSK();
#else
@ -673,7 +810,11 @@ void setup()
Serial.println(F("Failed!"));
}
Serial.printf("Freq:%.2f TxPower:%d Bandwidth:%.2f\n", CONFIG_RADIO_FREQ, CONFIG_RADIO_OUTPUT_POWER, CONFIG_RADIO_BW);
Serial.printf("\nRadioParams:\n\t->Freq:%.2fMhz\n\tSub1G TxPower:%d\n\t2.4G TxPower:%d\n\tBandwidth:%.2f\n",
factory_freq[freq_index],
CONFIG_RADIO_SUB1G_OUTPUT_POWER,
CONFIG_RADIO_2G4_OUTPUT_POWER,
CONFIG_RADIO_BW);
#if defined(RADIO_RX_PIN) && defined(RADIO_TX_PIN)
//The SX1280 version needs to set RX, TX antenna switching pins
@ -689,7 +830,7 @@ void setup()
* LR1121 : Allowed values are in range from 150.0 to 960.0 MHz, 1900 - 2200 MHz and 2400 - 2500 MHz. Will also perform calibrations.
* * * */
if (radio.setFrequency(CONFIG_RADIO_FREQ) == RADIOLIB_ERR_INVALID_FREQUENCY) {
if (radio.setFrequency(factory_freq[freq_index]) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("Selected frequency is invalid for this module!"));
while (true);
}
@ -741,6 +882,13 @@ void setup()
}
#endif /*RADIO_TX_CW*/
#if defined(USING_LR1121) || defined(USING_LR2021)
if (current_freq < 2400) {
txPowerLevel = CONFIG_RADIO_SUB1G_OUTPUT_POWER;
} else {
txPowerLevel = CONFIG_RADIO_2G4_OUTPUT_POWER;
}
#endif
/*
* Sets transmission output power.
* SX1278/SX1276 : Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA_BOOST pin). High power +20 dBm operation is also supported, on the PA_BOOST pin. Defaults to PA_BOOST.
@ -748,13 +896,15 @@ void setup()
* SX1268 : Allowed values are in range from -9 to 22 dBm.
* SX1280 : Allowed values are in range from -18 to 13 dBm. PA Version range : -18 ~ 3dBm
* LR1121 : Allowed values are in range from -17 to 22 dBm (high-power PA) or -18 to 13 dBm (High-frequency PA)
* LR2021 : Allowed values are in range from -9 to 22 dBm (sub-GHz PA) or -19 to 12 dBm (high-frequency PA).
* * * */
if (radio.setOutputPower(CONFIG_RADIO_OUTPUT_POWER) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
if (radio.setOutputPower(txPowerLevel) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
Serial.println(F("Selected output power is invalid for this module!"));
while (true);
}
#if !defined(USING_SX1280) && !defined(USING_LR1121) && !defined(USING_SX1280PA)
#if !defined(USING_SX1280) && !defined(USING_LR1121) && !defined(USING_SX1280PA) && !defined(USING_LR2021)
/*
* Sets current limit for over current protection at transmitter amplifier.
* SX1278/SX1276 : Allowed values range from 45 to 120 mA in 5 mA steps and 120 to 240 mA in 10 mA steps.
@ -786,7 +936,7 @@ void setup()
}
#if defined(USING_LR1121)
#if defined(USING_LR1121) && !defined(T_BEAM_1W_LR1121)
// LR1121
// set RF switch configuration for Wio WM1110
// Wio WM1110 uses DIO5 and DIO6 for RF switching
@ -811,6 +961,19 @@ void setup()
// LR1121 TCXO Voltage 2.85~3.15V
radio.setTCXO(3.0);
#elif defined(USING_LR1121) || defined(USING_LR2021)
// radio.setDioIrqParams(RADIOLIB_LR11X0_DIO10);
if (current_freq < 2400) {
Serial.printf("Using low frequency switch table for PA version\n");
radio.setRfSwitchTable(pa_version_rf_switch_dio_pins, low_sub1g_switch_table);
} else {
Serial.printf("Using high frequency switch table for PA version\n");
radio.setRfSwitchTable(pa_version_rf_switch_dio_pins, high_2g4_switch_table);
}
// LR1121 TCXO Voltage 2.85~3.15V
radio.setTCXO(3.0);
#endif
#if defined(USING_SX1262)
@ -821,6 +984,7 @@ void setup()
// when new packet is received
radio.setPacketReceivedAction(setFlag);
// radio.standby();
// start listening for LoRa packets
Serial.println(F("[Radio] Starting to listen ... "));
state = radio.startReceive();
@ -839,25 +1003,10 @@ void setup()
}
// PMU Power key callback
static uint8_t freq_index = 0;
const float factory_freq[] = {433.0, 470.0, 850.0, 868.0, 915.0, 923.0
#if defined(USING_LR1121)
, 2400, 2450
#endif
};
float current_freq = CONFIG_RADIO_FREQ;
void power_key_pressed()
void changeFreq()
{
#if defined(JAPAN_MIC_CERTIFICATION) || defined(T_BEAM_S3_BPF)
// Turn on/off display
static bool isOn = true;
isOn ? display->displayOff() : display->displayOn();
isOn ^= 1;
return;
#else /*defined(JAPAN_MIC_CERTIFICATION) || defined(T_BEAM_S3_BPF)*/
// Set freq function
radio.standby();
#if defined(USING_LR1121)
@ -883,6 +1032,15 @@ void power_key_pressed()
if (current_freq < 2400) {
max_tx_power = 22;
forceHighPower = true;
// #ifdef T_BEAM_1W_LR1121
// Serial.printf("Using low frequency switch table for PA version\n");
// radio.setRfSwitchTable(pa_version_rf_switch_dio_pins, high_2g4_switch_table);
// #endif
} else {
// #ifdef T_BEAM_1W_LR1121
// Serial.printf("Using high frequency switch table for PA version\n");
// radio.setRfSwitchTable(pa_version_rf_switch_dio_pins, low_sub1g_switch_table);
// #endif
}
if (radio.setOutputPower(max_tx_power, forceHighPower) == RADIOLIB_ERR_INVALID_OUTPUT_POWER) {
Serial.printf("Selected output power %d is invalid for this module!\n", max_tx_power);
@ -907,6 +1065,33 @@ void power_key_pressed()
}
break;
}
}
void power_key_long_pressed()
{
if (freqSelectMode) {
freqSelectDone = true;
}
}
void power_key_pressed()
{
#if defined(JAPAN_MIC_CERTIFICATION) || defined(T_BEAM_S3_BPF)
// Turn on/off display
static bool isOn = true;
isOn ? display->displayOff() : display->displayOn();
isOn ^= 1;
return;
#else /*defined(JAPAN_MIC_CERTIFICATION) || defined(T_BEAM_S3_BPF)*/
// changeFreq();
if (freqSelectMode) {
int tableSize = sizeof(freq_table) / sizeof(freq_table[0]);
freq_index = (freq_index - 1 < 0) ? (tableSize - 1) : freq_index - 1;
} else {
Serial.printf("nextButtonHandleEvent currentFrames:%d frames_count:%d\n", currentFrames, max_frames);
currentFrames = ((currentFrames - 1) < 0) ? currentFrames : currentFrames - 1;
handleMenu();
}
#endif /*defined(JAPAN_MIC_CERTIFICATION) || defined(T_BEAM_S3_BPF)*/
}
@ -1006,7 +1191,7 @@ void radioTx(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t
display->drawString(64 + x, 32 + y, buffer);
} else {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(0 + x, 16 + y, "Freq:" + String(current_freq) + "MHz");
display->drawString(0 + x, 16 + y, "Freq:" + String(freq_table[freq_index]));
display->drawString(0 + x, 32 + y, "TX :" + String(transmissionCounter));
}
@ -1072,8 +1257,8 @@ void radioRx(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t
} else {
// The coordinates define the left starting point of the text
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->drawString(0 + x, 16 + y, "Freq:" + String(current_freq) + "MHz");
display->drawString(0 + x, 32 + y, "RX :" + String(recvCounter));
display->drawString(0 + x, 16 + y, "Freq:" + String(freq_table[freq_index]));
display->drawString(0 + x, 32 + y, "RX :" + String(recvCounter));
display->drawString(0 + x, 48 + y, "RSSI:" + String(radioRSSI));
}
}
@ -1082,6 +1267,7 @@ void hwProbe(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t
{
display->setFont(Roboto_Mono_Medium_12);
display->setTextAlignment(TEXT_ALIGN_LEFT);
#if defined(T_BEAM_S3_SUPREME)
display->drawString(x, 3 + y, "6DOF");
display->drawString(x, 15 + y, "Power");
@ -1104,7 +1290,7 @@ void hwProbe(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t
display->drawString(62 + x, 51 + y, "OSC");
display->setTextAlignment(TEXT_ALIGN_RIGHT);
display->drawString(display->width() + x, 3 + y, ((deviceOnline & QMC6310U_ONLINE) || (deviceOnline & QMC6310N_ONLINE)) ? "+" : "-");
display->drawString(display->width() + x, 3 + y, ((deviceOnline & QMC6310U_ONLINE) || (deviceOnline & QMC6310N_ONLINE) || (deviceOnline & QMC6309_ONLINE)) ? "+" : "-");
display->drawString(display->width() + x, 15 + y, (deviceOnline & BME280_ONLINE ) || (deviceOnline & BMP280_ONLINE ) ? "+" : "-");
display->drawString(display->width() + x, 27 + y, (deviceOnline & PSRAM_ONLINE ) ? "+" : "-");
display->drawString(display->width() + x, 39 + y, (deviceOnline & SDCARD_ONLINE ) ? "+" : "-");
@ -1116,6 +1302,7 @@ void hwProbe(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t
display->drawString(x, 48 + y, "OLED");
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(52 + x, 0 + y, BOARD_VARIANT_NAME " " RADIO_TYPE_STR);
display->drawString(52 + x, 16 + y, (deviceOnline & RADIO_ONLINE ) ? "+" : "-");
display->drawString(52 + x, 32 + y, (deviceOnline & GPS_ONLINE ) ? "+" : "-");
@ -1327,90 +1514,33 @@ void sensorInfo(OLEDDisplay *display, OLEDDisplayUiState *disp_state, int16_t x,
display->drawString(display->width() + x, y + 48, String(pressure / 1000.0) + " kPa");
}
static const int centreX = 32;
static const int centreY = 40;
static const int radius = 10;
Madgwick filter;
int last_dx = centreX, last_dy = centreY, dx, dy;
void arrow(OLEDDisplay *display, int offsetX, int offsetY, int x2, int y2, int x1, int y1, int alength, int awidth, OLEDDISPLAY_COLOR color)
{
display->setColor(color);
float distance;
int dx, dy, x2o, y2o, x3, y3, x4, y4, k;
distance = sqrt(pow((x1 - x2), 2) + pow((y1 - y2), 2));
dx = x2 + (x1 - x2) * alength / distance;
dy = y2 + (y1 - y2) * alength / distance;
k = awidth / alength;
x2o = x2 - dx;
y2o = dy - y2;
x3 = y2o * k + dx;
y3 = x2o * k + dy;
x4 = dx - y2o * k;
y4 = dy - x2o * k;
display->drawLine(x1 + offsetX, y1 + offsetY, offsetX + x2, offsetY + y2);
display->drawLine(x1 + offsetX, y1 + offsetY, offsetX + dx, offsetY + dy);
display->drawLine(x3 + offsetX, y3 + offsetY, offsetX + x4, offsetY + y4);
display->drawLine(x3 + offsetX, y3 + offsetY, offsetX + x2, offsetY + y2);
display->drawLine(x2 + offsetX, y2 + offsetY, offsetX + x4, offsetY + y4);
}
int drawCompass(OLEDDisplay *display, int16_t x, int16_t y, float magX, float magY)
{
int angle;
display->drawString(x + 29, y + 16, "N");
display->drawString(x + 0, y + 32, "W");
display->drawString(x + 58, y + 32, "E");
display->drawString(x + 29, y + 50, "S");
float heading = atan2(magY, magX); // Result is in radians
// Now add the 'Declination Angle' for you location. Declination is the variation in magnetic field at your location.
// Find your declination here: http://www.magnetic-declination.com/
// At my location it is : -2° 20' W, or -2.33 Degrees, which needs to be in radians so = -2.33 / 180 * PI = -0.041 West is + E is -
// Make declination = 0 if you can't find your Declination value, the error is negible for nearly all locations
float declination = -0.041;
heading = heading + declination;
if (heading < 0) heading += 2 * PI; // Correct for when signs are reversed.
if (heading > 2 * PI) heading -= 2 * PI; // Correct for when heading exceeds 360-degree, especially when declination is included
angle = int(heading * 180 / M_PI); // Convert radians to degrees for more a more usual result
// For the screen -X = up and +X = down and -Y = left and +Y = right, so does not follow coordinate conventions
dx = (0.7 * radius * cos((angle - 90) * 3.14 / 180)) + centreX + x; // calculate X position for the screen coordinates - can be confusing!
dy = (0.7 * radius * sin((angle - 90) * 3.14 / 180)) + centreY + y; // calculate Y position for the screen coordinates - can be confusing!
arrow(display, x, y, last_dx, last_dy, centreX + x, centreY + y, 2, 2, BLACK); // Erase last arrow
arrow(display, x, y, dx, dy, x + centreX, centreY + y, 2, 2, WHITE); // Draw arrow in new position
return angle;
}
void getMagData(float *x, float *y)
{
float z = 0;
if (qmc.isDataReady()) {
qmc.readData();
qmc.getMag(*x, *y, z);
}
}
void imuInfo(OLEDDisplay *display, OLEDDisplayUiState *disp_state, int16_t x, int16_t y)
{
static float magX = 0, magY = 0;
static int angle = 0;
static float roll, pitch, heading;
static float roll, pitch, heading, strength;
static uint32_t interval = 0;
getMagData(&magX, &magY);
angle = drawCompass(display, x, y, magX, magY);
MagnetometerData data;
if (millis() - interval > 100) {
if (magnetometer) {
if (magnetometer->readData(data)) {
strength = MagnetometerUtils::calculateMagneticStrength(data);
strength = MagnetometerUtils::gaussToMicroTesla(strength);
}
}
interval = millis();
}
display->setFont(Roboto_Mono_Medium_12);
display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(64 + x, 0 + y, "IMU");
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setColor(BLACK);
display->fillRect(x + 80, y + 16, 25, 50);
display->setColor(WHITE);
display->setFont(Roboto_Mono_Medium_12);
display->drawString(x + 75, y + 16, String(angle) + "°");
display->drawString(x + 0, y + 16, "STRENGTH:");
display->drawString(x + 0, y + 32, "ROLL:");
display->drawString(x + 0, y + 48, "HEADING:");
// Read raw data from IMU
if (digitalRead(IMU_INT) == HIGH) {
@ -1422,29 +1552,112 @@ void imuInfo(OLEDDisplay *display, OLEDDisplayUiState *disp_state, int16_t x, in
roll = filter.getRoll();
pitch = filter.getPitch();
heading = filter.getYaw();
// Serial.printf("roll:%.2f pitch:%.2f heading:%.2f\n", roll, pitch, heading);
}
display->drawString(x + 75, y + 32, String(heading) + "°");
display->setTextAlignment(TEXT_ALIGN_RIGHT);
display->drawString(display->width() + x, y + 16, String(strength) + "uT");
display->drawString(display->width() + x, y + 32, String(roll) + "°");
display->drawString(display->width() + x, y + 48, String(heading) + "°");
}
static void beginSensor()
{
extern uint8_t mag_address;
// PMU and RTC share I2C bus
if (!rtc.begin(PMU_WIRE_PORT, I2C_SDA, I2C_SCL)) {
Serial.println("Failed to find PCF8563 - check your wiring!");
}
if (!qmc.begin(Wire, mag_address, I2C_SDA, I2C_SCL)) {
Serial.println("Failed to find QMC6310 - check your wiring!");
} else {
qmc.configMagnetometer(
SensorQMC6310::MODE_CONTINUOUS,
SensorQMC6310::RANGE_8G,
SensorQMC6310::DATARATE_200HZ,
SensorQMC6310::OSR_1,
SensorQMC6310::DSR_1);
// The desired output data rate in Hz. Allowed values are 1.0, 10.0, 50.0, 100.0 and 200.0HZ.
float data_rate_hz = 200.0f;
// op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
OperationMode op_mode = OperationMode::CONTINUOUS_MEASUREMENT;
// full_scale: Allowed values are FS_8G, FS_16G ,FS_32G
MagFullScaleRange full_scale = MagFullScaleRange::FS_8G;
// over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
MagOverSampleRatio over_sample_ratio = MagOverSampleRatio::OSR_1;
// down_sample_ratio: QMC6309 does not support downsampling rate settings; this parameter is ignored.
MagDownSampleRatio down_sample_ratio = MagDownSampleRatio::DSR_1;
Serial.printf("Probing magnetometer at address 0x%02X...\n", mag_address);
if (magnetometer == nullptr && mag_address == QMC6310U_SLAVE_ADDRESS) {
magnetometer = new SensorQMC6310();
if (!static_cast<SensorQMC6310*>(magnetometer)->begin(Wire, QMC6310U_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) {
Serial.println("Failed to find QMC6310U - check your wiring!");
delete magnetometer;
magnetometer = nullptr;
} else {
Serial.println("QMC6310U found!");
// The desired output data rate in Hz. Allowed values are 10.0, 50.0, 100.0 and 200.0HZ.
data_rate_hz = 10.0f;
// op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
op_mode = OperationMode::CONTINUOUS_MEASUREMENT;
// full_scale: Allowed values are FS_2G, FS_8G, FS_12G ,FS_30G
full_scale = MagFullScaleRange::FS_8G;
// over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
over_sample_ratio = MagOverSampleRatio::OSR_1;
// down_sample_ratio: Allowed values are DSR_1, DSR_2, DSR_4, DSR_8
down_sample_ratio = MagDownSampleRatio::DSR_1;
}
}
if (magnetometer == nullptr && mag_address == QMC6310N_SLAVE_ADDRESS) {
magnetometer = new SensorQMC6310();
if (!static_cast<SensorQMC6310*>(magnetometer)->begin(Wire, QMC6310N_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) {
Serial.println("Failed to find QMC6310 - check your wiring!");
delete magnetometer;
magnetometer = nullptr;
} else {
Serial.println("QMC6310N found!");
// The desired output data rate in Hz. Allowed values are 10.0, 50.0, 100.0 and 200.0HZ.
data_rate_hz = 10.0f;
// op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
op_mode = OperationMode::CONTINUOUS_MEASUREMENT;
// full_scale: Allowed values are FS_2G, FS_8G, FS_12G ,FS_30G
full_scale = MagFullScaleRange::FS_8G;
// over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
over_sample_ratio = MagOverSampleRatio::OSR_1;
// down_sample_ratio: Allowed values are DSR_1, DSR_2, DSR_4, DSR_8
down_sample_ratio = MagDownSampleRatio::DSR_1;
}
}
if (magnetometer == nullptr && mag_address == QMC6309_SLAVE_ADDRESS) {
magnetometer = new SensorQMC6309();
if (!static_cast<SensorQMC6309*>(magnetometer)->begin(Wire, QMC6309_SLAVE_ADDRESS, I2C_SDA, I2C_SCL)) {
Serial.println("Failed to find QMC6309 - check your wiring!");
delete magnetometer;
magnetometer = nullptr;
} else {
Serial.println("QMC6309 found!");
// The desired output data rate in Hz. Allowed values are 1.0, 10.0, 50.0, 100.0 and 200.0HZ.
data_rate_hz = 10.0f;
// op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
op_mode = OperationMode::CONTINUOUS_MEASUREMENT;
// full_scale: Allowed values are FS_8G, FS_16G ,FS_32G
full_scale = MagFullScaleRange::FS_8G;
// over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
over_sample_ratio = MagOverSampleRatio::OSR_1;
// down_sample_ratio: QMC6309 does not support downsampling rate settings; this parameter is ignored.
down_sample_ratio = MagDownSampleRatio::DSR_1;
}
}
if (magnetometer) {
/* Config Magnetometer */
if (magnetometer->configMagnetometer(
op_mode,
full_scale,
data_rate_hz,
over_sample_ratio,
down_sample_ratio)) {
Serial.println("Magnetometer configured successfully.");
} else {
Serial.println("Magnetometer configuration failed.");
}
}
extern uint8_t bme280_address;
if (!bme.begin(bme280_address)) {
Serial.println("Failed to find BME280 - check your wiring!");

View file

@ -326,7 +326,7 @@ bool beginPower()
// Set the time of pressing the button to turn off
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_4S);
PMU->setPowerKeyPressOffTime(XPOWERS_POWEROFF_8S);
uint8_t opt = PMU->getPowerKeyPressOffTime();
Serial.print("PowerKeyPressOffTime:");
switch (opt) {
@ -407,7 +407,7 @@ void disablePeripherals()
#endif
}
void loopPMU(void (*pressed_cb)(void))
void loopPMU(void (*pressed_cb)(void), void (*long_press_cb)(void))
{
if (!PMU) {
return;
@ -444,6 +444,9 @@ void loopPMU(void (*pressed_cb)(void))
}
if (PMU->isPekeyLongPressIrq()) {
Serial.println("isPekeyLongPress");
if (long_press_cb) {
long_press_cb();
}
}
if (PMU->isBatChargeDoneIrq()) {
Serial.println("isBatChargeDone");
@ -834,7 +837,7 @@ void setupBoards(bool disable_u8g2 )
#ifdef HAS_GPS
#if defined(T_BEAM_S3_SUPREME) || defined(T_BEAM_1W) || defined(T_BEAM_S3_BPF)
#if defined(T_BEAM_S3_SUPREME) || defined(T_BEAM_1W_SX1262) || defined(T_BEAM_1W_LR1121) || defined(T_BEAM_1W_LR2021) || defined(T_BEAM_S3_BPF)
// T-Beam v1.2 skips L76K
find_gps = beginGPS();
#endif
@ -996,6 +999,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};
@ -105,7 +106,7 @@ void scanWiFi();
#ifdef HAS_PMU
extern XPowersLibInterface *PMU;
extern bool pmuInterrupt;
void loopPMU(void (*pressed_cb)(void));
void loopPMU(void (*pressed_cb)(void), void (*long_press_cb)(void) = NULL);
bool beginPower();
void disablePeripherals();
#else

View file

@ -72,9 +72,10 @@
// #define T_BEAM_S3_BPF
// --------------LoRa 2W -------------------------------------
// Product: ...
// #define T_BEAM_1W
// Product: https://lilygo.cc/products/t-beam-1w
// #define T_BEAM_1W_SX1262
// #define T_BEAM_1W_LR1121
// #define T_BEAM_1W_LR2021
// #define T3_V1_6_SX1276_TCXO // Production has stopped
@ -86,7 +87,6 @@
#if defined(T_BEAM_SX1262) || defined(T_BEAM_SX1276) || defined(T_BEAM_SX1278) || defined(T_BEAM_LR1121)
#if defined(T_BEAM_SX1262)
#ifndef USING_SX1262
#define USING_SX1262
@ -128,6 +128,7 @@
// LR1121 Only
#define RADIO_DIO9_PIN 33
#define RADIO_DIO_IRQ_PIN (RADIO_DIO9_PIN)
#define BOARD_LED 4
@ -330,6 +331,7 @@
#define RADIO_DIO9_PIN 26 //LR1121 DIO9
#define RADIO_BUSY_PIN 32 //LR1121 BUSY
#define RADIO_DIO_IRQ_PIN (RADIO_DIO9_PIN)
#endif
@ -384,6 +386,10 @@
#ifndef USING_SX1280PA
#define USING_SX1280PA
#endif
#pragma message "Using SX1280PA,The transmit power must not exceed 3dBm, otherwise it will cause permanent damage to LoRa."
#define CONFIG_RADIO_2G4_OUTPUT_POWER 3
#define CONFIG_RADIO_OUTPUT_POWER CONFIG_RADIO_2G4_OUTPUT_POWER
#elif defined(T3_S3_V1_2_LR1121) || defined(ARDUINO_LILYGO_T3S3_LR1121)
#ifndef USING_LR1121
#define USING_LR1121
@ -392,6 +398,10 @@
#ifndef USING_LR1121PA
#define USING_LR1121PA
#endif
#pragma message "Using LR1121PA,The transmit power must not exceed 0dBm, otherwise it will cause permanent damage to LoRa."
#define CONFIG_RADIO_2G4_OUTPUT_POWER 0
#define CONFIG_RADIO_OUTPUT_POWER CONFIG_RADIO_2G4_OUTPUT_POWER
#endif // T3_S3_V1_2_SX1262
@ -455,6 +465,7 @@
#define RADIO_DIO9_PIN 36 //LR1121 DIO9 = IO36
#define RADIO_BUSY_PIN 34 //LR1121 BUSY = IO34
#define RADIO_DIO_IRQ_PIN (RADIO_DIO9_PIN)
#define LILYGO_RADIO_2G4_TX_POWER_LIMIT 13 //LR1121 2.4G TX Power Limit
@ -462,6 +473,7 @@
#define RADIO_DIO9_PIN 36 //LR1121 DIO9 = IO36
#define RADIO_BUSY_PIN 34 //LR1121 BUSY = IO34
#define RADIO_DIO_IRQ_PIN (RADIO_DIO9_PIN)
#define LILYGO_RADIO_2G4_TX_POWER_LIMIT 0 //LR1121 2.4G TX Power Limit
#define USING_LR1121
@ -521,6 +533,7 @@
// LR1121 Version
#define RADIO_DIO9_PIN (1)
#define RADIO_DIO_IRQ_PIN (RADIO_DIO9_PIN)
#define SPI_MOSI (35)
#define SPI_SCK (36)
@ -686,10 +699,28 @@
#define BOARD_VARIANT_NAME "T-Beam BPF"
#elif defined(T_BEAM_1W)
#elif defined(T_BEAM_1W_SX1262) || defined(T_BEAM_1W_LR1121) || defined(T_BEAM_1W_LR2021)
#ifdef T_BEAM_1W_SX1262
#ifndef USING_SX1262
#define USING_SX1262
#endif
#endif
#ifdef T_BEAM_1W_LR1121
#ifndef USING_LR1121
#define USING_LR1121
#endif
#pragma message "Using LR1121 PA Version,The transmit power must not exceed 0dBm, otherwise it will cause permanent damage to LoRa."
#define CONFIG_RADIO_2G4_OUTPUT_POWER 0
#endif
#ifdef T_BEAM_1W_LR2021
#ifndef USING_LR2021
#define USING_LR2021
#endif
#endif
#define I2C_SDA (8)
@ -720,10 +751,31 @@
#define RADIO_CS_PIN (15)
#define RADIO_RST_PIN (3)
#define RADIO_BUSY_PIN (38)
#define RADIO_LDO_EN (40)
#if defined(T_BEAM_1W_SX1262)
#define RADIO_CTRL (21)
#define RADIO_DIO1_PIN (1)
#define RADIO_BUSY_PIN (38)
#endif
#if defined(T_BEAM_1W_LR1121)
#define RADIO_DIO10_PIN (1) // Connect to DIO10
#define RADIO_DIO11_PIN (21) // Connect to DIO11
#define RADIO_DIO_IRQ_PIN (RADIO_DIO11_PIN)
#pragma message "Using LR2021 PA Version,The transmit power must not exceed 0dBm, otherwise it will cause permanent damage to LoRa."
#define CONFIG_RADIO_2G4_OUTPUT_POWER 1
#define CONFIG_RADIO_SUB1G_OUTPUT_POWER 22
#endif
#if defined(T_BEAM_1W_LR2021)
#define RADIO_IRQ_PIN (1) // Connect to DIO10
#define RADIO_DIO11_PIN (21) // Connect to DIO11
#define RADIO_DIO_NUM (10) // LR2021 DIO NUM NOT ESP32S3 GPIO NUM
#define CONFIG_RADIO_2G4_OUTPUT_POWER 8
#define CONFIG_RADIO_SUB1G_OUTPUT_POWER 22
#pragma message "Using LR2021 PA Version,The transmit power must not exceed 8dBm, otherwise it will cause permanent damage to LoRa."
#endif
#define BOARD_LED 18
#define LED_ON HIGH
@ -750,7 +802,7 @@
#define DISPLAY_MODEL U8G2_SH1106_128X64_NONAME_F_HW_I2C
#define DISPLAY_MODEL_SSD_LIB SH1106Wire
#define BOARD_VARIANT_NAME "LoRa 2W"
#define BOARD_VARIANT_NAME "LoRa 1W"
#else
#error "When using it for the first time, please define the board model in <utilities.h> 首次使用时,请在<utilities.h> 文件最上方定义板卡模型"
@ -761,20 +813,103 @@
#if defined(USING_SX1262)
#define RADIO_TYPE_STR "SX1262"
#ifndef CONFIG_RADIO_SUB1G_OUTPUT_POWER
#define CONFIG_RADIO_SUB1G_OUTPUT_POWER 22
#endif
#elif defined(USING_SX1276)
#define RADIO_TYPE_STR "SX1276"
#ifndef CONFIG_RADIO_SUB1G_OUTPUT_POWER
#define CONFIG_RADIO_SUB1G_OUTPUT_POWER 17
#endif
#elif defined(USING_SX1278)
#define RADIO_TYPE_STR "SX1278"
#ifndef CONFIG_RADIO_SUB1G_OUTPUT_POWER
#define CONFIG_RADIO_SUB1G_OUTPUT_POWER 17
#endif
#ifndef CONFIG_RADIO_FREQ
#define CONFIG_RADIO_FREQ 433.0
#endif
#elif defined(USING_LR1121)
#define RADIO_TYPE_STR "LR1121"
#ifndef CONFIG_RADIO_SUB1G_OUTPUT_POWER
#define CONFIG_RADIO_SUB1G_OUTPUT_POWER 22
#endif
#ifndef CONFIG_RADIO_2G4_OUTPUT_POWER
#define CONFIG_RADIO_2G4_OUTPUT_POWER 13
#endif
#elif defined(USING_SX1280)
#define RADIO_TYPE_STR "SX1280"
#ifndef CONFIG_RADIO_2G4_OUTPUT_POWER
#define CONFIG_RADIO_2G4_OUTPUT_POWER 13
#endif
#ifndef CONFIG_RADIO_FREQ
#define CONFIG_RADIO_FREQ 2400.0
#endif
#ifndef CONFIG_RADIO_BW
#define CONFIG_RADIO_BW 203.125
#endif
#elif defined(USING_SX1280PA)
#define RADIO_TYPE_STR "SX1280PA"
#ifndef CONFIG_RADIO_2G4_OUTPUT_POWER
#define CONFIG_RADIO_2G4_OUTPUT_POWER 13
#endif
#ifndef CONFIG_RADIO_FREQ
#define CONFIG_RADIO_FREQ 2400.0
#endif
#ifndef CONFIG_RADIO_BW
#define CONFIG_RADIO_BW 203.125
#endif
#elif defined(USING_LR2021)
#define RADIO_TYPE_STR "LR2021"
#ifndef CONFIG_RADIO_2G4_OUTPUT_POWER
#define CONFIG_RADIO_2G4_OUTPUT_POWER 12
#endif
#ifndef CONFIG_RADIO_SUB1G_OUTPUT_POWER
#define CONFIG_RADIO_SUB1G_OUTPUT_POWER 22
#endif
#endif
#ifndef CONFIG_RADIO_2G4_OUTPUT_POWER
#define CONFIG_RADIO_2G4_OUTPUT_POWER -1
#endif
#ifndef CONFIG_RADIO_FREQ
#define CONFIG_RADIO_FREQ 868.0
#endif
#ifndef CONFIG_RADIO_BW
#define CONFIG_RADIO_BW 125.0
#endif

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

View file

@ -996,6 +996,11 @@ void scanDevices(TwoWire *w)
}
}
break;
case 0x7C:
Serial.printf("\tFound QMC6309 Sensor at address 0x%02X\n", addr);
mag_address = addr;
deviceOnline |= QMC6309_ONLINE;
break;
case 0x51:
Serial.printf("\tFound PCF8563 RTC at address 0x%02X\n", addr);
deviceOnline |= PCF8563_ONLINE;

View file

@ -58,7 +58,8 @@ enum {
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
OSC32768_ONLINE = _BV(14),
QMC6309_ONLINE = _BV(15),
};

File diff suppressed because it is too large Load diff

View file

@ -1,144 +0,0 @@
/**
* @file boards.h
* @author Lewis He (lewishe@outlook.com)
* @license MIT
* @copyright Copyright (c) 2024 ShenZhen XinYuan Electronic Technology Co., Ltd
* @date 2024-04-25
* @last-update 2024-08-07
*/
#pragma once
#include "utilities.h"
#ifdef HAS_SDCARD
#include <SD.h>
#endif
#if defined(ARDUINO_ARCH_ESP32)
#include <FS.h>
#include <WiFi.h>
#endif
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#ifdef DISPLAY_MODEL
#include <U8g2lib.h>
#endif
#ifdef HAS_PMU
#include <XPowersLib.h>
#endif
#include <esp_mac.h>
#ifndef DISPLAY_ADDR
#define DISPLAY_ADDR 0x3C
#endif
// #define ENABLE_BLE //Enable ble function
enum {
POWERMANAGE_ONLINE = _BV(0),
DISPLAY_ONLINE = _BV(1),
RADIO_ONLINE = _BV(2),
GPS_ONLINE = _BV(3),
PSRAM_ONLINE = _BV(4),
SDCARD_ONLINE = _BV(5),
AXDL345_ONLINE = _BV(6),
BME280_ONLINE = _BV(7),
BMP280_ONLINE = _BV(8),
BME680_ONLINE = _BV(9),
QMC6310U_ONLINE = _BV(10),
QMC6310N_ONLINE = _BV(11),
QMI8658_ONLINE = _BV(12),
PCF8563_ONLINE = _BV(13),
OSC32768_ONLINE = _BV(14)
};
typedef struct {
String chipModel;
float psramSize;
uint8_t chipModelRev;
uint8_t chipFreq;
uint8_t flashSize;
uint8_t flashSpeed;
} DevInfo_t;
void setupBoards(bool disable_u8g2 = false);
#ifdef HAS_SDCARD
bool beginSDCard();
#else
#define beginSDCard()
#endif
#ifdef DISPLAY_MODEL
bool beginDisplay();
#endif
void printResult(bool radio_online);
#ifdef BOARD_LED
void flashLed();
#else
#define flashLed()
#endif
void scanDevices(TwoWire *w);
bool beginGPS();
bool recoveryGPS();
void scanWiFi();
#ifdef HAS_PMU
extern XPowersLibInterface *PMU;
extern bool pmuInterrupt;
void loopPMU(void (*pressed_cb)(void));
bool beginPower();
void disablePeripherals();
#else
#define beginPower()
#define disablePeripherals()
#endif
#ifdef DISPLAY_MODEL
extern U8G2 *disp;
#define U8G2_HOR_ALIGN_CENTER(t) ((disp->getDisplayWidth() - (disp->getUTF8Width(t))) / 2)
#define U8G2_HOR_ALIGN_RIGHT(t) ( disp->getDisplayWidth() - disp->getUTF8Width(t))
#endif
#if defined(ARDUINO_ARCH_ESP32)
#if defined(HAS_SDCARD)
extern SPIClass SDCardSPI;
#endif
#define SerialGPS Serial1
#elif defined(ARDUINO_ARCH_STM32)
extern HardwareSerial SerialGPS;
#endif
#ifdef NTC_PIN
float getTempForNTC();
#endif
#ifdef ENABLE_BLE
void setupBLE();
#else
#define setupBLE()
#endif
extern uint32_t deviceOnline;

View file

@ -2,7 +2,7 @@
*
* @license MIT License
*
* Copyright (c) 2022 lewis he
* Copyright (c) 2026 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
@ -24,20 +24,63 @@
*
* @file QMC6310_CalibrateExample.ino
* @author Lewis He (lewishe@outlook.com)
* @date 2022-10-16
* @date 2026-01-26
*
*/
#include <Wire.h>
#include <SPI.h>
#include <Arduino.h>
#include "SensorQMC6310.hpp"
#include "LoRaBoards.h"
#define ARDUINO_T_BEAM_S3_SUPREME
#ifdef ARDUINO_T_BEAM_S3_SUPREME
#include <XPowersAXP2101.tpp> //PMU Library https://github.com/lewisxhe/XPowersLib.git
#endif
SensorQMC6310 qmc;
#ifndef SENSOR_SDA
#define SENSOR_SDA 17
#endif
#ifndef SENSOR_SCL
#define SENSOR_SCL 18
#endif
SensorQMC6310 magnetometer;
void beginPower()
{
#if defined(ARDUINO_T_BEAM_S3_SUPREME)
XPowersAXP2101 power;
power.begin(Wire1, AXP2101_SLAVE_ADDRESS, 42, 41);
power.disableALDO1();
power.disableALDO2();
delay(250);
power.setALDO1Voltage(3300);
power.enableALDO1();
power.setALDO2Voltage(3300);
power.enableALDO2();
#endif
}
void calibrate()
{
qmc.setDataOutputRate(SensorQMC6310::DATARATE_200HZ);
if (!magnetometer.setOutputDataRate(200.0f)) {
Serial.println("Failed to set output data rate");
return ;
}
Serial.println("========================================");
Serial.println("Calibration Instructions:");
Serial.println("1. Rotate sensor in FIGURE-8 pattern");
Serial.println("2. Cover all axes (X, Y, Z directions)");
Serial.println("3. Rotate slowly and completely");
Serial.println("4. Wait for progress bar to complete");
Serial.println("5. Expected: Magnetic Strength ~25-65 uT");
Serial.println("========================================");
Serial.println();
Serial.println("Place the sensor on the plane and slowly rotate the sensor...");
Serial.println("Rotate in FIGURE-8 pattern to cover all directions!");
Serial.println();
int32_t x_min = 65535;
int32_t x_max = -65535;
@ -45,26 +88,25 @@ void calibrate()
int32_t y_max = -65535;
int32_t z_min = 65535;
int32_t z_max = -65535;
Serial.println("Place the sensor on the plane and slowly rotate the sensor...");
int32_t range = 1000;
int32_t i = 0;
int32_t x = 0, y = 0, z = 0;;
float a = 0.5 ;
float x_offset = 0;
float y_offset = 0;
float z_offset = 0;
int16_t x_offset = 0;
int16_t y_offset = 0;
int16_t z_offset = 0;
MagnetometerData data;
while (i < range) {
i += 1;
if (qmc.isDataReady()) {
if (magnetometer.isDataReady()) {
qmc.readData();
magnetometer.readData(data);
x = a * qmc.getRawX() + (1 - a) * x;
y = a * qmc.getRawY() + (1 - a) * y;
z = a * qmc.getRawZ() + (1 - a) * z;
x = (data.raw.x + x) / 2;
y = (data.raw.y + y) / 2;
z = (data.raw.z + z) / 2;
if (x < x_min) {
x_min = x;
i = 0;
@ -104,11 +146,41 @@ void calibrate()
y_offset = (y_max + y_min) / 2;
z_offset = (z_max + z_min) / 2;
Serial.printf("x_min:%d x_max:%d y_min:%d y_max:%d z_min:%d z_max:%d\n", x_min, x_max, y_min, y_max, z_min, z_max);
Serial.printf("x_offset:%.2f y_offset:%.2f z_offset:%.2f \n", x_offset, y_offset, z_offset);
Serial.print("x_min:");
Serial.println(x_min);
Serial.print("x_max:");
Serial.println(x_max);
Serial.print("y_min:");
Serial.println(y_min);
Serial.print("y_max:");
Serial.println(y_max);
Serial.print("z_min:");
Serial.println(z_min);
Serial.print("z_max:");
Serial.println(z_max);
Serial.print("x_offset:");
Serial.println(x_offset);
Serial.print("y_offset:");
Serial.println(y_offset);
Serial.print("z_offset:");
Serial.println(z_offset);
// Set the calibration value and the user calculates the deviation
qmc.setOffset(x_offset, y_offset, z_offset);
magnetometer.setOffset(x_offset, y_offset, z_offset);
Serial.println();
Serial.println("Calibration complete!");
Serial.println("Check if Magnetic Strength is ~25-65 uT");
Serial.println("If too low, repeat calibration with better rotation");
}
@ -117,118 +189,136 @@ void setup()
Serial.begin(115200);
while (!Serial);
setupBoards();
// LilyGo T-Beam-Supreme sensor requires a power source to function.
beginPower();
// For QMC6310U, the device address is 0x1C.
// For QMC6310N, the device address is 0x3C.
// The sensor device address is provided by the setupBoards I2C scanner.
extern uint8_t mag_address;
if (!qmc.begin(Wire, mag_address, I2C_SDA, I2C_SCL)) {
Serial.println("Failed to find QMC6310 - check your wiring!");
/**
* Supports QMC6310U and QMC6310N; simply pass the corresponding device address
* during initialization.
* - QMC6310U_SLAVE_ADDRESS
* - QMC6310N_SLAVE_ADDRESS
*/
uint8_t address = QMC6310U_SLAVE_ADDRESS;
// uint8_t address = QMC6310N_SLAVE_ADDRESS;
if (!magnetometer.begin(Wire, address, SENSOR_SDA, SENSOR_SCL)) {
while (1) {
Serial.println("Failed to find QMC6310 - check your wiring!");
delay(1000);
}
}
/* Get Magnetometer chip id*/
Serial.print("Device ID:");
Serial.println(qmc.getChipID(), HEX);
// The desired output data rate in Hz. Allowed values are 10.0, 50.0, 100.0 and 200.0HZ.
float data_rate_hz = 200.0f;
// op_mode: Allowed values are SUSPEND, NORMAL, SINGLE_MEASUREMENT, CONTINUOUS_MEASUREMENT
OperationMode op_mode = OperationMode::CONTINUOUS_MEASUREMENT;
// full_scale: Allowed values are FS_2G, FS_8G, FS_12G ,FS_30G
MagFullScaleRange full_scale = MagFullScaleRange::FS_8G;
// over_sample_ratio: Allowed values are OSR_1, OSR_2, OSR_4, OSR_8
MagOverSampleRatio over_sample_ratio = MagOverSampleRatio::OSR_1;
// down_sample_ratio: Allowed values are DSR_1, DSR_2, DSR_4, DSR_8
MagDownSampleRatio down_sample_ratio = MagDownSampleRatio::DSR_1;
/* Config Magnetometer */
qmc.configMagnetometer(
/*
* Run Mode
* MODE_SUSPEND
* MODE_NORMAL
* MODE_SINGLE
* MODE_CONTINUOUS
* * */
SensorQMC6310::MODE_CONTINUOUS,
/*
* Full Range
* RANGE_30G
* RANGE_12G
* RANGE_8G
* RANGE_2G
* * */
SensorQMC6310::RANGE_8G,
/*
* Output data rate
* DATARATE_10HZ
* DATARATE_50HZ
* DATARATE_100HZ
* DATARATE_200HZ
* * */
SensorQMC6310::DATARATE_200HZ,
/*
* Over sample Ratio1
* OSR_8
* OSR_4
* OSR_2
* OSR_1
* * * */
SensorQMC6310::OSR_1,
/*
* Down sample Ratio1
* DSR_8
* DSR_4
* DSR_2
* DSR_1
* * */
SensorQMC6310::DSR_1);
if (magnetometer.configMagnetometer(
op_mode,
full_scale,
data_rate_hz,
over_sample_ratio,
down_sample_ratio)) {
Serial.println("Magnetometer configured successfully.");
} else {
Serial.println("Magnetometer configuration failed.");
while (1);
}
// Calibration algorithm reference from
// https://github.com/CoreElectronics/CE-PiicoDev-QMC6310-MicroPython-Module
calibrate();
Serial.println("Calibration done .");
Serial.println("Calibration done.");
delay(5000);
SensorInfo info = magnetometer.getSensorInfo();
Serial.print("Manufacturer: "); Serial.println(info.manufacturer);
Serial.print("Model: "); Serial.println(info.model);
Serial.print("I2C Address: 0x"); Serial.println(info.i2c_address, HEX);
Serial.print("Version: "); Serial.println(info.version);
Serial.print("UID: 0x"); Serial.println(info.uid);
Serial.print("Type: "); Serial.println(SensorUtils::typeToString(info.type));
SensorConfig cfg = magnetometer.getConfig();
Serial.print("DataRate: "); Serial.println(cfg.sample_rate);
Serial.print("FullScaleRange: "); Serial.println(cfg.range);
Serial.print("Mode: "); Serial.println((uint8_t)cfg.mode);
Serial.println();
//Find the magnetic declination : https://www.magnetic-declination.com/
float declination_deg = MagnetometerUtils::dmsToDecimalDegrees(-3, 20); // -3.3333
magnetometer.setDeclination(declination_deg);
Serial.print(" Magnetic Declination: ");
Serial.print(declination_deg, 2);
Serial.println("°");
Serial.print(" Sensitivity: ");
Serial.print(magnetometer.getSensitivity(), 6);
Serial.println(" Gauss/LSB");
delay(3000);
Serial.println("Read data now...");
}
void loop()
{
MagnetometerData data;
//Wiat data ready
if (qmc.isDataReady()) {
if (magnetometer.readData(data)) {
qmc.readData();
// Gauss to μT
float x = MagnetometerUtils::gaussToMicroTesla(data.magnetic_field.x);
float y = MagnetometerUtils::gaussToMicroTesla(data.magnetic_field.y);
float z = MagnetometerUtils::gaussToMicroTesla(data.magnetic_field.z);
Serial.print("GYR: ");
Serial.print("X:");
Serial.print(qmc.getX());
Serial.print("Mag:");
Serial.print(" X:"); Serial.print(x);
Serial.print(" Y:"); Serial.print(y);
Serial.print(" Z:"); Serial.print(z);
Serial.print(" μT");
Serial.print(" Sensitivity: ");
Serial.print(magnetometer.getSensitivity(), 6);
Serial.print(" Gauss/LSB");
Serial.print(" Metadata:");
Serial.print(" X:");
Serial.print(data.raw.x);
Serial.print(" Y:");
Serial.print(qmc.getY());
Serial.print(data.raw.y);
Serial.print(" Z:");
Serial.print(qmc.getZ());
Serial.println(" uT");
Serial.print("RAW: ");
Serial.print("X:");
Serial.print(qmc.getRawX());
Serial.print(" Y:");
Serial.print(qmc.getRawY());
Serial.print(" Z:");
Serial.println(qmc.getRawZ());
Serial.print(data.raw.z);
/*
float x, y, z;
qmc.getMag(x, y, z);
Serial.print("X:");
Serial.print(x);
Serial.print(" Y:");
Serial.print(y);
Serial.print(" Z:");
Serial.println(x);
*/
Serial.print(" Heading (rad): ");
Serial.print(data.heading, 6);
Serial.print(" rad");
Serial.print(" Heading (deg): ");
Serial.print(data.heading_degrees, 2);
Serial.print("°");
float strength = MagnetometerUtils::calculateMagneticStrength(data);
strength = MagnetometerUtils::gaussToMicroTesla(strength);
Serial.print(" Magnetic Strength: ");
Serial.print(strength, 2);
Serial.println(" μT");
if (data.overflow) {
Serial.println("\tWarning: Data Overflow occurred!");
}
}
delay(100);
delay(10);
}

File diff suppressed because it is too large Load diff

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