made a nice PTT/RECV screen for audio module. And cleaned up screen graphics a bit.

This commit is contained in:
Thomas Göttgens 2022-12-13 17:31:01 +01:00
parent 0f2d0d1f07
commit 86d7860d86
6 changed files with 78 additions and 70 deletions

View File

@ -1419,17 +1419,22 @@ void DebugInfo::drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, i
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK); display->setColor(BLACK);
display->setColor(WHITE);
if (WiFi.status() != WL_CONNECTED) { if (WiFi.status() != WL_CONNECTED) {
display->drawString(x, y, String("WiFi: Not Connected")); display->drawString(x, y, String("WiFi: Not Connected"));
display->drawString(x + 1, y, String("WiFi: Not Connected"));
} else { } else {
display->drawString(x, y, String("WiFi: Connected")); display->drawString(x, y, String("WiFi: Connected"));
display->drawString(x + 1, y, String("WiFi: Connected"));
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())), y, display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())), y,
"RSSI " + String(WiFi.RSSI())); "RSSI " + String(WiFi.RSSI()));
display->drawString(x + SCREEN_WIDTH - display->getStringWidth("RSSI " + String(WiFi.RSSI())) - 1, y,
"RSSI " + String(WiFi.RSSI()));
} }
display->setColor(WHITE);
/* /*
- WL_CONNECTED: assigned when connected to a WiFi network; - WL_CONNECTED: assigned when connected to a WiFi network;
- WL_NO_SSID_AVAIL: assigned when no SSID are available; - WL_NO_SSID_AVAIL: assigned when no SSID are available;

View File

@ -15,33 +15,3 @@ const uint8_t imgPositionSolid[] PROGMEM = { 0x20, 0x30, 0x38, 0x3C, 0x7E, 0xFF
const uint8_t imgInfo[] PROGMEM = { 0xFF, 0x81, 0x81, 0xB5, 0xB5, 0x81, 0x81, 0xFF }; const uint8_t imgInfo[] PROGMEM = { 0xFF, 0x81, 0x81, 0xB5, 0xB5, 0x81, 0x81, 0xFF };
#include "img/icon.xbm" #include "img/icon.xbm"
// We now programmatically draw our compass
#if 0
const
#include "img/compass.xbm"
#endif
#if 0
const uint8_t activeSymbol[] PROGMEM = {
B00000000,
B00000000,
B00011000,
B00100100,
B01000010,
B01000010,
B00100100,
B00011000
};
const uint8_t inactiveSymbol[] PROGMEM = {
B00000000,
B00000000,
B00000000,
B00000000,
B00011000,
B00011000,
B00000000,
B00000000
};
#endif

View File

@ -1,28 +0,0 @@
#define compass_width 48
#define compass_height 48
static char compass_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00,
0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00,
0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0x01, 0x00,
0x00, 0xC0, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0x00,
0x00, 0xF8, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0xFC, 0x07, 0xE0, 0x3F, 0x00,
0x00, 0xFE, 0x01, 0x80, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00,
0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00, 0x80, 0x3F, 0x00, 0x00, 0xFC, 0x01,
0x80, 0x1F, 0x00, 0x00, 0xF8, 0x01, 0x80, 0x0F, 0x00, 0x00, 0xF0, 0x01,
0xC0, 0x0F, 0x00, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03,
0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03,
0xFC, 0x07, 0x00, 0x00, 0xE0, 0x3F, 0xFC, 0x07, 0x00, 0x00, 0xE0, 0x3F,
0xFC, 0x07, 0x00, 0x00, 0xE0, 0x3F, 0xFC, 0x07, 0x00, 0x00, 0xE0, 0x3F,
0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03,
0xC0, 0x07, 0x00, 0x00, 0xE0, 0x03, 0xC0, 0x0F, 0x00, 0x00, 0xF0, 0x03,
0x80, 0x0F, 0x00, 0x00, 0xF0, 0x01, 0x80, 0x1F, 0x00, 0x00, 0xF8, 0x01,
0x80, 0x3F, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x7F, 0x00, 0x00, 0xFE, 0x01, 0x80, 0x7F, 0x00,
0x00, 0xFC, 0x07, 0xE0, 0x3F, 0x00, 0x00, 0xF8, 0xFF, 0xFF, 0x1F, 0x00,
0x00, 0xF0, 0xFF, 0xFF, 0x0F, 0x00, 0x00, 0xC0, 0xFF, 0xFF, 0x03, 0x00,
0x00, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x00,
0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00,
0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@ -1,6 +0,0 @@
#define pin_width 13
#define pin_height 13
static char pin_bits[] = {
0x00, 0x00, 0xF0, 0x01, 0xF8, 0x03, 0xFC, 0x07, 0xBC, 0x07, 0xBC, 0x07,
0xFC, 0x07, 0xF8, 0x03, 0xF8, 0x03, 0xF0, 0x01, 0xE0, 0x00, 0xE0, 0x00,
0x00, 0x00, };

View File

@ -41,9 +41,26 @@ AudioModule *audioModule;
#define YIELD_FROM_ISR(x) portYIELD_FROM_ISR(x) #define YIELD_FROM_ISR(x) portYIELD_FROM_ISR(x)
#endif #endif
//int16_t 1KHz sine test tone #if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
int16_t Sine1KHz[8] = { -21210 , -30000, -21210, 0 , 21210 , 30000 , 21210, 0 }; // The screen is bigger so use bigger fonts
int Sine1KHz_index = 0; #define FONT_SMALL ArialMT_Plain_16
#define FONT_MEDIUM ArialMT_Plain_24
#define FONT_LARGE ArialMT_Plain_24
#else
#ifdef OLED_RU
#define FONT_SMALL ArialMT_Plain_10_RU
#else
#define FONT_SMALL ArialMT_Plain_10
#endif
#define FONT_MEDIUM ArialMT_Plain_16
#define FONT_LARGE ArialMT_Plain_24
#endif
#define fontHeight(font) ((font)[1] + 1) // height is position 1
#define FONT_HEIGHT_SMALL fontHeight(FONT_SMALL)
#define FONT_HEIGHT_MEDIUM fontHeight(FONT_MEDIUM)
#define FONT_HEIGHT_LARGE fontHeight(FONT_LARGE)
void run_codec2(void* parameter) void run_codec2(void* parameter)
{ {
@ -124,6 +141,30 @@ AudioModule::AudioModule() : SinglePortModule("AudioModule", PortNum_AUDIO_APP),
} }
} }
void AudioModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{
displayedNodeNum = 0; // Not currently showing a node pane
char buffer[50];
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
display->setColor(BLACK);
display->drawStringf(0 + x, 0 + y, buffer, "Codec2 Mode %d Audio", (moduleConfig.audio.bitrate ? moduleConfig.audio.bitrate : AUDIO_MODULE_MODE) - 1);
display->setColor(WHITE);
display->setFont(FONT_LARGE);
display->setTextAlignment(TEXT_ALIGN_CENTER);
switch (radio_state) {
case RadioState::tx:
display->drawString(display->getWidth() / 2 + x, (display->getHeight() - FONT_HEIGHT_SMALL) / 2 + y, "PTT");
break;
default:
display->drawString(display->getWidth() / 2 + x, (display->getHeight() - FONT_HEIGHT_SMALL) / 2 + y, "Receive");
break;
}
}
int32_t AudioModule::runOnce() int32_t AudioModule::runOnce()
{ {
if ((moduleConfig.audio.codec2_enabled) && (myRegion->audioPermitted)) { if ((moduleConfig.audio.codec2_enabled) && (myRegion->audioPermitted)) {
@ -170,11 +211,14 @@ int32_t AudioModule::runOnce()
firstTime = false; firstTime = false;
} else { } else {
UIFrameEvent e = {false, true};
// Check if PTT is pressed. TODO hook that into Onebutton/Interrupt drive. // Check if PTT is pressed. TODO hook that into Onebutton/Interrupt drive.
if (digitalRead(moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN) == HIGH) { if (digitalRead(moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN) == HIGH) {
if (radio_state == RadioState::rx) { if (radio_state == RadioState::rx) {
DEBUG_MSG("♪♫♪ PTT pressed, switching to TX\n"); DEBUG_MSG("♪♫♪ PTT pressed, switching to TX\n");
radio_state = RadioState::tx; radio_state = RadioState::tx;
e.frameChanged = true;
this->notifyObservers(&e);
} }
} else { } else {
if (radio_state == RadioState::tx) { if (radio_state == RadioState::tx) {
@ -183,9 +227,11 @@ int32_t AudioModule::runOnce()
DEBUG_MSG("♪♫♪ Sending %d codec2 bytes (incomplete)\n", tx_encode_frame_index); DEBUG_MSG("♪♫♪ Sending %d codec2 bytes (incomplete)\n", tx_encode_frame_index);
sendPayload(); sendPayload();
} }
DEBUG_MSG("♪♫♪ PTT released, switching to RX\n"); DEBUG_MSG("♪♫♪ PTT released, switching to RX\n");
tx_encode_frame_index = sizeof(tx_header); tx_encode_frame_index = sizeof(tx_header);
radio_state = RadioState::rx; radio_state = RadioState::rx;
e.frameChanged = true;
this->notifyObservers(&e);
} }
} }
if (radio_state == RadioState::tx) { if (radio_state == RadioState::tx) {
@ -222,6 +268,14 @@ MeshPacket *AudioModule::allocReply()
return reply; return reply;
} }
bool AudioModule::shouldDraw()
{
if (!moduleConfig.audio.codec2_enabled) {
return false;
}
return (radio_state == RadioState::tx);
}
void AudioModule::sendPayload(NodeNum dest, bool wantReplies) void AudioModule::sendPayload(NodeNum dest, bool wantReplies)
{ {
MeshPacket *p = allocReply(); MeshPacket *p = allocReply();

View File

@ -10,6 +10,8 @@
#include <functional> #include <functional>
#include <codec2.h> #include <codec2.h>
#include <ButterworthFilter.h> #include <ButterworthFilter.h>
#include <OLEDDisplay.h>
#include <OLEDDisplayUi.h>
enum RadioState { standby, rx, tx }; enum RadioState { standby, rx, tx };
@ -28,7 +30,7 @@ struct c2_header {
#define AUDIO_MODULE_RX_BUFFER 128 #define AUDIO_MODULE_RX_BUFFER 128
#define AUDIO_MODULE_MODE ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700 #define AUDIO_MODULE_MODE ModuleConfig_AudioConfig_Audio_Baud_CODEC2_700
class AudioModule : public SinglePortModule, private concurrency::OSThread class AudioModule : public SinglePortModule, public Observable<const UIFrameEvent *>, private concurrency::OSThread
{ {
public: public:
unsigned char rx_encode_frame[Constants_DATA_PAYLOAD_LEN] = {}; unsigned char rx_encode_frame[Constants_DATA_PAYLOAD_LEN] = {};
@ -50,6 +52,8 @@ class AudioModule : public SinglePortModule, private concurrency::OSThread
AudioModule(); AudioModule();
bool shouldDraw();
/** /**
* Send our payload into the mesh * Send our payload into the mesh
*/ */
@ -63,6 +67,15 @@ class AudioModule : public SinglePortModule, private concurrency::OSThread
virtual MeshPacket *allocReply() override; virtual MeshPacket *allocReply() override;
virtual bool wantUIFrame() override { return this->shouldDraw(); }
virtual Observable<const UIFrameEvent *>* getUIFrameObservable() override { return this; }
#if !HAS_SCREEN
void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
#else
virtual void drawFrame(
OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) override;
#endif
/** Called to handle a particular incoming message /** Called to handle a particular incoming message
* @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it * @return ProcessMessage::STOP if you've guaranteed you've handled this message and no other handlers should be considered for it
*/ */