Add Bluetooth + TLORA 32 + Fix AXP GPS register

This commit is contained in:
Valentin Saugnier 2023-08-02 18:01:39 +02:00
parent 4337afb0a1
commit c9e99b1e53
14 changed files with 203 additions and 46 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
.idea

View File

@ -70,7 +70,9 @@
"maxDistanceToTracker": 30,
"standingUpdateTime": 15,
"sendAltitude": true,
"sendBatteryInfo": false
"sendBatteryInfo": false,
"bluetooth": true,
"disableGps": false
},
"ptt_trigger": {
"active": false,

View File

@ -16,6 +16,7 @@ platform = espressif32 @ 6.3.1
framework = arduino
lib_ldf_mode = deep+
monitor_speed = 115200
upload_speed = 921600
monitor_filters = esp32_exception_decoder
lib_deps =
adafruit/Adafruit BusIO@^1.14.1
@ -29,11 +30,11 @@ lib_deps =
shaggydog/OneButton @ 1.5.0
peterus/esp-logger @ 1.0.0
lewisxhe/XPowersLib@^0.1.7
h2zero/NimBLE-Arduino@^1.4.1
check_tool = cppcheck
check_flags =
cppcheck: --suppress=*:*.pio\* --inline-suppr -DCPPCHECK
check_skip_packages = yes
board_build.partitions = no_ota.csv
[env:ttgo-t-beam-v1]
board = ttgo-t-beam
@ -46,3 +47,7 @@ build_flags = -Werror -Wall -DTTGO_T_Beam_V0_7
[env:ttgo-t-beam-v1_2]
board = ttgo-t-beam
build_flags = -Werror -Wall -DTTGO_T_Beam_V1_2
[env:ttgo-t-lora-v2_1]
board = ttgo-lora32-v21
build_flags = -Werror -Wall -DTTGO_T_LORA_V2_1

View File

@ -1,8 +1,5 @@
#ifdef ESP32
#include <esp_bt.h>
#endif
#include <BluetoothSerial.h>
#include <Arduino.h>
#include <NimBLEDevice.h>
#include <OneButton.h>
#include <TinyGPS++.h>
#include <logger.h>
@ -21,16 +18,17 @@
#include "display.h"
#include "SPIFFS.h"
#include "utils.h"
#include "bluetooth_utils.h"
Configuration Config;
PowerManagement powerManagement;
HardwareSerial neo6m_gps(1);
TinyGPSPlus gps;
NimBLECharacteristic* pCharacteristic;
BluetoothSerial SerialBT;
OneButton userButton = OneButton(BUTTON_PIN, true, true);
String versionDate = "2023.08.01";
String versionDate = "2023.08.02";
int myBeaconsIndex = 0;
int myBeaconsSize = Config.beacons.size();
@ -64,7 +62,6 @@ bool symbolAvailable = true;
logging::Logger logger;
void setup() {
Serial.begin(115200);
@ -82,13 +79,13 @@ void setup() {
MSG_Utils::loadNumMessages();
GPS_Utils::setup();
LoRa_Utils::setup();
WiFi.mode(WIFI_OFF);
btStop();
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "WiFi and BT controller stopped");
esp_bt_controller_disable();
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "BT controller disabled");
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "WiFi controller stopped");
BLUETOOTH_Utils::setup();
userButton.attachClick(BUTTON_Utils::singlePress);
userButton.attachLongPressStart(BUTTON_Utils::longPress);
@ -97,7 +94,7 @@ void setup() {
powerManagement.lowerCpuFrequency();
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "Smart Beacon is: %s", utils::getSmartBeaconState());
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "Setup Done!");
menuDisplay = 0;
menuDisplay = BUTTON_PIN == -1 ? 20 : 0;
}
void loop() {
@ -118,7 +115,7 @@ void loop() {
MSG_Utils::checkReceivedMessage(LoRa_Utils::receivePacket());
STATION_Utils::checkListenedTrackersByTimeAndDelete();
int currentSpeed = (int)gps.speed.kmph();
int currentSpeed = (int) gps.speed.kmph();
lastTx = millis() - lastTxTime;
if (!sendUpdate && gps_loc_update && currentBeacon->smartBeaconState) {
@ -136,8 +133,12 @@ void loop() {
}
if (gps_time_update) {
MENU_Utils::showOnScreen();
STATION_Utils::checkSmartBeaconInterval(currentSpeed);
}
GPS_Utils::checkStartUpFrames();
if (millis() - displayTime >= 1000 || gps_time_update) {
GPS_Utils::checkStartUpFrames();
MENU_Utils::showOnScreen();
displayTime = millis();
}
}

96
src/bluetooth_utils.cpp Normal file
View File

@ -0,0 +1,96 @@
#include <esp_bt.h>
#include "bluetooth_utils.h"
#include "logger.h"
#include "display.h"
#include "lora_utils.h"
#include "configuration.h"
#include "TinyGPSPlus.h"
extern Configuration Config;
extern BluetoothSerial SerialBT;
extern logging::Logger logger;
extern TinyGPSPlus gps;
namespace BLUETOOTH_Utils {
String serialReceived;
bool shouldSendToLoRa = false;
void setup() {
if (!Config.bluetooth) {
btStop();
esp_bt_controller_disable();
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "BT controller disabled");
return;
}
serialReceived.reserve(255);
SerialBT.register_callback(BLUETOOTH_Utils::bluetoothCallback);
SerialBT.onData(BLUETOOTH_Utils::getData); // callback instead of while to avoid RX buffer limit when NMEA data received
if (!SerialBT.begin(String("LoRa Tracker " + String((unsigned long) ESP.getEfuseMac())))) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "Bluetooth", "Starting Bluetooth failed!");
show_display("ERROR", "Starting Bluetooth failed!");
while(true) {
delay(1000);
}
}
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Bluetooth init done!");
}
void bluetoothCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
if (event == ESP_SPP_SRV_OPEN_EVT) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Bluetooth client connected !");
} else if (event == ESP_SPP_CLOSE_EVT) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Bluetooth", "Bluetooth client disconnected !");
}
}
void getData(const uint8_t *buffer, size_t size) {
if (size == 0) {
return;
}
shouldSendToLoRa = false;
serialReceived.clear();
bool isNmea = buffer[0] == '$';
for (int i = 0; i < size; i++) {
char c = (char) buffer[i];
if (isNmea) {
gps.encode(c);
} else {
serialReceived += c;
}
}
if (serialReceived.isEmpty()) {
return;
}
shouldSendToLoRa = true; // because we can't send here
}
void sendToLoRa() {
if (!shouldSendToLoRa) {
return;
}
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "BT TX", "%s", serialReceived.c_str());
show_display("BT Tx >>", "", serialReceived, 1000);
LoRa_Utils::sendNewPacket(serialReceived);
shouldSendToLoRa = false;
}
void sendPacket(const String& packet) {
if (Config.bluetooth && !packet.isEmpty()) {
SerialBT.println(packet);
}
}
}

14
src/bluetooth_utils.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef BLUETOOTH_UTILS_H
#define BLUETOOTH_UTILS_H
#include <BluetoothSerial.h>
namespace BLUETOOTH_Utils {
void setup();
void bluetoothCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param);
void getData(const uint8_t *buffer, size_t size);
void sendToLoRa();
void sendPacket(const String& packet);
}
#endif

View File

@ -68,6 +68,8 @@ void Configuration::readFile(fs::FS &fs, const char *fileName) {
standingUpdateTime = data["other"]["standingUpdateTime"].as<int>();
sendAltitude = data["other"]["sendAltitude"].as<bool>();
sendBatteryInfo = data["other"]["sendBatteryInfo"].as<bool>();
bluetooth = data["other"]["bluetooth"].as<bool>();
disableGps = data["other"]["disableGps"].as<bool>();
configFile.close();
}

View File

@ -58,6 +58,8 @@ public:
int standingUpdateTime;
bool sendAltitude;
bool sendBatteryInfo;
bool bluetooth;
bool disableGps;
Configuration();
void validateConfigFile(String currentBeaconCallsign);

View File

@ -30,7 +30,12 @@ extern uint32_t lastTx;
namespace GPS_Utils {
void setup() {
neo6m_gps.begin(9600, SERIAL_8N1, GPS_TX, GPS_RX);
if (Config.disableGps) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "GPS disabled");
return;
}
neo6m_gps.begin(9600, SERIAL_8N1, GPS_TX, GPS_RX);
}
void calculateDistanceCourse(String Callsign, double checkpointLatitude, double checkPointLongitude) {
@ -102,6 +107,10 @@ void getReceivedGPS(String packet, String sender) {
}
void getData() {
if (Config.disableGps) {
return;
}
while (neo6m_gps.available() > 0) {
gps.encode(neo6m_gps.read());
}
@ -141,6 +150,10 @@ void calculateHeadingDelta(int speed) {
}
void checkStartUpFrames() {
if (Config.disableGps) {
return;
}
if ((millis() > 8000 && gps.charsProcessed() < 10)) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_ERROR, "GPS",
"No GPS frames detected! Try to reset the GPS Chip with this "

View File

@ -117,7 +117,7 @@ void showOnScreen() {
if (powerManagement.getBatteryInfoIsConnected()) {
String batteryVoltage = powerManagement.getBatteryInfoVoltage();
String batteryChargeCurrent = powerManagement.getBatteryInfoCurrent();
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
if (batteryChargeCurrent.toInt() == 0) {
sixthRowMainMenu = "Battery Charged " + batteryVoltage + "V";
} else if (batteryChargeCurrent.toInt() > 0) {

View File

@ -7,6 +7,7 @@
#include "gps_utils.h"
#include "display.h"
#include "logger.h"
#include "bluetooth_utils.h"
extern Beacon *currentBeacon;
extern logging::Logger logger;
@ -141,6 +142,7 @@ void checkReceivedMessage(String packetReceived) {
}
String Sender, AddresseeAndMessage, Addressee, receivedMessage, ackMessage;
if (packetReceived.substring(0,3) == "\x3c\xff\x01") { // its an APRS packet
BLUETOOTH_Utils::sendPacket(packetReceived.substring(3));
Sender = packetReceived.substring(3,packetReceived.indexOf(">"));
if (Sender != currentBeacon->callsign) { // avoid listening yourself by digirepeating
if (packetReceived.indexOf("::") > 10) { // its a Message!

View File

@ -9,16 +9,25 @@
#define OLED_SCL 22
#define OLED_RST 16
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
#ifdef TTGO_T_Beam_V0_7
#define GPS_RX 15
#define GPS_TX 12
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
#endif
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_2)
#define GPS_RX 12
#define GPS_TX 34
#define BUTTON_PIN 38 // The middle button GPIO on the T-Beam
#endif
#ifdef TTGO_T_LORA_V2_1
#define GPS_RX -1
#define GPS_TX -1
#define BUTTON_PIN -1
#endif
#endif

View File

@ -1,14 +1,16 @@
#include "power_utils.h"
#include "logger.h"
#include "configuration.h"
#define I2C_SDA 21
#define I2C_SCL 22
extern Configuration Config;
extern logging::Logger logger;
// cppcheck-suppress unusedFunction
bool PowerManagement::begin(TwoWire &port) {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
bool result = axp.begin(port, AXP192_SLAVE_ADDRESS);
if (!result) {
axp.setDCDC1Voltage(3300);
@ -38,7 +40,7 @@ bool PowerManagement::begin(TwoWire &port) {
// cppcheck-suppress unusedFunction
void PowerManagement::activateLoRa() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);
#endif
#ifdef TTGO_T_Beam_V1_2
@ -49,7 +51,7 @@ void PowerManagement::activateLoRa() {
// cppcheck-suppress unusedFunction
void PowerManagement::deactivateLoRa() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF);
#endif
#ifdef TTGO_T_Beam_V1_2
@ -59,8 +61,8 @@ void PowerManagement::deactivateLoRa() {
// cppcheck-suppress unusedFunction
void PowerManagement::activateGPS() {
#ifdef TTGO_T_Beam_V1_0
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON);
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON);
#endif
#ifdef TTGO_T_Beam_V1_2
PMU.setALDO3Voltage(3300);
@ -70,8 +72,8 @@ void PowerManagement::activateGPS() {
// cppcheck-suppress unusedFunction
void PowerManagement::deactivateGPS() {
#ifdef TTGO_T_Beam_V1_0
axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF);
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF);
#endif
#ifdef TTGO_T_Beam_V1_2
PMU.disableALDO3();
@ -80,35 +82,35 @@ void PowerManagement::deactivateGPS() {
// cppcheck-suppress unusedFunction
void PowerManagement::activateOLED() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
#endif
}
// cppcheck-suppress unusedFunction
void PowerManagement::decativateOLED() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.setPowerOutPut(AXP192_DCDC1, AXP202_OFF);
#endif
}
// cppcheck-suppress unusedFunction
void PowerManagement::disableChgLed() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.setChgLEDMode(AXP20X_LED_OFF);
#endif
}
// cppcheck-suppress unusedFunction
void PowerManagement::enableChgLed() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.setChgLEDMode(AXP20X_LED_LOW_LEVEL);
#endif
}
// cppcheck-suppress unusedFunction
void PowerManagement::activateMeasurement() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.adc1Enable(AXP202_BATT_CUR_ADC1 | AXP202_BATT_VOL_ADC1, true);
#endif
#ifdef TTGO_T_Beam_V1_2
@ -122,14 +124,14 @@ void PowerManagement::activateMeasurement() {
// cppcheck-suppress unusedFunction
void PowerManagement::deactivateMeasurement() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
axp.adc1Enable(AXP202_BATT_CUR_ADC1 | AXP202_BATT_VOL_ADC1, false);
#endif
}
// cppcheck-suppress unusedFunction
double PowerManagement::getBatteryVoltage() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
return axp.getBattVoltage() / 1000.0;
#endif
#ifdef TTGO_T_Beam_V1_2
@ -139,7 +141,7 @@ double PowerManagement::getBatteryVoltage() {
// cppcheck-suppress unusedFunction
double PowerManagement::getBatteryChargeDischargeCurrent() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
if (axp.isChargeing()) {
return axp.getBattChargeCurrent();
}
@ -151,7 +153,7 @@ double PowerManagement::getBatteryChargeDischargeCurrent() {
}
bool PowerManagement::isBatteryConnected() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
return axp.isBatteryConnect();
#endif
#ifdef TTGO_T_Beam_V1_2
@ -160,7 +162,7 @@ bool PowerManagement::isBatteryConnected() {
}
bool PowerManagement::isChargeing() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
return axp.isChargeing();
#endif
#ifdef TTGO_T_Beam_V1_2
@ -169,7 +171,7 @@ bool PowerManagement::isChargeing() {
}
void PowerManagement::setup() {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
Wire.begin(SDA, SCL);
if (!begin(Wire)) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "AXP192", "init done!");
@ -178,7 +180,11 @@ void PowerManagement::setup() {
}
activateLoRa();
activateOLED();
activateGPS();
if (Config.disableGps) {
deactivateGPS();
} else {
activateGPS();
}
activateMeasurement();
#endif
#ifdef TTGO_T_Beam_V1_2
@ -190,7 +196,11 @@ void PowerManagement::setup() {
}
activateLoRa();
activateOLED();
activateGPS();
if (Config.disableGps) {
deactivateGPS();
} else {
activateGPS();
}
activateMeasurement();
PMU.setChargeTargetVoltage(XPOWERS_AXP2101_CHG_VOL_4V2);
PMU.setChargerConstantCurr(XPOWERS_AXP2101_CHG_CUR_500MA);
@ -199,7 +209,7 @@ void PowerManagement::setup() {
}
void PowerManagement::lowerCpuFrequency() {
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_2)
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_Beam_V1_2) || defined(TTGO_T_LORA_V2_1)
if (setCpuFrequencyMhz(80)) {
logger.log(logging::LoggerLevel::LOGGER_LEVEL_INFO, "Main", "CPU frequency set to 80MHz");
} else {
@ -221,7 +231,7 @@ void PowerManagement::obtainBatteryInfo() {
if (!(rate_limit_check_battery++ % 60))
BatteryIsConnected = isBatteryConnected();
if (BatteryIsConnected) {
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
batteryVoltage = String(getBatteryVoltage(), 2);
#endif
#ifdef TTGO_T_Beam_V1_2

View File

@ -2,7 +2,7 @@
#define POWER_UTILS_H_
#include <Arduino.h>
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
#include <axp20x.h>
#endif
#ifdef TTGO_T_Beam_V1_2
@ -49,7 +49,7 @@ private:
bool isBatteryConnected();
#ifdef TTGO_T_Beam_V1_0
#if defined(TTGO_T_Beam_V1_0) || defined(TTGO_T_LORA_V2_1)
AXP20X_Class axp;
#endif
#ifdef TTGO_T_Beam_V1_2