bt to mesh code is written

pull/1/head
geeksville 2020-02-01 16:14:34 -08:00
rodzic 490331f3cd
commit de03dc88f4
6 zmienionych plików z 185 dodań i 153 usunięć

Wyświetl plik

@ -1,6 +1,5 @@
#include "BluetoothUtil.h" #include "BluetoothUtil.h"
#include "BluetoothSoftwareUpdate.h" #include "BluetoothSoftwareUpdate.h"
#include "MeshBluetoothService.h"
#include <esp_gatt_defs.h> #include <esp_gatt_defs.h>
#include <BLE2902.h> #include <BLE2902.h>
#include <Arduino.h> #include <Arduino.h>
@ -122,14 +121,10 @@ BLEServer *initBLE(std::string deviceName) {
BLEService *pUpdate = createUpdateService(pServer); // We need to advertise this so our android ble scan operation can see it BLEService *pUpdate = createUpdateService(pServer); // We need to advertise this so our android ble scan operation can see it
pServer->getAdvertising()->addServiceUUID(pUpdate->getUUID()); pServer->getAdvertising()->addServiceUUID(pUpdate->getUUID());
BLEService *pMesh = createMeshBluetoothService(pServer); // We need to advertise this so our android ble scan operation can see it
pServer->getAdvertising()->addServiceUUID(pMesh->getUUID());
// start all our services (do this after creating all of them) // start all our services (do this after creating all of them)
pDevInfo->start(); pDevInfo->start();
pBattery->start(); pBattery->start();
pUpdate->start(); pUpdate->start();
pMesh->start();
// Start advertising // Start advertising
pServer->getAdvertising()->start(); pServer->getAdvertising()->start();

Wyświetl plik

@ -1,5 +0,0 @@
#pragma once
#include <Arduino.h>
BLEService *createMeshBluetoothService(BLEServer* server);

Wyświetl plik

@ -205,3 +205,7 @@ BLEService *createMeshBluetoothService(BLEServer *server)
return service; return service;
} }

Wyświetl plik

@ -0,0 +1,6 @@
#pragma once
#include <Arduino.h>
BLEService *createMeshBluetoothService(BLEServer* server);

Wyświetl plik

@ -84,7 +84,6 @@ void mesh_init() {
} }
} }
int16_t packetnum = 0; // packet counter, we increment per xmission int16_t packetnum = 0; // packet counter, we increment per xmission
void mesh_loop() void mesh_loop()

Wyświetl plik

@ -26,6 +26,7 @@
#include <TinyGPS++.h> #include <TinyGPS++.h>
#include <Wire.h> #include <Wire.h>
#include "BluetoothUtil.h" #include "BluetoothUtil.h"
#include "MeshBluetoothService.h"
#include "MeshRadio.h" #include "MeshRadio.h"
#ifdef T_BEAM_V10 #ifdef T_BEAM_V10
@ -50,47 +51,49 @@ esp_sleep_source_t wakeCause; // the reason we booted this time
void doDeepSleep(uint64_t msecToWake) void doDeepSleep(uint64_t msecToWake)
{ {
Serial.printf("Entering deep sleep for %llu seconds\n", msecToWake / 1000); Serial.printf("Entering deep sleep for %llu seconds\n", msecToWake / 1000);
// not using wifi yet, but once we are this is needed to shutoff the radio hw // not using wifi yet, but once we are this is needed to shutoff the radio hw
// esp_wifi_stop(); // esp_wifi_stop();
screen_off(); // datasheet says this will draw only 10ua screen_off(); // datasheet says this will draw only 10ua
// FIXME, shutdown radio headinterups before powering off device
#ifdef T_BEAM_V10
if(axp192_found) {
// turn on after initial testing with real hardware
axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LORA radio
axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // GPS main power
}
#endif
// FIXME - use an external 10k pulldown so we can leave the RTC peripherals powered off // FIXME, shutdown radio headinterups before powering off device
// until then we need the following lines
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
#ifdef BUTTON_PIN #ifdef T_BEAM_V10
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39. if (axp192_found)
uint64_t gpioMask = (1ULL << BUTTON_PIN); {
// turn on after initial testing with real hardware
// FIXME change polarity so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of just the first) axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF); // LORA radio
gpio_pullup_en((gpio_num_t) BUTTON_PIN); axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF); // GPS main power
}
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
#endif #endif
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs // FIXME - use an external 10k pulldown so we can leave the RTC peripherals powered off
esp_deep_sleep_start(); // TBD mA sleep current (battery) // until then we need the following lines
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
#ifdef BUTTON_PIN
// Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.
uint64_t gpioMask = (1ULL << BUTTON_PIN);
// FIXME change polarity so we can wake on ANY_HIGH instead - that would allow us to use all three buttons (instead of just the first)
gpio_pullup_en((gpio_num_t)BUTTON_PIN);
esp_sleep_enable_ext1_wakeup(gpioMask, ESP_EXT1_WAKEUP_ALL_LOW);
#endif
esp_sleep_enable_timer_wakeup(msecToWake * 1000ULL); // call expects usecs
esp_deep_sleep_start(); // TBD mA sleep current (battery)
} }
void sleep()
void sleep() { {
#if SLEEP_BETWEEN_MESSAGES #if SLEEP_BETWEEN_MESSAGES
// If the user has a screen, tell them we are about to sleep // If the user has a screen, tell them we are about to sleep
if(ssd1306_found) { if (ssd1306_found)
{
// Show the going to sleep message on the screen // Show the going to sleep message on the screen
char buffer[20]; char buffer[20];
snprintf(buffer, sizeof(buffer), "Sleeping in %3.1fs\n", (MESSAGE_TO_SLEEP_DELAY / 1000.0)); snprintf(buffer, sizeof(buffer), "Sleeping in %3.1fs\n", (MESSAGE_TO_SLEEP_DELAY / 1000.0));
@ -101,7 +104,7 @@ void sleep() {
// Turn off screen // Turn off screen
screen_off(); screen_off();
} }
// We sleep for the interval between messages minus the current millis // We sleep for the interval between messages minus the current millis
// this way we distribute the messages evenly every SEND_INTERVAL millis // this way we distribute the messages evenly every SEND_INTERVAL millis
@ -111,43 +114,48 @@ void sleep() {
#endif #endif
} }
void scanI2Cdevice(void) void scanI2Cdevice(void)
{ {
byte err, addr; byte err, addr;
int nDevices = 0; int nDevices = 0;
for (addr = 1; addr < 127; addr++) { for (addr = 1; addr < 127; addr++)
Wire.beginTransmission(addr); {
err = Wire.endTransmission(); Wire.beginTransmission(addr);
if (err == 0) { err = Wire.endTransmission();
Serial.print("I2C device found at address 0x"); if (err == 0)
if (addr < 16) {
Serial.print("0"); Serial.print("I2C device found at address 0x");
Serial.print(addr, HEX); if (addr < 16)
Serial.println(" !"); Serial.print("0");
nDevices++; Serial.print(addr, HEX);
Serial.println(" !");
nDevices++;
if (addr == SSD1306_ADDRESS) { if (addr == SSD1306_ADDRESS)
ssd1306_found = true; {
Serial.println("ssd1306 display found"); ssd1306_found = true;
} Serial.println("ssd1306 display found");
#ifdef T_BEAM_V10 }
if (addr == AXP192_SLAVE_ADDRESS) { #ifdef T_BEAM_V10
axp192_found = true; if (addr == AXP192_SLAVE_ADDRESS)
Serial.println("axp192 PMU found"); {
} axp192_found = true;
#endif Serial.println("axp192 PMU found");
} else if (err == 4) { }
Serial.print("Unknow error at address 0x"); #endif
if (addr < 16)
Serial.print("0");
Serial.println(addr, HEX);
}
} }
if (nDevices == 0) else if (err == 4)
Serial.println("No I2C devices found\n"); {
else Serial.print("Unknow error at address 0x");
Serial.println("done\n"); if (addr < 16)
Serial.print("0");
Serial.println(addr, HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
} }
/** /**
@ -161,61 +169,70 @@ void scanI2Cdevice(void)
LDO2 200mA -> LORA LDO2 200mA -> LORA
LDO3 200mA -> GPS LDO3 200mA -> GPS
*/ */
void axp192Init() { void axp192Init()
#ifdef T_BEAM_V10 {
if (axp192_found) { #ifdef T_BEAM_V10
if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS)) { if (axp192_found)
Serial.println("AXP192 Begin PASS"); {
} else { if (!axp.begin(Wire, AXP192_SLAVE_ADDRESS))
Serial.println("AXP192 Begin FAIL"); {
} Serial.println("AXP192 Begin PASS");
// axp.setChgLEDMode(LED_BLINK_4HZ);
Serial.printf("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
Serial.printf("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
Serial.printf("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
Serial.printf("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
Serial.printf("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
Serial.printf("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
Serial.println("----------------------------------------");
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LORA radio
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
axp.setDCDC1Voltage(3300); // for the OLED power
Serial.printf("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
Serial.printf("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
Serial.printf("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
Serial.printf("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
Serial.printf("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
Serial.printf("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
pinMode(PMU_IRQ, INPUT_PULLUP);
attachInterrupt(PMU_IRQ, [] {
pmu_irq = true;
}, FALLING);
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
axp.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ, 1);
axp.clearIRQ();
if (axp.isChargeing()) {
baChStatus = "Charging";
}
} else {
Serial.println("AXP192 not found");
} }
#endif else
{
Serial.println("AXP192 Begin FAIL");
}
// axp.setChgLEDMode(LED_BLINK_4HZ);
Serial.printf("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
Serial.printf("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
Serial.printf("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
Serial.printf("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
Serial.printf("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
Serial.printf("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
Serial.println("----------------------------------------");
axp.setPowerOutPut(AXP192_LDO2, AXP202_ON); // LORA radio
axp.setPowerOutPut(AXP192_LDO3, AXP202_ON); // GPS main power
axp.setPowerOutPut(AXP192_DCDC2, AXP202_ON);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_ON);
axp.setPowerOutPut(AXP192_DCDC1, AXP202_ON);
axp.setDCDC1Voltage(3300); // for the OLED power
Serial.printf("DCDC1: %s\n", axp.isDCDC1Enable() ? "ENABLE" : "DISABLE");
Serial.printf("DCDC2: %s\n", axp.isDCDC2Enable() ? "ENABLE" : "DISABLE");
Serial.printf("LDO2: %s\n", axp.isLDO2Enable() ? "ENABLE" : "DISABLE");
Serial.printf("LDO3: %s\n", axp.isLDO3Enable() ? "ENABLE" : "DISABLE");
Serial.printf("DCDC3: %s\n", axp.isDCDC3Enable() ? "ENABLE" : "DISABLE");
Serial.printf("Exten: %s\n", axp.isExtenEnable() ? "ENABLE" : "DISABLE");
pinMode(PMU_IRQ, INPUT_PULLUP);
attachInterrupt(PMU_IRQ, [] {
pmu_irq = true;
},
FALLING);
axp.adc1Enable(AXP202_BATT_CUR_ADC1, 1);
axp.enableIRQ(AXP202_VBUS_REMOVED_IRQ | AXP202_VBUS_CONNECT_IRQ | AXP202_BATT_REMOVED_IRQ | AXP202_BATT_CONNECT_IRQ, 1);
axp.clearIRQ();
if (axp.isChargeing())
{
baChStatus = "Charging";
}
}
else
{
Serial.println("AXP192 not found");
}
#endif
} }
// Perform power on init that we do on each wake from deep sleep // Perform power on init that we do on each wake from deep sleep
void initDeepSleep() { void initDeepSleep()
bootCount++; {
wakeCause = esp_sleep_get_wakeup_cause(); bootCount++;
/* wakeCause = esp_sleep_get_wakeup_cause();
/*
Not using yet because we are using wake on all buttons being low Not using yet because we are using wake on all buttons being low
wakeButtons = esp_sleep_get_ext1_wakeup_status(); // If one of these buttons is set it was the reason we woke wakeButtons = esp_sleep_get_ext1_wakeup_status(); // If one of these buttons is set it was the reason we woke
@ -223,14 +240,15 @@ void initDeepSleep() {
wakeButtons = ((uint64_t)1) << buttons.gpios[0]; wakeButtons = ((uint64_t)1) << buttons.gpios[0];
*/ */
Serial.printf("booted, wake cause %d (boot count %d)\n", wakeCause, bootCount); Serial.printf("booted, wake cause %d (boot count %d)\n", wakeCause, bootCount);
} }
void setup() { void setup()
// Debug {
#ifdef DEBUG_PORT // Debug
#ifdef DEBUG_PORT
DEBUG_PORT.begin(SERIAL_BAUD); DEBUG_PORT.begin(SERIAL_BAUD);
#endif #endif
initDeepSleep(); initDeepSleep();
// delay(1000); FIXME - remove // delay(1000); FIXME - remove
@ -238,12 +256,12 @@ void setup() {
#ifdef VEXT_ENABLE #ifdef VEXT_ENABLE
pinMode(VEXT_ENABLE, OUTPUT); pinMode(VEXT_ENABLE, OUTPUT);
digitalWrite(VEXT_ENABLE, 0); // turn on the display power digitalWrite(VEXT_ENABLE, 0); // turn on the display power
#endif #endif
#ifdef RESET_OLED #ifdef RESET_OLED
pinMode(RESET_OLED, OUTPUT); pinMode(RESET_OLED, OUTPUT);
digitalWrite(RESET_OLED, 1); digitalWrite(RESET_OLED, 1);
#endif #endif
Wire.begin(I2C_SDA, I2C_SCL); Wire.begin(I2C_SDA, I2C_SCL);
scanI2Cdevice(); scanI2Cdevice();
@ -264,10 +282,10 @@ void setup() {
DEBUG_MSG(APP_NAME " " APP_VERSION "\n"); DEBUG_MSG(APP_NAME " " APP_VERSION "\n");
// Don't init display if we don't have one or we are waking headless due to a timer event // Don't init display if we don't have one or we are waking headless due to a timer event
if(wakeCause == ESP_SLEEP_WAKEUP_TIMER) if (wakeCause == ESP_SLEEP_WAKEUP_TIMER)
ssd1306_found = false; // forget we even have the hardware ssd1306_found = false; // forget we even have the hardware
if(ssd1306_found) if (ssd1306_found)
screen_setup(); screen_setup();
// Init GPS // Init GPS
@ -275,24 +293,28 @@ void setup() {
// Show logo on first boot after removing battery // Show logo on first boot after removing battery
//if (bootCount == 0) { //if (bootCount == 0) {
screen_print(APP_NAME " " APP_VERSION, 0, 0); screen_print(APP_NAME " " APP_VERSION, 0, 0);
screen_show_logo(); screen_show_logo();
screen_update(); screen_update();
delay(LOGO_DELAY); delay(LOGO_DELAY);
//} //}
initBLE("KHBT Test"); // FIXME, use a real name based on the macaddr
mesh_init(); mesh_init();
BLEServer *serve = initBLE("KHBT Test"); // FIXME, use a real name based on the macaddr
BLEService *bts = createMeshBluetoothService(serve);
bts->start();
serve->getAdvertising()->addServiceUUID(bts->getUUID());
} }
void loop() { void loop()
{
gps_loop(); gps_loop();
screen_loop(); screen_loop();
mesh_loop(); mesh_loop();
loopBLE(); loopBLE();
if(packetSent) { if (packetSent)
{
packetSent = false; packetSent = false;
sleep(); sleep();
} }
@ -301,16 +323,21 @@ void loop() {
// if user presses button for more than 3 secs, discard our network prefs and reboot (FIXME, use a debounce lib instead of this boilerplate) // if user presses button for more than 3 secs, discard our network prefs and reboot (FIXME, use a debounce lib instead of this boilerplate)
static bool wasPressed = false; static bool wasPressed = false;
static uint32_t minPressMs; // what tick should we call this press long enough static uint32_t minPressMs; // what tick should we call this press long enough
if(!digitalRead(BUTTON_PIN)) { if (!digitalRead(BUTTON_PIN))
if(!wasPressed) { // just started a new press {
if (!wasPressed)
{ // just started a new press
Serial.println("pressing"); Serial.println("pressing");
wasPressed = true; wasPressed = true;
minPressMs = millis() + 3000; minPressMs = millis() + 3000;
} }
} else if(wasPressed) { }
else if (wasPressed)
{
// we just did a release // we just did a release
wasPressed = false; wasPressed = false;
if(millis() > minPressMs) { if (millis() > minPressMs)
{
// held long enough // held long enough
screen_print("Erasing prefs"); screen_print("Erasing prefs");
delay(5000); // Give some time to read the screen delay(5000); // Give some time to read the screen
@ -322,18 +349,24 @@ void loop() {
// Send every SEND_INTERVAL millis // Send every SEND_INTERVAL millis
static uint32_t last = 0; static uint32_t last = 0;
static bool first = true; static bool first = true;
if (0 == last || millis() - last > SEND_INTERVAL) { if (0 == last || millis() - last > SEND_INTERVAL)
if (false) { {
if (false)
{
last = millis(); last = millis();
first = false; first = false;
Serial.println("TRANSMITTED"); Serial.println("TRANSMITTED");
} else { }
if (first) { else
{
if (first)
{
screen_print("Waiting GPS lock\n"); screen_print("Waiting GPS lock\n");
first = false; first = false;
} }
#ifdef GPS_WAIT_FOR_LOCK #ifdef GPS_WAIT_FOR_LOCK
if (millis() > GPS_WAIT_FOR_LOCK) { if (millis() > GPS_WAIT_FOR_LOCK)
{
sleep(); sleep();
} }
#endif #endif