Merge pull request #57 from DzikuVx/oled-framework

proper OLED handling
This commit is contained in:
Paweł Spychalski
2018-05-15 17:59:26 +02:00
committed by GitHub
7 changed files with 322 additions and 68 deletions

View File

@@ -1,6 +1,6 @@
{ {
"board": "bsfrance:avr:lora32u4", "board": "bsfrance:avr:lora32u4",
"sketch": "crossbow/crossbow.ino", "sketch": "crossbow/crossbow.ino",
"port": "COM5", "port": "COM11",
"output": "../build" "output": "../build"
} }

View File

@@ -3,12 +3,14 @@
{ {
"name": "Win32", "name": "Win32",
"includePath": [ "includePath": [
"${workspaceRoot}" "${workspaceRoot}",
"C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino"
], ],
"browse": { "browse": {
"limitSymbolsToIncludedHeaders": false, "limitSymbolsToIncludedHeaders": false,
"path": [ "path": [
"${workspaceRoot}" "${workspaceRoot}",
"C:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino"
] ]
}, },
"intelliSenseMode": "msvc-x64", "intelliSenseMode": "msvc-x64",
@@ -38,7 +40,7 @@
"SPI_HAS_NOTUSINGINTERRUPT", "SPI_HAS_NOTUSINGINTERRUPT",
"FEATURE_TX_INPUT_SBUS", "FEATURE_TX_INPUT_SBUS",
"DEVICE_MODE_TX", "DEVICE_MODE_TX",
"DEVICE_MODE_RX" "FEATURE_TX_OLED"
], ],
"compilerPath": "/usr/bin/clang", "compilerPath": "/usr/bin/clang",
"cStandard": "c11", "cStandard": "c11",

View File

@@ -1,6 +1,7 @@
{ {
"files.associations": { "files.associations": {
"variables.h": "c" "variables.h": "c",
"arduino.h": "c"
}, },
"files.exclude": { "files.exclude": {
"**/build": true "**/build": true

View File

@@ -18,7 +18,7 @@
#define DEVICE_MODE_TX #define DEVICE_MODE_TX
// #define DEVICE_MODE_RX // #define DEVICE_MODE_RX
// #define FEATURE_TX_OLED #define FEATURE_TX_OLED
// #define FORCE_TX_WITHOUT_INPUT // #define FORCE_TX_WITHOUT_INPUT
/* /*
@@ -29,9 +29,8 @@
*/ */
#define FEATURE_TX_INPUT_SBUS #define FEATURE_TX_INPUT_SBUS
#define DEBUG_SERIAL // #define DEBUG_SERIAL
// #define DEBUG_PING_PONG // #define DEBUG_PING_PONG
// #define DEBUG_LED // #define DEBUG_LED
// #define DEBUG_TX_INPUT_ON_OLED
#endif #endif

View File

@@ -57,13 +57,8 @@ volatile int16_t TxInput::channels[TX_INPUT_CHANNEL_COUNT];
BuzzerState_t buzzer; BuzzerState_t buzzer;
#ifdef FEATURE_TX_OLED #ifdef FEATURE_TX_OLED
#include "Wire.h" #include "tx_oled.h"
TxOled oled;
#define OLED_RESET -1
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display(OLED_RESET);
uint32_t lastOledTaskTime = 0;
#endif #endif
#include "tactile.h" #include "tactile.h"
@@ -71,11 +66,6 @@ uint32_t lastOledTaskTime = 0;
Tactile button0(BUTTON_0_PIN); Tactile button0(BUTTON_0_PIN);
Tactile button1(BUTTON_1_PIN); Tactile button1(BUTTON_1_PIN);
// uint8_t buttonStates[2] = {HIGH, HIGH};
// uint8_t previousButtonStates[2] = {HIGH, HIGH};
// uint32_t buttonPressMillis[2] = {0, 0};
// uint8_t buttonAction[2] = {BUTTON_ACTION_NONE, BUTTON_ACTION_NONE};
#endif #endif
/* /*
@@ -252,13 +242,13 @@ void setup(void)
#ifdef DEVICE_MODE_TX #ifdef DEVICE_MODE_TX
#ifdef FEATURE_TX_OLED #ifdef FEATURE_TX_OLED
Wire.setClock(400000); oled.init();
oled.page(
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32) &radioState,
display.setTextSize(1); &rxDeviceState,
display.setTextColor(WHITE); &txDeviceState,
display.clearDisplay(); TX_PAGE_INIT
display.display(); );
#endif #endif
/* /*
@@ -356,17 +346,27 @@ void loop(void)
uint32_t currentMillis = millis(); uint32_t currentMillis = millis();
/*
* If we are not receiving SBUS frames from radio, try to restart serial
*/
#ifdef DEVICE_MODE_TX #ifdef DEVICE_MODE_TX
//Process buttons //Process buttons
button0.loop(); button0.loop();
button1.loop(); button1.loop();
#ifdef FEATURE_TX_OLED
oled.loop(
&radioState,
&rxDeviceState,
&txDeviceState,
&button0,
&button1
);
#endif
txInput.recoverStuckFrames(); txInput.recoverStuckFrames();
/*
* If we are not receiving SBUS frames from radio, try to restart serial
*/
static uint32_t serialRestartMillis = 0; static uint32_t serialRestartMillis = 0;
/* /*
@@ -624,44 +624,6 @@ void loop(void)
buzzerContinousMode(BUZZER_MODE_OFF, &buzzer); buzzerContinousMode(BUZZER_MODE_OFF, &buzzer);
} }
#ifdef FEATURE_TX_OLED
if (
currentMillis - lastOledTaskTime > OLED_UPDATE_RATE
) {
lastOledTaskTime = currentMillis;
display.clearDisplay();
display.setTextColor(WHITE, BLACK);
display.setCursor(0, 0);
display.setTextSize(3);
display.print(radioState.rssi);
display.setCursor(18, 28);
display.setTextSize(2);
display.print(radioState.snr);
display.setCursor(74, 0);
display.setTextSize(3);
display.print(rxDeviceState.rssi);
display.setCursor(92, 28);
display.setTextSize(2);
display.print(rxDeviceState.snr);
#ifdef DEBUG_TX_INPUT_ON_OLED
display.setCursor(0, 48);
display.setTextSize(2);
display.print(txInput.channels[0]);
#endif
display.setCursor(54, 48);
display.setTextSize(2);
display.print(txDeviceState.roundtrip);
display.display();
}
#endif
/* /*
* Handle LED updates * Handle LED updates
*/ */

212
crossbow/tx_oled.cpp Normal file
View File

@@ -0,0 +1,212 @@
#include "tx_oled.h"
TxOled::TxOled(void) {
Adafruit_SSD1306 _display(-1);
}
void TxOled::init() {
_display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
_display.setTextSize(1);
_display.setTextColor(WHITE);
_display.clearDisplay();
_display.display();
}
void TxOled::loop(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState,
Tactile *button0,
Tactile *button1
) {
bool update = false;
//Depending on page, things might be different
switch (_page) {
case TX_PAGE_INIT:
//Second button has notthing to do over here
break;
case TX_PAGE_STATS:
//Second button refreshes this page
if (button1->getState() == TACTILE_STATE_SHORT_PRESS) {
update = true;
}
break;
}
//Short press of button0 always toggles no next page
if (button0->getState() == TACTILE_STATE_SHORT_PRESS) {
_mainPageSequenceIndex++;
if (_mainPageSequenceIndex == TX_OLED_PAGE_COUNT) {
_mainPageSequenceIndex = 0;
}
update = true;
}
if (update) {
page(
radioState,
rxDeviceState,
txDeviceState,
pageSequence[_mainPageSequenceIndex]
);
}
}
void TxOled::page(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState,
int page
) {
switch (page) {
case TX_PAGE_INIT:
renderPageInit(radioState, rxDeviceState, txDeviceState);
break;
case TX_PAGE_STATS:
renderPageStats(radioState, rxDeviceState, txDeviceState);
break;
case TX_PAGE_PWR:
renderPagePwr(radioState, rxDeviceState, txDeviceState);
break;
case TX_PAGE_BIND:
renderPageBind(radioState, rxDeviceState, txDeviceState);
break;
case TX_PAGE_MODE:
renderPageMode(radioState, rxDeviceState, txDeviceState);
break;
}
_page = page;
}
void TxOled::renderPagePwr(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
) {
_display.clearDisplay();
_display.setTextColor(WHITE, BLACK);
_display.setCursor(0, 0);
_display.setTextSize(2);
_display.print("PWR");
//TODO content
_display.setCursor(0, 25);
_display.setTextSize(3);
_display.print(radioState->loraTxPower);
_display.print("dBm");
_display.display();
}
void TxOled::renderPageBind(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
) {
_display.clearDisplay();
_display.setTextColor(WHITE, BLACK);
_display.setCursor(0, 0);
_display.setTextSize(2);
_display.print("Bind");
//TODO content
_display.display();
}
void TxOled::renderPageMode(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
) {
_display.clearDisplay();
_display.setTextColor(WHITE, BLACK);
_display.setCursor(0, 0);
_display.setTextSize(2);
_display.print("Mode");
_display.setCursor(0, 25);
_display.setTextSize(3);
_display.print("Full");
_display.display();
}
void TxOled::renderPageStats(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
) {
_display.clearDisplay();
_display.setTextColor(WHITE, BLACK);
_display.setCursor(0, 0);
_display.setTextSize(3);
_display.print(radioState->rssi);
_display.setCursor(18, 28);
_display.setTextSize(2);
_display.print(radioState->snr);
_display.setCursor(74, 0);
_display.setTextSize(3);
_display.print(rxDeviceState->rssi);
_display.setCursor(92, 28);
_display.setTextSize(2);
_display.print(rxDeviceState->snr);
_display.setCursor(54, 48);
_display.setTextSize(2);
_display.print(txDeviceState->roundtrip);
_display.display();
}
void TxOled::renderPageInit(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
) {
_display.clearDisplay();
_display.setTextColor(WHITE, BLACK);
_display.setTextSize(2);
_display.setCursor(0, 0);
_display.print("Rdy ");
_display.print(radioState->loraTxPower);
_display.print("dBm");
_display.setTextSize(1);
_display.setCursor(0, 32);
_display.print("Bandwitdh: ");
_display.print(radioState->loraBandwidth / 1000);
_display.print("kHz");
_display.setCursor(0, 42);
_display.print("SF: ");
_display.print(radioState->loraSpreadingFactor);
_display.setCursor(64, 42);
_display.print("CR: ");
_display.print(radioState->loraCodingRate);
_display.setCursor(0, 52);
_display.print("Rate: ");
_display.print(1000 / TX_TRANSMIT_SLOT_RATE);
_display.print("Hz");
_display.display();
}

78
crossbow/tx_oled.h Normal file
View File

@@ -0,0 +1,78 @@
#pragma once
#ifndef TX_OLED_H
#define TX_OLED_H
#include <Adafruit_SSD1306.h>
#include "Wire.h"
#include "variables.h"
#include "tactile.h"
enum txOledPages {
TX_PAGE_NONE,
TX_PAGE_INIT,
TX_PAGE_STATS,
TX_PAGE_PWR,
TX_PAGE_BIND,
TX_PAGE_MODE
};
#define TX_OLED_PAGE_COUNT 5
const uint8_t pageSequence[TX_OLED_PAGE_COUNT] = {
TX_PAGE_INIT,
TX_PAGE_STATS,
TX_PAGE_PWR,
TX_PAGE_BIND,
TX_PAGE_MODE
};
class TxOled {
public:
TxOled(void);
void init();
void loop(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState,
Tactile *button0,
Tactile *button1
);
void page(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState,
int page
);
private:
Adafruit_SSD1306 _display;
void renderPageInit(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
);
void renderPageStats(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
);
void renderPagePwr(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
);
void renderPageBind(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
);
void renderPageMode(
volatile RadioState_t *radioState,
RxDeviceState_t *rxDeviceState,
TxDeviceState_t *txDeviceState
);
uint8_t _page = TX_PAGE_NONE;
uint8_t _mainPageSequenceIndex = 0;
};
#endif