├── .gitignore ├── Dashboard.png ├── LICENSE ├── README.md ├── images ├── 20211016_160146.jpg ├── Dashboard.png ├── console1_edited.png ├── console2_edited.png ├── console3.png ├── console4.png ├── pio3.png ├── pio4.png ├── pio5.png ├── pio6.png ├── tago1.png ├── tago2.png ├── tago3.png ├── tago4a.png ├── tago5.png ├── tago6.png └── tbeam.bmp ├── keyfiles └── lorawan-keys_example.h ├── payload-formatters └── lmic-node-uplink-formatters.js ├── platformio.ini └── src ├── LMIC-node.cpp ├── LMIC-node.h └── boards ├── bsf_adafruit_feather_m0_lora.h ├── bsf_adafruit_qt_py_m0.h ├── bsf_blackpill_f103c8.h ├── bsf_bluepill_f103c8.h ├── bsf_disco_l072cz_lrwan1.h ├── bsf_heltec_wifi_lora_32.h ├── bsf_heltec_wifi_lora_32_v2.h ├── bsf_heltec_wireless_stick.h ├── bsf_heltec_wireless_stick_lite.h ├── bsf_lolin32.h ├── bsf_lolin_d32.h ├── bsf_lolin_d32_pro.h ├── bsf_lopy4.h ├── bsf_lora32u4II.h ├── bsf_nodemcu_32s.h ├── bsf_nodemcuv2.h ├── bsf_pico.h ├── bsf_pro8mhzatmega328.h ├── bsf_samd21_m0_mini.h ├── bsf_teensylc.h ├── bsf_ttgo_lora32_v1.h ├── bsf_ttgo_lora32_v2.h ├── bsf_ttgo_lora32_v21.h ├── bsf_ttgo_t_beam.h └── bsf_ttgo_t_beam_v1.h /.gitignore: -------------------------------------------------------------------------------- 1 | # .gitignore file for LMIC-node 2 | 3 | # Exclude any Visual Studio Code and PlatformIO folders/files 4 | .pio 5 | .vscode 6 | .vs 7 | .pioenvs 8 | .piolibdeps 9 | 10 | # Exclude all contents from any keyfiles folder 11 | keyfiles/** 12 | # Except following example file 13 | !keyfiles/lorawan-keys_example.h 14 | 15 | # Exclude any LoRaWAN key files with following pattern 16 | *lorawan-keys.h 17 | 18 | # Exlude lib and include project folders (PlatformIO) 19 | /lib/ 20 | /include/ 21 | -------------------------------------------------------------------------------- /Dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/Dashboard.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Leonel Lopes Parente 4 | Copyright (c) 2018 Terry Moore, MCCI 5 | Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /images/20211016_160146.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/20211016_160146.jpg -------------------------------------------------------------------------------- /images/Dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/Dashboard.png -------------------------------------------------------------------------------- /images/console1_edited.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/console1_edited.png -------------------------------------------------------------------------------- /images/console2_edited.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/console2_edited.png -------------------------------------------------------------------------------- /images/console3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/console3.png -------------------------------------------------------------------------------- /images/console4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/console4.png -------------------------------------------------------------------------------- /images/pio3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/pio3.png -------------------------------------------------------------------------------- /images/pio4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/pio4.png -------------------------------------------------------------------------------- /images/pio5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/pio5.png -------------------------------------------------------------------------------- /images/pio6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/pio6.png -------------------------------------------------------------------------------- /images/tago1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/tago1.png -------------------------------------------------------------------------------- /images/tago2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/tago2.png -------------------------------------------------------------------------------- /images/tago3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/tago3.png -------------------------------------------------------------------------------- /images/tago4a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/tago4a.png -------------------------------------------------------------------------------- /images/tago5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/tago5.png -------------------------------------------------------------------------------- /images/tago6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/tago6.png -------------------------------------------------------------------------------- /images/tbeam.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Chiumanfu/LMIC-node_Sensor-for-Helium-Network/b982bdcfeccae29501e32730fce982dc0df1644c/images/tbeam.bmp -------------------------------------------------------------------------------- /keyfiles/lorawan-keys_example.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: lorawan-keys_example.h 4 | * 5 | * Function: Example for lorawan-keys.h required by LMIC-node. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * Important ██ DO NOT EDIT THIS EXAMPLE FILE (see instructions below) ██ 10 | * 11 | * Decription: lorawan-keys.h defines LoRaWAN keys needed by the LMIC library. 12 | * It can contain keys for both OTAA and for ABP activation. 13 | * Only the keys for the used activation type need to be specified. 14 | * 15 | * It is essential that each key is specified in the correct format. 16 | * lsb: least-significant-byte first, msb: most-significant-byte first. 17 | * 18 | * For security reasons all files in the keyfiles folder (except file 19 | * lorawan-keys_example.h) are excluded from the Git(Hub) repository. 20 | * Also excluded are all files matching the pattern *lorawan-keys.h. 21 | * This way they cannot be accidentally committed to a public repository. 22 | * 23 | * Instructions: 1. Copy this file lorawan-keys_example.h to file lorawan-keys.h 24 | * in the same folder (keyfiles). 25 | * 2. Place/edit required LoRaWAN keys in the new lorawan-keys.h file. 26 | * 27 | ******************************************************************************/ 28 | 29 | #pragma once 30 | 31 | #ifndef LORAWAN_KEYS_H_ 32 | #define LORAWAN_KEYS_H_ 33 | 34 | // Optional: If DEVICEID is defined it will be used instead of the default defined in the BSF. 35 | // #define DEVICEID "" 36 | 37 | // Keys required for OTAA activation: 38 | 39 | // End-device Identifier (u1_t[8]) in lsb format 40 | #define OTAA_DEVEUI 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 41 | 42 | // Application Identifier (u1_t[8]) in lsb format 43 | #define OTAA_APPEUI 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 44 | 45 | // Application Key (u1_t[16]) in msb format 46 | #define OTAA_APPKEY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 47 | 48 | 49 | // ----------------------------------------------------------------------------- 50 | 51 | // Optional: If ABP_DEVICEID is defined it will be used for ABP instead of the default defined in the BSF. 52 | // #define ABP_DEVICEID "" 53 | 54 | // Keys required for ABP activation: 55 | 56 | // End-device Address (u4_t) in uint32_t format. 57 | // Note: The value must start with 0x (current version of TTN Console does not provide this). 58 | #define ABP_DEVADDR 0x00000000 59 | 60 | // Network Session Key (u1_t[16]) in msb format 61 | #define ABP_NWKSKEY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 62 | 63 | // Application Session K (u1_t[16]) in msb format 64 | #define ABP_APPSKEY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 65 | 66 | 67 | #endif // LORAWAN_KEYS_H_ 68 | -------------------------------------------------------------------------------- /payload-formatters/lmic-node-uplink-formatters.js: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: lmic-node-uplink-formatters.js 4 | * 5 | * Function: LMIC-node uplink payload formatter JavaScript function(s). 6 | * 7 | * Author: Leonel Lopes Parente 8 | * 9 | * Description: These function(s) are for use with The Things Network V3. 10 | * 11 | ******************************************************************************/ 12 | 13 | function decodeUplink(input) { 14 | var data = {}; 15 | var warnings = []; 16 | 17 | if (input.fPort == 10) { 18 | data.counter = (input.bytes[0] << 8) + input.bytes[1]; 19 | } 20 | else { 21 | warnings.push("Unsupported fPort"); 22 | } 23 | return { 24 | data: data, 25 | warnings: warnings 26 | }; 27 | } -------------------------------------------------------------------------------- /platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = 13 | 14 | 15 | ttgo_t_beam_v1 16 | 17 | [common] 18 | monitor_speed = 115200 19 | build_flags = 20 | -D DO_WORK_INTERVAL_SECONDS=3600 21 | lib_deps = 22 | olikraus/U8g2 23 | lnlp/EasyLed 24 | 25 | [pico] 26 | upload_port = E: 27 | 28 | [mcci_lmic] 29 | lib_deps = 30 | mcci-catena/MCCI LoRaWAN LMIC library 31 | build_flags = 32 | -D ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS 33 | 34 | -D DISABLE_PING 35 | -D DISABLE_BEACONS 36 | 37 | 38 | -D CFG_sx1276_radio=1 39 | -D USE_ORIGINAL_AES 40 | 41 | -D CFG_us915=1 42 | 43 | [classic_lmic] 44 | lib_deps = 45 | matthijskooijman/IBM LMIC framework 46 | build_flags = 47 | 48 | -D DISABLE_PING 49 | -D DISABLE_BEACONS 50 | 51 | [env:adafruit_feather_m0_lora] 52 | platform = atmelsam 53 | board = adafruit_feather_m0 54 | framework = arduino 55 | monitor_speed = ${common.monitor_speed} 56 | lib_deps = 57 | ${common.lib_deps} 58 | ${mcci_lmic.lib_deps} 59 | sabas1080/CayenneLPP@^1.1.0 60 | markruys/DHT@^1.0.0 61 | milesburton/DallasTemperature@^3.9.1 62 | paulstoffregen/OneWire@^2.3.5 63 | adafruit/DHT sensor library@^1.4.2 64 | adafruit/Adafruit Unified Sensor@^1.1.4 65 | matmunk/DS18B20@^1.0.0 66 | build_flags = 67 | ${common.build_flags} 68 | ${mcci_lmic.build_flags} 69 | -D BSFILE=\"boards/bsf_adafruit_feather_m0_lora.h\" 70 | -D MONITOR_SPEED=${common.monitor_speed} 71 | -D _GNU_SOURCE 72 | -D LMIC_PRINTF_TO=Serial 73 | -D USE_SERIAL 74 | -D USE_LED 75 | 76 | [env:disco_l072cz_lrwan1] 77 | platform = ststm32 78 | board = disco_l072cz_lrwan1 79 | framework = arduino 80 | upload_protocol = stlink 81 | monitor_speed = ${common.monitor_speed} 82 | lib_deps = 83 | ${common.lib_deps} 84 | ${mcci_lmic.lib_deps} 85 | sabas1080/CayenneLPP@^1.1.0 86 | markruys/DHT@^1.0.0 87 | milesburton/DallasTemperature@^3.9.1 88 | paulstoffregen/OneWire@^2.3.5 89 | adafruit/DHT sensor library@^1.4.2 90 | adafruit/Adafruit Unified Sensor@^1.1.4 91 | matmunk/DS18B20@^1.0.0 92 | build_flags = 93 | ${common.build_flags} 94 | ${mcci_lmic.build_flags} 95 | -D BSFILE=\"boards/bsf_disco_l072cz_lrwan1.h\" 96 | -D MONITOR_SPEED=${common.monitor_speed} 97 | -D _GNU_SOURCE 98 | -D LMIC_PRINTF_TO=Serial 99 | -D USE_SERIAL 100 | -D USE_LED 101 | 102 | [env:heltec_wifi_lora_32_v2] 103 | platform = espressif32 104 | board = heltec_wifi_lora_32_V2 105 | framework = arduino 106 | upload_speed = 921600 107 | monitor_speed = ${common.monitor_speed} 108 | lib_deps = 109 | ${common.lib_deps} 110 | ${mcci_lmic.lib_deps} 111 | sabas1080/CayenneLPP@^1.1.0 112 | markruys/DHT@^1.0.0 113 | milesburton/DallasTemperature@^3.9.1 114 | paulstoffregen/OneWire@^2.3.5 115 | adafruit/DHT sensor library@^1.4.2 116 | adafruit/Adafruit Unified Sensor@^1.1.4 117 | matmunk/DS18B20@^1.0.0 118 | build_flags = 119 | ${common.build_flags} 120 | ${mcci_lmic.build_flags} 121 | -D BSFILE=\"boards/bsf_heltec_wifi_lora_32_v2.h\" 122 | -D MONITOR_SPEED=${common.monitor_speed} 123 | -D LMIC_PRINTF_TO=Serial 124 | -D USE_SERIAL 125 | -D USE_LED 126 | -D USE_DISPLAY 127 | 128 | [env:heltec_wifi_lora_32] 129 | platform = espressif32 130 | board = heltec_wifi_lora_32 131 | framework = arduino 132 | upload_speed = 921600 133 | monitor_speed = ${common.monitor_speed} 134 | lib_deps = 135 | ${common.lib_deps} 136 | ${mcci_lmic.lib_deps} 137 | sabas1080/CayenneLPP@^1.1.0 138 | markruys/DHT@^1.0.0 139 | milesburton/DallasTemperature@^3.9.1 140 | paulstoffregen/OneWire@^2.3.5 141 | adafruit/DHT sensor library@^1.4.2 142 | adafruit/Adafruit Unified Sensor@^1.1.4 143 | matmunk/DS18B20@^1.0.0 144 | build_flags = 145 | ${common.build_flags} 146 | ${mcci_lmic.build_flags} 147 | -D BSFILE=\"boards/bsf_heltec_wifi_lora_32.h\" 148 | -D MONITOR_SPEED=${common.monitor_speed} 149 | -D LMIC_PRINTF_TO=Serial 150 | -D USE_SERIAL 151 | -D USE_LED 152 | -D USE_DISPLAY 153 | 154 | [env:heltec_wireless_stick_lite] 155 | platform = espressif32 156 | board = heltec_wireless_stick_lite 157 | framework = arduino 158 | upload_speed = 921600 159 | monitor_speed = ${common.monitor_speed} 160 | lib_deps = 161 | ${common.lib_deps} 162 | ${mcci_lmic.lib_deps} 163 | sabas1080/CayenneLPP@^1.1.0 164 | markruys/DHT@^1.0.0 165 | milesburton/DallasTemperature@^3.9.1 166 | paulstoffregen/OneWire@^2.3.5 167 | adafruit/DHT sensor library@^1.4.2 168 | adafruit/Adafruit Unified Sensor@^1.1.4 169 | matmunk/DS18B20@^1.0.0 170 | build_flags = 171 | ${common.build_flags} 172 | ${mcci_lmic.build_flags} 173 | -D BSFILE=\"boards/bsf_heltec_wireless_stick_lite.h\" 174 | -D MONITOR_SPEED=${common.monitor_speed} 175 | -D LMIC_PRINTF_TO=Serial 176 | -D USE_SERIAL 177 | -D USE_LED 178 | 179 | [env:heltec_wireless_stick] 180 | platform = espressif32 181 | board = heltec_wireless_stick 182 | framework = arduino 183 | upload_speed = 921600 184 | monitor_speed = ${common.monitor_speed} 185 | lib_deps = 186 | ${common.lib_deps} 187 | ${mcci_lmic.lib_deps} 188 | sabas1080/CayenneLPP@^1.1.0 189 | markruys/DHT@^1.0.0 190 | milesburton/DallasTemperature@^3.9.1 191 | paulstoffregen/OneWire@^2.3.5 192 | adafruit/DHT sensor library@^1.4.2 193 | adafruit/Adafruit Unified Sensor@^1.1.4 194 | matmunk/DS18B20@^1.0.0 195 | build_flags = 196 | ${common.build_flags} 197 | ${mcci_lmic.build_flags} 198 | -D BSFILE=\"boards/bsf_heltec_wireless_stick.h\" 199 | -D MONITOR_SPEED=${common.monitor_speed} 200 | -D LMIC_PRINTF_TO=Serial 201 | -D USE_SERIAL 202 | -D USE_LED 203 | 204 | [env:lopy4] 205 | platform = espressif32 206 | board = lopy4 207 | framework = arduino 208 | upload_speed = 921600 209 | monitor_speed = ${common.monitor_speed} 210 | lib_deps = 211 | ${common.lib_deps} 212 | ${mcci_lmic.lib_deps} 213 | sabas1080/CayenneLPP@^1.1.0 214 | markruys/DHT@^1.0.0 215 | milesburton/DallasTemperature@^3.9.1 216 | paulstoffregen/OneWire@^2.3.5 217 | adafruit/DHT sensor library@^1.4.2 218 | adafruit/Adafruit Unified Sensor@^1.1.4 219 | matmunk/DS18B20@^1.0.0 220 | build_flags = 221 | ${common.build_flags} 222 | ${mcci_lmic.build_flags} 223 | -D BSFILE=\"boards/bsf_lopy4.h\" 224 | -D MONITOR_SPEED=${common.monitor_speed} 225 | -D LMIC_PRINTF_TO=Serial 226 | -D USE_SERIAL 227 | 228 | [env:lora32u4II] 229 | platform = atmelavr 230 | board = lora32u4II 231 | framework = arduino 232 | monitor_speed = ${common.monitor_speed} 233 | lib_deps = 234 | ${common.lib_deps} 235 | ${classic_lmic.lib_deps} 236 | sabas1080/CayenneLPP@^1.1.0 237 | markruys/DHT@^1.0.0 238 | milesburton/DallasTemperature@^3.9.1 239 | paulstoffregen/OneWire@^2.3.5 240 | adafruit/DHT sensor library@^1.4.2 241 | adafruit/Adafruit Unified Sensor@^1.1.4 242 | matmunk/DS18B20@^1.0.0 243 | build_flags = 244 | ${common.build_flags} 245 | ${classic_lmic.build_flags} 246 | -D BSFILE=\"boards/bsf_lora32u4II.h\" 247 | -D MONITOR_SPEED=${common.monitor_speed} 248 | -D USE_SERIAL 249 | -D USE_LED 250 | 251 | [env:ttgo_lora32_v1] 252 | platform = espressif32 253 | board = ttgo-lora32-v1 254 | framework = arduino 255 | upload_speed = 921600 256 | monitor_speed = ${common.monitor_speed} 257 | lib_deps = 258 | ${common.lib_deps} 259 | ${mcci_lmic.lib_deps} 260 | sabas1080/CayenneLPP@^1.1.0 261 | markruys/DHT@^1.0.0 262 | milesburton/DallasTemperature@^3.9.1 263 | paulstoffregen/OneWire@^2.3.5 264 | adafruit/DHT sensor library@^1.4.2 265 | adafruit/Adafruit Unified Sensor@^1.1.4 266 | matmunk/DS18B20@^1.0.0 267 | build_flags = 268 | ${common.build_flags} 269 | ${mcci_lmic.build_flags} 270 | -D BSFILE=\"boards/bsf_ttgo_lora32_v1.h\" 271 | -D MONITOR_SPEED=${common.monitor_speed} 272 | -D LMIC_PRINTF_TO=Serial 273 | -D USE_SERIAL 274 | -D USE_DISPLAY 275 | 276 | [env:ttgo_lora32_v2] 277 | platform = espressif32 278 | board = ttgo-lora32-v2 279 | framework = arduino 280 | upload_speed = 921600 281 | monitor_speed = ${common.monitor_speed} 282 | lib_deps = 283 | ${common.lib_deps} 284 | ${mcci_lmic.lib_deps} 285 | sabas1080/CayenneLPP@^1.1.0 286 | markruys/DHT@^1.0.0 287 | milesburton/DallasTemperature@^3.9.1 288 | paulstoffregen/OneWire@^2.3.5 289 | adafruit/DHT sensor library@^1.4.2 290 | adafruit/Adafruit Unified Sensor@^1.1.4 291 | matmunk/DS18B20@^1.0.0 292 | build_flags = 293 | ${common.build_flags} 294 | ${mcci_lmic.build_flags} 295 | -D BSFILE=\"boards/bsf_ttgo_lora32_v2.h\" 296 | -D MONITOR_SPEED=${common.monitor_speed} 297 | -D LMIC_PRINTF_TO=Serial 298 | -D USE_SERIAL 299 | -D USE_DISPLAY 300 | 301 | [env:ttgo_lora32_v21] 302 | platform = espressif32 303 | board = ttgo-lora32-v21 304 | framework = arduino 305 | upload_speed = 921600 306 | monitor_speed = ${common.monitor_speed} 307 | lib_deps = 308 | ${common.lib_deps} 309 | ${mcci_lmic.lib_deps} 310 | sabas1080/CayenneLPP@^1.1.0 311 | markruys/DHT@^1.0.0 312 | milesburton/DallasTemperature@^3.9.1 313 | paulstoffregen/OneWire@^2.3.5 314 | adafruit/DHT sensor library@^1.4.2 315 | adafruit/Adafruit Unified Sensor@^1.1.4 316 | matmunk/DS18B20@^1.0.0 317 | build_flags = 318 | ${common.build_flags} 319 | ${mcci_lmic.build_flags} 320 | -D BSFILE=\"boards/bsf_ttgo_lora32_v21.h\" 321 | -D MONITOR_SPEED=${common.monitor_speed} 322 | -D LMIC_PRINTF_TO=Serial 323 | -D USE_SERIAL 324 | -D USE_LED 325 | -D USE_DISPLAY 326 | 327 | [env:ttgo_t_beam] 328 | platform = espressif32 329 | board = ttgo-t-beam 330 | framework = arduino 331 | upload_speed = 921600 332 | monitor_speed = ${common.monitor_speed} 333 | lib_deps = 334 | ${common.lib_deps} 335 | ${mcci_lmic.lib_deps} 336 | sabas1080/CayenneLPP@^1.1.0 337 | markruys/DHT@^1.0.0 338 | milesburton/DallasTemperature@^3.9.1 339 | paulstoffregen/OneWire@^2.3.5 340 | adafruit/DHT sensor library@^1.4.2 341 | adafruit/Adafruit Unified Sensor@^1.1.4 342 | matmunk/DS18B20@^1.0.0 343 | build_flags = 344 | ${common.build_flags} 345 | ${mcci_lmic.build_flags} 346 | -D BSFILE=\"boards/bsf_ttgo_t_beam.h\" 347 | -D MONITOR_SPEED=${common.monitor_speed} 348 | -D LMIC_PRINTF_TO=Serial 349 | -D USE_SERIAL 350 | -D USE_LED 351 | 352 | [env:ttgo_t_beam_v1] 353 | platform = espressif32 354 | board = ttgo-t-beam 355 | framework = arduino 356 | upload_speed = 921600 357 | monitor_speed = ${common.monitor_speed} 358 | lib_deps = 359 | ${common.lib_deps} 360 | ${mcci_lmic.lib_deps} 361 | lewisxhe/AXP202X_Library 362 | sabas1080/CayenneLPP@^1.1.0 363 | markruys/DHT@^1.0.0 364 | milesburton/DallasTemperature@^3.9.1 365 | paulstoffregen/OneWire@^2.3.5 366 | adafruit/DHT sensor library@^1.4.2 367 | adafruit/Adafruit Unified Sensor@^1.1.4 368 | matmunk/DS18B20@^1.0.0 369 | build_flags = 370 | ${common.build_flags} 371 | ${mcci_lmic.build_flags} 372 | -D BSFILE=\"boards/bsf_ttgo_t_beam_v1.h\" 373 | -D MONITOR_SPEED=${common.monitor_speed} 374 | -D LMIC_PRINTF_TO=Serial 375 | -D USE_SERIAL 376 | -D USE_DISPLAY 377 | 378 | [env:adafruit_qt_py_m0] 379 | platform = atmelsam 380 | board = adafruit_qt_py_m0 381 | framework = arduino 382 | monitor_speed = ${common.monitor_speed} 383 | lib_deps = 384 | ${common.lib_deps} 385 | ${mcci_lmic.lib_deps} 386 | sabas1080/CayenneLPP@^1.1.0 387 | markruys/DHT@^1.0.0 388 | milesburton/DallasTemperature@^3.9.1 389 | paulstoffregen/OneWire@^2.3.5 390 | adafruit/DHT sensor library@^1.4.2 391 | adafruit/Adafruit Unified Sensor@^1.1.4 392 | matmunk/DS18B20@^1.0.0 393 | build_flags = 394 | ${common.build_flags} 395 | ${mcci_lmic.build_flags} 396 | -D BSFILE=\"boards/bsf_adafruit_qt_py_m0.h\" 397 | -D MONITOR_SPEED=${common.monitor_speed} 398 | -D _GNU_SOURCE 399 | -D LMIC_PRINTF_TO=Serial 400 | -D USE_SERIAL 401 | 402 | [env:blackpill_f103c8_128k] 403 | platform = ststm32 404 | board = blackpill_f103c8_128 405 | framework = arduino 406 | upload_protocol = stlink 407 | monitor_speed = ${common.monitor_speed} 408 | lib_deps = 409 | ${common.lib_deps} 410 | ${mcci_lmic.lib_deps} 411 | sabas1080/CayenneLPP@^1.1.0 412 | markruys/DHT@^1.0.0 413 | milesburton/DallasTemperature@^3.9.1 414 | paulstoffregen/OneWire@^2.3.5 415 | adafruit/DHT sensor library@^1.4.2 416 | adafruit/Adafruit Unified Sensor@^1.1.4 417 | matmunk/DS18B20@^1.0.0 418 | build_flags = 419 | ${common.build_flags} 420 | ${mcci_lmic.build_flags} 421 | -D BSFILE=\"boards/bsf_blackpill_f103c8.h\" 422 | -D MONITOR_SPEED=${common.monitor_speed} 423 | -D _GNU_SOURCE 424 | -D LMIC_PRINTF_TO=Serial 425 | -D USE_SERIAL 426 | -D USE_LED 427 | 428 | [env:blackpill_f103c8] 429 | platform = ststm32 430 | board = blackpill_f103c8 431 | framework = arduino 432 | upload_protocol = stlink 433 | monitor_speed = ${common.monitor_speed} 434 | lib_deps = 435 | ${common.lib_deps} 436 | ${mcci_lmic.lib_deps} 437 | sabas1080/CayenneLPP@^1.1.0 438 | markruys/DHT@^1.0.0 439 | milesburton/DallasTemperature@^3.9.1 440 | paulstoffregen/OneWire@^2.3.5 441 | adafruit/DHT sensor library@^1.4.2 442 | adafruit/Adafruit Unified Sensor@^1.1.4 443 | matmunk/DS18B20@^1.0.0 444 | build_flags = 445 | ${common.build_flags} 446 | ${mcci_lmic.build_flags} 447 | -D BSFILE=\"boards/bsf_blackpill_f103c8.h\" 448 | -D MONITOR_SPEED=${common.monitor_speed} 449 | -D _GNU_SOURCE 450 | -D LMIC_PRINTF_TO=Serial 451 | -D USE_SERIAL 452 | -D USE_LED 453 | 454 | [env:bluepill_f103c8_128k] 455 | platform = ststm32 456 | board = bluepill_f103c8_128k 457 | framework = arduino 458 | upload_protocol = stlink 459 | monitor_speed = ${common.monitor_speed} 460 | lib_deps = 461 | ${common.lib_deps} 462 | ${mcci_lmic.lib_deps} 463 | sabas1080/CayenneLPP@^1.1.0 464 | markruys/DHT@^1.0.0 465 | milesburton/DallasTemperature@^3.9.1 466 | paulstoffregen/OneWire@^2.3.5 467 | adafruit/DHT sensor library@^1.4.2 468 | adafruit/Adafruit Unified Sensor@^1.1.4 469 | matmunk/DS18B20@^1.0.0 470 | build_flags = 471 | ${common.build_flags} 472 | ${mcci_lmic.build_flags} 473 | -D BSFILE=\"boards/bsf_bluepill_f103c8.h\" 474 | -D MONITOR_SPEED=${common.monitor_speed} 475 | -D _GNU_SOURCE 476 | -D LMIC_PRINTF_TO=Serial 477 | -D USE_SERIAL 478 | -D USE_LED 479 | 480 | [env:bluepill_f103c8] 481 | platform = ststm32 482 | board = bluepill_f103c8 483 | framework = arduino 484 | upload_protocol = stlink 485 | monitor_speed = ${common.monitor_speed} 486 | lib_deps = 487 | ${common.lib_deps} 488 | ${mcci_lmic.lib_deps} 489 | sabas1080/CayenneLPP@^1.1.0 490 | markruys/DHT@^1.0.0 491 | milesburton/DallasTemperature@^3.9.1 492 | paulstoffregen/OneWire@^2.3.5 493 | adafruit/DHT sensor library@^1.4.2 494 | adafruit/Adafruit Unified Sensor@^1.1.4 495 | matmunk/DS18B20@^1.0.0 496 | build_flags = 497 | ${common.build_flags} 498 | ${mcci_lmic.build_flags} 499 | -D BSFILE=\"boards/bsf_bluepill_f103c8.h\" 500 | -D MONITOR_SPEED=${common.monitor_speed} 501 | -D _GNU_SOURCE 502 | -D LMIC_PRINTF_TO=Serial 503 | -D USE_SERIAL 504 | -D USE_LED 505 | 506 | [env:lolin_d32_pro] 507 | platform = espressif32 508 | board = lolin_d32_pro 509 | framework = arduino 510 | upload_speed = 921600 511 | monitor_speed = ${common.monitor_speed} 512 | lib_deps = 513 | ${common.lib_deps} 514 | ${mcci_lmic.lib_deps} 515 | sabas1080/CayenneLPP@^1.1.0 516 | markruys/DHT@^1.0.0 517 | milesburton/DallasTemperature@^3.9.1 518 | paulstoffregen/OneWire@^2.3.5 519 | adafruit/DHT sensor library@^1.4.2 520 | adafruit/Adafruit Unified Sensor@^1.1.4 521 | matmunk/DS18B20@^1.0.0 522 | build_flags = 523 | ${common.build_flags} 524 | ${mcci_lmic.build_flags} 525 | -D BSFILE=\"boards/bsf_lolin_d32_pro.h\" 526 | -D MONITOR_SPEED=${common.monitor_speed} 527 | -D LMIC_PRINTF_TO=Serial 528 | -D USE_SERIAL 529 | -D USE_LED 530 | 531 | [env:lolin_d32] 532 | platform = espressif32 533 | board = lolin_d32 534 | framework = arduino 535 | upload_speed = 921600 536 | monitor_speed = ${common.monitor_speed} 537 | lib_deps = 538 | ${common.lib_deps} 539 | ${mcci_lmic.lib_deps} 540 | sabas1080/CayenneLPP@^1.1.0 541 | markruys/DHT@^1.0.0 542 | milesburton/DallasTemperature@^3.9.1 543 | paulstoffregen/OneWire@^2.3.5 544 | adafruit/DHT sensor library@^1.4.2 545 | adafruit/Adafruit Unified Sensor@^1.1.4 546 | matmunk/DS18B20@^1.0.0 547 | build_flags = 548 | ${common.build_flags} 549 | ${mcci_lmic.build_flags} 550 | -D BSFILE=\"boards/bsf_lolin_d32.h\" 551 | -D MONITOR_SPEED=${common.monitor_speed} 552 | -D LMIC_PRINTF_TO=Serial 553 | -D USE_SERIAL 554 | -D USE_LED 555 | 556 | [env:lolin32] 557 | platform = espressif32 558 | board = lolin32 559 | framework = arduino 560 | upload_speed = 921600 561 | monitor_speed = ${common.monitor_speed} 562 | lib_deps = 563 | ${common.lib_deps} 564 | ${mcci_lmic.lib_deps} 565 | sabas1080/CayenneLPP@^1.1.0 566 | markruys/DHT@^1.0.0 567 | milesburton/DallasTemperature@^3.9.1 568 | paulstoffregen/OneWire@^2.3.5 569 | adafruit/DHT sensor library@^1.4.2 570 | adafruit/Adafruit Unified Sensor@^1.1.4 571 | matmunk/DS18B20@^1.0.0 572 | build_flags = 573 | ${common.build_flags} 574 | ${mcci_lmic.build_flags} 575 | -D BSFILE=\"boards/bsf_lolin32.h\" 576 | -D MONITOR_SPEED=${common.monitor_speed} 577 | -D LMIC_PRINTF_TO=Serial 578 | -D USE_SERIAL 579 | -D USE_LED 580 | 581 | [env:nodemcu_32s] 582 | platform = espressif32 583 | board = nodemcu-32s 584 | framework = arduino 585 | upload_speed = 921600 586 | monitor_speed = ${common.monitor_speed} 587 | lib_deps = 588 | ${common.lib_deps} 589 | ${mcci_lmic.lib_deps} 590 | sabas1080/CayenneLPP@^1.1.0 591 | markruys/DHT@^1.0.0 592 | milesburton/DallasTemperature@^3.9.1 593 | paulstoffregen/OneWire@^2.3.5 594 | adafruit/DHT sensor library@^1.4.2 595 | adafruit/Adafruit Unified Sensor@^1.1.4 596 | matmunk/DS18B20@^1.0.0 597 | build_flags = 598 | ${common.build_flags} 599 | ${mcci_lmic.build_flags} 600 | -D BSFILE=\"boards/bsf_nodemcu_32s.h\" 601 | -D MONITOR_SPEED=${common.monitor_speed} 602 | -D LMIC_PRINTF_TO=Serial 603 | -D USE_SERIAL 604 | -D USE_LED 605 | 606 | [env:nodemcuv2] 607 | platform = espressif8266 608 | board = nodemcuv2 609 | framework = arduino 610 | upload_speed = 921600 611 | monitor_speed = 74880 612 | lib_deps = 613 | ${common.lib_deps} 614 | ${mcci_lmic.lib_deps} 615 | sabas1080/CayenneLPP@^1.1.0 616 | markruys/DHT@^1.0.0 617 | milesburton/DallasTemperature@^3.9.1 618 | paulstoffregen/OneWire@^2.3.5 619 | adafruit/DHT sensor library@^1.4.2 620 | adafruit/Adafruit Unified Sensor@^1.1.4 621 | matmunk/DS18B20@^1.0.0 622 | build_flags = 623 | ${common.build_flags} 624 | ${mcci_lmic.build_flags} 625 | -D BSFILE=\"boards/bsf_nodemcuv2.h\" 626 | -D MONITOR_SPEED=${env:nodemcuv2.monitor_speed} 627 | -D _GNU_SOURCE 628 | -D LMIC_PRINTF_TO=Serial 629 | -D USE_SERIAL 630 | -D USE_LED 631 | 632 | [env:pico] 633 | platform = raspberrypi 634 | framework = arduino 635 | board = pico 636 | upload_protocol = picotool 637 | upload_port = ${pico.upload_port} 638 | monitor_speed = ${common.monitor_speed} 639 | lib_deps = 640 | ${common.lib_deps} 641 | ${mcci_lmic.lib_deps} 642 | sabas1080/CayenneLPP@^1.1.0 643 | markruys/DHT@^1.0.0 644 | milesburton/DallasTemperature@^3.9.1 645 | paulstoffregen/OneWire@^2.3.5 646 | adafruit/DHT sensor library@^1.4.2 647 | adafruit/Adafruit Unified Sensor@^1.1.4 648 | matmunk/DS18B20@^1.0.0 649 | build_flags = 650 | ${common.build_flags} 651 | ${mcci_lmic.build_flags} 652 | -D BSFILE=\"boards/bsf_pico.h\" 653 | -D MONITOR_SPEED=${common.monitor_speed} 654 | -D _GNU_SOURCE 655 | -D LMIC_PRINTF_TO=SerialUSB 656 | -D USE_SERIAL 657 | -D USE_LED 658 | 659 | [env:pro8mhzatmega328] 660 | platform = atmelavr 661 | board = pro8MHzatmega328 662 | framework = arduino 663 | monitor_speed = ${common.monitor_speed} 664 | lib_deps = 665 | ${common.lib_deps} 666 | ${classic_lmic.lib_deps} 667 | sabas1080/CayenneLPP@^1.1.0 668 | markruys/DHT@^1.0.0 669 | milesburton/DallasTemperature@^3.9.1 670 | paulstoffregen/OneWire@^2.3.5 671 | adafruit/DHT sensor library@^1.4.2 672 | adafruit/Adafruit Unified Sensor@^1.1.4 673 | matmunk/DS18B20@^1.0.0 674 | build_flags = 675 | ${common.build_flags} 676 | ${classic_lmic.build_flags} 677 | -D BSFILE=\"boards/bsf_pro8mhzatmega328.h\" 678 | -D MONITOR_SPEED=${common.monitor_speed} 679 | -D USE_SERIAL 680 | 681 | [env:samd21_m0_mini] 682 | platform = atmelsam 683 | board = zeroUSB 684 | framework = arduino 685 | monitor_speed = ${common.monitor_speed} 686 | lib_deps = 687 | ${common.lib_deps} 688 | ${mcci_lmic.lib_deps} 689 | sabas1080/CayenneLPP@^1.1.0 690 | markruys/DHT@^1.0.0 691 | milesburton/DallasTemperature@^3.9.1 692 | paulstoffregen/OneWire@^2.3.5 693 | adafruit/DHT sensor library@^1.4.2 694 | adafruit/Adafruit Unified Sensor@^1.1.4 695 | matmunk/DS18B20@^1.0.0 696 | build_flags = 697 | ${common.build_flags} 698 | ${mcci_lmic.build_flags} 699 | -D BSFILE=\"boards/bsf_samd21_m0_mini.h\" 700 | -D MONITOR_SPEED=${common.monitor_speed} 701 | -D _GNU_SOURCE 702 | -D LMIC_PRINTF_TO=SerialUSB 703 | -D USE_SERIAL 704 | 705 | [env:teensylc] 706 | platform = teensy 707 | board = teensylc 708 | framework = arduino 709 | monitor_speed = ${common.monitor_speed} 710 | lib_deps = 711 | ${common.lib_deps} 712 | ${mcci_lmic.lib_deps} 713 | sabas1080/CayenneLPP@^1.1.0 714 | markruys/DHT@^1.0.0 715 | milesburton/DallasTemperature@^3.9.1 716 | paulstoffregen/OneWire@^2.3.5 717 | adafruit/DHT sensor library@^1.4.2 718 | adafruit/Adafruit Unified Sensor@^1.1.4 719 | matmunk/DS18B20@^1.0.0 720 | build_flags = 721 | ${common.build_flags} 722 | ${mcci_lmic.build_flags} 723 | -D BSFILE=\"boards/bsf_teensylc.h\" 724 | -D MONITOR_SPEED=${common.monitor_speed} 725 | -D _GNU_SOURCE 726 | -D LMIC_PRINTF_TO=Serial 727 | -D USE_SERIAL 728 | -D USE_LED 729 | -------------------------------------------------------------------------------- /src/LMIC-node.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: LMIC-node.cpp 4 | * 5 | * Function: LMIC-node main application file. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * Copyright (c) 2018 Terry Moore, MCCI 9 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 10 | * 11 | * Permission is hereby granted, free of charge, to anyone 12 | * obtaining a copy of this document and accompanying files to do, 13 | * whatever they want with them without any restriction, including, 14 | * but not limited to, copying, modification and redistribution. 15 | * The above copyright notice and this permission notice shall be 16 | * included in all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY. 19 | * 20 | * License: MIT License. See accompanying LICENSE file. 21 | * 22 | * Author: Leonel Lopes Parente 23 | * 24 | * Description: To get LMIC-node up and running no changes need to be made 25 | * to any source code. Only configuration is required 26 | * in platform-io.ini and lorawan-keys.h. 27 | * 28 | * If you want to modify the code e.g. to add your own sensors, 29 | * that can be done in the two area's that start with 30 | * USER CODE BEGIN and end with USER CODE END. There's no need 31 | * to change code in other locations (unless you have a reason). 32 | * See README.md for documentation and how to use LMIC-node. 33 | * 34 | * LMIC-node uses the concepts from the original ttn-otaa.ino 35 | * and ttn-abp.ino examples provided with the LMIC libraries. 36 | * LMIC-node combines both OTAA and ABP support in a single example, 37 | * supports multiple LMIC libraries, contains several improvements 38 | * and enhancements like display support, support for downlinks, 39 | * separates LoRaWAN keys from source code into a separate keyfile, 40 | * provides formatted output to serial port and display 41 | * and supports many popular development boards out of the box. 42 | * To get a working node up and running only requires some configuration. 43 | * No programming or customization of source code required. 44 | * 45 | * Dependencies: External libraries: 46 | * MCCI LoRaWAN LMIC library https://github.com/mcci-catena/arduino-lmic 47 | * IBM LMIC framework https://github.com/matthijskooijman/arduino-lmic 48 | * U8g2 https://github.com/olikraus/u8g2 49 | * EasyLed https://github.com/lnlp/EasyLed 50 | * 51 | ******************************************************************************/ 52 | 53 | #include "LMIC-node.h" 54 | 55 | 56 | // █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▄ █▀▀ █▀▀ ▀█▀ █▀█ 57 | // █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▄ █▀▀ █ █ █ █ █ 58 | // ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ 59 | 60 | // Include libraries 61 | #include 62 | #include 63 | #include 64 | 65 | // Pin definitions 66 | #define DHTPIN 4 67 | #define DHTTYPE DHT22 68 | #define FLOWPIN 2 69 | #define TANKPIN 13 70 | 71 | // Variable definitions 72 | volatile int flowrate; 73 | 74 | DS18B20 ds(0); 75 | 76 | DHT dht(DHTPIN, DHTTYPE); 77 | 78 | CayenneLPP lpp(21); 79 | 80 | // █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▀ █▀█ █▀▄ 81 | // █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▀ █ █ █ █ 82 | // ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀ 83 | 84 | 85 | //uint8_t payloadBuffer[payloadBufferLength]; 86 | static osjob_t doWorkJob; 87 | uint32_t doWorkIntervalSeconds = DO_WORK_INTERVAL_SECONDS; // Change value in platformio.ini 88 | 89 | // Note: LoRa module pin mappings are defined in the Board Support Files. 90 | 91 | // Set LoRaWAN keys defined in lorawan-keys.h. 92 | #ifdef OTAA_ACTIVATION 93 | static const u1_t PROGMEM DEVEUI[8] = { OTAA_DEVEUI } ; 94 | static const u1_t PROGMEM APPEUI[8] = { OTAA_APPEUI }; 95 | static const u1_t PROGMEM APPKEY[16] = { OTAA_APPKEY }; 96 | // Below callbacks are used by LMIC for reading above values. 97 | void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8); } 98 | void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8); } 99 | void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16); } 100 | #else 101 | // ABP activation 102 | static const u4_t DEVADDR = ABP_DEVADDR ; 103 | static const PROGMEM u1_t NWKSKEY[16] = { ABP_NWKSKEY }; 104 | static const u1_t PROGMEM APPSKEY[16] = { ABP_APPSKEY }; 105 | // Below callbacks are not used be they must be defined. 106 | void os_getDevEui (u1_t* buf) { } 107 | void os_getArtEui (u1_t* buf) { } 108 | void os_getDevKey (u1_t* buf) { } 109 | #endif 110 | 111 | 112 | int16_t getSnrTenfold() 113 | { 114 | // Returns ten times the SNR (dB) value of the last received packet. 115 | // Ten times to prevent the use of float but keep 1 decimal digit accuracy. 116 | // Calculation per SX1276 datasheet rev.7 §6.4, SX1276 datasheet rev.4 §6.4. 117 | // LMIC.snr contains value of PacketSnr, which is 4 times the actual SNR value. 118 | return (LMIC.snr * 10) / 4; 119 | } 120 | 121 | 122 | int16_t getRssi(int8_t snr) 123 | { 124 | // Returns correct RSSI (dBm) value of the last received packet. 125 | // Calculation per SX1276 datasheet rev.7 §5.5.5, SX1272 datasheet rev.4 §5.5.5. 126 | 127 | #define RSSI_OFFSET 64 128 | #define SX1276_FREQ_LF_MAX 525000000 // per datasheet 6.3 129 | #define SX1272_RSSI_ADJUST -139 130 | #define SX1276_RSSI_ADJUST_LF -164 131 | #define SX1276_RSSI_ADJUST_HF -157 132 | 133 | int16_t rssi; 134 | 135 | #ifdef MCCI_LMIC 136 | 137 | rssi = LMIC.rssi - RSSI_OFFSET; 138 | 139 | #else 140 | int16_t rssiAdjust; 141 | #ifdef CFG_sx1276_radio 142 | if (LMIC.freq > SX1276_FREQ_LF_MAX) 143 | { 144 | rssiAdjust = SX1276_RSSI_ADJUST_HF; 145 | } 146 | else 147 | { 148 | rssiAdjust = SX1276_RSSI_ADJUST_LF; 149 | } 150 | #else 151 | // CFG_sx1272_radio 152 | rssiAdjust = SX1272_RSSI_ADJUST; 153 | #endif 154 | 155 | // Revert modification (applied in lmic/radio.c) to get PacketRssi. 156 | int16_t packetRssi = LMIC.rssi + 125 - RSSI_OFFSET; 157 | if (snr < 0) 158 | { 159 | rssi = rssiAdjust + packetRssi + snr; 160 | } 161 | else 162 | { 163 | rssi = rssiAdjust + (16 * packetRssi) / 15; 164 | } 165 | #endif 166 | 167 | return rssi; 168 | } 169 | 170 | 171 | void printEvent(ostime_t timestamp, 172 | const char * const message, 173 | PrintTarget target = PrintTarget::All, 174 | bool clearDisplayStatusRow = true, 175 | bool eventLabel = false) 176 | { 177 | #ifdef USE_DISPLAY 178 | if (target == PrintTarget::All || target == PrintTarget::Display) 179 | { 180 | display.clearLine(TIME_ROW); 181 | display.setCursor(COL_0, TIME_ROW); 182 | display.print(F("Time:")); 183 | display.print(timestamp); 184 | display.clearLine(EVENT_ROW); 185 | if (clearDisplayStatusRow) 186 | { 187 | display.clearLine(STATUS_ROW); 188 | } 189 | display.setCursor(COL_0, EVENT_ROW); 190 | display.print(message); 191 | } 192 | #endif 193 | 194 | #ifdef USE_SERIAL 195 | // Create padded/indented output without using printf(). 196 | // printf() is not default supported/enabled in each Arduino core. 197 | // Not using printf() will save memory for memory constrainted devices. 198 | String timeString(timestamp); 199 | uint8_t len = timeString.length(); 200 | uint8_t zerosCount = TIMESTAMP_WIDTH > len ? TIMESTAMP_WIDTH - len : 0; 201 | 202 | if (target == PrintTarget::All || target == PrintTarget::Serial) 203 | { 204 | printChars(serial, '0', zerosCount); 205 | serial.print(timeString); 206 | serial.print(": "); 207 | if (eventLabel) 208 | { 209 | serial.print(F("Event: ")); 210 | } 211 | serial.println(message); 212 | } 213 | #endif 214 | } 215 | 216 | void printEvent(ostime_t timestamp, 217 | ev_t ev, 218 | PrintTarget target = PrintTarget::All, 219 | bool clearDisplayStatusRow = true) 220 | { 221 | #if defined(USE_DISPLAY) || defined(USE_SERIAL) 222 | printEvent(timestamp, lmicEventNames[ev], target, clearDisplayStatusRow, true); 223 | #endif 224 | } 225 | 226 | 227 | void printFrameCounters(PrintTarget target = PrintTarget::All) 228 | { 229 | #ifdef USE_DISPLAY 230 | if (target == PrintTarget::Display || target == PrintTarget::All) 231 | { 232 | display.clearLine(FRMCNTRS_ROW); 233 | display.setCursor(COL_0, FRMCNTRS_ROW); 234 | display.print(F("Up:")); 235 | display.print(LMIC.seqnoUp); 236 | display.print(F(" Dn:")); 237 | display.print(LMIC.seqnoDn); 238 | } 239 | #endif 240 | 241 | #ifdef USE_SERIAL 242 | if (target == PrintTarget::Serial || target == PrintTarget::All) 243 | { 244 | printSpaces(serial, MESSAGE_INDENT); 245 | serial.print(F("Up: ")); 246 | serial.print(LMIC.seqnoUp); 247 | serial.print(F(", Down: ")); 248 | serial.println(LMIC.seqnoDn); 249 | } 250 | #endif 251 | } 252 | 253 | 254 | void printSessionKeys() 255 | { 256 | #if defined(USE_SERIAL) && defined(MCCI_LMIC) 257 | u4_t networkId = 0; 258 | devaddr_t deviceAddress = 0; 259 | u1_t networkSessionKey[16]; 260 | u1_t applicationSessionKey[16]; 261 | LMIC_getSessionKeys(&networkId, &deviceAddress, 262 | networkSessionKey, applicationSessionKey); 263 | 264 | printSpaces(serial, MESSAGE_INDENT); 265 | serial.print(F("Network Id: ")); 266 | serial.println(networkId, DEC); 267 | 268 | printSpaces(serial, MESSAGE_INDENT); 269 | serial.print(F("Device Address: ")); 270 | serial.println(deviceAddress, HEX); 271 | 272 | printSpaces(serial, MESSAGE_INDENT); 273 | serial.print(F("Application Session Key: ")); 274 | printHex(serial, applicationSessionKey, 16, true, '-'); 275 | 276 | printSpaces(serial, MESSAGE_INDENT); 277 | serial.print(F("Network Session Key: ")); 278 | printHex(serial, networkSessionKey, 16, true, '-'); 279 | #endif 280 | } 281 | 282 | 283 | void printDownlinkInfo(void) 284 | { 285 | #if defined(USE_SERIAL) || defined(USE_DISPLAY) 286 | 287 | uint8_t dataLength = LMIC.dataLen; 288 | // bool ackReceived = LMIC.txrxFlags & TXRX_ACK; 289 | 290 | int16_t snrTenfold = getSnrTenfold(); 291 | int8_t snr = snrTenfold / 10; 292 | int8_t snrDecimalFraction = snrTenfold % 10; 293 | int16_t rssi = getRssi(snr); 294 | 295 | uint8_t fPort = 0; 296 | if (LMIC.txrxFlags & TXRX_PORT) 297 | { 298 | fPort = LMIC.frame[LMIC.dataBeg -1]; 299 | } 300 | 301 | #ifdef USE_DISPLAY 302 | display.clearLine(EVENT_ROW); 303 | display.setCursor(COL_0, EVENT_ROW); 304 | display.print(F("RX P:")); 305 | display.print(fPort); 306 | if (dataLength != 0) 307 | { 308 | display.print(" Len:"); 309 | display.print(LMIC.dataLen); 310 | } 311 | display.clearLine(STATUS_ROW); 312 | display.setCursor(COL_0, STATUS_ROW); 313 | display.print(F("RSSI")); 314 | display.print(rssi); 315 | display.print(F(" SNR")); 316 | display.print(snr); 317 | display.print("."); 318 | display.print(snrDecimalFraction); 319 | #endif 320 | 321 | #ifdef USE_SERIAL 322 | printSpaces(serial, MESSAGE_INDENT); 323 | serial.println(F("Downlink received")); 324 | 325 | printSpaces(serial, MESSAGE_INDENT); 326 | serial.print(F("RSSI: ")); 327 | serial.print(rssi); 328 | serial.print(F(" dBm, SNR: ")); 329 | serial.print(snr); 330 | serial.print("."); 331 | serial.print(snrDecimalFraction); 332 | serial.println(F(" dB")); 333 | 334 | printSpaces(serial, MESSAGE_INDENT); 335 | serial.print(F("Port: ")); 336 | serial.println(fPort); 337 | 338 | if (dataLength != 0) 339 | { 340 | printSpaces(serial, MESSAGE_INDENT); 341 | serial.print(F("Length: ")); 342 | serial.println(LMIC.dataLen); 343 | printSpaces(serial, MESSAGE_INDENT); 344 | serial.print(F("Data: ")); 345 | printHex(serial, LMIC.frame+LMIC.dataBeg, LMIC.dataLen, true, ' '); 346 | } 347 | #endif 348 | #endif 349 | } 350 | 351 | 352 | void printHeader(void) 353 | { 354 | #ifdef USE_DISPLAY 355 | display.clear(); 356 | display.setCursor(COL_0, HEADER_ROW); 357 | display.print(F("LMIC-node")); 358 | #ifdef ABP_ACTIVATION 359 | display.drawString(ABPMODE_COL, HEADER_ROW, "ABP"); 360 | #endif 361 | #ifdef CLASSIC_LMIC 362 | display.drawString(CLMICSYMBOL_COL, HEADER_ROW, "*"); 363 | #endif 364 | display.drawString(COL_0, DEVICEID_ROW, deviceId); 365 | display.setCursor(COL_0, INTERVAL_ROW); 366 | display.print(F("Interval:")); 367 | display.print(doWorkIntervalSeconds); 368 | display.print("s"); 369 | #endif 370 | 371 | #ifdef USE_SERIAL 372 | serial.println(F("\n\nLMIC-node\n")); 373 | serial.print(F("Device-id: ")); 374 | serial.println(deviceId); 375 | serial.print(F("LMIC library: ")); 376 | #ifdef MCCI_LMIC 377 | serial.println(F("MCCI")); 378 | #else 379 | serial.println(F("Classic [Deprecated]")); 380 | #endif 381 | serial.print(F("Activation: ")); 382 | #ifdef OTAA_ACTIVATION 383 | serial.println(F("OTAA")); 384 | #else 385 | serial.println(F("ABP")); 386 | #endif 387 | #if defined(LMIC_DEBUG_LEVEL) && LMIC_DEBUG_LEVEL > 0 388 | serial.print(F("LMIC debug: ")); 389 | serial.println(LMIC_DEBUG_LEVEL); 390 | #endif 391 | serial.print(F("Interval: ")); 392 | serial.print(doWorkIntervalSeconds); 393 | serial.println(F(" seconds")); 394 | if (activationMode == ActivationMode::OTAA) 395 | { 396 | serial.println(); 397 | } 398 | #endif 399 | } 400 | 401 | 402 | #ifdef ABP_ACTIVATION 403 | void setAbpParameters(dr_t dataRate = DefaultABPDataRate, s1_t txPower = DefaultABPTxPower) 404 | { 405 | // Set static session parameters. Instead of dynamically establishing a session 406 | // by joining the network, precomputed session parameters are be provided. 407 | #ifdef PROGMEM 408 | // On AVR, these values are stored in flash and only copied to RAM 409 | // once. Copy them to a temporary buffer here, LMIC_setSession will 410 | // copy them into a buffer of its own again. 411 | uint8_t appskey[sizeof(APPSKEY)]; 412 | uint8_t nwkskey[sizeof(NWKSKEY)]; 413 | memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); 414 | memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); 415 | LMIC_setSession (0x1, DEVADDR, nwkskey, appskey); 416 | #else 417 | // If not running an AVR with PROGMEM, just use the arrays directly 418 | LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY); 419 | #endif 420 | 421 | #if defined(CFG_eu868) 422 | // Set up the channels used by the Things Network, which corresponds 423 | // to the defaults of most gateways. Without this, only three base 424 | // channels from the LoRaWAN specification are used, which certainly 425 | // works, so it is good for debugging, but can overload those 426 | // frequencies, so be sure to configure the full frequency range of 427 | // your network here (unless your network autoconfigures them). 428 | // Setting up channels should happen after LMIC_setSession, as that 429 | // configures the minimal channel set. The LMIC doesn't let you change 430 | // the three basic settings, but we show them here. 431 | LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 432 | LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band 433 | LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 434 | LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 435 | LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 436 | LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 437 | LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 438 | LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band 439 | LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band 440 | // TTN defines an additional channel at 869.525Mhz using SF9 for class B 441 | // devices' ping slots. LMIC does not have an easy way to define set this 442 | // frequency and support for class B is spotty and untested, so this 443 | // frequency is not configured here. 444 | #elif defined(CFG_us915) || defined(CFG_au915) 445 | // NA-US and AU channels 0-71 are configured automatically 446 | // but only one group of 8 should (a subband) should be active 447 | // TTN recommends the second sub band, 1 in a zero based count. 448 | // https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json 449 | LMIC_selectSubBand(1); 450 | #elif defined(CFG_as923) 451 | // Set up the channels used in your country. Only two are defined by default, 452 | // and they cannot be changed. Use BAND_CENTI to indicate 1% duty cycle. 453 | // LMIC_setupChannel(0, 923200000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); 454 | // LMIC_setupChannel(1, 923400000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); 455 | 456 | // ... extra definitions for channels 2..n here 457 | #elif defined(CFG_kr920) 458 | // Set up the channels used in your country. Three are defined by default, 459 | // and they cannot be changed. Duty cycle doesn't matter, but is conventionally 460 | // BAND_MILLI. 461 | // LMIC_setupChannel(0, 922100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI); 462 | // LMIC_setupChannel(1, 922300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI); 463 | // LMIC_setupChannel(2, 922500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI); 464 | 465 | // ... extra definitions for channels 3..n here. 466 | #elif defined(CFG_in866) 467 | // Set up the channels used in your country. Three are defined by default, 468 | // and they cannot be changed. Duty cycle doesn't matter, but is conventionally 469 | // BAND_MILLI. 470 | // LMIC_setupChannel(0, 865062500, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI); 471 | // LMIC_setupChannel(1, 865402500, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI); 472 | // LMIC_setupChannel(2, 865985000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_MILLI); 473 | 474 | // ... extra definitions for channels 3..n here. 475 | #endif 476 | 477 | // Disable link check validation 478 | LMIC_setLinkCheckMode(0); 479 | 480 | // TTN uses SF9 for its RX2 window. 481 | LMIC.dn2Dr = DR_SF9; 482 | 483 | // Set data rate and transmit power (note: txpow is possibly ignored by the library) 484 | LMIC_setDrTxpow(dataRate, txPower); 485 | } 486 | #endif //ABP_ACTIVATION 487 | 488 | 489 | void initLmic(bit_t adrEnabled = 0, 490 | dr_t abpDataRate = DefaultABPDataRate, 491 | s1_t abpTxPower = DefaultABPTxPower) 492 | { 493 | // ostime_t timestamp = os_getTime(); 494 | 495 | // Initialize LMIC runtime environment 496 | os_init(); 497 | // Reset MAC state 498 | LMIC_reset(); 499 | 500 | #ifdef ABP_ACTIVATION 501 | setAbpParameters(abpDataRate, abpTxPower); 502 | #endif 503 | 504 | // Enable or disable ADR (data rate adaptation). 505 | // Should be turned off if the device is not stationary (mobile). 506 | // 1 is on, 0 is off. 507 | LMIC_setAdrMode(adrEnabled); 508 | 509 | LMIC.dn2Dr = DR_SF9; 510 | LMIC_setDrTxpow(DR_SF7, 14); 511 | 512 | 513 | if (activationMode == ActivationMode::OTAA) 514 | { 515 | #if defined(CFG_us915) || defined(CFG_au915) 516 | // NA-US and AU channels 0-71 are configured automatically 517 | // but only one group of 8 should (a subband) should be active 518 | // TTN recommends the second sub band, 1 in a zero based count. 519 | // https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json 520 | LMIC_selectSubBand(1); 521 | #endif 522 | } 523 | 524 | // Relax LMIC timing if defined 525 | #if defined(LMIC_CLOCK_ERROR_PPM) 526 | uint32_t clockError = 0; 527 | #if LMIC_CLOCK_ERROR_PPM > 0 528 | #if defined(MCCI_LMIC) && LMIC_CLOCK_ERROR_PPM > 4000 529 | // Allow clock error percentage to be > 0.4% 530 | #define LMIC_ENABLE_arbitrary_clock_error 1 531 | #endif 532 | clockError = (LMIC_CLOCK_ERROR_PPM / 100) * (MAX_CLOCK_ERROR / 100) / 100; 533 | LMIC_setClockError(clockError); 534 | #endif 535 | 536 | #ifdef USE_SERIAL 537 | serial.print(F("Clock Error: ")); 538 | serial.print(LMIC_CLOCK_ERROR_PPM); 539 | serial.print(" ppm ("); 540 | serial.print(clockError); 541 | serial.println(")"); 542 | #endif 543 | #endif 544 | 545 | #ifdef MCCI_LMIC 546 | // Register a custom eventhandler and don't use default onEvent() to enable 547 | // additional features (e.g. make EV_RXSTART available). User data pointer is omitted. 548 | LMIC_registerEventCb(&onLmicEvent, nullptr); 549 | #endif 550 | } 551 | 552 | 553 | #ifdef MCCI_LMIC 554 | void onLmicEvent(void *pUserData, ev_t ev) 555 | #else 556 | void onEvent(ev_t ev) 557 | #endif 558 | { 559 | // LMIC event handler 560 | ostime_t timestamp = os_getTime(); 561 | 562 | switch (ev) 563 | { 564 | #ifdef MCCI_LMIC 565 | // Only supported in MCCI LMIC library: 566 | case EV_RXSTART: 567 | // Do not print anything for this event or it will mess up timing. 568 | break; 569 | 570 | case EV_TXSTART: 571 | setTxIndicatorsOn(); 572 | printEvent(timestamp, ev); 573 | break; 574 | 575 | case EV_JOIN_TXCOMPLETE: 576 | case EV_TXCANCELED: 577 | setTxIndicatorsOn(false); 578 | printEvent(timestamp, ev); 579 | break; 580 | #endif 581 | case EV_JOINED: 582 | setTxIndicatorsOn(false); 583 | printEvent(timestamp, ev); 584 | printSessionKeys(); 585 | 586 | // Disable link check validation. 587 | // Link check validation is automatically enabled 588 | // during join, but because slow data rates change 589 | // max TX size, it is not used in this example. 590 | LMIC_setLinkCheckMode(0); 591 | 592 | // The doWork job has probably run already (while 593 | // the node was still joining) and have rescheduled itself. 594 | // Cancel the next scheduled doWork job and re-schedule 595 | // for immediate execution to prevent that any uplink will 596 | // have to wait until the current doWork interval ends. 597 | os_clearCallback(&doWorkJob); 598 | os_setCallback(&doWorkJob, doWorkCallback); 599 | break; 600 | 601 | case EV_TXCOMPLETE: 602 | // Transmit completed, includes waiting for RX windows. 603 | setTxIndicatorsOn(false); 604 | printEvent(timestamp, ev); 605 | printFrameCounters(); 606 | 607 | // Check if downlink was received 608 | if (LMIC.dataLen != 0 || LMIC.dataBeg != 0) 609 | { 610 | uint8_t fPort = 0; 611 | if (LMIC.txrxFlags & TXRX_PORT) 612 | { 613 | fPort = LMIC.frame[LMIC.dataBeg -1]; 614 | } 615 | printDownlinkInfo(); 616 | processDownlink(timestamp, fPort, LMIC.frame + LMIC.dataBeg, LMIC.dataLen); 617 | } 618 | break; 619 | 620 | // Below events are printed only. 621 | case EV_SCAN_TIMEOUT: 622 | case EV_BEACON_FOUND: 623 | case EV_BEACON_MISSED: 624 | case EV_BEACON_TRACKED: 625 | case EV_RFU1: // This event is defined but not used in code 626 | case EV_JOINING: 627 | case EV_JOIN_FAILED: 628 | case EV_REJOIN_FAILED: 629 | case EV_LOST_TSYNC: 630 | case EV_RESET: 631 | case EV_RXCOMPLETE: 632 | case EV_LINK_DEAD: 633 | case EV_LINK_ALIVE: 634 | #ifdef MCCI_LMIC 635 | // Only supported in MCCI LMIC library: 636 | case EV_SCAN_FOUND: // This event is defined but not used in code 637 | #endif 638 | printEvent(timestamp, ev); 639 | break; 640 | 641 | default: 642 | printEvent(timestamp, "Unknown Event"); 643 | break; 644 | } 645 | } 646 | 647 | 648 | static void doWorkCallback(osjob_t* job) 649 | { 650 | // Event hander for doWorkJob. Gets called by the LMIC scheduler. 651 | // The actual work is performed in function processWork() which is called below. 652 | 653 | ostime_t timestamp = os_getTime(); 654 | #ifdef USE_SERIAL 655 | serial.println(); 656 | printEvent(timestamp, "doWork job started", PrintTarget::Serial); 657 | #endif 658 | 659 | // Do the work that needs to be performed. 660 | processWork(timestamp); 661 | 662 | // This job must explicitly reschedule itself for the next run. 663 | ostime_t startAt = timestamp + sec2osticks((int64_t)doWorkIntervalSeconds); 664 | os_setTimedCallback(&doWorkJob, startAt, doWorkCallback); 665 | } 666 | 667 | 668 | lmic_tx_error_t scheduleUplink(uint8_t fPort, uint8_t* data, uint8_t dataLength, bool confirmed = false) 669 | { 670 | // This function is called from the processWork() function to schedule 671 | // transmission of an uplink message that was prepared by processWork(). 672 | // Transmission will be performed at the next possible time 673 | 674 | ostime_t timestamp = os_getTime(); 675 | printEvent(timestamp, "Packet queued"); 676 | 677 | lmic_tx_error_t retval = LMIC_setTxData2(fPort, data, dataLength, confirmed ? 1 : 0); 678 | timestamp = os_getTime(); 679 | 680 | if (retval == LMIC_ERROR_SUCCESS) 681 | { 682 | #ifdef CLASSIC_LMIC 683 | // For MCCI_LMIC this will be handled in EV_TXSTART 684 | setTxIndicatorsOn(); 685 | #endif 686 | } 687 | else 688 | { 689 | String errmsg; 690 | #ifdef USE_SERIAL 691 | errmsg = "LMIC Error: "; 692 | #ifdef MCCI_LMIC 693 | errmsg.concat(lmicErrorNames[abs(retval)]); 694 | #else 695 | errmsg.concat(retval); 696 | #endif 697 | printEvent(timestamp, errmsg.c_str(), PrintTarget::Serial); 698 | #endif 699 | #ifdef USE_DISPLAY 700 | errmsg = "LMIC Err: "; 701 | errmsg.concat(retval); 702 | printEvent(timestamp, errmsg.c_str(), PrintTarget::Display); 703 | #endif 704 | } 705 | return retval; 706 | } 707 | 708 | 709 | // █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▄ █▀▀ █▀▀ ▀█▀ █▀█ 710 | // █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▄ █▀▀ █ █ █ █ █ 711 | // ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ 712 | 713 | void flow() 714 | { 715 | // This function is called when the Flow Meter triggers an interrupt 716 | flowrate++; 717 | } 718 | 719 | void processWork(ostime_t doWorkJobTimeStamp) 720 | { 721 | // This function is called from the doWorkCallback() 722 | // callback function when the doWork job is executed. 723 | 724 | // Uses globals: payloadBuffer and LMIC data structure. 725 | 726 | // This is where the main work is performed like 727 | // reading sensor and GPS data and schedule uplink 728 | // messages if anything needs to be transmitted. 729 | 730 | // Skip processWork if using OTAA and still joining. 731 | if (LMIC.devaddr != 0) 732 | { 733 | // Collect input data. 734 | // For simplicity LMIC-node uses a counter to simulate a sensor. 735 | // The counter is increased automatically by getCounterValue() 736 | // and can be reset with a 'reset counter' command downlink message. 737 | 738 | // Read data from DHT22 sensor 739 | Serial.print("DHT22 - \t"); 740 | float temp = dht.readTemperature(); 741 | float humi = dht.readHumidity(); 742 | Serial.println(" OK,\t"); 743 | 744 | // Read data from DS18B20 Sensor 745 | float water = ds.getTempC(); 746 | 747 | // Read data from Flow meter. Count interrupt events in one second 748 | flowrate = 0; 749 | interrupts(); 750 | delay(1000); 751 | noInterrupts(); 752 | 753 | // Read input from Float Sensor 754 | uint8_t tank = digitalRead(TANKPIN); 755 | 756 | ostime_t timestamp = os_getTime(); 757 | 758 | #ifdef USE_DISPLAY 759 | // Interval and Counter values are combined on a single row. 760 | // This allows to keep the 3rd row empty which makes the 761 | // information better readable on the small display. 762 | display.clearLine(INTERVAL_ROW); 763 | display.setCursor(COL_0, INTERVAL_ROW); 764 | display.print("I:"); 765 | display.print(doWorkIntervalSeconds); 766 | display.print("s"); 767 | display.print(" W:"); 768 | display.print(water); 769 | #endif 770 | #ifdef USE_SERIAL 771 | printEvent(timestamp, "Input data collected", PrintTarget::Serial); 772 | printSpaces(serial, MESSAGE_INDENT); 773 | #endif 774 | 775 | // For simplicity LMIC-node will try to send an uplink 776 | // message every time processWork() is executed. 777 | 778 | // Schedule uplink message if possible 779 | if (LMIC.opmode & OP_TXRXPEND) 780 | { 781 | // TxRx is currently pending, do not send. 782 | #ifdef USE_SERIAL 783 | printEvent(timestamp, "Uplink not scheduled because TxRx pending", PrintTarget::Serial); 784 | #endif 785 | #ifdef USE_DISPLAY 786 | printEvent(timestamp, "UL not scheduled", PrintTarget::Display); 787 | #endif 788 | } 789 | else 790 | { 791 | // Prepare uplink payload. 792 | uint8_t fPort = 10; 793 | 794 | // Print serial debug data 795 | Serial.print(temp); 796 | Serial.println(F(" ºC air temperature DHT22")); 797 | Serial.print(humi); 798 | Serial.println(F(" percent humidity DHT22")); 799 | Serial.print(water); 800 | Serial.println(F(" ºC water temperature DS18B20")); 801 | Serial.print(flowrate); 802 | Serial.println(F(" Flowrate")); 803 | Serial.print(tank); 804 | Serial.println(F(" Tank Sensor")); 805 | 806 | // Create the CayennaLPP packet 807 | lpp.reset(); 808 | lpp.addTemperature(1, temp); 809 | lpp.addRelativeHumidity(2, humi); 810 | lpp.addTemperature(3, water); 811 | lpp.addDigitalInput(4, flowrate); 812 | lpp.addDigitalInput(5, tank); 813 | uint8_t payloadLength = (lpp.getSize()); 814 | uint8_t* payloadbuffer = (lpp.getBuffer()); 815 | scheduleUplink(fPort, payloadbuffer, payloadLength); 816 | } 817 | } 818 | } 819 | 820 | 821 | void processDownlink(ostime_t txCompleteTimestamp, uint8_t fPort, uint8_t* data, uint8_t dataLength) 822 | { 823 | // This function is called from the onEvent() event handler 824 | // on EV_TXCOMPLETE when a downlink message was received. 825 | 826 | // Implements a 'reset counter' command that can be sent via a downlink message. 827 | // To send the reset counter command to the node, send a downlink message 828 | // (e.g. from the TTN Console) with single byte value resetCmd on port cmdPort. 829 | 830 | const uint8_t cmdPort = 100; 831 | const uint8_t resetCmd= 0xC0; 832 | 833 | if (fPort == cmdPort && dataLength == 1 && data[0] == resetCmd) 834 | { 835 | #ifdef USE_SERIAL 836 | printSpaces(serial, MESSAGE_INDENT); 837 | serial.println(F("Reset cmd received")); 838 | #endif 839 | ostime_t timestamp = os_getTime(); 840 | // resetCounter(); 841 | printEvent(timestamp, "Counter reset", PrintTarget::All, false); 842 | } 843 | } 844 | 845 | 846 | // █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▀ █▀█ █▀▄ 847 | // █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▀ █ █ █ █ 848 | // ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀ 849 | 850 | 851 | void setup() 852 | { 853 | // boardInit(InitType::Hardware) must be called at start of setup() before anything else. 854 | bool hardwareInitSucceeded = boardInit(InitType::Hardware); 855 | 856 | #ifdef USE_DISPLAY 857 | initDisplay(); 858 | #endif 859 | 860 | #ifdef USE_SERIAL 861 | initSerial(MONITOR_SPEED, WAITFOR_SERIAL_S); 862 | #endif 863 | 864 | boardInit(InitType::PostInitSerial); 865 | 866 | #if defined(USE_SERIAL) || defined(USE_DISPLAY) 867 | printHeader(); 868 | #endif 869 | 870 | if (!hardwareInitSucceeded) 871 | { 872 | #ifdef USE_SERIAL 873 | serial.println(F("Error: hardware init failed.")); 874 | serial.flush(); 875 | #endif 876 | #ifdef USE_DISPLAY 877 | // Following mesage shown only if failure was unrelated to I2C. 878 | display.setCursor(COL_0, FRMCNTRS_ROW); 879 | display.print(F("HW init failed")); 880 | #endif 881 | abort(); 882 | } 883 | 884 | initLmic(); 885 | 886 | // █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▄ █▀▀ █▀▀ ▀█▀ █▀█ 887 | // █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▄ █▀▀ █ █ █ █ █ 888 | // ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ 889 | 890 | // Place code for initializing sensors etc. here. 891 | 892 | // Initialize DHT22 sensor 893 | dht.begin(); 894 | Serial.println("DHT Begin..."); 895 | 896 | // Initialize Flow meter 897 | pinMode(FLOWPIN, INPUT); 898 | attachInterrupt(FLOWPIN, flow, RISING); 899 | 900 | // Initialize Float sensor 901 | pinMode(TANKPIN, INPUT); 902 | 903 | // █ █ █▀▀ █▀▀ █▀▄ █▀▀ █▀█ █▀▄ █▀▀ █▀▀ █▀█ █▀▄ 904 | // █ █ ▀▀█ █▀▀ █▀▄ █ █ █ █ █ █▀▀ █▀▀ █ █ █ █ 905 | // ▀▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀▀ ▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀ ▀ ▀▀ 906 | 907 | if (activationMode == ActivationMode::OTAA) 908 | { 909 | LMIC_startJoining(); 910 | } 911 | 912 | // Schedule initial doWork job for immediate execution. 913 | os_setCallback(&doWorkJob, doWorkCallback); 914 | } 915 | 916 | 917 | void loop() 918 | { 919 | os_runloop_once(); 920 | } 921 | -------------------------------------------------------------------------------- /src/LMIC-node.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: LMIC-node.h 4 | * 5 | * Function: LMIC-node main header file. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * Portions Copyright (c) 2018 Terry Moore, MCCI 9 | * 10 | * Permission is hereby granted, free of charge, to anyone 11 | * obtaining a copy of this document and accompanying files to do, 12 | * whatever they want with them without any restriction, including, 13 | * but not limited to, copying, modification and redistribution. 14 | * The above copyright notice and this permission notice shall be 15 | * included in all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT ANY WARRANTY. 18 | * 19 | * License: MIT License. See accompanying LICENSE file. 20 | * 21 | * Author: Leonel Lopes Parente 22 | * 23 | ******************************************************************************/ 24 | 25 | #pragma once 26 | 27 | #ifndef LMIC_NODE_H_ 28 | #define LMIC_NODE_H_ 29 | 30 | #include 31 | #include "lmic.h" 32 | #include "hal/hal.h" 33 | 34 | #ifdef USE_DISPLAY 35 | #include 36 | #include "U8x8lib.h" 37 | #endif 38 | 39 | #ifdef USE_LED 40 | #include "EasyLed.h" 41 | #endif 42 | 43 | enum class InitType { Hardware, PostInitSerial }; 44 | enum class PrintTarget { All, Serial, Display }; 45 | 46 | const dr_t DefaultABPDataRate = DR_SF7; 47 | const s1_t DefaultABPTxPower = 14; 48 | 49 | // Forward declarations 50 | static void doWorkCallback(osjob_t* job); 51 | void processWork(ostime_t timestamp); 52 | void processDownlink(ostime_t eventTimestamp, uint8_t fPort, uint8_t* data, uint8_t dataLength); 53 | void onLmicEvent(void *pUserData, ev_t ev); 54 | void displayTxSymbol(bool visible); 55 | 56 | #ifndef DO_WORK_INTERVAL_SECONDS // Should be set in platformio.ini 57 | #define DO_WORK_INTERVAL_SECONDS 300 // Default 5 minutes if not set 58 | #endif 59 | 60 | #define TIMESTAMP_WIDTH 12 // Number of columns to display eventtime (zero-padded) 61 | #define MESSAGE_INDENT TIMESTAMP_WIDTH + 3 62 | 63 | // Determine which LMIC library is used 64 | #ifdef _LMIC_CONFIG_PRECONDITIONS_H_ 65 | #define MCCI_LMIC 66 | #else 67 | #define CLASSIC_LMIC 68 | #endif 69 | 70 | #if !defined(ABP_ACTIVATION) && !defined(OTAA_ACTIVATION) 71 | #define OTAA_ACTIVATION 72 | #endif 73 | 74 | enum class ActivationMode {OTAA, ABP}; 75 | #ifdef OTAA_ACTIVATION 76 | const ActivationMode activationMode = ActivationMode::OTAA; 77 | #else 78 | const ActivationMode activationMode = ActivationMode::ABP; 79 | #endif 80 | 81 | 82 | #include BSFILE // Include Board Support File 83 | #include "../keyfiles/lorawan-keys.h" 84 | 85 | 86 | #if defined(ABP_ACTIVATION) && defined(OTAA_ACTIVATION) 87 | #error Only one of ABP_ACTIVATION and OTAA_ACTIVATION can be defined. 88 | #endif 89 | 90 | #if defined(ABP_ACTIVATION) && defined(ABP_DEVICEID) 91 | const char deviceId[] = ABP_DEVICEID; 92 | #elif defined(DEVICEID) 93 | const char deviceId[] = DEVICEID; 94 | #else 95 | const char deviceId[] = DEVICEID_DEFAULT; 96 | #endif 97 | 98 | // Allow WAITFOR_SERIAL_SECONDS to be defined in platformio.ini. 99 | // If used it shall be defined in the [common] section. 100 | // The common setting will only be used for boards that have 101 | // WAITFOR_SERIAL_SECONDS_DEFAULT defined (in BSP) with a value != 0 102 | #if defined(WAITFOR_SERIAL_SECONDS_DEFAULT) && WAITFOR_SERIAL_SECONDS_DEFAULT != 0 103 | #ifdef WAITFOR_SERIAL_SECONDS 104 | #define WAITFOR_SERIAL_S WAITFOR_SERIAL_SECONDS 105 | #else 106 | #define WAITFOR_SERIAL_S WAITFOR_SERIAL_SECONDS_DEFAULT 107 | #endif 108 | #else 109 | #define WAITFOR_SERIAL_S 0 110 | #endif 111 | 112 | #if defined(ABP_ACTIVATION) && defined(CLASSIC_LMIC) 113 | #error Do NOT use ABP activation when using the deprecated IBM LMIC framework library. \ 114 | On The Things Network V3 this will cause a downlink message for EVERY uplink message \ 115 | because it does properly handle MAC commands. 116 | #endif 117 | 118 | #ifdef OTAA_ACTIVATION 119 | #if !defined(OTAA_DEVEUI) || !defined(OTAA_APPEUI) || !defined(OTAA_APPKEY) 120 | #error One or more LoRaWAN keys (OTAA_DEVEUI, OTAA_APPEUI, OTAA_APPKEY) are not defined. 121 | #endif 122 | #else 123 | // ABP activation 124 | #if !defined(ABP_DEVADDR) || !defined(ABP_NWKSKEY) || !defined(ABP_APPSKEY) 125 | #error One or more LoRaWAN keys (ABP_DEVADDR, ABP_NWKSKEY, ABP_APPSKEY) are not defined. 126 | #endif 127 | #endif 128 | 129 | // Determine if a valid region is defined. 130 | // This actually has little effect because 131 | // CLASSIC LMIC: defines CFG_eu868 by default, 132 | // MCCI LMIC: if no region is defined it 133 | // sets CFG_eu868 as default. 134 | #if ( \ 135 | ( defined(CLASSIC_LMIC) \ 136 | && !( defined(CFG_eu868) \ 137 | || defined(CFG_us915) ) ) \ 138 | || \ 139 | ( defined(MCCI_LMIC) \ 140 | && !( defined(CFG_as923) \ 141 | || defined(CFG_as923jp) \ 142 | || defined(CFG_au915) \ 143 | || defined(CFG_eu868) \ 144 | || defined(CFG_in866) \ 145 | || defined(CFG_kr920) \ 146 | || defined(CFG_us915) ) ) \ 147 | ) 148 | #Error No valid LoRaWAN region defined 149 | #endif 150 | 151 | #ifndef LMIC_MCCI 152 | #define LMIC_ERROR_SUCCESS 0 153 | typedef int lmic_tx_error_t; 154 | 155 | // In MCCI LMIC these are already defined. 156 | // This macro can be used to initalize an array of event strings 157 | #define LEGACY_LMIC_EVENT_NAME_TABLE__INIT \ 158 | "<>", \ 159 | "EV_SCAN_TIMEOUT", "EV_BEACON_FOUND", \ 160 | "EV_BEACON_MISSED", "EV_BEACON_TRACKED", "EV_JOINING", \ 161 | "EV_JOINED", "EV_RFU1", "EV_JOIN_FAILED", "EV_REJOIN_FAILED", \ 162 | "EV_TXCOMPLETE", "EV_LOST_TSYNC", "EV_RESET", \ 163 | "EV_RXCOMPLETE", "EV_LINK_DEAD", "EV_LINK_ALIVE" 164 | 165 | // If working on an AVR (or worried about memory size), you can use this multi-zero 166 | // string and put this in a single const F() string to store it in program memory. 167 | // Index through this counting up from 0, until you get to the entry you want or 168 | // to an entry that begins with a \0. 169 | #define LEGACY_LMIC_EVENT_NAME_MULTISZ__INIT \ 170 | "<>\0" \ \ 171 | "EV_SCAN_TIMEOUT\0" "EV_BEACON_FOUND\0" \ 172 | "EV_BEACON_MISSED\0" "EV_BEACON_TRACKED\0" "EV_JOINING\0" \ 173 | "EV_JOINED\0" "EV_RFU1\0" "EV_JOIN_FAILED\0" "EV_REJOIN_FAILED\0" \ 174 | "EV_TXCOMPLETE\0" "EV_LOST_TSYNC\0" "EV_RESET\0" \ 175 | "EV_RXCOMPLETE\0" "EV_LINK_DEAD\0" "EV_LINK_ALIVE\0" 176 | #endif // LMIC_MCCI 177 | 178 | 179 | #if defined(USE_SERIAL) || defined(USE_DISPLAY) 180 | 181 | #ifdef MCCI_LMIC 182 | static const char * const lmicEventNames[] = { LMIC_EVENT_NAME_TABLE__INIT }; 183 | static const char * const lmicErrorNames[] = { LMIC_ERROR_NAME__INIT }; 184 | #else 185 | static const char * const lmicEventNames[] = { LEGACY_LMIC_EVENT_NAME_TABLE__INIT }; 186 | #endif 187 | 188 | 189 | void printChars(Print& printer, char ch, uint8_t count, bool linefeed = false) 190 | { 191 | for (uint8_t i = 0; i < count; ++i) 192 | { 193 | printer.print(ch); 194 | } 195 | if (linefeed) 196 | { 197 | printer.println(); 198 | } 199 | } 200 | 201 | 202 | void printSpaces(Print& printer, uint8_t count, bool linefeed = false) 203 | { 204 | printChars(printer, ' ', count, linefeed); 205 | } 206 | 207 | 208 | void printHex(Print& printer, uint8_t* bytes, size_t length = 1, bool linefeed = false, char separator = 0) 209 | { 210 | for (size_t i = 0; i < length; ++i) 211 | { 212 | if (i > 0 && separator != 0) 213 | { 214 | printer.print(separator); 215 | } 216 | if (bytes[i] <= 0x0F) 217 | { 218 | printer.print('0'); 219 | } 220 | printer.print(bytes[i], HEX); 221 | } 222 | if (linefeed) 223 | { 224 | printer.println(); 225 | } 226 | } 227 | 228 | 229 | void setTxIndicatorsOn(bool on = true) 230 | { 231 | if (on) 232 | { 233 | #ifdef USE_LED 234 | led.on(); 235 | #endif 236 | #ifdef USE_DISPLAY 237 | displayTxSymbol(true); 238 | #endif 239 | } 240 | else 241 | { 242 | #ifdef USE_LED 243 | led.off(); 244 | #endif 245 | #ifdef USE_DISPLAY 246 | displayTxSymbol(false); 247 | #endif 248 | } 249 | } 250 | 251 | #endif // USE_SERIAL || USE_DISPLAY 252 | 253 | 254 | #ifdef USE_DISPLAY 255 | uint8_t transmitSymbol[8] = {0x18, 0x18, 0x00, 0x24, 0x99, 0x42, 0x3c, 0x00}; 256 | #define ROW_0 0 257 | #define ROW_1 1 258 | #define ROW_2 2 259 | #define ROW_3 3 260 | #define ROW_4 4 261 | #define ROW_5 5 262 | #define ROW_6 6 263 | #define ROW_7 7 264 | #define HEADER_ROW ROW_0 265 | #define DEVICEID_ROW ROW_1 266 | #define INTERVAL_ROW ROW_2 267 | #define TIME_ROW ROW_4 268 | #define EVENT_ROW ROW_5 269 | #define STATUS_ROW ROW_6 270 | #define FRMCNTRS_ROW ROW_7 271 | #define COL_0 0 272 | #define ABPMODE_COL 10 273 | #define CLMICSYMBOL_COL 14 274 | #define TXSYMBOL_COL 15 275 | 276 | void initDisplay() 277 | { 278 | display.begin(); 279 | display.setFont(u8x8_font_victoriamedium8_r); 280 | } 281 | 282 | void displayTxSymbol(bool visible = true) 283 | { 284 | if (visible) 285 | { 286 | display.drawTile(TXSYMBOL_COL, ROW_0, 1, transmitSymbol); 287 | } 288 | else 289 | { 290 | display.drawGlyph(TXSYMBOL_COL, ROW_0, char(0x20)); 291 | } 292 | } 293 | #endif // USE_DISPLAY 294 | 295 | 296 | #ifdef USE_SERIAL 297 | bool initSerial(unsigned long speed = 115200, int16_t timeoutSeconds = 0) 298 | { 299 | // Initializes the serial port. 300 | // Optionally waits for serial port to be ready. 301 | // Will display status and progress on display (if enabled) 302 | // which can be useful for tracing (e.g. ATmega328u4) serial port issues. 303 | // A negative timeoutSeconds value will wait indefinitely. 304 | // A value of 0 (default) will not wait. 305 | // Returns: true when serial port ready, 306 | // false when not ready. 307 | 308 | serial.begin(speed); 309 | 310 | #if WAITFOR_SERIAL_S != 0 311 | if (timeoutSeconds != 0) 312 | { 313 | bool indefinite = (timeoutSeconds < 0); 314 | uint16_t secondsLeft = timeoutSeconds; 315 | #ifdef USE_DISPLAY 316 | display.setCursor(0, ROW_1); 317 | display.print(F("Waiting for")); 318 | display.setCursor(0, ROW_2); 319 | display.print(F("serial port")); 320 | #endif 321 | 322 | while (!serial && (indefinite || secondsLeft > 0)) 323 | { 324 | if (!indefinite) 325 | { 326 | #ifdef USE_DISPLAY 327 | display.clearLine(ROW_4); 328 | display.setCursor(0, ROW_4); 329 | display.print(F("timeout in ")); 330 | display.print(secondsLeft); 331 | display.print('s'); 332 | #endif 333 | --secondsLeft; 334 | } 335 | delay(1000); 336 | } 337 | #ifdef USE_DISPLAY 338 | display.setCursor(0, ROW_4); 339 | if (serial) 340 | { 341 | display.print(F("Connected")); 342 | } 343 | else 344 | { 345 | display.print(F("NOT connected")); 346 | } 347 | #endif 348 | } 349 | #endif 350 | 351 | return serial; 352 | } 353 | #endif 354 | 355 | 356 | #endif // LMIC_NODE_H_ 357 | -------------------------------------------------------------------------------- /src/boards/bsf_adafruit_feather_m0_lora.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_adafruit_feather_m0_lora.h 4 | * 5 | * Function: Board Support File for Adafruit Feather M0 RFMx LoRa. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by the MCU). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display can be connected. 16 | * 17 | * ██ DIO1 MUST BE MANUALLY WIRED TO GPIO6 (see below) ██ 18 | * 19 | * GPIO6 is what Adafruit uses in their tutorial. 20 | * 21 | * Connect DIO1 and optional display 22 | * according to below connection details. 23 | * 24 | * CONNECTIONS AND PIN DEFINITIONS: 25 | * 26 | * Indentifiers between parentheses are defined in the board's 27 | * Board Support Package (BSP) which is part of the Arduino core. 28 | * 29 | * Leds GPIO 30 | * ---- ---- 31 | * LED <――――――――――> 13 (LED_BUILTIN, PIN_LED, PIN_LED_13) active-high 32 | * LED2 <――――――――――> 25 (RX, PIN_LED2, PIN_LED_RXL) 33 | * LED3 <――――――――――> 26 (TX, PIN_LED3, PIN_LED_TXL) 34 | * 35 | * I2C [display] GPIO 36 | * --- ---- 37 | * SDA <――――――――――> 20 (SDA) 38 | * SCL <――――――――――> 21 (SCL) 39 | * 40 | * SPI/LoRa GPIO 41 | * --- ---- 42 | * MOSI <――――――――――> 23 (MOSI) 43 | * MISO <――――――――――> 22 (MISO) 44 | * SCK <――――――――――> 24 (SCK) 45 | * NSS <――――――――――> 8 46 | * RST <――――――――――> 4 47 | * DIO0 <――――――――――> 3 48 | * DIO1 <----------> 6 ██ NOT WIRED on PCB ██ 49 | * DIO2 - Not needed for LoRa 50 | * 51 | * Docs: https://docs.platformio.org/en/latest/boards/atmelsam/adafruit_feather_m0.html 52 | * https://learn.adafruit.com/the-things-network-for-feather/arduino-wiring 53 | * 54 | * Identifiers: LMIC-node 55 | * board-id: adafruit_feather_m0_lora 56 | * PlatformIO 57 | * board: adafruit_feather_m0 58 | * platform: atmelsam 59 | * Arduino 60 | * board: ARDUINO_SAMD_FEATHER_M0 61 | * architecture: ARDUINO_ARCH_SAMD 62 | * 63 | ******************************************************************************/ 64 | 65 | #pragma once 66 | 67 | #ifndef BSF_ADAFRUIT_FEATHER_M0_LORA_H_ 68 | #define BSF_ADAFRUIT_FEATHER_M0_LORA_H_ 69 | 70 | #include "LMIC-node.h" 71 | 72 | #define DEVICEID_DEFAULT "feather-m0" // Default deviceid value 73 | 74 | // Wait for Serial 75 | // Can be useful for boards with MCU with integrated USB support. 76 | #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 77 | 78 | // LMIC Clock Error 79 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 80 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 81 | // #ifndef LMIC_CLOCK_ERROR_PPM 82 | // #define LMIC_CLOCK_ERROR_PPM 0 83 | // #endif 84 | 85 | // Pin mappings for LoRa tranceiver 86 | const lmic_pinmap lmic_pins = { 87 | .nss = 8, 88 | .rxtx = LMIC_UNUSED_PIN, 89 | .rst = 4, 90 | .dio = { /*dio0*/ 3, /*dio1*/ 6, /*dio2*/ LMIC_UNUSED_PIN } 91 | #ifdef MCCI_LMIC 92 | , 93 | .rxtx_rx_active = 0, 94 | .rssi_cal = 8, 95 | .spi_freq = 8000000 /* 8 MHz */ 96 | #endif 97 | }; 98 | 99 | #ifdef USE_SERIAL 100 | Serial_& serial = Serial; 101 | #endif 102 | 103 | #ifdef USE_LED 104 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High); 105 | #endif 106 | 107 | #ifdef USE_DISPLAY 108 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 109 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 110 | #endif 111 | 112 | 113 | bool boardInit(InitType initType) 114 | { 115 | // This function is used to perform board specific initializations. 116 | // Required as part of standard template. 117 | 118 | // InitType::Hardware Must be called at start of setup() before anything else. 119 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 120 | 121 | bool success = true; 122 | switch (initType) 123 | { 124 | case InitType::Hardware: 125 | // Note: Serial port and display are not yet initialized and cannot be used use here. 126 | // No actions required for this board. 127 | break; 128 | 129 | case InitType::PostInitSerial: 130 | // Note: If enabled Serial port and display are already initialized here. 131 | // No actions required for this board. 132 | break; 133 | } 134 | return success; 135 | } 136 | 137 | 138 | #endif // BSF_ADAFRUIT_FEATHER_M0_LORA_H_ -------------------------------------------------------------------------------- /src/boards/bsf_adafruit_qt_py_m0.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_adafruit_qt_py_m0.h 4 | * 5 | * Function: Board Support File for Adafruit QT Py (SAMD21) 6 | * with external SPI LoRa module. 7 | * 8 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 9 | * 10 | * License: MIT License. See accompanying LICENSE file. 11 | * 12 | * Author: Leonel Lopes Parente 13 | * 14 | * Description: This board has onboard USB (provided by the MCU). 15 | * It supports automatic firmware upload and serial over USB. 16 | * No onboard display. Optionally an external display can be connected. 17 | * Has onboard LED but this is a Neopixel RGB LED which requires 18 | * a separate library and is currently not supported by LMIC-node. 19 | * 20 | * Connect the LoRa module and optional display 21 | * according to below connection details. 22 | * 23 | * CONNECTIONS AND PIN DEFINITIONS: 24 | * 25 | * Indentifiers between parentheses are defined in the board's 26 | * Board Support Package (BSP) which is part of the Arduino core. 27 | * 28 | * Leds GPIO 29 | * ---- ---- 30 | * 13 (LED_BUILTIN) defined but there is no LED 31 | * NEOPIX <――――――――――> 11 (PIN_NEOPIXEL) WS2812B Neopixel LED 32 | * 12 Neopixel enable. Default enabled = HIGH. 33 | * 34 | * I2C [display] GPIO 35 | * --- ---- 36 | * SDA <――――――――――> 20 (SDA) 37 | * SCL <――――――――――> 21 (SCL) 38 | * 39 | * SPI/LoRa GPIO 40 | * --- ---- 41 | * MOSI <――――――――――> 10 (MOSI) 42 | * MISO <――――――――――> 9 (MISO) 43 | * SCK <――――――――――> 8 (SCK) 44 | * NSS <――――――――――> 1 NOT SS, SS = 0 45 | * RST <――――――――――> - not connected 46 | * DIO0 <――――――――――> 2 47 | * DIO1 <----------> 3 48 | * DIO2 - Not needed for LoRa 49 | * 50 | * Docs: https://docs.platformio.org/en/latest/boards/atmelsam/adafruit_qt_py_m0.html 51 | * 52 | * Identifiers: LMIC-node 53 | * board-id: adafruit_qt_py_m0 54 | * PlatformIO 55 | * board: adafruit_qt_py_m0 56 | * platform: atmelsam 57 | * Arduino 58 | * board: ADAFRUIT_QTPY_M0 59 | * architecture: ARDUINO_ARCH_SAMD 60 | * 61 | ******************************************************************************/ 62 | 63 | #pragma once 64 | 65 | #ifndef BSF_ADAFRUIT_QT_PY_M0_H_ 66 | #define BSF_ADAFRUIT_QT_PY_M0_H_ 67 | 68 | #include "LMIC-node.h" 69 | 70 | #define DEVICEID_DEFAULT "qt-py" // Default deviceid value 71 | 72 | // Wait for Serial 73 | // Can be useful for boards with MCU with integrated USB support. 74 | #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 75 | 76 | // LMIC Clock Error 77 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 78 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 79 | // #ifndef LMIC_CLOCK_ERROR_PPM 80 | // #define LMIC_CLOCK_ERROR_PPM 0 81 | // #endif 82 | 83 | // Pin mappings for LoRa tranceiver 84 | const lmic_pinmap lmic_pins = { 85 | .nss = 1, 86 | .rxtx = LMIC_UNUSED_PIN, 87 | .rst = LMIC_UNUSED_PIN, 88 | .dio = { /*dio0*/ 2, /*dio1*/ 3, /*dio2*/ LMIC_UNUSED_PIN } 89 | #ifdef MCCI_LMIC 90 | , 91 | .rxtx_rx_active = 0, 92 | .rssi_cal = 8, 93 | .spi_freq = 8000000 /* 8 MHz */ 94 | #endif 95 | }; 96 | 97 | #ifdef USE_SERIAL 98 | Serial_& serial = Serial; 99 | #endif 100 | 101 | #ifdef USE_LED 102 | #error "Invalid option: USE_LED. Onboard Neopixel RGB LED is currently not supported." 103 | #endif 104 | 105 | #ifdef USE_DISPLAY 106 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 107 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 108 | #endif 109 | 110 | 111 | bool boardInit(InitType initType) 112 | { 113 | // This function is used to perform board specific initializations. 114 | // Required as part of standard template. 115 | 116 | // InitType::Hardware Must be called at start of setup() before anything else. 117 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 118 | 119 | bool success = true; 120 | switch (initType) 121 | { 122 | case InitType::Hardware: 123 | // Note: Serial port and display are not yet initialized and cannot be used use here. 124 | // No actions required for this board. 125 | break; 126 | 127 | case InitType::PostInitSerial: 128 | // Note: If enabled Serial port and display are already initialized here. 129 | // No actions required for this board. 130 | break; 131 | } 132 | return success; 133 | } 134 | 135 | 136 | #endif // BSF_ADAFRUIT_QT_PY_M0_H_ -------------------------------------------------------------------------------- /src/boards/bsf_blackpill_f103c8.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_blackpill_f103c8.h 4 | * 5 | * Function: Board Support File for STM32 F103C8T6 'blackpill' 64k and 128k 6 | * with external SPI LoRa module. 7 | * 8 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 9 | * 10 | * License: MIT License. See accompanying LICENSE file. 11 | * 12 | * Author: Leonel Lopes Parente 13 | * 14 | * Description: This Board has onboard USB (provided by the MCU). 15 | * However, the default bootloader does not support automatic 16 | * firmware upload and serial over USB. 17 | * No onboard display. Optionally an external display can be connected. 18 | * 19 | * For firmware upload use a USB to serial adapter, STLink programmer, 20 | * or special bootloader (not standard supported). 21 | * The upload_protocol setting for this board (in platformio.ini) 22 | * must be set to the preferred upload method (default is stlink). 23 | * For serial monitor use a USB to serial adapter. 24 | * (It may also be possible to configure the onboard USB 25 | * for this but I haven't yet figured out how.) 26 | * 27 | * This board requires a workaround to prevent losing output 28 | * printed to the serial port (see boardInit() below). 29 | * 30 | * Connect the LoRa module and optional display 31 | * according to below connection details. 32 | * 33 | * CONNECTIONS AND PIN DEFINITIONS: 34 | * 35 | * Indentifiers between parentheses are defined in the board's 36 | * Board Support Package (BSP) which is part of the Arduino core. 37 | * 38 | * Leds GPIO 39 | * ---- ---- 40 | * LED <――――――――――> PB12 / 16 (LED_BUILTIN) Active-low 41 | * 42 | * I2C [display] GPIO 43 | * --- ---- 44 | * SDA <――――――――――> PB7 / 2 (SCA) 45 | * SCL <――――――――――> PB6 / 3 (SCL) 46 | * 47 | * SPI/LoRa module GPIO 48 | * --- ---- 49 | * MOSI <――――――――――> PA7 / 27 (MOSI) 50 | * MISO <――――――――――> PA6 / 26 (MISO) 51 | * SCK <――――――――――> PA5 / 25 (SCK) 52 | * NSS <――――――――――> PA4 / 24 (SS) 53 | * RST <――――――――――> PB0 / 28 54 | * DIO0 <――――――――――> PA3 / 23 55 | * DIO1 <――――――――――> PA2 / 22 56 | * DIO2 - Not needed for LoRa. 57 | * 58 | * Serial GPIO 59 | * ------ ---- 60 | * RX <――――――――――> PA10 / 10 (PIN_SERIAL_RX) 61 | * TX <――――――――――> PA9 / 11 (PIN_SERIAL_TX) 62 | * 63 | * SWD GPIO 64 | * --- ---- 65 | * SWCLK <――――――――――> PA14 / 34 66 | * SWDIO <――――――――――> PA13 / 33 67 | * 68 | * USB GPIO 69 | * --- ---- 70 | * D- <――――――――――> PA11 / 9 71 | * D+ <――――――――――> PA12 / 8 72 | * 73 | * Docs: https://docs.platformio.org/en/latest/boards/ststm32/blackpill_f103c8.html 74 | * https://docs.platformio.org/en/latest/boards/ststm32/blackpill_f103c8_128.html 75 | * 76 | * Identifiers: LMIC-node 77 | * board-id: blackpill_f103c8 (64k version) 78 | * blackpill_f103c8_128k (128k version) 79 | * PlatformIO 80 | * board: blackpill_f103c8 (64k version) 81 | * blackpill_f103c8_128k (128k version) 82 | * platform: ststm32 83 | * Arduino 84 | * board: ARDUINO_BLACKPILL_F103C8 85 | * architecture: ARDUINO_ARCH_STM32 86 | * 87 | ******************************************************************************/ 88 | 89 | #pragma once 90 | 91 | #ifndef BSF_BLACKPILL_F103C8_H_ 92 | #define BSF_BLACKPILL_F103C8_H_ 93 | 94 | #include "LMIC-node.h" 95 | 96 | #define DEVICEID_DEFAULT "blackpill" 97 | 98 | // Wait for Serial 99 | // Can be useful for boards with MCU with integrated USB support. 100 | // This board by default does not support serial over USB but 101 | // wait for serial is enabled anyway for if boards have a different bootloader. 102 | #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 103 | 104 | // LMIC Clock Error 105 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 106 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 107 | // #ifndef LMIC_CLOCK_ERROR_PPM 108 | // #define LMIC_CLOCK_ERROR_PPM 0 109 | // #endif 110 | 111 | // Pin mappings for LoRa tranceiver 112 | const lmic_pinmap lmic_pins = { 113 | .nss = PA4, 114 | .rxtx = LMIC_UNUSED_PIN, 115 | .rst = PB0, 116 | .dio = { /*dio0*/ PA3, /*dio1*/ PA2, /*dio2*/ LMIC_UNUSED_PIN } 117 | #ifdef MCCI_LMIC 118 | , 119 | .rxtx_rx_active = 0, 120 | .rssi_cal = 10, 121 | .spi_freq = 8000000 /* 8 MHz */ 122 | #endif 123 | }; 124 | 125 | #ifdef USE_SERIAL 126 | HardwareSerial& serial = Serial; 127 | #endif 128 | 129 | #ifdef USE_LED 130 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low); 131 | #endif 132 | 133 | #ifdef USE_DISPLAY 134 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 135 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 136 | #endif 137 | 138 | #ifndef STM32_POST_INITSERIAL_DELAY_MS 139 | #define STM32_POST_INITSERIAL_DELAY_MS 1500 140 | #endif 141 | 142 | 143 | bool boardInit(InitType initType) 144 | { 145 | // This function is used to perform board specific initializations. 146 | // Required as part of standard template. 147 | 148 | // InitType::Hardware Must be called at start of setup() before anything else. 149 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 150 | 151 | bool success = true; 152 | switch (initType) 153 | { 154 | case InitType::Hardware: 155 | // Note: Serial port and display are not yet initialized and cannot be used use here. 156 | // No actions required for this board. 157 | break; 158 | 159 | case InitType::PostInitSerial: 160 | // Note: If enabled Serial port and display are already initialized here. 161 | 162 | // Required workaround: 163 | // Data printed to the serial port during the first second gets lost. 164 | // Inserting a sufficient delay will usually fix this. 165 | #ifdef USE_SERIAL 166 | delay(STM32_POST_INITSERIAL_DELAY_MS); 167 | #endif 168 | break; 169 | } 170 | return success; 171 | } 172 | 173 | 174 | #endif // BSF_BLACKPILL_F103C8_H_ -------------------------------------------------------------------------------- /src/boards/bsf_bluepill_f103c8.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_bluepill_f103c8.h 4 | * 5 | * Function: Board Support File for STM32 F103C8T6 'bluepill' 64k and 128k 6 | * with external SPI LoRa module. 7 | * 8 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 9 | * 10 | * License: MIT License. See accompanying LICENSE file. 11 | * 12 | * Author: Leonel Lopes Parente 13 | * 14 | * Description: Board has onboard USB but the default bootloader does not 15 | * support automatic upload via USB and serial over USB. 16 | * No onboard display. Optionally an external display 17 | * can be connected to the I2C pins. 18 | * 19 | * For firmware upload use a USB to serial adapter, STLink programmer, 20 | * or special bootloader (not standard supported). 21 | * The upload_protocol setting for this board (in platformio.ini) 22 | * must be set to the preferred upload method (default is stlink). 23 | * For serial monitor use a USB to serial adapter. 24 | * (It may also be possible to configure the onboard USB 25 | * for this but I haven't yet figured out how.) 26 | * 27 | * This board requires a workaround to prevent losing output 28 | * printed to the serial port (see boardInit() below). 29 | * 30 | * Connect the LoRa module and optional display 31 | * according to below connection details. 32 | * 33 | * CONNECTIONS AND PIN DEFINITIONS: 34 | * 35 | * Indentifiers between parentheses are defined in the board's 36 | * Board Support Package (BSP) which is part of the Arduino core. 37 | * 38 | * Leds GPIO 39 | * ---- ---- 40 | * LED <――――――――――> PC13 / 17 (LED_BUILTIN) Active-low 41 | * 42 | * I2C [display] GPIO 43 | * --- ---- 44 | * SDA <――――――――――> PB7 / 2 (SCA) 45 | * SCL <――――――――――> PB6 / 3 (SCL) 46 | * 47 | * SPI/LoRa module GPIO 48 | * --- ---- 49 | * MOSI <――――――――――> PA7 / 27 (MOSI) 50 | * MISO <――――――――――> PA6 / 26 (MISO) 51 | * SCK <――――――――――> PA5 / 25 (SCK) 52 | * NSS <――――――――――> PA4 / 24 (SS) 53 | * RST <――――――――――> PB0 / 28 54 | * DIO0 <――――――――――> PA3 / 23 55 | * DIO1 <――――――――――> PA2 / 22 56 | * DIO2 - Not needed for LoRa. 57 | * 58 | * Serial GPIO 59 | * ------ ---- 60 | * RX <――――――――――> PA10 / 10 (PIN_SERIAL_RX) 61 | * TX <――――――――――> PA9 / 11 (PIN_SERIAL_TX) 62 | * 63 | * SWD GPIO 64 | * --- ---- 65 | * SWCLK <――――――――――> PA14 / 34 66 | * SWDIO <――――――――――> PA13 / 33 67 | * 68 | * USB GPIO 69 | * --- ---- 70 | * D- <――――――――――> PA11 / 9 71 | * D+ <――――――――――> PA12 / 8 72 | * 73 | * Docs: https://docs.platformio.org/en/latest/boards/ststm32/bluepill_f103c8.html 74 | * https://docs.platformio.org/en/latest/boards/ststm32/bluepill_f103c8_128k.html 75 | * 76 | * Identifiers: LMIC-node 77 | * board-id: bluepill_f103c8 (64k version) 78 | * bluepill_f103c8_128k (128k version) 79 | * PlatformIO 80 | * board: bluepill_f103c8 (64k version) 81 | * bluepill_f103c8_128k (128k version) 82 | * platform: ststm32 83 | * Arduino 84 | * board: ARDUINO_BLUEPILL_F103C8 85 | * architecture: ARDUINO_ARCH_STM32 86 | * 87 | ******************************************************************************/ 88 | 89 | #pragma once 90 | 91 | #ifndef BSF_BLUEPILL_F103C8_H_ 92 | #define BSF_BLUEPILL_F103C8_H_ 93 | 94 | #include "LMIC-node.h" 95 | 96 | #define DEVICEID_DEFAULT "bluepill" 97 | 98 | // Wait for Serial 99 | // Can be useful for boards with MCU with integrated USB support. 100 | // This board by default does not support serial over USB but 101 | // wait for serial is enabled anyway for if boards have a different bootloader. 102 | #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 103 | 104 | // LMIC Clock Error 105 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 106 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 107 | // #ifndef LMIC_CLOCK_ERROR_PPM 108 | // #define LMIC_CLOCK_ERROR_PPM 0 109 | // #endif 110 | 111 | // Pin mappings for LoRa tranceiver 112 | const lmic_pinmap lmic_pins = { 113 | .nss = PA4, 114 | .rxtx = LMIC_UNUSED_PIN, 115 | .rst = PB0, 116 | .dio = { /*dio0*/ PA3, /*dio1*/ PA2, /*dio2*/ LMIC_UNUSED_PIN } 117 | #ifdef MCCI_LMIC 118 | , 119 | .rxtx_rx_active = 0, 120 | .rssi_cal = 10, 121 | .spi_freq = 8000000 /* 8 MHz */ 122 | #endif 123 | }; 124 | 125 | #ifdef USE_SERIAL 126 | HardwareSerial& serial = Serial; 127 | #endif 128 | 129 | #ifdef USE_LED 130 | EasyLed led(PC13, EasyLed::ActiveLevel::Low); 131 | #endif 132 | 133 | #ifdef USE_DISPLAY 134 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 135 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 136 | #endif 137 | 138 | #ifndef STM32_POST_INITSERIAL_DELAY_MS 139 | #define STM32_POST_INITSERIAL_DELAY_MS 1500 140 | #endif 141 | 142 | 143 | bool boardInit(InitType initType) 144 | { 145 | // This function is used to perform board specific initializations. 146 | // Required as part of standard template. 147 | 148 | // InitType::Hardware Must be called at start of setup() before anything else. 149 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 150 | 151 | bool success = true; 152 | switch (initType) 153 | { 154 | case InitType::Hardware: 155 | // Note: Serial port and display are not yet initialized and cannot be used use here. 156 | // No actions required for this board. 157 | break; 158 | 159 | case InitType::PostInitSerial: 160 | // Note: If enabled Serial port and display are already initialized here. 161 | 162 | // Required workaround: 163 | // Data printed to the serial port during the first second gets lost. 164 | // Inserting a sufficient delay will usually fix this. 165 | #ifdef USE_SERIAL 166 | delay(STM32_POST_INITSERIAL_DELAY_MS); 167 | #endif 168 | break; 169 | } 170 | return success; 171 | } 172 | 173 | 174 | #endif // BSF_BLUEPILL_F103C8_H_ -------------------------------------------------------------------------------- /src/boards/bsf_disco_l072cz_lrwan1.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_disco_l072cz_lrwan1.h 4 | * 5 | * Function: Board Support File for ST B-L072Z-LRWAN1 Discovery kit. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard STLink programmer). 14 | * It supports automatic upload (via stlink) and serial over USB. 15 | * No onboard display. Optionally an external display can be connected. 16 | * 17 | * The standard SPI pins defined in the BSP do not match the 18 | * GPIO pins that the SX1276 LoRa chip is connected to. 19 | * LMIC uses the default SPI parameters for initializing the SPI bus 20 | * which will not work here. Therefore the SPI object is explicitly 21 | * initialized with the correct pins (see boardInit() below). 22 | * 23 | * This board requires a workaround to prevent losing the first 24 | * output printed to the serial port (see boardInit() below). 25 | * 26 | * Connect an optional display according to below connection details. 27 | * 28 | * CONNECTIONS AND PIN DEFINITIONS: 29 | * 30 | * Indentifiers between parentheses are defined in the board's 31 | * Board Support Package (BSP) which is part of the Arduino core. 32 | * 33 | * Leds GPIO 34 | * ---- ---- 35 | * LED <――――――――――> PA5 / 32 (LED_BUILTIN) Useless because PA5 is used for DIO4 36 | * RED <――――――――――> PB7 / 5 (LED_RED, LED_LD4) 37 | * GREEN <――――――――――> PB5 / 4 (LED_GREEN, LED_LD1) Also used for SS1 38 | * BLUE <――――――――――> PB6 / 10 (LED_BLUE, LED3) Also used for SS 39 | * 40 | * I2C [display] GPIO 41 | * --- ---- 42 | * SDA <――――――――――> PB9 / 14 (SDA) 43 | * SCL <――――――――――> PB8 / 15 (SCL) 44 | * 45 | * SPI GPIO 46 | * --- ---- 47 | * MOSI <――――――――――> PB15 / 11 (MOSI) 48 | * MISO <――――――――――> PB14 / 12 (MISO) 49 | * SCK <――――――――――> PB13 / 13 (SCK) 50 | * SS <――――――――――> PB6 / 10 (SS) 51 | * SS1 <――――――――――> PB5 / 4 (SS1) 52 | * SS2 <――――――――――> PA8 / 7 (SS2) 53 | * SS3 <――――――――――> PA9 / 8 (SS3) 54 | * 55 | * LoRa GPIO 56 | * ---- ---- 57 | * MOSI <――――――――――> PA7 / 34 (RADIO_MOSI_PORT) 58 | * MISO <――――――――――> PA6 / 35 (RADIO_MISO_PORT) 59 | * SCK <――――――――――> PB3 / 36 (RADIO_SCLK_PORT) 60 | * NSS <――――――――――> PA15 / 37 (RADIO_NSS_PORT) 61 | * RST <――――――――――> PC0 / 33 (RADIO_RESET_PORT) 62 | * RXTX <――――――――――> PA1 / 21 63 | * DIO0 <――――――――――> PB4 / 38 (RADIO_DIO_0_PORT) 64 | * DIO1 <――――――――――> PB1 / 39 (RADIO_DIO_1_PORT) 65 | * DIO2 <――――――――――> PB0 / 40 (RADIO_DIO_2_PORT) 66 | * DIO3 <――――――――――> PC13 / 41 (RADIO_DIO_3_PORT) 67 | * DIO4 <――――――――――> PA5 / 32 (RADIO_DIO_4_PORT) 68 | * DIO5 <――――――――――> PA4 / 28 (RADIO_DIO_5_PORT) 69 | * 70 | * Serial GPIO 71 | * ------ ---- 72 | * RX <――――――――――> PA3 / 0 (PIN_SERIAL_RX) ST-Link RX 73 | * TX <――――――――――> PA2 / 1 (PIN_SERIAL_TX) ST-Link TX 74 | * 75 | * Button switch GPIO 76 | * ------ ---- 77 | * USER <――――――――――> PB2 / 6 (USER_BTN) 78 | * 79 | * Docs: https://docs.platformio.org/en/latest/boards/ststm32/disco_l072cz_lrwan1.html 80 | * 81 | * Definitions: LMIC-node 82 | * board-id: disco_l072cz_lrwan1 83 | * PlatformIO 84 | * board: disco_l072cz_lrwan1 85 | * platform: ststm32 86 | * Arduino 87 | * board: ARDUINO_DISCO_L072CZ_LRWAN1 88 | * architecture: ARDUINO_ARCH_STM32 89 | * 90 | ******************************************************************************/ 91 | 92 | #pragma once 93 | 94 | #ifndef BSF_DISCO_L072CZ_LRWAN1_H_ 95 | #define BSF_DISCO_L072CZ_LRWAN1_H_ 96 | 97 | #include 98 | #include "LMIC-node.h" 99 | 100 | #define DEVICEID_DEFAULT "l072cz-lrwan1" // Default deviceid value 101 | 102 | // Wait for Serial 103 | // Can be useful for boards with MCU with integrated USB support. 104 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 105 | 106 | // LMIC Clock Error 107 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 108 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 109 | // Board appears to work better with clock error enabled (value 4000 empirically determined). 110 | #ifndef LMIC_CLOCK_ERROR_PPM 111 | #define LMIC_CLOCK_ERROR_PPM 4000 112 | #endif 113 | 114 | // Pin mappings for LoRa tranceiver 115 | const lmic_pinmap lmic_pins = { 116 | .nss = PA15, 117 | .rxtx = PA1, 118 | .rst = PC0, 119 | .dio = { /*dio0*/ PB4, /*dio1*/ PB1, /*dio2*/ PB0 } 120 | #ifdef MCCI_LMIC 121 | , 122 | .rxtx_rx_active = 1, 123 | .rssi_cal = 10, 124 | .spi_freq = 8000000 /* 8 MHz */ 125 | #endif 126 | }; 127 | 128 | #ifdef USE_SERIAL 129 | HardwareSerial& serial = Serial; 130 | #endif 131 | 132 | #ifdef USE_LED 133 | EasyLed led(LED_BLUE, EasyLed::ActiveLevel::High); 134 | #endif 135 | 136 | #ifdef USE_DISPLAY 137 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 138 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ PB8, /*sda*/ PB9); 139 | #endif 140 | 141 | #ifndef STM32_POST_INITSERIAL_DELAY_MS 142 | #define STM32_POST_INITSERIAL_DELAY_MS 1500 143 | #endif 144 | 145 | 146 | bool boardInit(InitType initType) 147 | { 148 | // This function is used to perform board specific initializations. 149 | // Required as part of standard template. 150 | 151 | // InitType::Hardware Must be called at start of setup() before anything else. 152 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 153 | 154 | bool success = true; 155 | 156 | switch (initType) 157 | { 158 | case InitType::Hardware: 159 | // Note: Serial port and display are not yet initialized and cannot be used use here. 160 | 161 | // Redefine GPIO pins of default SPI object. 162 | // These pins will be remembered and will not change if any library 163 | // later calls SPI.begin() without parameters. 164 | SPI.setMOSI(PA7); 165 | SPI.setMISO(PA6); 166 | SPI.setSCLK(PB3); 167 | SPI.setSSEL(PA15); 168 | SPI.begin(); 169 | break; 170 | 171 | case InitType::PostInitSerial: 172 | // Note: If enabled Serial port and display are already initialized here. 173 | 174 | // Required workaround: 175 | // Data printed to the serial port during the first second gets lost. 176 | // Inserting a sufficient delay will usually fix this. 177 | #ifdef USE_SERIAL 178 | delay(STM32_POST_INITSERIAL_DELAY_MS); 179 | #endif 180 | break; 181 | } 182 | return success; 183 | } 184 | 185 | 186 | #endif // BSF_DISCO_L072CZ_LRWAN1_H_ -------------------------------------------------------------------------------- /src/boards/bsf_heltec_wifi_lora_32.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_heltec_wifi_lora_32.h 4 | * 5 | * Function: Board Support File for Heltec Wifi LoRa 32 (1.x versions). 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * Has onboard display. 16 | * 17 | * The standard I2C pins defined in the BSP do not match the 18 | * GPIO pins that the display is connected to. Therefore the 19 | * the I2C Wire object is explicitly initialized with the 20 | * correct pins (see boardInit() below). 21 | * 22 | * CONNECTIONS AND PIN DEFINITIONS: 23 | * 24 | * Indentifiers between parentheses are defined in the board's 25 | * Board Support Package (BSP) which is part of the Arduino core. 26 | * 27 | * Leds GPIO 28 | * ---- ---- 29 | * LED <――――――――――> 25 (LED_BUILTIN) Active-high 30 | * 31 | * I2C/Display GPIO 32 | * --- ---- 33 | * SDA <――――――――――> 4 (SDA_OLED) - NOT SDA! 34 | * SCL <――――――――――> 15 (SCL_OLED) - NOT SCL! 35 | * RST <――――――――――> 16 (RST_OLED) 36 | * - 21 (SDA) 37 | * - 22 (SCL) 38 | * 39 | * SPI/LoRa GPIO 40 | * --- ---- 41 | * MOSI <――――――――――> 27 (MOSI) 42 | * MISO <――――――――――> 19 (MISO) 43 | * SCK <――――――――――> 5 (SCK) 44 | * NSS <――――――――――> 18 (SS) 45 | * RST <――――――――――> 14 (RST_LoRa) 46 | * DIO0 <――――――――――> 26 (DIO0) 47 | * DIO1 <――――――――――> 33 (DIO1) 48 | * DIO2 <――――――――――> 32 (DIO2) 49 | * 50 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/heltec_wifi_lora_32.html 51 | * 52 | * Identifiers: LMIC-node: 53 | * board-id: heltec_wifi_lora_32 54 | * PlatformIO 55 | * board: heltec_wifi_lora_32 56 | * platform: espressif32 57 | * Arduino 58 | * board: ARDUINO_HELTEC_WIFI_LORA_32 59 | * architecture: ARDUINO_ARCH_ESP32 60 | * 61 | ******************************************************************************/ 62 | 63 | #pragma once 64 | 65 | #ifndef BSF_HELTEC_WIFI_LORA_32_H_ 66 | #define BSF_HELTEC_WIFI_LORA_32_H_ 67 | 68 | #include "LMIC-node.h" 69 | 70 | #define DEVICEID_DEFAULT "wifi-lora-32" // Default deviceid value 71 | 72 | // Wait for Serial 73 | // Can be useful for boards with MCU with integrated USB support. 74 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 75 | 76 | // LMIC Clock Error 77 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 78 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 79 | // #ifndef LMIC_CLOCK_ERROR_PPM 80 | // #define LMIC_CLOCK_ERROR_PPM 0 81 | // #endif 82 | 83 | // Pin mappings for LoRa tranceiver 84 | const lmic_pinmap lmic_pins = { 85 | .nss = 18, 86 | .rxtx = LMIC_UNUSED_PIN, 87 | .rst =14, 88 | .dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 } 89 | #ifdef MCCI_LMIC 90 | , 91 | .rxtx_rx_active = 0, 92 | .rssi_cal = 10, 93 | .spi_freq = 8000000 /* 8 MHz */ 94 | #endif 95 | }; 96 | 97 | #ifdef USE_SERIAL 98 | HardwareSerial& serial = Serial; 99 | #endif 100 | 101 | #ifdef USE_LED 102 | EasyLed led(25, EasyLed::ActiveLevel::High); 103 | #endif 104 | 105 | #ifdef USE_DISPLAY 106 | // Create U8x8 instance for SSD1306 OLED display using hardware I2C. 107 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ 16, /*scl*/ 15, /*sda*/ 4); 108 | #endif 109 | 110 | 111 | bool boardInit(InitType initType) 112 | { 113 | // This function is used to perform board specific initializations. 114 | // Required as part of standard template. 115 | 116 | // InitType::Hardware Must be called at start of setup() before anything else. 117 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 118 | 119 | bool success = true; 120 | switch (initType) 121 | { 122 | case InitType::Hardware: 123 | // Note: Serial port and display are not yet initialized and cannot be used use here. 124 | 125 | #ifdef USE_DISPLAY 126 | // Initialize I2C Wire object with GPIO pins the display is connected to. 127 | // These pins will be remembered and will not change if any library 128 | // later calls Wire.begin() without parameters. 129 | Wire.begin(/*sda*/ 4, /*scl*/ 15); 130 | #endif 131 | break; 132 | 133 | case InitType::PostInitSerial: 134 | // Note: If enabled Serial port and display are already initialized here. 135 | // No actions required for this board. 136 | break; 137 | } 138 | return success; 139 | } 140 | 141 | 142 | #endif // BSF_HELTEC_WIFI_LORA_32_H_ -------------------------------------------------------------------------------- /src/boards/bsf_heltec_wifi_lora_32_v2.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_heltec_wifi_lora_32_v2.h 4 | * 5 | * Function: Board Support File for Heltec Wifi LoRa 32 V2. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * Has onboard display. 16 | * 17 | * The standard I2C pins defined in the BSP do not match the 18 | * GPIO pins that the display is connected to. Therefore the 19 | * the I2C Wire object is explicitly initialized with the 20 | * correct pins (see boardInit() below). 21 | * 22 | * WARNING: Vext and the standard I2C SDA pin are both defined as GPIO21. 23 | * 24 | * CONNECTIONS AND PIN DEFINITIONS: 25 | * 26 | * Indentifiers between parentheses are defined in the board's 27 | * Board Support Package (BSP) which is part of the Arduino core. 28 | * 29 | * Leds GPIO 30 | * ---- ---- 31 | * LED <――――――――――> 25 (LED_BUILTIN) Active-high 32 | * 33 | * I2C/Display GPIO 34 | * --- ---- 35 | * SDA <――――――――――> 4 (SDA_OLED) - NOT SDA! 36 | * SCL <――――――――――> 15 (SCL_OLED) - NOT SCL! 37 | * RST <――――――――――> 16 (RST_OLED) 38 | * - 21 (SDA) used for VExt!!! 39 | * - 22 (SCL) 40 | * 41 | * SPI/LoRa GPIO 42 | * --- ---- 43 | * MOSI <――――――――――> 27 (MOSI) 44 | * MISO <――――――――――> 19 (MISO) 45 | * SCK <――――――――――> 5 (SCK) 46 | * NSS <――――――――――> 18 (SS) 47 | * RST <――――――――――> 14 (RST_LoRa) 48 | * DIO0 <――――――――――> 26 (DIO0) 49 | * DIO1 <――――――――――> 35 (DIO1) 50 | * DIO2 <――――――――――> 34 (DIO2) 51 | * 52 | * Other GPIO 53 | * ----- ---- 54 | * VExt <――――――――――> 21 (Vext, SDA) Active-low 55 | * 56 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/heltec_wifi_lora_32_V2.html 57 | * 58 | * Identifiers: LMIC-node: 59 | * board-id: heltec_wifi_lora_32_v2 60 | * PlatformIO 61 | * board: heltec_wifi_lora_32_V2 62 | * platform: espressif32 63 | * Arduino 64 | * board: ARDUINO_HELTEC_WIFI_LORA_32_V2 65 | * architecture: ARDUINO_ARCH_ESP32 66 | * 67 | ******************************************************************************/ 68 | 69 | #pragma once 70 | 71 | #ifndef BSF_HELTEC_WIFI_LORA_32_V2_H_ 72 | #define BSF_HELTEC_WIFI_LORA_32_V2_H_ 73 | 74 | #include "LMIC-node.h" 75 | 76 | #define DEVICEID_DEFAULT "wifi-lora-32-v2" // Default deviceid value 77 | 78 | // Wait for Serial 79 | // Can be useful for boards with MCU with integrated USB support. 80 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 81 | 82 | // LMIC Clock Error 83 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 84 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 85 | // #ifndef LMIC_CLOCK_ERROR_PPM 86 | // #define LMIC_CLOCK_ERROR_PPM 0 87 | // #endif 88 | 89 | // Pin mappings for LoRa tranceiver 90 | const lmic_pinmap lmic_pins = { 91 | .nss = 18, 92 | .rxtx = LMIC_UNUSED_PIN, 93 | .rst =14, 94 | .dio = { /*dio0*/ 26, /*dio1*/ 35, /*dio2*/ 34 } 95 | #ifdef MCCI_LMIC 96 | , 97 | .rxtx_rx_active = 0, 98 | .rssi_cal = 10, 99 | .spi_freq = 8000000 /* 8 MHz */ 100 | #endif 101 | }; 102 | 103 | #ifdef USE_SERIAL 104 | HardwareSerial& serial = Serial; 105 | #endif 106 | 107 | #ifdef USE_LED 108 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High); 109 | #endif 110 | 111 | #ifdef USE_DISPLAY 112 | // Create U8x8 instance for SSD1306 OLED display using hardware I2C. 113 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ 16, /*scl*/ 15, /*sda*/ 4); 114 | #endif 115 | 116 | 117 | bool boardInit(InitType initType) 118 | { 119 | // This function is used to perform board specific initializations. 120 | // Required as part of standard template. 121 | 122 | // InitType::Hardware Must be called at start of setup() before anything else. 123 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 124 | 125 | bool success = true; 126 | switch (initType) 127 | { 128 | case InitType::Hardware: 129 | // Note: Serial port and display are not yet initialized and cannot be used use here. 130 | 131 | #ifdef USE_DISPLAY 132 | // Initialize I2C Wire object with GPIO pins the display is connected to. 133 | // These pins will be remembered and will not change if any library 134 | // later calls Wire.begin() without parameters. 135 | Wire.begin(/*sda*/ 4, /*scl*/ 15); 136 | #endif 137 | break; 138 | 139 | case InitType::PostInitSerial: 140 | // Note: If enabled Serial port and display are already initialized here. 141 | // No actions required for this board. 142 | break; 143 | } 144 | return success; 145 | } 146 | 147 | 148 | #endif // BSF_HELTEC_WIFI_LORA_32_V2_H_ -------------------------------------------------------------------------------- /src/boards/bsf_heltec_wireless_stick.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_heltec_wireless_stick.h 4 | * 5 | * Function: Board Support File for Heltec Wireless Stick. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * Has onboard display (SSD1306 I2C OLED display 0.49" 64x32). 16 | * Display is not supported by LMIC-node because resolution is too low. 17 | * 18 | * The standard I2C pins defined in the BSP do not match the 19 | * GPIO pins that the display is connected to. Therefore the 20 | * the I2C Wire object is explicitly initialized with the 21 | * correct pins (see boardInit() below). 22 | * 23 | * WARNING: Vext and the standard I2C SDA pin are both defined as GPIO21. 24 | * 25 | * CONNECTIONS AND PIN DEFINITIONS: 26 | * 27 | * Indentifiers between parentheses are defined in the board's 28 | * Board Support Package (BSP) which is part of the Arduino core. 29 | * 30 | * Leds GPIO 31 | * ---- ---- 32 | * LED <――――――――――> 25 (LED_BUILTIN) Active-high 33 | * 34 | * I2C/Display GPIO 35 | * ---- ---- 36 | * SDA <――――――――――> 4 (SDA_OLED) - NOT SDA! 37 | * SCL <――――――――――> 15 (SCL_OLED) - NOT SCL! 38 | * RST <――――――――――> 16 (RST_OLED) 39 | * - 21 (SDA, Vext) used for VExt!!! 40 | * - 22 (SCL) 41 | * 42 | * SPI/LoRa GPIO 43 | * --- ---- 44 | * MOSI <――――――――――> 27 (MOSI) 45 | * MISO <――――――――――> 19 (MISO) 46 | * SCK <――――――――――> 5 (SCK) 47 | * NSS <――――――――――> 18 (SS) 48 | * RST <――――――――――> 14 (RST_LoRa) 49 | * DIO0 <――――――――――> 26 (DIO0) 50 | * DIO1 <――――――――――> 35 (DIO1) 51 | * DIO2 <――――――――――> 34 (DIO2) 52 | * 53 | * Other GPIO 54 | * ----- ---- 55 | * VExt <――――――――――> 21 (Vext, SDA) Active-low - see remarks 56 | * 57 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/heltec_wireless_stick.html 58 | * 59 | * Identifiers: LMIC-node: 60 | * board-id: heltec_wireless_stick 61 | * PlatformIO 62 | * board: heltec_wireless_stick 63 | * platform: espressif32 64 | * Arduino 65 | * board: ARDUINO_HELTEC_WIRELESS_STICK 66 | * architecture: ARDUINO_ARCH_ESP32 67 | * 68 | ******************************************************************************/ 69 | 70 | #pragma once 71 | 72 | #ifndef BSF_HELTEC_WIRELESS_STICK_H_ 73 | #define BSF_HELTEC_WIRELESS_STICK_H_ 74 | 75 | #include "LMIC-node.h" 76 | 77 | #define DEVICEID_DEFAULT "wireless-stick" // Default deviceid value 78 | 79 | // Wait for Serial 80 | // Can be useful for boards with MCU with integrated USB support. 81 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 82 | 83 | // LMIC Clock Error 84 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 85 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 86 | // #ifndef LMIC_CLOCK_ERROR_PPM 87 | // #define LMIC_CLOCK_ERROR_PPM 0 88 | // #endif 89 | 90 | // Pin mappings for LoRa tranceiver 91 | const lmic_pinmap lmic_pins = { 92 | .nss = 18, 93 | .rxtx = LMIC_UNUSED_PIN, 94 | .rst =14, 95 | .dio = { /*dio0*/ 26, /*dio1*/ 35, /*dio2*/ 34 } 96 | #ifdef MCCI_LMIC 97 | , 98 | .rxtx_rx_active = 0, 99 | .rssi_cal = 10, 100 | .spi_freq = 8000000 /* 8 MHz */ 101 | #endif 102 | }; 103 | 104 | #ifdef USE_SERIAL 105 | HardwareSerial& serial = Serial; 106 | #endif 107 | 108 | #ifdef USE_LED 109 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High); 110 | #endif 111 | 112 | #ifdef USE_DISPLAY 113 | #error Invalid option: USE_DISPLAY. Onboard display is not supported because resolution is too low. 114 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 115 | U8X8_SSD1306_64X32_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ 15, /*sda*/ 4); 116 | #endif 117 | 118 | 119 | bool boardInit(InitType initType) 120 | { 121 | // This function is used to perform board specific initializations. 122 | // Required as part of standard template. 123 | 124 | // InitType::Hardware Must be called at start of setup() before anything else. 125 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 126 | 127 | bool success = true; 128 | switch (initType) 129 | { 130 | case InitType::Hardware: 131 | // Note: Serial port and display are not yet initialized and cannot be used use here. 132 | 133 | #ifdef USE_DISPLAY 134 | // Initialize I2C Wire object with GPIO pins the display is connected to. 135 | // These pins will be remembered and will not change if any library 136 | // later calls Wire.begin() without parameters. 137 | Wire.begin(/*sda*/ 4, /*scl*/ 15); 138 | #endif 139 | break; 140 | 141 | case InitType::PostInitSerial: 142 | // Note: If enabled Serial port and display are already initialized here. 143 | // No actions required for this board. 144 | break; 145 | } 146 | return success; 147 | } 148 | 149 | 150 | #endif // BSF_HELTEC_WIRELESS_STICK_H_ -------------------------------------------------------------------------------- /src/boards/bsf_heltec_wireless_stick_lite.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_heltec_wireless_stick_lite.h 4 | * 5 | * Function: Board Support File for Heltec Wireless Stick Lite. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display con be connected. 16 | * 17 | * The standard I2C pins defined in the BSP do not match the 18 | * GPIO pins that the display is connected to. Therefore the 19 | * the I2C Wire object is explicitly initialized with the 20 | * correct pins (see boardInit() below). 21 | * 22 | * WARNING: Vext and the standard I2C SDA pin are both defined as GPIO21. 23 | * 24 | * Connect the LoRa module and optional display 25 | * according to below connection details. 26 | * 27 | * CONNECTIONS AND PIN DEFINITIONS: 28 | * 29 | * Indentifiers between parentheses are defined in the board's 30 | * Board Support Package (BSP) which is part of the Arduino core. 31 | * 32 | * Leds GPIO 33 | * ---- ---- 34 | * LED <――――――――――> 25 (LED_BUILTIN) Active-high 35 | * 36 | * I2C [display] GPIO 37 | * ---- ---- 38 | * SDA <――――――――――> 4 NOT SDA! 39 | * SCL <――――――――――> 15 NOT SCL! 40 | * - 21 (SDA, Vext) used for VExt!!! 41 | * - 22 (SCL) 42 | * 43 | * SPI/LoRa GPIO 44 | * --- ---- 45 | * MOSI <――――――――――> 27 (MOSI) 46 | * MISO <――――――――――> 19 (MISO) 47 | * SCK <――――――――――> 5 (SCK) 48 | * NSS <――――――――――> 18 (SS) 49 | * RST <――――――――――> 14 (RST_LoRa) 50 | * DIO0 <――――――――――> 26 (DIO0) 51 | * DIO1 <――――――――――> 35 (DIO1) 52 | * DIO2 <――――――――――> 34 (DIO2) 53 | * 54 | * Other GPIO 55 | * ----- ---- 56 | * VExt <――――――――――> 21 (Vext, SDA) Active-low 57 | * 58 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/heltec_wireless_stick_lite.html 59 | * 60 | * Identifiers: LMIC-node: 61 | * board-id: heltec_wireless_stick_lite 62 | * PlatformIO 63 | * board: heltec_wireless_stick_lite 64 | * platform: espressif32 65 | * Arduino 66 | * board: ARDUINO_HELTEC_WIRELESS_STICK_LITE 67 | * architecture: ARDUINO_ARCH_ESP32 68 | * 69 | ******************************************************************************/ 70 | 71 | #pragma once 72 | 73 | #ifndef BSF_HELTEC_WIRELESS_STICK_LITE_H_ 74 | #define BSF_HELTEC_WIRELESS_STICK_LITE_H_ 75 | 76 | #include "LMIC-node.h" 77 | 78 | #define DEVICEID_DEFAULT "wireless-sticklt" // Default deviceid value 79 | 80 | // Wait for Serial 81 | // Can be useful for boards with MCU with integrated USB support. 82 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 83 | 84 | // LMIC Clock Error 85 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 86 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 87 | // #ifndef LMIC_CLOCK_ERROR_PPM 88 | // #define LMIC_CLOCK_ERROR_PPM 0 89 | // #endif 90 | 91 | // Pin mappings for LoRa tranceiver 92 | const lmic_pinmap lmic_pins = { 93 | .nss = 18, 94 | .rxtx = LMIC_UNUSED_PIN, 95 | .rst =14, 96 | .dio = { /*dio0*/ 26, /*dio1*/ 35, /*dio2*/ 34 } 97 | #ifdef MCCI_LMIC 98 | , 99 | .rxtx_rx_active = 0, 100 | .rssi_cal = 10, 101 | .spi_freq = 8000000 /* 8 MHz */ 102 | #endif 103 | }; 104 | 105 | #ifdef USE_SERIAL 106 | HardwareSerial& serial = Serial; 107 | #endif 108 | 109 | #ifdef USE_LED 110 | EasyLed led(25, EasyLed::ActiveLevel::High); 111 | #endif 112 | 113 | #ifdef USE_DISPLAY 114 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 115 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ 15, /*sda*/ 4); 116 | #endif 117 | 118 | 119 | bool boardInit(InitType initType) 120 | { 121 | // This function is used to perform board specific initializations. 122 | // Required as part of standard template. 123 | 124 | // InitType::Hardware Must be called at start of setup() before anything else. 125 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 126 | 127 | bool success = true; 128 | switch (initType) 129 | { 130 | case InitType::Hardware: 131 | // Note: Serial port and display are not yet initialized and cannot be used use here. 132 | 133 | #ifdef USE_DISPLAY 134 | // Initialize I2C Wire object with GPIO pins the display is connected to. 135 | // These pins will be remembered and will not change if any library 136 | // later calls Wire.begin() without parameters. 137 | Wire.begin(/*sda*/ 4, /*scl*/ 15); 138 | #endif 139 | break; 140 | 141 | case InitType::PostInitSerial: 142 | // Note: If enabled Serial port and display are already initialized here. 143 | // No actions required for this board. 144 | break; 145 | } 146 | return success; 147 | } 148 | 149 | 150 | #endif // BSF_HELTEC_WIRELESS_STICK_LITE_H_ -------------------------------------------------------------------------------- /src/boards/bsf_lolin32.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_lolin32.h 4 | * 5 | * Function: Board Support File for Lolin32 with external SPI LoRa module. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display can be connected. 16 | * 17 | * Connect the LoRa module and optional display 18 | * according to below connection details. 19 | * 20 | * CONNECTIONS AND PIN DEFINITIONS: 21 | * 22 | * Indentifiers between parentheses are defined in the board's 23 | * Board Support Package (BSP) which is part of the Arduino core. 24 | * 25 | * Leds GPIO 26 | * ---- ---- 27 | * LED <――――――――――> 5 (LED_BUILTIN) (SS) Active-low 28 | * Conflicts with SS. 29 | * 30 | * I2C [display] GPIO 31 | * --- ---- 32 | * SDA <――――――――――> 21 (SDA) 33 | * SCL <――――――――――> 22 (SCL) 34 | * 35 | * SPI/LoRa module GPIO 36 | * --- ---- 37 | * MOSI <――――――――――> 23 (MOSI) 38 | * MISO <――――――――――> 19 (MISO) 39 | * SCK <――――――――――> 18 (SCK) 40 | * NSS <――――――――――> 32 Do not use SS because conflicts with LED_BUILTIN. 41 | * RST <――――――――――> 33 42 | * DIO0 <――――――――――> 34 43 | * DIO1 <――――――――――> 35 44 | * DIO2 - Not needed for LoRa. 45 | * 46 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/lolin32.html 47 | * 48 | * Identifiers: LMIC-node 49 | * board: lolin32 50 | * PlatformIO 51 | * board: lolin32 52 | * platform: espressif32 53 | * Arduino 54 | * board: ARDUINO_LOLIN32 55 | * architecture: ARDUINO_ARCH_ESP32 56 | * 57 | ******************************************************************************/ 58 | 59 | #pragma once 60 | 61 | #ifndef BSF_LOLIN32_H_ 62 | #define BSF_LOLIN32_H_ 63 | 64 | #include "LMIC-node.h" 65 | 66 | #define DEVICEID_DEFAULT "lolin32" // Default deviceid value 67 | 68 | // Wait for Serial 69 | // Can be useful for boards with MCU with integrated USB support. 70 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 71 | 72 | // LMIC Clock Error 73 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 74 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 75 | // #ifndef LMIC_CLOCK_ERROR_PPM 76 | // #define LMIC_CLOCK_ERROR_PPM 0 77 | // #endif 78 | 79 | // Pin mappings for LoRa tranceiver 80 | const lmic_pinmap lmic_pins = { 81 | .nss = 32, 82 | .rxtx = LMIC_UNUSED_PIN, 83 | .rst =33, 84 | .dio = { /*dio0*/ 34, /*dio1*/ 35, /*dio2*/ LMIC_UNUSED_PIN } 85 | #ifdef MCCI_LMIC 86 | , 87 | .rxtx_rx_active = 0, 88 | .rssi_cal = 10, 89 | .spi_freq = 8000000 /* 8 MHz */ 90 | #endif 91 | }; 92 | 93 | #ifdef USE_SERIAL 94 | HardwareSerial& serial = Serial; 95 | #endif 96 | 97 | #ifdef USE_LED 98 | EasyLed led(5, EasyLed::ActiveLevel::Low); 99 | #endif 100 | 101 | #ifdef USE_DISPLAY 102 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 103 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 104 | #endif 105 | 106 | 107 | bool boardInit(InitType initType) 108 | { 109 | // This function is used to perform board specific initializations. 110 | // Required as part of standard template. 111 | 112 | // InitType::Hardware Must be called at start of setup() before anything else. 113 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 114 | 115 | bool success = true; 116 | switch (initType) 117 | { 118 | case InitType::Hardware: 119 | // Note: Serial port and display are not yet initialized and cannot be used use here. 120 | // No actions required for this board. 121 | break; 122 | 123 | case InitType::PostInitSerial: 124 | // Note: If enabled Serial port and display are already initialized here. 125 | // No actions required for this board. 126 | break; 127 | } 128 | return success; 129 | } 130 | 131 | 132 | #endif // BSF_LOLIN32_H_ -------------------------------------------------------------------------------- /src/boards/bsf_lolin_d32.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_lolin_d32.h 4 | * 5 | * Function: Board Support File for Lolin D32 with external SPI LoRa module. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display can be connected. 16 | * 17 | * Connect the LoRa module and optional display 18 | * according to below connection details. 19 | * 20 | * CONNECTIONS AND PIN DEFINITIONS: 21 | * 22 | * Indentifiers between parentheses are defined in the board's 23 | * Board Support Package (BSP) which is part of the Arduino core. 24 | * 25 | * Leds GPIO 26 | * ---- ---- 27 | * LED <――――――――――> 5 (LED_BUILTIN) (SS) Active-low 28 | * Conflicts with SS. 29 | * 30 | * I2C [display] GPIO 31 | * --- ---- 32 | * SDA <――――――――――> 21 (SDA) 33 | * SCL <――――――――――> 22 (SCL) 34 | * 35 | * SPI/LoRa module GPIO 36 | * --- ---- 37 | * MOSI <――――――――――> 23 (MOSI) 38 | * MISO <――――――――――> 19 (MISO) 39 | * SCK <――――――――――> 18 (SCK) 40 | * NSS <――――――――――> 27 Do not use SS because conflicts with LED_BUILTIN. 41 | * RST <――――――――――> 32 42 | * DIO0 <――――――――――> 33 43 | * DIO1 <――――――――――> 34 44 | * DIO2 - Not needed for LoRa. 45 | * 46 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/lolin_d32.html 47 | * 48 | * Identifiers: LMIC-node 49 | * board-id: lolin_d32 50 | * PlatformIO 51 | * board: lolin_d32 52 | * platform: espressif32 53 | * Arduino 54 | * board: ARDUINO_LOLIN_D32 55 | * architecture: ARDUINO_ARCH_ESP32 56 | * 57 | ******************************************************************************/ 58 | 59 | #pragma once 60 | 61 | #ifndef BSF_LOLIN_D32_H_ 62 | #define BSF_LOLIN_D32_H_ 63 | 64 | #include "LMIC-node.h" 65 | 66 | #define DEVICEID_DEFAULT "lolin-d32" // Default deviceid value 67 | 68 | // Wait for Serial 69 | // Can be useful for boards with MCU with integrated USB support. 70 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 71 | 72 | // LMIC Clock Error 73 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 74 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 75 | // #ifndef LMIC_CLOCK_ERROR_PPM 76 | // #define LMIC_CLOCK_ERROR_PPM 0 77 | // #endif 78 | 79 | // Pin mappings for LoRa tranceiver 80 | const lmic_pinmap lmic_pins = { 81 | .nss = 27, 82 | .rxtx = LMIC_UNUSED_PIN, 83 | .rst =32, 84 | .dio = { /*dio0*/ 33, /*dio1*/ 34, /*dio2*/ LMIC_UNUSED_PIN } 85 | #ifdef MCCI_LMIC 86 | , 87 | .rxtx_rx_active = 0, 88 | .rssi_cal = 10, 89 | .spi_freq = 8000000 /* 8 MHz */ 90 | #endif 91 | }; 92 | 93 | #ifdef USE_SERIAL 94 | HardwareSerial& serial = Serial; 95 | #endif 96 | 97 | #ifdef USE_LED 98 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low); 99 | #endif 100 | 101 | #ifdef USE_DISPLAY 102 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 103 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 104 | #endif 105 | 106 | 107 | bool boardInit(InitType initType) 108 | { 109 | // This function is used to perform board specific initializations. 110 | // Required as part of standard template. 111 | 112 | // InitType::Hardware Must be called at start of setup() before anything else. 113 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 114 | 115 | bool success = true; 116 | switch (initType) 117 | { 118 | case InitType::Hardware: 119 | // Note: Serial port and display are not yet initialized and cannot be used use here. 120 | // No actions required for this board. 121 | break; 122 | 123 | case InitType::PostInitSerial: 124 | // Note: If enabled Serial port and display are already initialized here. 125 | // No actions required for this board. 126 | break; 127 | } 128 | return success; 129 | } 130 | 131 | 132 | #endif // BSF_LOLIN_D32_H_ -------------------------------------------------------------------------------- /src/boards/bsf_lolin_d32_pro.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_lolin_d32_pro.h 4 | * 5 | * Function: Board Support File for Lolin D32 Pro with external SPI LoRa module. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display can be connected. 16 | * 17 | * Connect the LoRa module and optional display 18 | * according to below connection details. 19 | * 20 | * CONNECTIONS AND PIN DEFINITIONS: 21 | * 22 | * Indentifiers between parentheses are defined in the board's 23 | * Board Support Package (BSP) which is part of the Arduino core. 24 | * 25 | * Leds GPIO 26 | * ---- ---- 27 | * LED <――――――――――> 5 (LED_BUILTIN) (SS) Active-low 28 | * Conflicts with SS. 29 | * 30 | * I2C [display] GPIO 31 | * --- ---- 32 | * SDA <――――――――――> 21 (SDA) 33 | * SCL <――――――――――> 22 (SCL) 34 | * 35 | * SPI/LoRa module GPIO 36 | * --- ---- 37 | * MOSI <――――――――――> 23 (MOSI) 38 | * MISO <――――――――――> 19 (MISO) 39 | * SCK <――――――――――> 18 (SCK) 40 | * NSS <――――――――――> 27 Do not use SS because conflicts with LED_BUILTIN. 41 | * RST <――――――――――> 32 42 | * DIO0 <――――――――――> 33 43 | * DIO1 <――――――――――> 34 44 | * DIO2 - Not needed for LoRa. 45 | * 46 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/lolin_d32_pro.html 47 | * 48 | * Identifiers: LMIC-node 49 | * board-id: lolin_d32_pro 50 | * PlatformIO 51 | * board: lolin_d32_pro 52 | * platform: espressif32 53 | * Arduino 54 | * board: ARDUINO_LOLIN_D32_PRO 55 | * architecture: ARDUINO_ARCH_ESP32 56 | * 57 | ******************************************************************************/ 58 | 59 | #pragma once 60 | 61 | #ifndef BSF_LOLIN_D32_PRO_H_ 62 | #define BSF_LOLIN_D32_PRO_H_ 63 | 64 | #include "LMIC-node.h" 65 | 66 | #define DEVICEID_DEFAULT "lolin-d32-pro" // Default deviceid value 67 | 68 | // Wait for Serial 69 | // Can be useful for boards with MCU with integrated USB support. 70 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 71 | 72 | // LMIC Clock Error 73 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 74 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 75 | // #ifndef LMIC_CLOCK_ERROR_PPM 76 | // #define LMIC_CLOCK_ERROR_PPM 0 77 | // #endif 78 | 79 | // Pin mappings for LoRa tranceiver 80 | const lmic_pinmap lmic_pins = { 81 | .nss = 27, 82 | .rxtx = LMIC_UNUSED_PIN, 83 | .rst = 32, 84 | .dio = { /*dio0*/ 33, /*dio1*/ 34, /*dio2*/ LMIC_UNUSED_PIN } 85 | #ifdef MCCI_LMIC 86 | , 87 | .rxtx_rx_active = 0, 88 | .rssi_cal = 10, 89 | .spi_freq = 8000000 /* 8 MHz */ 90 | #endif 91 | }; 92 | 93 | #ifdef USE_SERIAL 94 | HardwareSerial& serial = Serial; 95 | #endif 96 | 97 | #ifdef USE_LED 98 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low); 99 | #endif 100 | 101 | #ifdef USE_DISPLAY 102 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 103 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 104 | #endif 105 | 106 | 107 | bool boardInit(InitType initType) 108 | { 109 | // This function is used to perform board specific initializations. 110 | // Required as part of standard template. 111 | 112 | // InitType::Hardware Must be called at start of setup() before anything else. 113 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 114 | 115 | bool success = true; 116 | switch (initType) 117 | { 118 | case InitType::Hardware: 119 | // Note: Serial port and display are not yet initialized and cannot be used use here. 120 | // No actions required for this board. 121 | break; 122 | 123 | case InitType::PostInitSerial: 124 | // Note: If enabled Serial port and display are already initialized here. 125 | // No actions required for this board. 126 | break; 127 | } 128 | return success; 129 | } 130 | 131 | 132 | #endif // BSF_LOLIN_D32_PRO_H_ -------------------------------------------------------------------------------- /src/boards/bsf_lopy4.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_lopy4.h 4 | * 5 | * Description: Board Support File for Pycom LoPy4. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This Board has no onboard USB and no onboard display. 14 | * Optionally an external display can be connected. 15 | * Has onboard LED but this is a special WS2812 RGB LED which requires 16 | * a separate library and is currently not supported by LMIC-node. 17 | * 18 | * The standard SPI pins defined in the BSP do not match the 19 | * GPIO pins that the SX1276 LoRa chip is connected to. 20 | * LMIC uses the default SPI parameters for initializing the SPI bus 21 | * which will not work here. Therefore the SPI object is explicitly 22 | * initialized with the correct pins (see boardInit() below). 23 | * 24 | * For firmware upload and serial monitor use a USB to serial adapter. 25 | * Lopy4 is made for use with MicroPython and does not provide 26 | * automatic upload for C/C++ firmware (and no GPIO0 button). 27 | * To put an ESP32 in firmware upload mode: First press the GPIO0 28 | * button, then while keeping it pressed press the reset button, 29 | * then release the reset button and then release the GPIO0 button. 30 | * Because the Lopy4 does not have a GPIO0 button, instead of pressing 31 | * the GPIO0 button connect a wire from GPIO0 (labeled '2' on the PCB) 32 | * to GND and instead of releasing the GPIO0 button remove the wire again. 33 | * Pycom also sells an Expansion board with onboard USB that 34 | * supports firmware upload and serial over USB. The upload is not 35 | * automatic however and the ESP32 must still be put in upload mode 36 | * manually which still requires a wire because it also has no GPIO0 button. 37 | * After firmware upload the Lopy4 must be manually reset (with button). 38 | * 39 | * LoRa DIO0, DIO1 and DIO2 are all wired (via diodes) to the same single GPIO port. 40 | * 41 | * WARNING: The 3.3V pin is OUTPUT ONLY don't use it to power the board!! 42 | * The board must be powered on pin Vin with +3.5V to +5V. 43 | * 44 | * Connect the LoRa module and optional display 45 | * according to below connection details. 46 | * 47 | * CONNECTIONS AND PIN DEFINITIONS: 48 | * 49 | * Indentifiers between parentheses are defined in the board's 50 | * Board Support Package (BSP) which is part of the Arduino core. 51 | * 52 | * Leds GPIO 53 | * ---- ---- 54 | * WS2812 <---------> 0 (LED_BUILTIN) WS2812 RGB LED, not regular LED! 55 | * pin labeled '2' on the PCB. 56 | * 57 | * I2C [display] GPIO 58 | * --- ---- 59 | * SDA <――――――――――> 12 (SDA) 60 | * SCL <――――――――――> 13 (SCL) 61 | * 62 | * SPI GPIO 63 | * --- ---- 64 | * MOSI <――――――――――> 22 (MOSI) 65 | * MISO <――――――――――> 37 (MISO) 66 | * SCK <――――――――――> 13 (SCK) 67 | * SS <――――――――――> 18 (SS) 68 | * 69 | * LoRa GPIO 70 | * ---- ---- 71 | * MOSI <――――――――――> 27 (LORA_MOSI) 72 | * MISO <――――――――――> 19 (LORA_MISO) 73 | * SCK <――――――――――> 5 (LORA_SCK) 74 | * NSS <――――――――――> 18 (LORA_CS) 75 | * RST - 76 | * RXTX - 77 | * DIO0 <――――――――――> 23 (LORA_IRQ, LORA_IO0) 78 | * DIO1 <――――――――――> 23 (LORA_IRQ, LORA_IO1) 79 | * DIO2 <――――――――――> 23 (LORA_IRQ, LORA_IO2) 80 | * 81 | * Serial GPIO 82 | * ------ ---- 83 | * RX <――――――――――> 3 (RX) pin labeled '0' on the PCB. 84 | * TX <――――――――――> 1 (TX) pin labeled '1' on the PCB. 85 | * 86 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/lopy4.html 87 | * 88 | * Identifiers: LMIC-node 89 | * board-id: lopy4 90 | * PlatformIO 91 | * board: lopy4 92 | * platform: espressif32 93 | * Arduino 94 | * board: ARDUINO_LoPy4 95 | * architecture: ARDUINO_ARCH_ESP32 96 | * 97 | ******************************************************************************/ 98 | 99 | #pragma once 100 | 101 | #ifndef BSF_LOPY4_H_ 102 | #define BSF_LOPY4_H_ 103 | 104 | #include 105 | #include "LMIC-node.h" 106 | 107 | #define DEVICEID_DEFAULT "lopy4" // Default deviceid value 108 | 109 | // Wait for Serial 110 | // Can be useful for boards with MCU with integrated USB support. 111 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 112 | 113 | // LMIC Clock Error 114 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 115 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 116 | // #ifndef LMIC_CLOCK_ERROR_PPM 117 | // #define LMIC_CLOCK_ERROR_PPM 0 118 | // #endif 119 | 120 | // Pin mappings for LoRa tranceiver 121 | const lmic_pinmap lmic_pins = { 122 | .nss = 18, 123 | .rxtx = LMIC_UNUSED_PIN, 124 | .rst =LMIC_UNUSED_PIN, 125 | .dio = { /*dio0*/ 23, /*dio1*/ 23, /*dio2*/ 23 } 126 | #ifdef MCCI_LMIC 127 | , 128 | .rxtx_rx_active = 0, 129 | .rssi_cal = 10, 130 | .spi_freq = 8000000 /* 8 MHz */ 131 | #endif 132 | }; 133 | 134 | #ifdef USE_SERIAL 135 | HardwareSerial& serial = Serial; 136 | #endif 137 | 138 | #ifdef USE_LED 139 | #error "Invalid option: USE_LED. Onboard WS2812 RGB LED is currently not supported." 140 | #endif 141 | 142 | #ifdef USE_DISPLAY 143 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 144 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 145 | #endif 146 | 147 | 148 | bool boardInit(InitType initType) 149 | { 150 | // This function is used to perform board specific initializations. 151 | // Required as part of standard template. 152 | 153 | // InitType::Hardware Must be called at start of setup() before anything else. 154 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 155 | 156 | bool success = true; 157 | switch (initType) 158 | { 159 | case InitType::Hardware: 160 | // Note: Serial port and display are not yet initialized and cannot be used use here. 161 | 162 | // Initialize standard SPI object with non-standard SPI pins for LoRa module. 163 | // These pins will be remembered and will not change if any library 164 | // later calls SPI.begin() without parameters. 165 | SPI.begin(5, 19, 27, 18); 166 | break; 167 | 168 | case InitType::PostInitSerial: 169 | // Note: If enabled Serial port and display are already initialized here. 170 | // No actions required for this board. 171 | break; 172 | } 173 | return success; 174 | } 175 | 176 | 177 | #endif // BSF_LOPY4_H_ -------------------------------------------------------------------------------- /src/boards/bsf_lora32u4II.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_lora32u4II.h 4 | * 5 | * Function: Board Support File for BSFrance LoRa32u4 II versions 1.0 to 1.3. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by the MCU). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display con be connected. 16 | * 17 | * ██ DIO1 MUST BE MANUALLY WIRED TO GPIO5 for versions < 1.3 (see below) ██ 18 | * For version 1.3 (see label on PCB) DIO1 is already wired on PCB. 19 | * 20 | * On versions 1.0 and 1.1 DIO1 is available as a separate pin. On 21 | * version 1.2 DIO1 is available on a solder pad (from a solder jumper) 22 | * on the bottom side of the PCB. On version 1.3 DIO is already wired on the PCB. 23 | * 24 | * Connect DIO1 and optional display according to below connection details. 25 | * 26 | * CONNECTIONS AND PIN DEFINITIONS: 27 | * 28 | * Indentifiers between parentheses are defined in the board's 29 | * Board Support Package (BSP) which is part of the Arduino core. 30 | * 31 | * Leds GPIO 32 | * ---- ---- 33 | * LED <――――――――――> 13 (LED_BUILTIN) Active-high 34 | * 35 | * I2C [display] GPIO 36 | * SDA <――――――――――> 2 (SDA) 37 | * SCL <――――――――――> 3 (SCL) 38 | * 39 | * SPI/LoRa module GPIO 40 | * MOSI <――――――――――> 16 (MOSI) 41 | * MISO <――――――――――> 14 (MISO) 42 | * SCK <――――――――――> 15 (SCK) 43 | * NSS <――――――――――> 8 44 | * RST <――――――――――> 4 45 | * DIO0 <――――――――――> 7 46 | * DIO1 <----------> 5 ██ NOT WIRED on PCB for versions < 1.3 ██ 47 | * DIO2 - Not needed for LoRa 48 | * 49 | * Docs: https://docs.platformio.org/en/latest/boards/atmelavr/lora32u4II.html 50 | * 51 | * Identifiers: LMIC-node 52 | * board-id: lora32u4II 53 | * PlatformIO 54 | * board: lora32u4II 55 | * platform: atmelavr 56 | * Arduino 57 | * board: ARDUINO_AVR_FEATHER32U4 58 | * architecture: ARDUINO_ARCH_AVR 59 | * 60 | ******************************************************************************/ 61 | 62 | #pragma once 63 | 64 | #ifndef BSF_LORA32U4II_H_ 65 | #define BSF_LORA32U4II_H_ 66 | 67 | #include "LMIC-node.h" 68 | 69 | #define DEVICEID_DEFAULT "lora32u4II" // Default deviceid value 70 | 71 | // Wait for Serial 72 | // Can be useful for boards with MCU with integrated USB support. 73 | #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 74 | 75 | // LMIC Clock Error 76 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 77 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 78 | // Value (30000) was determined empirically. 79 | #ifndef LMIC_CLOCK_ERROR_PPM 80 | #define LMIC_CLOCK_ERROR_PPM 30000 81 | #endif 82 | 83 | // Pin mappings for LoRa tranceiver 84 | const lmic_pinmap lmic_pins = { 85 | .nss = 8, 86 | .rxtx = LMIC_UNUSED_PIN, 87 | .rst = 4, 88 | .dio = { /*dio0*/ 7, /*dio1*/ 5, /*dio2*/ LMIC_UNUSED_PIN } 89 | #ifdef MCCI_LMIC 90 | , 91 | .rxtx_rx_active = 0, 92 | .rssi_cal = 8, 93 | .spi_freq = 1000000 /* 1 MHz */ 94 | #endif 95 | }; 96 | 97 | #ifdef USE_SERIAL 98 | Serial_& serial = Serial; 99 | // HardwareSerial& serial = Serial; 100 | #endif 101 | 102 | #ifdef USE_LED 103 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High); 104 | #endif 105 | 106 | #ifdef USE_DISPLAY 107 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 108 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 109 | #endif 110 | 111 | 112 | bool boardInit(InitType initType) 113 | { 114 | // This function is used to perform board specific initializations. 115 | // Required as part of standard template. 116 | 117 | // InitType::Hardware Must be called at start of setup() before anything else. 118 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 119 | 120 | bool success = true; 121 | switch (initType) 122 | { 123 | case InitType::Hardware: 124 | // Note: Serial port and display are not yet initialized and cannot be used use here. 125 | // No actions required for this board. 126 | break; 127 | 128 | case InitType::PostInitSerial: 129 | // Note: If enabled Serial port and display are already initialized here. 130 | // No actions required for this board. 131 | break; 132 | } 133 | return success; 134 | } 135 | 136 | 137 | #endif // BSF_LORA32U4II_H_ -------------------------------------------------------------------------------- /src/boards/bsf_nodemcu_32s.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_nodemcu_32s.h 4 | * 5 | * Function: Board Support File for NodeMCU-32S with external SPI LoRa module. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display can be connected. 16 | * 17 | * Connect the LoRa module and optional display 18 | * according to below connection details. 19 | * 20 | * CONNECTIONS AND PIN DEFINITIONS: 21 | * 22 | * Indentifiers between parentheses are defined in the board's 23 | * Board Support Package (BSP) which is part of the Arduino core. 24 | * 25 | * Leds GPIO 26 | * ---- ---- 27 | * LED <――――――――――> 2 (LED_BUILTIN) Active-high 28 | * 29 | * I2C [display] GPIO 30 | * --- ---- 31 | * SDA <――――――――――> 21 (SDA) 32 | * SCL <――――――――――> 22 (SCL) 33 | * 34 | * SPI/LoRa module GPIO 35 | * --- ---- 36 | * MOSI <――――――――――> 23 (MOSI) 37 | * MISO <――――――――――> 19 (MISO) 38 | * SCK <――――――――――> 18 (SCK) 39 | * NSS <――――――――――> 5 (SS) 40 | * RST <――――――――――> 27 41 | * DIO0 <――――――――――> 34 42 | * DIO1 <――――――――――> 35 43 | * DIO2 - Not needed for LoRa. 44 | * 45 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/nodemcu-32s.html 46 | * 47 | * Identifiers: LMIC-node 48 | * board: nodemcu_32s 49 | * PlatformIO 50 | * board: nodemcu-32s 51 | * platform: espressif32 52 | * rduino 53 | * board: ARDUINO_NodeMCU_32S 54 | * architecture: ARDUINO_ARCH_ESP32 55 | * 56 | ******************************************************************************/ 57 | 58 | #pragma once 59 | 60 | #ifndef BSF_NODEMCU_32S_H_ 61 | #define BSF_NODEMCU_32S_H_ 62 | 63 | #include "LMIC-node.h" 64 | 65 | #define DEVICEID_DEFAULT "nodemcu-32s" // Default deviceid value 66 | 67 | // Wait for Serial 68 | // Can be useful for boards with MCU with integrated USB support. 69 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 70 | 71 | // LMIC Clock Error 72 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 73 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 74 | // #ifndef LMIC_CLOCK_ERROR_PPM 75 | // #define LMIC_CLOCK_ERROR_PPM 0 76 | // #endif 77 | 78 | // Pin mappings for LoRa tranceiver 79 | const lmic_pinmap lmic_pins = { 80 | .nss = 5, 81 | .rxtx = LMIC_UNUSED_PIN, 82 | .rst =27, 83 | .dio = { /*dio0*/ 34, /*dio1*/ 35, /*dio2*/ LMIC_UNUSED_PIN } 84 | #ifdef MCCI_LMIC 85 | , 86 | .rxtx_rx_active = 0, 87 | .rssi_cal = 10, 88 | .spi_freq = 8000000 /* 8 MHz */ 89 | #endif 90 | }; 91 | 92 | #ifdef USE_SERIAL 93 | HardwareSerial& serial = Serial; 94 | #endif 95 | 96 | #ifdef USE_LED 97 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High); 98 | #endif 99 | 100 | #ifdef USE_DISPLAY 101 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 102 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 103 | #endif 104 | 105 | 106 | bool boardInit(InitType initType) 107 | { 108 | // This function is used to perform board specific initializations. 109 | // Required as part of standard template. 110 | 111 | // InitType::Hardware Must be called at start of setup() before anything else. 112 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 113 | 114 | bool success = true; 115 | switch (initType) 116 | { 117 | case InitType::Hardware: 118 | // Note: Serial port and display are not yet initialized and cannot be used use here. 119 | // No actions required for this board. 120 | break; 121 | 122 | case InitType::PostInitSerial: 123 | // Note: If enabled Serial port and display are already initialized here. 124 | // No actions required for this board. 125 | break; 126 | } 127 | return success; 128 | } 129 | 130 | 131 | #endif // BSF_NODEMCU_32S_H_ -------------------------------------------------------------------------------- /src/boards/bsf_nodemcuv2.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_nodemcuv2.h 4 | * 5 | * Function: Board Support File for NodeMCU V2 (aka NodeMCU 1.0) with 6 | * external SPI LoRa module. 7 | * 8 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 9 | * 10 | * License: MIT License. See accompanying LICENSE file. 11 | * 12 | * Author: Leonel Lopes Parente 13 | * 14 | * Description: This board has onboard USB (provided by onboard USB to serial). 15 | * It supports automatic firmware upload and serial over USB. 16 | * No onboard display. 17 | * 18 | * Due to the limited amount of available GPIO pins on the ESP8266 19 | * and limitations for some of those pins it is not possible 20 | * to use I2C and an external display. 21 | * 22 | * Connect the LoRa module according to below connection details. 23 | * 24 | * CONNECTIONS AND PIN DEFINITIONS: 25 | * 26 | * Indentifiers between parentheses are defined in the board's 27 | * Board Support Package (BSP) which is part of the Arduino core. 28 | * 29 | * Leds GPIO 30 | * ---- ---- 31 | * On NodeMCU <―――――> D0 / 16 (LED_BUILTIN) 32 | * On ESP12E <―――――> D4 / 2 On ESP12E module, Active-low. 33 | * 34 | * I2C GPIO ██ I2C cannot be used ██ 35 | * --- ---- 36 | * SCL <――――――――――> D1 / 5 (SCL) is used for DIO0 37 | * SDA <――――――――――> D2 / 4 (SDA) is used for DIO1 38 | * 39 | * SPI/LoRa module GPIO 40 | * --- ---- 41 | * NSS <――――――――――> D8 / 15 (SS) 42 | * MOSI <――――――――――> D7 / 13 (MOSI) 43 | * MISO <――――――――――> D6 / 12 (MISO) 44 | * SCK <――――――――――> D5 / 14 (SCK) 45 | * RST <――――――――――> - Not connected (or connect to NodeMCU RST) 46 | * DIO0 <――――――――――> D1 / 5 (SCL) 47 | * DIO1 <――――――――――> D2 / 6 (SDA) 48 | * DIO2 - Not needed for LoRa. 49 | * 50 | * Docs: https://docs.platformio.org/en/latest/boards/espressif8266/nodemcuv2.html 51 | * 52 | * Identifiers: LMIC-node 53 | * board: nodemcuv2 54 | * PlatformIO 55 | * board: nodemcuv2 56 | * platform: espressif8266 57 | * Arduino 58 | * board: ARDUINO_ESP8266_NODEMCU 59 | * architecture: ARDUINO_ARCH_ESP8266 60 | * 61 | ******************************************************************************/ 62 | 63 | #pragma once 64 | 65 | #ifndef BSF_NODEMCU_V2_H_ 66 | #define BSF_NODEMCU_V2_H_ 67 | 68 | #include 69 | #include "LMIC-node.h" 70 | 71 | #define DEVICEID_DEFAULT "nodemcuv2" // Default deviceid value 72 | 73 | // Wait for Serial 74 | // Can be useful for boards with MCU with integrated USB support. 75 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 76 | 77 | // LMIC Clock Error 78 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 79 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 80 | // #ifndef LMIC_CLOCK_ERROR_PPM 81 | // #define LMIC_CLOCK_ERROR_PPM 0 82 | // #endif 83 | 84 | // Pin mappings for LoRa tranceiver 85 | const lmic_pinmap lmic_pins = { 86 | .nss = 15, 87 | .rxtx = LMIC_UNUSED_PIN, 88 | .rst = LMIC_UNUSED_PIN, 89 | .dio = { /*dio0*/ 5, /*dio1*/ 4, /*dio2*/ LMIC_UNUSED_PIN } 90 | #ifdef MCCI_LMIC 91 | , 92 | .rxtx_rx_active = 0, 93 | .rssi_cal = 10, 94 | .spi_freq = 1000000 /* 1 MHz */ 95 | #endif 96 | }; 97 | 98 | #define LORA_NSS 15 //D8 99 | #define LORA_RST LMIC_UNUSED_PIN 100 | #define LORA_DIO0 5 //D1 101 | #define LORA_DIO1 4 //D2 102 | #define LORA_DIO2 LMIC_UNUSED_PIN 103 | #define LORA_RXTX LMIC_UNUSED_PIN 104 | 105 | #ifdef USE_SERIAL 106 | HardwareSerial& serial = Serial; 107 | #endif 108 | 109 | #ifdef USE_LED 110 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low); 111 | #endif 112 | 113 | #ifdef USE_DISPLAY 114 | #error "Invalid option: USE_DISPLAY. I2C and display are not supported due to shortage of available GPIO pins." 115 | #endif 116 | 117 | 118 | bool boardInit(InitType initType) 119 | { 120 | // This function is used to perform board specific initializations. 121 | // Required as part of standard template. 122 | 123 | // InitType::Hardware Must be called at start of setup() before anything else. 124 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 125 | 126 | bool success = true; 127 | switch (initType) 128 | { 129 | case InitType::Hardware: 130 | // Note: Serial port and display are not yet initialized and cannot be used use here. 131 | // No actions required for this board. 132 | break; 133 | 134 | case InitType::PostInitSerial: 135 | // Note: If enabled Serial port and display are already initialized here. 136 | // No actions required for this board. 137 | break; 138 | } 139 | return success; 140 | } 141 | 142 | 143 | #endif // BSF_NODEMCU_V2_H_ -------------------------------------------------------------------------------- /src/boards/bsf_pico.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_pico.h 4 | * 5 | * Note: This file cannot be called pico.h due to conflict 6 | * with identical named file in Arduino-embed core. 7 | * 8 | * Function: Board Support File for Raspberry Pi Pico 9 | * with external SPI LoRa module. 10 | * 11 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 12 | * 13 | * License: MIT License. See accompanying LICENSE file. 14 | * 15 | * Author: Leonel Lopes Parente 16 | * 17 | * Description: This board has onboard USB (provided by the MCU). 18 | * It supports automatic firmware upload and serial over USB. 19 | * No onboard display. Optionally an external display con be connected. 20 | * 21 | * IMPORTANT information for firmware upload: 22 | * ------------------------------------------ 23 | * Device must be in BOOTSEL mode to upload firmware. 24 | * (To put in BOOTSEL mode: press BOOTSEL button, power on or reset board, release BOOTSEL button.) 25 | * In platformio.ini: 26 | * For Windows specify: upload_protocol = picotool (appears not needed for Mac and Linux). 27 | * upload_port is operating system and hardware dependent. 28 | * For convenience, to set upload_port: set upload_port in [pico] section (on top). 29 | * Examples: 30 | * Windows: upload_port = E: 31 | * Mac: upload_port = /Volumes/RPI-RP2 32 | * Linux: upload_port = /media//RSPI-RP2 33 | * On Windows USB driver for Pico [RP2 Boot (interface 1)] needs be installed with Zadig, 34 | * see: https://community.platformio.org/t/official-platformio-arduino-ide-support-for-the-raspberry-pi-pico-is-now-available/20792 35 | * 36 | * Connect the LoRa module and optional display 37 | * according to below connection details. 38 | * 39 | * CONNECTIONS AND PIN DEFINITIONS: 40 | * 41 | * Indentifiers between parentheses are defined in the board's 42 | * Board Support Package (BSP) which is part of the Arduino core. 43 | * 44 | * Leds GPIO 45 | * ---- ---- 46 | * LED <――――――――――> 25 (LED_BUILTIN) (PIN_LED) 47 | * 48 | * I2C [display] GPIO 49 | * --- ---- 50 | * SDA <――――――――――> 6 (PIN_WIRE_SDA) 51 | * SCL <――――――――――> 7 (PIN_WIRE_SCL) 52 | * 53 | * SPI/LoRa module GPIO 54 | * --- ---- 55 | * SCK <――――――――――> 2 (SCK) (PIN_SPI_SCK) 56 | * MOSI <――――――――――> 3 (MOSI) (PIN_SPI_MOSI) 57 | * MISO <――――――――――> 4 (MISO) (PIN_SPI_MISO) 58 | * NSS <――――――――――> 5 (SS) (PIN_SPI_SS) 59 | * RST <――――――――――> 8 60 | * DIO0 <――――――――――> 9 61 | * DIO1 <――――――――――> 10 62 | * DIO2 - Not needed for LoRa. 63 | * 64 | * Docs: https://docs.platformio.org/en/latest/boards/atmelsam/zeroUSB.html 65 | * 66 | * Identifiers: LMIC-node 67 | * board: pico 68 | * PlatformIO 69 | * board: pico 70 | * platform: raspberrypi 71 | * Arduino 72 | * board: 73 | * architecture: 74 | * 75 | ******************************************************************************/ 76 | 77 | #pragma once 78 | 79 | #ifndef BSF_PICO_H_ 80 | #define BSF_PICO_H_ 81 | 82 | #include "LMIC-node.h" 83 | 84 | #ifndef SDA 85 | #define SDA PIN_WIRE_SDA 86 | #endif 87 | #ifndef SCL 88 | #define SCL PIN_WIRE_SCL 89 | #endif 90 | 91 | #define DEVICEID_DEFAULT "rpi-pico" // Default deviceid value 92 | 93 | // Wait for Serial 94 | // Can be useful for boards with MCU with integrated USB support. 95 | #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 96 | 97 | // LMIC Clock Error 98 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 99 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 100 | // #ifndef LMIC_CLOCK_ERROR_PPM 101 | // #define LMIC_CLOCK_ERROR_PPM 0 102 | // #endif 103 | 104 | // Pin mappings for LoRa tranceiver 105 | const lmic_pinmap lmic_pins = { 106 | .nss = SS, 107 | .rxtx = LMIC_UNUSED_PIN, 108 | .rst = 8, 109 | .dio = { /*dio0*/ 9, /*dio1*/ 10, /*dio2*/ LMIC_UNUSED_PIN } 110 | #ifdef MCCI_LMIC 111 | , 112 | .rxtx_rx_active = 0, 113 | .rssi_cal = 10, 114 | .spi_freq = 8000000 /* 8 MHz */ 115 | #endif 116 | }; 117 | 118 | #ifdef USE_SERIAL 119 | UART& serial = SerialUSB; 120 | #endif 121 | 122 | #ifdef USE_LED 123 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High); 124 | #endif 125 | 126 | #ifdef USE_DISPLAY 127 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 128 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 129 | #endif 130 | 131 | 132 | bool boardInit(InitType initType) 133 | { 134 | // This function is used to perform board specific initializations. 135 | // Required as part of standard template. 136 | 137 | // InitType::Hardware Must be called at start of setup() before anything else. 138 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 139 | 140 | bool success = true; 141 | switch (initType) 142 | { 143 | case InitType::Hardware: 144 | // Note: Serial port and display are not yet initialized and cannot be used use here. 145 | // No actions required for this board. 146 | break; 147 | 148 | case InitType::PostInitSerial: 149 | // Note: If enabled Serial port and display are already initialized here. 150 | // No actions required for this board. 151 | break; 152 | } 153 | return success; 154 | } 155 | 156 | 157 | #endif // BSF_PICO_H_ -------------------------------------------------------------------------------- /src/boards/bsf_pro8mhzatmega328.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_pro8mhzatmega328.h 4 | * 5 | * Description: Board Support File for Arduino Pro Mini ATmega328 3.3V 8MHz 6 | * with external SPI LoRa module. 7 | * 8 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 9 | * 10 | * License: MIT License. See included LICENSE file. 11 | * 12 | * Description: This Board has no onboard USB and no onboard display. 13 | * Optionally an external display can be connected. 14 | * Onboard LED cannot be used due to hardware conflict. 15 | * 16 | * For firmware upload and serial monitor use a USB to serial 17 | * adapter that supports DTR (for automatic firmware upload). 18 | * 19 | * Connect the LoRa module and optional display 20 | * according to below connection details. 21 | * 22 | * CONNECTIONS AND PIN DEFINITIONS: 23 | * 24 | * Indentifiers between parentheses are defined in the board's 25 | * Board Support Package (BSP) which is part of the Arduino core. 26 | * 27 | * Leds GPIO 28 | * ---- ---- 29 | * LED <――――――――――> 13 (LED_BUILTIN) (SCK) Active-high, 30 | * Useless, shared with SCK. 31 | * 32 | * I2C [display] GPIO 33 | * --- ---- 34 | * SDA <――――――――――> 2 (SDA) This is labeled A4 on the PCB. 35 | * SCL <――――――――――> 3 (SCL) This is labeled A5 on the PCB. 36 | * 37 | * SPI/LoRa module GPIO 38 | * ---- ---- 39 | * MOSI <――――――――――> 11 (MOSI) 40 | * MISO <――――――――――> 12 (MISO) 41 | * SCK <――――――――――> 13 (SCK) 42 | * NSS <――――――――――> 10 (SS) 43 | * RST <――――――――――> 7 44 | * DIO0 <――――――――――> 8 45 | * DIO1 <――――――――――> 9 46 | * DIO2 - Not needed for LoRa. 47 | * 48 | * Docs: https://docs.platformio.org/en/latest/boards/atmelavr/pro8MHzatmega328.html 49 | * 50 | * Identifiers: LMIC-node 51 | * board: pro8mhzatmega328 52 | * PlatformIO 53 | * board: pro8MHzatmega328 54 | * platform: atmelavr 55 | * Arduino 56 | * board: ARDUINO_AVR_PRO 57 | * architecture: ARDUINO_ARCH_AVR 58 | * 59 | ******************************************************************************/ 60 | 61 | #pragma once 62 | 63 | #ifndef BSF_PRO8MHZATMEGA328_H_ 64 | #define BSF_PRO8MHZATMEGA328_H_ 65 | 66 | #include "LMIC-node.h" 67 | 68 | #define DEVICEID_DEFAULT "pro-mini" // Default deviceid value 69 | 70 | // Wait for Serial 71 | // Can be useful for boards with MCU with integrated USB support. 72 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 73 | 74 | // LMIC Clock Error 75 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 76 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 77 | // Value 30000 was determined empirically. 78 | #ifndef LMIC_CLOCK_ERROR_PPM 79 | #define LMIC_CLOCK_ERROR_PPM 30000 80 | #endif 81 | 82 | // Pin mappings for LoRa tranceiver 83 | const lmic_pinmap lmic_pins = { 84 | .nss = 10, 85 | .rxtx = LMIC_UNUSED_PIN, 86 | .rst = 7, 87 | .dio = { /*dio0*/ 8, /*dio1*/ 9, /*dio2*/ LMIC_UNUSED_PIN } 88 | #ifdef MCCI_LMIC 89 | , 90 | .rxtx_rx_active = 0, 91 | .rssi_cal = 10, 92 | .spi_freq = 1000000 /* 1 MHz */ 93 | #endif 94 | }; 95 | 96 | #ifdef USE_SERIAL 97 | HardwareSerial& serial = Serial; 98 | #endif 99 | 100 | #ifdef USE_LED 101 | #error Invalid option: USE_LED. Onboard LED cannot be used due to hardware conflict. 102 | // EasyLed led(, EasyLed::ActiveLevel::Low); 103 | #endif 104 | 105 | #ifdef USE_DISPLAY 106 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 107 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 108 | #endif 109 | 110 | 111 | bool boardInit(InitType initType) 112 | { 113 | // This function is used to perform board specific initializations. 114 | // Required as part of standard template. 115 | 116 | // InitType::Hardware Must be called at start of setup() before anything else. 117 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 118 | 119 | bool success = true; 120 | switch (initType) 121 | { 122 | case InitType::Hardware: 123 | // Note: Serial port and display are not yet initialized and cannot be used use here. 124 | // No actions required for this board. 125 | break; 126 | 127 | case InitType::PostInitSerial: 128 | // Note: If enabled Serial port and display are already initialized here. 129 | // No actions required for this board. 130 | break; 131 | } 132 | return success; 133 | } 134 | 135 | 136 | #endif // BSF_PRO8MHZATMEGA328_H_ -------------------------------------------------------------------------------- /src/boards/bsf_samd21_m0_mini.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_samd21_m0_mini.h 4 | * 5 | * Function: Board Support File for SAMD21 M0-Mini 6 | * with external SPI LoRa module. 7 | * 8 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 9 | * 10 | * License: MIT License. See accompanying LICENSE file. 11 | * 12 | * Author: Leonel Lopes Parente 13 | * 14 | * Description: This board has onboard USB (provided by the MCU). 15 | * It supports automatic firmware upload and serial over USB. 16 | * No onboard display. Optionally an external display con be connected. 17 | * 18 | * On some boards a user LED is present while on 19 | * others it PA17 / 13 which is shared which is also used for SPI SCK. 20 | * Therefore onboard LED is not supported by LMIC-node. 21 | * 22 | * The SPI pins are located on the top side of the PCB as part of 23 | * the ICSP connector. It is strange that this board has an ICSP 24 | * connector because the board has an ARM MCU (not AVR) 25 | * So the SPI pins are not breadboard friendly. 26 | * 27 | * Connect the LoRa module and optional display 28 | * according to below connection details. 29 | * 30 | * CONNECTIONS AND PIN DEFINITIONS: 31 | * 32 | * Indentifiers between parentheses are defined in the board's 33 | * Board Support Package (BSP) which is part of the Arduino core. 34 | * 35 | * Leds GPIO 36 | * ---- ---- 37 | * LED - (LED_BUILTIN, PIN_LED, PIN_LED_13) 38 | * LED2 <――――――――――> PB03 / 25 (RX, PIN_LED2, PIN_LED_RXL) 39 | * LED3 <――――――――――> PA27 / 26 (TX, PIN_LED3, PIN_LED_TXL) 40 | * 41 | * I2C [display] GPIO 42 | * --- ---- 43 | * SDA <――――――――――> PA22 / 20 (SDA) 44 | * SCL <――――――――――> PA23 / 21 (SCL) 45 | * 46 | * SPI/LoRa module GPIO 47 | * --- ---- 48 | * MOSI <――――――――――> PB10 / 23 (MOSI) ICSP connector pin 4 49 | * MISO <――――――――――> PA12 / 22 (MISO) ICSP connector pin 1 50 | * SCK <――――――――――> PB11 / 24 (SCK) ICSP connector pin 3 51 | * NSS <――――――――――> PA20 / 6 52 | * RST <――――――――――> PA21 / 7 53 | * DIO0 <――――――――――> PA06 / 8 54 | * DIO1 <――――――――――> PA07 / 9 55 | * DIO2 - Not needed for LoRa. 56 | * 57 | * Docs: https://docs.platformio.org/en/latest/boards/atmelsam/zeroUSB.html 58 | * 59 | * Identifiers: LMIC-node 60 | * board: samd21_m0_mini 61 | * PlatformIO 62 | * board: zeroUSB 63 | * platform: atmelsam 64 | * Arduino 65 | * board: ARDUINO_SAMD_ZERO 66 | * architecture: ARDUINO_ARCH_SAMD 67 | * 68 | ******************************************************************************/ 69 | 70 | #pragma once 71 | 72 | #ifndef BSF_SAMD21_M0_MINI_ 73 | #define BSF_SAMD21_M0_MINI_ 74 | 75 | #include "LMIC-node.h" 76 | 77 | #define DEVICEID_DEFAULT "samd21-m0-mini" // Default deviceid value 78 | 79 | // Wait for Serial 80 | // Can be useful for boards with MCU with integrated USB support. 81 | #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 82 | 83 | // LMIC Clock Error 84 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 85 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 86 | // #ifndef LMIC_CLOCK_ERROR_PPM 87 | // #define LMIC_CLOCK_ERROR_PPM 0 88 | // #endif 89 | 90 | // Pin mappings for LoRa tranceiver 91 | const lmic_pinmap lmic_pins = { 92 | .nss = 6, 93 | .rxtx = LMIC_UNUSED_PIN, 94 | .rst = 7, 95 | .dio = { /*dio0*/ 8, /*dio1*/ 9, /*dio2*/ LMIC_UNUSED_PIN } 96 | #ifdef MCCI_LMIC 97 | , 98 | .rxtx_rx_active = 0, 99 | .rssi_cal = 10, 100 | .spi_freq = 8000000 /* 8 MHz */ 101 | #endif 102 | }; 103 | 104 | #ifdef USE_SERIAL 105 | Serial_& serial = SerialUSB; 106 | #endif 107 | 108 | #ifdef USE_LED 109 | #error Invalid option: USE_LED. Onboard LED is not supported. 110 | // EasyLed led(, EasyLed::ActiveLevel::Low); 111 | #endif 112 | 113 | #ifdef USE_DISPLAY 114 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 115 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 116 | #endif 117 | 118 | 119 | bool boardInit(InitType initType) 120 | { 121 | // This function is used to perform board specific initializations. 122 | // Required as part of standard template. 123 | 124 | // InitType::Hardware Must be called at start of setup() before anything else. 125 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 126 | 127 | bool success = true; 128 | switch (initType) 129 | { 130 | case InitType::Hardware: 131 | // Note: Serial port and display are not yet initialized and cannot be used use here. 132 | // No actions required for this board. 133 | break; 134 | 135 | case InitType::PostInitSerial: 136 | // Note: If enabled Serial port and display are already initialized here. 137 | // No actions required for this board. 138 | break; 139 | } 140 | return success; 141 | } 142 | 143 | 144 | #endif // BSF_SAMD21_M0_MINI_ 145 | -------------------------------------------------------------------------------- /src/boards/bsf_teensylc.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_teensylc.h 4 | * 5 | * Function: Board Support File for Teensy LC with external SPI LoRa module. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by the MCU). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display con be connected. 16 | * 17 | * Onboard LED and SPI SCK use the same GPIO (13) which causes a hardware conflict. 18 | * Fortunately SCK can be remapped to a different GPIO (14). 19 | * 20 | * Connect the LoRa module and optional display 21 | * according to below connection details. 22 | * 23 | * CONNECTIONS AND PIN DEFINITIONS: 24 | * 25 | * Indentifiers between parentheses are defined in the board's 26 | * Board Support Package (BSP) which is part of the Arduino core. 27 | * 28 | * Leds GPIO 29 | * ---- ---- 30 | * LED <――――――――――> 13 (LED_BUILTIN) (SCK) Hardware conflict. 31 | * Cannot use LED_BUILTIN and SCK together. 32 | * 33 | * I2C [display] GPIO 34 | * --- ---- 35 | * SDA <――――――――――> 18 (SDA) 36 | * SCL <――――――――――> 19 (SCL) 37 | * 38 | * SPI/LoRa module GPIO 39 | * --- ---- 40 | * MOSI <――――――――――> 11 (MOSI) 41 | * MISO <――――――――――> 12 (MISO) 42 | * SCK <――――――――――> 14 NOT SCK! 43 | * SPI SCK is remapped to GPIO14 because 44 | * SCK definition conflicts with onboard LED. 45 | * NSS <――――――――――> 10 46 | * RST <――――――――――> 9 47 | * DIO0 <――――――――――> 8 48 | * DIO1 <――――――――――> 7 49 | * DIO2 - Not needed for LoRa. 50 | * 51 | * Docs: https://docs.platformio.org/en/latest/boards/teensy/teensylc.html 52 | * 53 | * Identifiers: LMIC-node 54 | * board: teensylc 55 | * PlatformIO 56 | * board: teensylc 57 | * platform: teensy 58 | * Arduino 59 | * board: ARDUINO_TEENSYLC 60 | * architecture: 61 | * 62 | ******************************************************************************/ 63 | 64 | #pragma once 65 | 66 | #ifndef BSF_TEENSYLC_H_ 67 | #define BSF_TEENSYLC_H_ 68 | 69 | #include "LMIC-node.h" 70 | #include 71 | 72 | #define DEVICEID_DEFAULT "teensylc" // Default deviceid value 73 | 74 | // Wait for Serial 75 | // Can be useful for boards with MCU with integrated USB support. 76 | #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 77 | 78 | // LMIC Clock Error 79 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 80 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 81 | // #ifndef LMIC_CLOCK_ERROR_PPM 82 | // #define LMIC_CLOCK_ERROR_PPM 0 83 | // #endif 84 | 85 | // Pin mappings for LoRa tranceiver 86 | const lmic_pinmap lmic_pins = { 87 | .nss = 10, 88 | .rxtx = LMIC_UNUSED_PIN, 89 | .rst = 9, 90 | .dio = { /*dio0*/ 8, /*dio1*/ 7, /*dio2*/ LMIC_UNUSED_PIN } 91 | #ifdef MCCI_LMIC 92 | , 93 | .rxtx_rx_active = 0, 94 | .rssi_cal = 10, 95 | .spi_freq = 8000000 /* 8 MHz */ 96 | #endif 97 | }; 98 | 99 | #ifdef USE_SERIAL 100 | usb_serial_class& serial = Serial; 101 | #endif 102 | 103 | #ifdef USE_LED 104 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High); 105 | #endif 106 | 107 | #ifdef USE_DISPLAY 108 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 109 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 110 | #endif 111 | 112 | 113 | bool boardInit(InitType initType) 114 | { 115 | // This function is used to perform board specific initializations. 116 | // Required as part of standard template. 117 | 118 | // InitType::Hardware Must be called at start of setup() before anything else. 119 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 120 | 121 | bool success = true; 122 | switch (initType) 123 | { 124 | case InitType::Hardware: 125 | // Note: Serial port and display are not yet initialized and cannot be used use here. 126 | // SPI SCK needs to remapped to GPIO14 because it conflicts with LED_BUILTIN. 127 | SPI.setSCK(14); 128 | break; 129 | 130 | case InitType::PostInitSerial: 131 | // Note: If enabled Serial port and display are already initialized here. 132 | // No actions required for this board. 133 | break; 134 | } 135 | return success; 136 | } 137 | 138 | 139 | #endif // BSF_TEENSYLC_H_ -------------------------------------------------------------------------------- /src/boards/bsf_ttgo_lora32_v1.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_ttgo_lora32_v1.h 4 | * 5 | * Function: Board Support File for TTGO LoRa32 (aka T3) v1.3. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * Has onboard display. 16 | * 17 | * The standard I2C pins defined in the BSP do not match the 18 | * GPIO pins that the display is connected to. Therefore the 19 | * the I2C Wire object is explicitly initialized with the 20 | * correct pins (see boardInit() below). 21 | * 22 | * Schematic diagram and and pinout diagram show no onboard 23 | * user programmable LED while LED_BUILTIN is defined in BSP. 24 | * Definition in BSP is incorrect. 25 | * 26 | * OLED_RST and LORA_RST are defined in BSP but neither is connected to GPIO. 27 | * Definitions in BSP are incorrect. 28 | * 29 | * CONNECTIONS AND PIN DEFINITIONS: 30 | * 31 | * Indentifiers between parentheses are defined in the board's 32 | * Board Support Package (BSP) which is part of the Arduino core. 33 | * 34 | * Leds GPIO 35 | * ---- ---- 36 | * LED - Incorrectly defined in BSP as LED_BUILTIN (2). 37 | * 38 | * I2C/Display GPIO 39 | * --- ---- 40 | * SDA <――――――――――> 4 Not SDA! (OLED_SDA) 41 | * SCL <――――――――――> 15 Not SCL! (OLED_SCL) 42 | * RST OLED_RST is defined in BSP but not connected to GPIO. 43 | * 44 | * SPI/LoRa GPIO 45 | * --- ---- 46 | * MOSI <――――――――――> 27 (MOSI) (LORA_MOSI) 47 | * MISO <――――――――――> 19 (MISO) (LORA_MISO) 48 | * SCK <――――――――――> 5 (SCK) (LORA_SCK) 49 | * NSS <――――――――――> 18 (SS) (LORA_CS) 50 | * RST <――――――――――> 14 (LORA_RST) 51 | * DIO0 <――――――――――> 26 (LORA_IRQ) 52 | * DIO1 <――――――――――> 33 53 | * DIO2 <――――――――――> 32 54 | * 55 | * Button switches GPIO 56 | * ------ ---- 57 | * Button <―――――――――> 36 (V_SP) Active-low 58 | * 59 | * Battery measure GPIO 60 | * ------- ---- 61 | * VBAT <――――――――――> 35 Battery voltage via 50% voltage divider 62 | * 63 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/ttgo-lora32-v1.html 64 | * 65 | * Identifiers: LMIC-node 66 | * board: ttgo_lora32_v1 67 | * PlatformIO 68 | * board: ttgo-lora32-v1 69 | * platform: espressif32 70 | * Arduino 71 | * board: ARDUINO_TTGO_LoRa32_V1 72 | * architecture: ARDUINO_ARCH_ESP32 73 | * 74 | ******************************************************************************/ 75 | 76 | #pragma once 77 | 78 | #ifndef BSF_TTGO_LORA32_V1_H_ 79 | #define BSF_TTGO_LORA32_V1_H_ 80 | 81 | #include "LMIC-node.h" 82 | 83 | #define DEVICEID_DEFAULT "ttgo-lora32-v1" // Default deviceid value 84 | 85 | // Wait for Serial 86 | // Can be useful for boards with MCU with integrated USB support. 87 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 88 | 89 | // LMIC Clock Error 90 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 91 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 92 | // #ifndef LMIC_CLOCK_ERROR_PPM 93 | // #define LMIC_CLOCK_ERROR_PPM 0 94 | // #endif 95 | 96 | // Pin mappings for LoRa tranceiver 97 | const lmic_pinmap lmic_pins = { 98 | .nss = 18, 99 | .rxtx = LMIC_UNUSED_PIN, 100 | .rst = 14, // See remark about LORA_RST above. 101 | .dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 } 102 | #ifdef MCCI_LMIC 103 | , 104 | .rxtx_rx_active = 0, 105 | .rssi_cal = 10, 106 | .spi_freq = 8000000 /* 8 MHz */ 107 | #endif 108 | }; 109 | 110 | #ifdef USE_SERIAL 111 | HardwareSerial& serial = Serial; 112 | #endif 113 | 114 | #ifdef USE_LED 115 | #error Invalid option: USE_LED. This board has no onboard user LED. 116 | // EasyLed led(, EasyLed::ActiveLevel::Low); 117 | #endif 118 | 119 | #ifdef USE_DISPLAY 120 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 121 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ 15, /*sda*/ 4); 122 | #endif 123 | 124 | 125 | bool boardInit(InitType initType) 126 | { 127 | // This function is used to perform board specific initializations. 128 | // Required as part of standard template. 129 | 130 | // InitType::Hardware Must be called at start of setup() before anything else. 131 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 132 | 133 | bool success = true; 134 | switch (initType) 135 | { 136 | case InitType::Hardware: 137 | // Note: Serial port and display are not yet initialized and cannot be used use here. 138 | 139 | #ifdef USE_DISPLAY 140 | // Initialize I2C Wire object with GPIO pins the display is connected to. 141 | // These pins will be remembered and will not change if any library 142 | // later calls Wire.begin() without parameters. 143 | Wire.begin(4, 15); 144 | #endif 145 | break; 146 | 147 | case InitType::PostInitSerial: 148 | // Note: If enabled Serial port and display are already initialized here. 149 | // No actions required for this board. 150 | break; 151 | } 152 | return success; 153 | } 154 | 155 | 156 | #endif // BSF_TTGO_LORA32_V1_H_ -------------------------------------------------------------------------------- /src/boards/bsf_ttgo_lora32_v2.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_ttgo_lora32_v2.h 4 | * 5 | * Description: Board Support File for TTGO LoRa32 (aka T3) v2.0. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * Has onboard display. 16 | * 17 | * ██ DIO1 MUST BE MANUALLY WIRED TO GPIO33 (see below) ██ 18 | * 19 | * LED_BUILTIN and I2C SCL share the same pin. 20 | * Therefore cannot use USE_DISPLAY and USE_LED together. 21 | * 22 | * OLED_RST and LORA_RST are defined in BSP but neither is connected to GPIO. 23 | * 24 | * CONNECTIONS AND PIN DEFINITIONS: 25 | * 26 | * Indentifiers between parentheses are defined in the board's 27 | * Board Support Package (BSP) which is part of the Arduino core. 28 | * 29 | * Leds GPIO 30 | * ---- ---- 31 | * LED <――――――――――> 22 (LED_BUILTIN) (SCL) Active-low 32 | * Shared with I2C SCL 33 | * 34 | * I2C/Display GPIO 35 | * --- ---- 36 | * SDA <――――――――――> 21 (SDA) (OLED_SDA) 37 | * SCL <――――――――――> 22 (SCL) (OLED_SCL) (LED_BUILTIN) 38 | * RST - OLED_RST is defined in BSP but not wired to GPIO 39 | * 40 | * SPI/LoRa GPIO 41 | * MOSI <――――――――――> 27 (MOSI) (LORA_MOSI) 42 | * MISO <――――――――――> 19 (MISO) (LORA_MISO) 43 | * SCK <――――――――――> 5 (SCK) (LORA_SCK) 44 | * NSS <――――――――――> 18 (SS) (LORA_CS) 45 | * RST <――――――――――> - Not LORA_RST 46 | * DIO0 <――――――――――> 26 (LORA_IRQ) 47 | * DIO1 <----------> 33 ██ NOT WIRED on PCB ██ 48 | * DIO2 - Not needed for LoRa 49 | * 50 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/ttgo-lora32-v2.html 51 | * 52 | * Identifiers: LMIC-node 53 | * board: ttgo_lora32_v2 54 | * PlatformIO 55 | * board: ttgo-lora32-v2 56 | * platform: espressif32 57 | * Arduino 58 | * board: ARDUINO_TTGO_LoRa32_V2 59 | * architecture: ARDUINO_ARCH_ESP32 60 | * 61 | ******************************************************************************/ 62 | 63 | #pragma once 64 | 65 | #ifndef BSF_TTGO_LORA32_V2_H_ 66 | #define BSF_TTGO_LORA32_V2_H_ 67 | 68 | #include "LMIC-node.h" 69 | 70 | #define DEVICEID_DEFAULT "ttgo-lora32-v2" // Default deviceid value 71 | 72 | // Wait for Serial 73 | // Can be useful for boards with MCU with integrated USB support. 74 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 75 | 76 | // LMIC Clock Error 77 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 78 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 79 | // #ifndef LMIC_CLOCK_ERROR_PPM 80 | // #define LMIC_CLOCK_ERROR_PPM 0 81 | // #endif 82 | 83 | // Pin mappings for LoRa tranceiver 84 | const lmic_pinmap lmic_pins = { 85 | .nss = 18, 86 | .rxtx = LMIC_UNUSED_PIN, 87 | .rst = LMIC_UNUSED_PIN, 88 | .dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ LMIC_UNUSED_PIN } 89 | #ifdef MCCI_LMIC 90 | , 91 | .rxtx_rx_active = 0, 92 | .rssi_cal = 10, 93 | .spi_freq = 8000000 /* 8 MHz */ 94 | #endif 95 | }; 96 | 97 | #if defined(USE_DISPLAY) && defined(USE_LED) && LED_PIN == LED_ONBOARD 98 | #error Invalid option: USE_DISPLAY and USE_LED cannot be used together. 99 | #endif 100 | 101 | #ifdef USE_SERIAL 102 | HardwareSerial& serial = Serial; 103 | #endif 104 | 105 | #ifdef USE_LED 106 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low); 107 | #endif 108 | 109 | #ifdef USE_DISPLAY 110 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 111 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 112 | #endif 113 | 114 | 115 | bool boardInit(InitType initType) 116 | { 117 | // This function is used to perform board specific initializations. 118 | // Required as part of standard template. 119 | 120 | // InitType::Hardware Must be called at start of setup() before anything else. 121 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 122 | 123 | bool success = true; 124 | switch (initType) 125 | { 126 | case InitType::Hardware: 127 | // Note: Serial port and display are not yet initialized and cannot be used use here. 128 | // No actions required for this board. 129 | break; 130 | 131 | case InitType::PostInitSerial: 132 | // Note: If enabled Serial port and display are already initialized here. 133 | // No actions required for this board. 134 | break; 135 | } 136 | return success; 137 | } 138 | 139 | 140 | #endif // BSF_TTGO_LORA32_V2_H_ -------------------------------------------------------------------------------- /src/boards/bsf_ttgo_lora32_v21.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_ttgo_lora32_v216.h 4 | * 5 | * Description: Board Support File for TTGO LoRa32 v2.1.6 6 | * (aka T3 V1.6 and LoRa32 V2.1 release 1.6). 7 | * 8 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 9 | * 10 | * License: MIT License. See accompanying LICENSE file. 11 | * 12 | * Author: Leonel Lopes Parente 13 | * 14 | * Description: This board has onboard USB (provided by onboard USB to serial). 15 | * It supports automatic firmware upload and serial over USB. 16 | * Has onboard display. 17 | * 18 | * LORA_RST is defined in BSP but has incorrect value (12). 19 | * 20 | * CONNECTIONS AND PIN DEFINITIONS: 21 | * 22 | * Indentifiers between parentheses are defined in the board's 23 | * Board Support Package (BSP) which is part of the Arduino core. 24 | * 25 | * Leds GPIO 26 | * ---- ---- 27 | * LED <――――――――――> 25 (LED_BUILTIN) Active-low (?) 28 | * 29 | * I2C/Display GPIO 30 | * SDA <――――――――――> 21 (SDA) (OLED_SDA) 31 | * SCL <――――――――――> 22 (SCL) (OLED_SCL) 32 | * RST <――――――――――> 16 (OLED_RST) 33 | * 34 | * SPI/LoRa GPIO 35 | * MOSI <――――――――――> 27 (MOSI) (LORA_MOSI) 36 | * MISO <――――――――――> 19 (MISO) (LORA_MISO) 37 | * SCK <――――――――――> 5 (SCK) (LORA_SCK) 38 | * NSS <――――――――――> 18 (SS) (LORA_CS) 39 | * RST <――――――――――> 23 Not LORA_RST 40 | * DIO0 <――――――――――> 26 (LORA_IRQ) 41 | * DIO1 <――――――――――> 33 (LORA_D1) 42 | * DIO2 <――――――――――> 32 (LORA_D2) 43 | * 44 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/ttgo-lora32-v21.html 45 | * 46 | * Identifiers: LMIC-node 47 | * board: ttgo_lora32_v21 48 | * PlatformIO 49 | * board: ttgo-lora32-v21 50 | * platform: espressif32 51 | * Arduino 52 | * board: ARDUINO_TTGO_LoRa32_v21new 53 | * architecture: ARDUINO_ARCH_ESP32 54 | * 55 | ******************************************************************************/ 56 | 57 | #pragma once 58 | 59 | #ifndef BSF_TTGO_LORA32_V21_H_ 60 | #define BSF_TTGO_LORA32_V21_H_ 61 | 62 | #include "LMIC-node.h" 63 | 64 | #define DEVICEID_DEFAULT "ttgo-lora32-v21" // Default deviceid value 65 | 66 | // Wait for Serial 67 | // Can be useful for boards with MCU with integrated USB support. 68 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 69 | 70 | // LMIC Clock Error 71 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 72 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 73 | // #ifndef LMIC_CLOCK_ERROR_PPM 74 | // #define LMIC_CLOCK_ERROR_PPM 0 75 | // #endif 76 | 77 | // Pin mappings for LoRa tranceiver 78 | const lmic_pinmap lmic_pins = { 79 | .nss = 18, 80 | .rxtx = LMIC_UNUSED_PIN, 81 | .rst = 23, 82 | .dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 } 83 | #ifdef MCCI_LMIC 84 | , 85 | .rxtx_rx_active = 0, 86 | .rssi_cal = 10, 87 | .spi_freq = 8000000 /* 8 MHz */ 88 | #endif 89 | }; 90 | 91 | #ifdef USE_SERIAL 92 | HardwareSerial& serial = Serial; 93 | #endif 94 | 95 | #ifdef USE_LED 96 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::Low); 97 | #endif 98 | 99 | #ifdef USE_DISPLAY 100 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 101 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ OLED_RST, /*scl*/ SCL, /*sda*/ SDA); 102 | #endif 103 | 104 | 105 | bool boardInit(InitType initType) 106 | { 107 | // This function is used to perform board specific initializations. 108 | // Required as part of standard template. 109 | 110 | // InitType::Hardware Must be called at start of setup() before anything else. 111 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 112 | 113 | bool success = true; 114 | switch (initType) 115 | { 116 | case InitType::Hardware: 117 | // Note: Serial port and display are not yet initialized and cannot be used use here. 118 | // No actions required for this board. 119 | break; 120 | 121 | case InitType::PostInitSerial: 122 | // Note: If enabled Serial port and display are already initialized here. 123 | // No actions required for this board. 124 | break; 125 | } 126 | return success; 127 | } 128 | 129 | 130 | #endif // BSF_TTGO_LORA32_V21_H_ -------------------------------------------------------------------------------- /src/boards/bsf_ttgo_t_beam.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_ttgo_t_beam.h 4 | * 5 | * Description: Board Support File for TTGO T-Beam (aka T22) V0.5, V0.6 and V0.7. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display con be connected. 16 | * Also has onboard GPS which is not used by LMIC-node. 17 | * 18 | * Connect an optional display according to below connection details. 19 | * 20 | * CONNECTIONS AND PIN DEFINITIONS: 21 | * 22 | * Indentifiers between parentheses are defined in the board's 23 | * Board Support Package (BSP) which is part of the Arduino core. 24 | * 25 | * Leds GPIO 26 | * ---- ---- 27 | * LED <――――――――――> 14 (LED_BUILTIN) Active-high 28 | * 29 | * I2C [display] GPIO 30 | * ---- ---- 31 | * SDA <――――――――――> 21 (SDA) 32 | * SCL <――――――――――> 22 (SCL) 33 | * RST - 34 | * 35 | * SPI/LoRa GPIO 36 | * --- ---- 37 | * MOSI <――――――――――> 27 (MOSI) (LORA_MOSI) 38 | * MISO <――――――――――> 19 (MISO) (LORA_MISO) 39 | * SCK <――――――――――> 5 (SCK) (LORA_SCK) 40 | * NSS <――――――――――> 18 (SS) (LORA_CS) 41 | * RST <――――――――――> 23 (LORA_RST) 42 | * DIO0 <――――――――――> 26 (LORA_IO0) 43 | * DIO1 <――――――――――> 33 (LORA_IO1) 44 | * DIO2 <――――――――――> 32 (LORA_IO2) 45 | * 46 | * GPS GPIO 47 | * --- ---- 48 | * RX <――――――――――> 15 49 | * TX <――――――――――> 12 50 | * 51 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/ttgo-t-beam.html 52 | * 53 | * Identifiers: LMIC-node 54 | * board: ttgo_t_beam 55 | * PlatformIO 56 | * board: ttgo-t-beam 57 | * platform: espressif32 58 | * Arduino 59 | * board: ARDUINO_T_Beam 60 | * architecture: ARDUINO_ARCH_ESP32 61 | * 62 | ******************************************************************************/ 63 | 64 | #pragma once 65 | 66 | #ifndef BSF_TTGO_T_BEAM_H_ 67 | #define BSF_TTGO_T_BEAM_H_ 68 | 69 | #include "LMIC-node.h" 70 | 71 | #define DEVICEID_DEFAULT "ttgo-tbeam" // Default deviceid value 72 | 73 | // Wait for Serial 74 | // Can be useful for boards with MCU with integrated USB support. 75 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 76 | 77 | // LMIC Clock Error 78 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 79 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 80 | // #ifndef LMIC_CLOCK_ERROR_PPM 81 | // #define LMIC_CLOCK_ERROR_PPM 0 82 | // #endif 83 | 84 | // Pin mappings for LoRa tranceiver 85 | const lmic_pinmap lmic_pins = { 86 | .nss = 18, 87 | .rxtx = LMIC_UNUSED_PIN, 88 | .rst = 23, 89 | .dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 } 90 | #ifdef MCCI_LMIC 91 | , 92 | .rxtx_rx_active = 0, 93 | .rssi_cal = 10, 94 | .spi_freq = 8000000 /* 8 MHz */ 95 | #endif 96 | }; 97 | 98 | #ifdef USE_SERIAL 99 | HardwareSerial& serial = Serial; 100 | #endif 101 | 102 | #ifdef USE_LED 103 | EasyLed led(LED_BUILTIN, EasyLed::ActiveLevel::High); 104 | #endif 105 | 106 | #ifdef USE_DISPLAY 107 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 108 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 109 | #endif 110 | 111 | 112 | bool boardInit(InitType initType) 113 | { 114 | // This function is used to perform board specific initializations. 115 | // Required as part of standard template. 116 | 117 | // InitType::Hardware Must be called at start of setup() before anything else. 118 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 119 | 120 | bool success = true; 121 | switch (initType) 122 | { 123 | case InitType::Hardware: 124 | // Note: Serial port and display are not yet initialized and cannot be used use here. 125 | // No actions required for this board. 126 | break; 127 | 128 | case InitType::PostInitSerial: 129 | // Note: If enabled Serial port and display are already initialized here. 130 | // No actions required for this board. 131 | break; 132 | } 133 | return success; 134 | } 135 | 136 | 137 | #endif // BSF_TTGO_T_BEAM_H_ -------------------------------------------------------------------------------- /src/boards/bsf_ttgo_t_beam_v1.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * 3 | * File: bsf_ttgo_t_beam_v1.h 4 | * 5 | * Description: Board Support File for TTGO T-Beam (aka T22) V1.0. 6 | * 7 | * Copyright: Copyright (c) 2021 Leonel Lopes Parente 8 | * 9 | * License: MIT License. See accompanying LICENSE file. 10 | * 11 | * Author: Leonel Lopes Parente 12 | * 13 | * Description: This board has onboard USB (provided by onboard USB to serial). 14 | * It supports automatic firmware upload and serial over USB. 15 | * No onboard display. Optionally an external display con be connected. 16 | * No onboard user programmable LED. Onboard GPS not used by LMIC-node. 17 | * 18 | * This board uses an AXP192 power management chip to power 19 | * onboard components and the +3.3V output pin. 20 | * The AXP192 must be correctly configured for things to work 21 | * (see boardInit() below). 22 | * 23 | * Connect an optional display according to below connection details. 24 | * 25 | * CONNECTIONS AND PIN DEFINITIONS: 26 | * 27 | * Indentifiers between parentheses are defined in the board's 28 | * Board Support Package (BSP) which is part of the Arduino core. 29 | * 30 | * Leds GPIO 31 | * ---- ---- 32 | * LED - No onboard user LED 33 | * 34 | * I2C [display] GPIO 35 | * ---- ---- 36 | * SDA <――――――――――> 21 (SDA) 37 | * SCL <――――――――――> 22 (SCL) 38 | * RST - 39 | * 40 | * SPI/LoRa GPIO 41 | * --- ---- 42 | * MOSI <――――――――――> 27 (MOSI) (LORA_MOSI) 43 | * MISO <――――――――――> 19 (MISO) (LORA_MISO) 44 | * SCK <――――――――――> 5 (SCK) (LORA_SCK) 45 | * NSS <――――――――――> 18 (SS) (LORA_CS) 46 | * RST <――――――――――> 23 (LORA_RST) 47 | * DIO0 <――――――――――> 26 (LORA_IO0) 48 | * DIO1 <――――――――――> 33 (LORA_IO1) 49 | * DIO2 <――――――――――> 32 (LORA_IO2) 50 | * 51 | * GPS GPIO 52 | * --- ---- 53 | * RX <――――――――――> 34 (or 12?) 54 | * TX <――――――――――> 12 (or 34?) 55 | * PPS <――――――――――> 37 56 | * 57 | * Power Management GPIO 58 | * ----- ---- 59 | * PMU <――――――――――> 35 60 | * 61 | * Button switches GPIO 62 | * ------ ---- 63 | * USR_SW <――――――――――> 39 (KEY_BUILTIN) 64 | * 65 | * Docs: https://docs.platformio.org/en/latest/boards/espressif32/ttgo-t-beam.html 66 | * 67 | * Identifiers: LMIC-node 68 | * board: ttgo_tbeam_v1 69 | * PlatformIO 70 | * board: ttgo-t-beam 71 | * platform: espressif32 72 | * Arduino 73 | * board: ARDUINO_T_Beam 74 | * architecture: ARDUINO_ARCH_ESP32 75 | * 76 | ******************************************************************************/ 77 | 78 | #pragma once 79 | 80 | #ifndef BSF_TTGO_T_BEAM_V1_H_ 81 | #define BSF_TTGO_T_BEAM_V1_H_ 82 | 83 | #include "axp20x.h" 84 | #include "LMIC-node.h" 85 | 86 | #define DEVICEID_DEFAULT "ttgo-tbeam-v1" // Default deviceid value 87 | 88 | // Wait for Serial 89 | // Can be useful for boards with MCU with integrated USB support. 90 | // #define WAITFOR_SERIAL_SECONDS_DEFAULT 10 // -1 waits indefinitely 91 | 92 | // LMIC Clock Error 93 | // This is only needed for slower 8-bit MCUs (e.g. 8MHz ATmega328 and ATmega32u4). 94 | // Value is defined in parts per million (of MAX_CLOCK_ERROR). 95 | // #ifndef LMIC_CLOCK_ERROR_PPM 96 | // #define LMIC_CLOCK_ERROR_PPM 0 97 | // #endif 98 | 99 | // Pin mappings for LoRa tranceiver 100 | const lmic_pinmap lmic_pins = { 101 | .nss = 18, 102 | .rxtx = LMIC_UNUSED_PIN, 103 | .rst = 23, 104 | .dio = { /*dio0*/ 26, /*dio1*/ 33, /*dio2*/ 32 } 105 | #ifdef MCCI_LMIC 106 | , 107 | .rxtx_rx_active = 0, 108 | .rssi_cal = 10, 109 | .spi_freq = 8000000 /* 8 MHz */ 110 | #endif 111 | }; 112 | 113 | AXP20X_Class axp; 114 | 115 | #ifdef USE_SERIAL 116 | HardwareSerial& serial = Serial; 117 | #endif 118 | 119 | #ifdef USE_LED 120 | #error Invalid option: USE_LED. This board has no onboard user LED. 121 | // EasyLed led(, EasyLed::ActiveLevel::Low); 122 | #endif 123 | 124 | #ifdef USE_DISPLAY 125 | // Create U8x8 instance for SSD1306 OLED display (no reset) using hardware I2C. 126 | U8X8_SSD1306_128X64_NONAME_HW_I2C display(/*rst*/ U8X8_PIN_NONE, /*scl*/ SCL, /*sda*/ SDA); 127 | #endif 128 | 129 | 130 | bool boardInit(InitType initType) 131 | { 132 | // This function is used to perform board specific initializations. 133 | // Required as part of standard template. 134 | 135 | // InitType::Hardware Must be called at start of setup() before anything else. 136 | // InitType::PostInitSerial Must be called after initSerial() before other initializations. 137 | 138 | bool success = true; 139 | switch (initType) 140 | { 141 | case InitType::Hardware: 142 | // Note: Serial port and display are not yet initialized and cannot be used use here. 143 | 144 | // This board contains an AXP192 power management chip. 145 | // Power output must be enabled for several components before they can be initialized. 146 | Wire.begin(SDA, SCL); 147 | if (axp.begin(Wire, AXP192_SLAVE_ADDRESS) != 0) 148 | { 149 | success = false; 150 | } 151 | else 152 | { 153 | axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); 154 | axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); 155 | axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON); 156 | axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON); 157 | axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON); 158 | 159 | // Explicitly set voltages because AXP192 power-on values may be lower. 160 | axp.setDCDC1Voltage(3300); // 3.3V pin 161 | axp.setLDO2Voltage (3300); // LoRa 162 | axp.setLDO3Voltage (3000); // GPS (unknown if this must be 3.0 or 3.3V) 163 | } 164 | break; 165 | 166 | case InitType::PostInitSerial: 167 | // Note: If enabled Serial port and display are already initialized here. 168 | // No actions required for this board. 169 | break; 170 | } 171 | return success; 172 | } 173 | 174 | 175 | #endif // BSF_TTGO_T_BEAM_V1_H_ --------------------------------------------------------------------------------