add signal strength meter

This commit is contained in:
Kyle Isom 2023-10-07 13:38:17 -07:00
parent 63faf519c1
commit e5cf44c3a6
14 changed files with 414 additions and 148 deletions

View File

@ -1,3 +1,4 @@
#BOARD := featheresp32
BOARD := sparkfun_esp32micromod
FIRMWARE := .pioenvs/$(BOARD)/firmware.bin
SOURCES := \

View File

@ -2,7 +2,7 @@
#define KIMODEM_PREFS_H
namespace config {
namespace Config {
// Networking
@ -14,6 +14,11 @@ void SetStartTryConnecting(bool opt);
// Misc.
bool EnableMeter();
void SetEnableMeter(bool opt);
// Misc. control
void FactoryDefaults();
}

View File

@ -6,29 +6,20 @@
#define ANSI_CLEAR_SCREEN "\33[2J"
/*
class Display {
public:
Display();
namespace Display {
void Clear();
void Draw();
bool HasDisplay();
void Init();
void Clear();
void Clear(bool hint);
void Draw();
bool HasDisplay();
void Print(const char *);
void Println(const char *);
void SetCursor(int16_t x, int16_t y);
};
*/
#if defined(ADAFRUIT_OLED)
#include "internal/DisplayAdafruitOLED.h"
#else
#include "internal/DisplayNone.h"
#endif
void Print(const char *);
void Println(const char *);
void SetCursor(int16_t x, int16_t y);
static Display display;
} // namespace Display
#endif

20
include/WiFiMeter.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef KIMODEM_WIFI_METER_H
#define KIMODEM_WIFI_METER_H
#include <Arduino.h>
namespace Meter {
void Begin();
void Enable();
void Disable();
void Update();
}
#endif

View File

@ -10,6 +10,7 @@ bool SetupWiFi();
bool Autoconnect(Dictionary &pb);
bool Autoconnect(Dictionary &pb, bool reset);
bool TryConnect(Dictionary &pb);
void WiFiRefresh(Dictionary &pb);
#endif

View File

@ -1,26 +0,0 @@
#ifndef KIMODEM_ADAFRUIT_OLED_H
#define KIMODEM_ADAFRUIT_OLED_H
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
class Display {
public:
Display();
void Clear();
void Draw();
bool HasDisplay();
void Print(const char *);
void Println(const char *);
void SetCursor(int16_t x, int16_t y);
private:
Adafruit_SSD1306 oled;
};
#endif

View File

@ -1,20 +0,0 @@
#ifndef KIMODEM_DISPLAY_SERIAL
#define KIMODEM_DISPLAY_SERIAL
#include <Arduino.h>
class Display {
public:
Display() {};
void Clear();
void Draw();
bool HasDisplay();
void Print(const char *);
void Println(const char *);
void SetCursor(int16_t x, int16_t y);
};
#endif

View File

@ -13,6 +13,8 @@ framework = arduino
platform = espressif32
monitor_speed = 115200
extra_scripts = scripts/download_fs.py
monitor_filters =
esp32_exception_decoder
[env:featheresp32]
board = featheresp32
@ -27,7 +29,13 @@ lib_deps =
board = sparkfun_esp32micromod
build_flags =
-DSPARKFUN_HYPERDISPLAY
-DDISPLAY_NONE
-DAPA102_ENABLED
lib_deps =
sparkfun/SparkFun HyperDisplay@^2.0.1
sparkfun/SparkFun HyperDisplay ILI9341@^1.0.0
sparkfun/SparkFun HyperDisplay 4DLCD-320240@^1.0.0
pololu/APA102@^3.0.0
[env:d1mini]
board = wemos_d1_mini32

View File

@ -1,8 +1,9 @@
#include <Preferences.h>
#include "prefs.h"
#include "Config.h"
namespace config {
namespace Config {
static bool isLoaded = false;
@ -61,6 +62,22 @@ SetStartTryConnecting(bool opt)
}
bool
EnableMeter()
{
checkReady();
return preferences.getBool("WCM", true);
}
void
SetEnableMeter(bool opt)
{
checkReady();
preferences.putBool("WCM", opt);
}
void
FactoryDefaults()
{

View File

@ -5,64 +5,84 @@
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "internal/DisplayAdafruitOLED.h"
#include "Display.h"
static Adafruit_SSD1306 oled(SSD1306_SWITCHCAPVCC, 0x3C);
namespace Display {
static Adafruit_SSD1306 oled(SSD1306_SWITCHCAPVCC, 0x3C);
Display::Display()
: oled(oled)
void
Init()
{
Serial.println("initialized display");
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.display();
oled.clearDisplay();
oled.setTextSize(1);
oled.setTextColor(SSD1306_WHITE);
oled.setTextColor(WHITE);
oled.fillScreen(BLACK);
oled.display();
Serial.println("DISP INIT");
}
void
Display::Clear()
Clear()
{
this->oled.clearDisplay();
this->SetCursor(0, 0);
this->Draw();
Clear(false);
}
void
Display::Draw()
Clear(bool hint)
{
this->oled.display();
oled.clearDisplay();
SetCursor(0, 0);
oled.display();
}
void
Draw()
{
oled.display();
}
bool
Display::HasDisplay()
HasDisplay()
{
return true;
}
void
Display::Print(const char *s)
Print(const char *s)
{
this->oled.print(s);
oled.print(s);
Serial.print(s);
oled.display();
}
void
Display::Println(const char *s)
Println(const char *s)
{
this->oled.println(s);
oled.println(s);
Serial.println(s);
oled.display();
}
void
Display::SetCursor(int16_t x, int16_t y)
SetCursor(int16_t x, int16_t y)
{
this->oled.setCursor(x, y);
oled.setCursor(x, y);
}
} // namespace Display
#endif

View File

@ -0,0 +1,88 @@
#if defined(SPARKFUN_HYPERDISPLAY)
#include <Arduino.h>
#include <HyperDisplay_4DLCD-320240_4WSPI.h>
#include "Display.h"
namespace Display {
static LCD320240_4WSPI tft;
static ILI9341_color_18_t defaultColor;
static uint16_t line = 0;
void
Init()
{
tft.begin(D1, D0, PWM0, SPI, 32000000);
tft.setInterfacePixelFormat(ILI9341_PXLFMT_18);
tft.clearDisplay();
defaultColor = tft.rgbTo18b(255, 255, 255);
tft.setCurrentWindowColorSequence((color_t)&defaultColor);
}
void
Clear()
{
Clear(false);
}
void
Clear(bool hint)
{
if (hint) {
return;
}
tft.clearDisplay();
SetCursor(0, 0);
line = 0;
}
void
Draw()
{
}
bool
HasDisplay()
{
return true;
}
void
Print(const char *s)
{
tft.print(s);
Serial.print(s);
}
void
Println(const char *s)
{
tft.println(s);
Serial.println(s);
line++;
SetCursor(0, line*10);
}
void
SetCursor(int16_t x, int16_t y)
{
tft.setTextCursor(x, y);
}
} // namespace Display
#endif

132
src/WiFiMeter.cc Normal file
View File

@ -0,0 +1,132 @@
#include <Arduino.h>
#include <WiFi.h>
#include "Config.h"
#include "WiFiMeter.h"
namespace Meter {
static bool enabled = false;
#if defined(APA102_ENABLED)
#include <APA102.h>
constexpr uint8_t APA102_DATA = 25;
constexpr uint8_t APA102_CLOCK = 15;
constexpr uint8_t APA102_COUNT = 6;
constexpr uint8_t APA102_BRIGHTNESS = 5;
APA102<APA102_DATA, APA102_CLOCK> ledBar;
static void
setLED(uint8_t brightness)
{
brightness = brightness & 0x1f;
ledBar.sendColor(0, 0, 255, brightness);
}
static void
clearBar()
{
ledBar.startFrame();
for (int i = 0; i < APA102_COUNT; i++) {
setLED(0);
}
ledBar.endFrame(APA102_COUNT);
}
static void
setLedCount(uint8_t on)
{
ledBar.startFrame();
for (int i = 0; i < APA102_COUNT; i++) {
if (i >= on) {
setLED(0);
} else {
setLED(APA102_BRIGHTNESS);
}
}
ledBar.endFrame(APA102_CLOCK);
}
void
Begin()
{
enabled = Config::EnableMeter();
}
void
Enable()
{
enabled = true;
Config::SetEnableMeter(true);
}
void
Disable()
{
enabled = false;
Config::SetEnableMeter(false);
}
void
Update()
{
if (!enabled) {
return;
}
int8_t rssi;
uint8_t count = 0;
if (WiFi.status() != WL_CONNECTED) {
rssi = -127;
} else {
rssi = WiFi.RSSI();
}
if (rssi >= -30) {
count = 6;
} else if (rssi >= -55) {
count = 5;
} else if (rssi >= -67) {
count = 4;
} else if (rssi >= -70) {
count = 3;
} else if (rssi >= -80) {
count = 2;
} else if (rssi >= -90) {
count = 1;
} else {
count = 0;
}
setLedCount(count);
}
#else
void Begin() {}
void Enable() {}
void Disable() {}
void Update() {}
#endif
}

View File

@ -2,10 +2,11 @@
#include <WiFi.h>
#include <string.h>
#include "Config.h"
#include "Dictionary.h"
#include "Display.h"
#include "WiFiMeter.h"
#include "TLV.h"
#include "prefs.h"
#include "WiFiMgr.h"
@ -14,6 +15,10 @@
#define CONN_WAIT 250
static TLV::Record ssidrec;
static TLV::Record wpakeyrec;
bool
SetupWiFi()
{
@ -27,32 +32,30 @@ tryConnect(const char *ssid, const char *wpakey)
{
size_t waitedFor = 0;
Serial.print("CONNECT ");
Serial.println(ssid);
Display::Print("CONNECT ");
Display::Println(ssid);
WiFi.begin(ssid, wpakey);
while ((WiFi.status() != WL_CONNECTED) && (waitedFor < MAX_WAIT)) {
waitedFor += CONN_WAIT;
if ((waitedFor % 1000) == 0) {
Serial.print(".");
Display::Print(".");
}
delay(250);
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("MODEM ADDR ");
Serial.println(WiFi.localIP());
Display::Clear(true);
Display::Print("SSID: ");
Display::Println(ssid);
Display::Print("IP: ");
Display::Println(WiFi.localIP().toString().c_str());
display.Clear();
display.Print("SSID: ");
display.Println(ssid);
display.Print("IP: ");
display.Println(WiFi.localIP().toString().c_str());
display.Draw();
Config::SetLastSSID(ssid);
return true;
}
Serial.println("CARRIER SIGNAL LOST");
Display::Println("CARRIER SIGNAL LOST");
return false;
}
@ -60,30 +63,28 @@ tryConnect(const char *ssid, const char *wpakey)
bool
TryConnect(Dictionary &pb)
{
TLV::Record ssid;
TLV::Record wpakey;
uint8_t *cursor;
if ((ssid.Len = config::LastSSID(ssid.Val, 32)) != 0) {
Serial.print("LAST SSID: ");
Serial.println(ssid.Val);
if (pb.Lookup(ssid.Val, ssid.Len, wpakey)) {
if (tryConnect((const char *)ssid.Val, (const char *)wpakey.Val)) {
if ((ssidrec.Len = Config::LastSSID(ssidrec.Val, 32)) != 0) {
Display::Print("LAST SSID: ");
Display::Println(ssidrec.Val);
if (pb.Lookup(ssidrec.Val, ssidrec.Len, wpakeyrec)) {
if (tryConnect((const char *)ssidrec.Val, (const char *)wpakeyrec.Val)) {
return true;
}
} else {
Serial.println("WPAKEY NOT FOUND");
Display::Println("WPAKEY NOT FOUND");
}
}
while ((cursor != NULL) && (cursor[0] != TAG_EMPTY)) {
TLV::ReadFromMemory(ssid, cursor);
TLV::SkipRecord(ssid, cursor);
TLV::ReadFromMemory(ssidrec, cursor);
TLV::SkipRecord(ssidrec, cursor);
TLV::ReadFromMemory(wpakey, cursor);
TLV::SkipRecord(ssid, cursor);
TLV::ReadFromMemory(wpakeyrec, cursor);
TLV::SkipRecord(wpakeyrec, cursor);
if (tryConnect(ssid.Val, wpakey.Val)) {
if (tryConnect(ssidrec.Val, wpakeyrec.Val)) {
return true;
}
}
@ -103,16 +104,16 @@ tryConnect(Dictionary &pb, int network)
return false;
}
Serial.print("MODEM: CHECK ");
Serial.print(ssid);
Serial.print(": ");
Display::Print("MODEM: CHECK ");
Display::Print(ssid);
Display::Print(": ");
if (!pb.Lookup(ssid, uint8_t(ssidLen), password)) {
Serial.println("NOT FOUND");
Display::Println("NOT FOUND");
return false;
}
Serial.println("CONNECTING");
Display::Println("CONNECTING");
return tryConnect(ssid, password.Val);
}
@ -129,15 +130,15 @@ Autoconnect(Dictionary &pb, bool reset)
int networkCount = 0;
int network = 0;
Serial.println("MODEM: TRY AUTOCONNECT");
Display::Println("MODEM: TRY AUTOCONNECT");
if (reset) {
Serial.println("RADIO RESET");
Display::Println("RADIO RESET");
SetupWiFi();
WiFi.disconnect();
delay(1000);
} else {
Serial.println("NO RESET");
Display::Println("NO RESET");
}
networkCount = WiFi.scanNetworks();
@ -147,7 +148,31 @@ Autoconnect(Dictionary &pb, bool reset)
}
}
Serial.println("NO CARRIER");
Display::Println("NO CARRIER");
return false;
}
bool
Reconnect(Dictionary &pb)
{
if (!tryConnect(ssidrec.Val, wpakeyrec.Val)) {
return TryConnect(pb);
}
return true;
}
void
WiFiRefresh(Dictionary &pb)
{
Meter::Update();
if (WiFi.status() == WL_CONNECTED) {
return;
}
Display::Println("CARRIER SIGNAL LOST: ATC");
Reconnect(pb);
}

View File

@ -2,10 +2,11 @@
#include <SPIFFS.h>
#include "Arena.h"
#include "Config.h"
#include "Dictionary.h"
#include "Display.h"
#include "WiFiMgr.h"
#include "prefs.h"
#include "WiFiMeter.h"
#include "homenet.h"
@ -23,31 +24,31 @@ setupPhonebook()
size_t fileSize = pbFile.size();
bool ok = false;
Serial.print("DAT FILE ");
Serial.print(fileSize);
Serial.println("B");
Display::Print("DAT FILE ");
Display::Print(String(fileSize).c_str());
Display::Println("B");
if (fileSize == 0) {
Serial.println("INIT PHONEBOOK");
Display::Println("INIT PHONEBOOK");
phonebook.Set(HOME_SSID, HOME_SSIDLEN, HOME_WPA, HOME_WPALEN);
if (WriteArena(arena, pbFilePath) == 0) {
ok = true;
}
pbFile.close();
config::SetLastSSID(HOME_SSID);
Config::SetLastSSID(HOME_SSID);
return ok;
}
fileSize = fileSize > PHONEBOOK_SIZE ? PHONEBOOK_SIZE : fileSize;
Serial.print("LOAD PHONEBOOK ");
Display::Print("LOAD PHONEBOOK ");
if (fileSize != pbFile.read(phonebookBuffer, fileSize)) {
Serial.println("FAILED");
Display::Println("FAILED");
pbFile.close();
return false;
}
Serial.println("OK");
Display::Println("OK");
pbFile.close();
phonebook.DumpKVPairs();
return true;
@ -56,32 +57,35 @@ setupPhonebook()
void setup() {
Serial.begin(115200);
while (!Serial) ;
Display::Init();
display.Clear();
Serial.println("MODEM BOOT");
Display::Println("MODEM BOOT");
Display::Clear();
Display::Println("MODEM BOOT");
InitializeArena(arena);
NewStaticArena(arena, phonebookBuffer, PHONEBOOK_SIZE);
Meter::Begin();
Meter::Enable();
while (true);
Display::Println("SPIFFS INIT");
if (!SPIFFS.begin(true) && !SPIFFS.begin(false)) {
Serial.println("SPIFFS BEGIN FAIL");
Display::Println("SPIFFS BEGIN FAIL");
while (true) ;
}
setupPhonebook();
if (config::StartTryConnecting()) {
if (Config::StartTryConnecting()) {
Display::Println("AUTO ATC");
if (!TryConnect(phonebook)) {
Autoconnect(phonebook);
}
}
Serial.println("MODEM READY");
Display::Println("MODEM READY");
}
void loop() {
// put your main code here, to run repeatedly:
delay(1000);
Meter::Update();
}