Skip to content

Commit

Permalink
Merge pull request #3 from akchan/bt_gps
Browse files Browse the repository at this point in the history
Bt gps
  • Loading branch information
akchan authored Jan 7, 2024
2 parents 9d647f8 + 89d4014 commit c063606
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 13 deletions.
18 changes: 18 additions & 0 deletions m5core2/cycle_navi/bluetooth_icon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const unsigned char bluetooth_icon_png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00,
0x5e, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0xa5, 0x93, 0x31, 0x12, 0x00,
0x21, 0x0c, 0x02, 0x81, 0xff, 0xff, 0x19, 0xdb, 0x2b, 0x8e, 0x04, 0x47,
0xda, 0x8c, 0x10, 0x5d, 0x24, 0x00, 0x63, 0x90, 0x6d, 0x90, 0x8c, 0x73,
0xa1, 0x90, 0xed, 0x37, 0x03, 0x92, 0xd1, 0x44, 0x6d, 0x52, 0x32, 0x51,
0x9b, 0x94, 0xe6, 0xba, 0x59, 0xf7, 0xef, 0x41, 0xd5, 0x26, 0x25, 0x1a,
0x9c, 0x30, 0x7e, 0x4d, 0x12, 0xca, 0x8a, 0xc2, 0x24, 0x35, 0x05, 0xaa,
0x31, 0x4e, 0xf7, 0xad, 0x30, 0x6e, 0xd5, 0x5d, 0x31, 0x6e, 0xbd, 0x5f,
0x31, 0xde, 0x1e, 0xbe, 0xfa, 0x4c, 0x4f, 0x18, 0xa7, 0xcd, 0x0e, 0x3c,
0x8c, 0x44, 0x1d, 0xbe, 0x69, 0xd0, 0xed, 0x00, 0x00, 0x00, 0x00, 0x49,
0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
unsigned int bluetooth_icon_png_len = 151;
const int bluetooth_icon_png_width = 16;
const int bluetooth_icon_png_height = 16;
176 changes: 163 additions & 13 deletions m5core2/cycle_navi/cycle_navi.ino
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "sound_gps_active.h"
#include "sound_gps_inactive.h"
#include "satellite_icon.h"
#include "bluetooth_icon.h"

// ===============================================================================
// Variables declaration
Expand All @@ -46,6 +47,7 @@

// Settings
const unsigned long interval_sec = 1;
const unsigned long bt_discover_interval_sec = 20;
const float is_moved_cutoff_m = 0.7;
const char map_dir_path[] = "/map";
const char route_dir_path[] = "/route_dat";
Expand All @@ -60,6 +62,8 @@ bool is_gps_active = false;
const int gps_count_th = 3;
bool isUpdatedPrev = false;
int gps_active_counter = 0;
const unsigned long bt_discover_interval_ms = 1000 * bt_discover_interval_sec;
unsigned long bt_last_discover_ms = 0;

struct st_tile_coords
{
Expand Down Expand Up @@ -99,7 +103,9 @@ static LGFX lcd;
static LGFX_Sprite canvas(&lcd); // screen buffer
LGFX_Sprite dir_icon(&canvas);
LGFX_Sprite gps_icon(&canvas);
LGFX_Sprite bt_icon(&canvas);
LGFX_Sprite updating_icon(&canvas);

struct sprite_struct
{
st_tile_coords tile_coords;
Expand Down Expand Up @@ -178,6 +184,116 @@ FsFile file;
// M5Core2 shares SPI but between SD card and the LCD display
#define SD_CONFIG SdSpiConfig(TFCARD_CS_PIN, SHARED_SPI, SPI_CLOCK)

/* ================================================================================
* Bluetooth
* ================================================================================
* Change RX_QUEUE_SIZE 512 -> 1024 in:
* (macOS) ~/Library/Arduino15/packages/m5stack/hardware/esp32/2.0.8/libraries/BluetoothSerial/src/BluetoohSerial.cpp
*
*/
#include <map>
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gap_bt_api.h"
#include "esp_err.h"
#include "BluetoothSerial.h" // install via Arduino library manager

BluetoothSerial SerialBT;

esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE; // or ESP_SPP_SEC_ENCRYPT|ESP_SPP_SEC_AUTHENTICATE to request pincode confirmation
esp_spp_role_t role = ESP_SPP_ROLE_SLAVE; // or ESP_SPP_ROLE_MASTER

#define BT_DEVICE_NAME "ESP32 cycle_navi"
#define REMOVE_BONDED_DEVICES false // Set true to reset pairing
#define PAIR_MAX_DEVICES 20
uint8_t pairedDeviceBtAddr[PAIR_MAX_DEVICES][6];
char bda_str[18];

void BTAuthCompleteCallback(boolean success)
{
if (success)
{
Serial.println("[BT] Pairing success!!");
}
else
{
Serial.println("[BT] Pairing failed, rejected by user!!");
}
}

char *bda2str(const uint8_t *bda, char *str, size_t size)
{
if (bda == NULL || str == NULL || size < 18)
{
return NULL;
}
sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
return str;
}

void BTTryToConnectSPP()
{

int count = esp_bt_gap_get_bond_device_num();
if (!count)
{
Serial.println("[BT] No bonded device found.");
}
else
{
Serial.print("[BT] Bonded device count: ");
Serial.println(count);
if (PAIR_MAX_DEVICES < count)
{
count = PAIR_MAX_DEVICES;
Serial.print("[BT] Reset bonded device count: ");
Serial.println(count);
}
esp_err_t tError = esp_bt_gap_get_bond_device_list(&count, pairedDeviceBtAddr);
if (ESP_OK == tError)
{
for (int i = 0; i < count; i++)
{
Serial.print("[BT] Found bonded device # ");
Serial.print(i);
Serial.print(" -> ");
Serial.println(bda2str(pairedDeviceBtAddr[i], bda_str, 18));

int channel = 0;
BTAddress bt_address(pairedDeviceBtAddr[i]);

std::map<int, std::string> channels = SerialBT.getChannels(bt_address);
Serial.printf("[BT] scanned for services, found %d\n", channels.size());
for (auto const &entry : channels)
{
Serial.printf("[BT] channel %d (%s)\n", entry.first, entry.second.c_str());
}
if (channels.size() > 0 && bt_address && !SerialBT.connected())
{
channel = channels.begin()->first;
Serial.printf("[BT] connecting to %s - %d\n", bt_address.toString().c_str(), channel);
SerialBT.connect(bt_address, channel, sec_mask, role);
}

if (REMOVE_BONDED_DEVICES)
{
esp_err_t tError = esp_bt_gap_remove_bond_device(pairedDeviceBtAddr[i]);
if (ESP_OK == tError)
{
Serial.print("[BT] Removed bonded device # ");
}
else
{
Serial.print("[BT] Failed to remove bonded device # ");
}
Serial.println(i);
}
}
}
}
}

/* ================================================================================
* GPS
* ================================================================================
Expand Down Expand Up @@ -295,6 +411,7 @@ void checkGPS()
{
if (gps.location.isValid())
{
// gps.location status is updated on calling gps.location.lng() or gps.location.lat()
bool isUpdated = gps.location.isUpdated();

if (isUpdated != isUpdatedPrev)
Expand Down Expand Up @@ -1074,28 +1191,51 @@ void initGPSIcon()
gps_icon.drawPng((std::uint8_t *)satellite_icon_png, satellite_icon_png_len, 0, 0);
}

void initBTIcon()
{
Serial.printf("initBTIcon(): Initializing Bluetooth icon\n");
bt_icon.setPsram(false);
bt_icon.createSprite(bluetooth_icon_png_width, bluetooth_icon_png_height);
bt_icon.fillSprite(TFT_WHITE);
bt_icon.drawPng((std::uint8_t *)bluetooth_icon_png, bluetooth_icon_png_len, 0, 0);
}

void pushInfoTopRight()
{
// [Memo] 12 x 18 = Character size in case of `canvas.setTextSize(2);`.
// The variable w is calculated from right to left.
int pad = 1;
int clock_width = 12 * 5; // 5 characters
int gps_icon_width = satellite_icon_png_width;
int w = pad + gps_icon_width + pad + clock_width + pad;
int h = pad + 16 + pad;
const int pad = 1;
const int clock_width = 12 * 5; // 5 characters
const int gps_icon_width = satellite_icon_png_width;
const int bt_icon_width = bluetooth_icon_png_width;
const int w = pad + gps_icon_width + pad + bt_icon_width + clock_width + pad;
const int h = pad + 16 + pad;

canvas.fillRect(lcd.width() - w, 0, w, h, TFT_BLACK);

// Show clock
canvas.setCursor(lcd.width() - (pad + clock_width), pad);
canvas.setTextSize(2);
canvas.setTextColor(WHITE, BLACK);
canvas.printf("%02d:%02d", (gps.time.hour() + 9) % 24, gps.time.minute());
if (gps.time.second() % 2)
{
canvas.printf("%02d:%02d", (gps.time.hour() + 9) % 24, gps.time.minute());
}
else
{
canvas.printf("%02d %02d", (gps.time.hour() + 9) % 24, gps.time.minute());
}

// GPS state
// Bluetooth status
if (SerialBT.connected())
{
bt_icon.pushSprite(lcd.width() - (bt_icon_width + pad + clock_width + pad), pad, TFT_BLACK);
}

// GPS status
if (is_gps_active)
{
gps_icon.pushSprite(lcd.width() - (gps_icon_width + pad + clock_width + pad), pad, TFT_BLACK);
gps_icon.pushSprite(lcd.width() - (gps_icon_width + pad + bt_icon_width + pad + clock_width + pad), pad, TFT_BLACK);
}
}

Expand Down Expand Up @@ -1468,9 +1608,6 @@ void setup(void)
// Serial connection for debug
Serial.println("Initializing cycle_navi");

// Serial connection to GPS module
Serial2.begin(9600, SERIAL_8N1, 13, 14);

// Initialize the SD card.
if (!sd.begin(SD_CONFIG))
{
Expand All @@ -1490,6 +1627,7 @@ void setup(void)
// Initializing small parts
initGPSIcon();
initDirIcon();
initBTIcon();
// initUpdatingIcon();

// Initializing button handlers
Expand All @@ -1503,6 +1641,11 @@ void setup(void)
initTileCache();
updateTileCache();

// Initialize bluetooth
SerialBT.enableSSP();
SerialBT.onAuthComplete(BTAuthCompleteCallback);
SerialBT.begin(BT_DEVICE_NAME, true); // Bluetooth device name

Serial.println("Waiting GPS signals...");
t_prev = millis();
}
Expand All @@ -1515,15 +1658,22 @@ void loop()
drawCanvas();
smartTileLoading();

Serial.printf("SerialBT.connected(): %d\n", SerialBT.connected());
if (!SerialBT.connected() && (millis() - bt_last_discover_ms) > bt_discover_interval_ms)
{
BTTryToConnectSPP();
bt_last_discover_ms = millis();
}

do // Smart delay
{
// Update button & touch screen
M5.update();

// Feed GPS parser
while (Serial2.available() > 0)
while (SerialBT.available() > 0)
{
gps.encode(Serial2.read());
gps.encode(SerialBT.read());
}
t_curr = millis();
} while (t_curr - t_prev < interval_ms);
Expand Down

0 comments on commit c063606

Please sign in to comment.