Browse Source

Added display menu icons...

master
Englebert 4 years ago
parent
commit
3bdd04f640
  1. 303
      OpenFlightTX.ino

303
OpenFlightTX.ino

@ -1,3 +1,144 @@
#include <Arduino.h>
#include <SPI.h>
#include <LoRa.h>
#include <U8g2lib.h>
#include <Wire.h>
typedef enum {
SCREEN_INTRO = 0,
SCREEN_SELECTIONS,
SCREEN_CONTROL
} OPENFLIGHT_SCREEN;
/*
Icon configuration
Width and height must match the icon font size
GAP: Space between the icons
BGAP: Gap between the display border and the cursor.
*/
#define ICON_WIDTH 32
#define ICON_HEIGHT 32
#define ICON_GAP 4
#define ICON_BGAP 16
#define ICON_Y 32+ ICON_GAP
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
struct menu_entry_type {
const uint8_t *font;
uint16_t icon;
const char *name;
};
struct menu_state {
int16_t menu_start; /* in pixel */
int16_t frame_position; /* in pixel */
uint8_t position; /* position, array index */
};
struct menu_entry_type menu_entry_alpha_list[] = {
{ u8g2_font_open_iconic_all_4x_t, 129, "Configuration"},
{ u8g2_font_open_iconic_all_4x_t, 104, "Debug"},
{ u8g2_font_open_iconic_all_4x_t, 90, "Battery"},
{ u8g2_font_open_iconic_all_4x_t, 65, "Exit"},
{ NULL, 0, NULL }
};
struct menu_state current_alpha_state = { ICON_BGAP, ICON_BGAP, 0 };
struct menu_state destination_alpha_state = { ICON_BGAP, ICON_BGAP, 0 };
void draw_menu(struct menu_state *state) {
int16_t x;
uint8_t i;
x = state->menu_start;
i = 0;
while( menu_entry_alpha_list[i].icon > 0 ) {
if ( x >= -ICON_WIDTH && x < u8g2.getDisplayWidth()) {
u8g2.setFont(menu_entry_alpha_list[i].font);
u8g2.drawGlyph(x, ICON_Y, menu_entry_alpha_list[i].icon );
}
i++;
x += ICON_WIDTH + ICON_GAP;
}
//u8g2.drawFrame(state->frame_position-1, ICON_Y-ICON_HEIGHT-1, ICON_WIDTH+2, ICON_WIDTH+2);
//u8g2.drawFrame(state->frame_position-2, ICON_Y-ICON_HEIGHT-2, ICON_WIDTH+4, ICON_WIDTH+4);
u8g2.drawFrame(state->frame_position-3, ICON_Y-ICON_HEIGHT-3, ICON_WIDTH+6, ICON_WIDTH+6);
}
void to_right(struct menu_state *state) {
if(menu_entry_alpha_list[state->position+1].font != NULL) {
if((int16_t)state->frame_position+ 2*(int16_t)ICON_WIDTH + (int16_t)ICON_BGAP < (int16_t)u8g2.getDisplayWidth()) {
state->position++;
state->frame_position += ICON_WIDTH + (int16_t)ICON_GAP;
} else {
state->position++;
state->frame_position = (int16_t)u8g2.getDisplayWidth() - (int16_t)ICON_WIDTH - (int16_t)ICON_BGAP;
state->menu_start = state->frame_position - state->position*((int16_t)ICON_WIDTH + (int16_t)ICON_GAP);
}
}
}
void to_left(struct menu_state *state){
if(state->position > 0){
if ( (int16_t)state->frame_position >= (int16_t)ICON_BGAP+(int16_t)ICON_WIDTH+ (int16_t)ICON_GAP ){
state->position--;
state->frame_position -= ICON_WIDTH + (int16_t)ICON_GAP;
} else {
state->position--;
state->frame_position = ICON_BGAP;
state->menu_start = state->frame_position - state->position*((int16_t)ICON_WIDTH + (int16_t)ICON_GAP);
}
}
}
uint8_t towards_int16(int16_t *current, int16_t dest) {
if ( *current < dest ){
(*current)++;
return 1;
} else if ( *current > dest ) {
(*current)--;
return 1;
}
return 0;
}
uint8_t towards(struct menu_state *current, struct menu_state *destination) {
uint8_t r = 0;
uint8_t i;
for( i = 0; i < 6; i++ ) {
r |= towards_int16( &(current->frame_position), destination->frame_position);
r |= towards_int16( &(current->menu_start), destination->menu_start);
}
return r;
}
// For Menu Navigation and Setup
#define MENU_STICK_ROLL_MAX 3000
#define MENU_STICK_ROLL_MIN 800
#define MENU_STICK_PITCH_MAX 3000
#define MENU_STICK_PITCH_MIN 800
typedef enum {
MENU_NONE = 0,
MENU_LEFT,
MENU_RIGHT,
MENU_BACK,
MENU_OK
} MENU_NAVIGATION;
MENU_NAVIGATION stick_navigation_position;
bool menu_entry_alpha_selected = false;
//define the pins used by the transceiver module
#define SS 5
#define RST 14
#define DIO0 2
int counter = 0;
#define BUZZER_PIN 15
#define THROTTLE_PIN 36
#define YAW_PIN 39
@ -23,6 +164,9 @@ uint16_t roll_value = 0;
#define PITCH 2
#define ROLL 3
uint64_t last_update = 0;
uint16_t last_menu_stick_read = 0;
uint16_t throttle_pool[MEDIAN_TOTAL];
uint16_t yaw_pool[MEDIAN_TOTAL];
uint16_t pitch_pool[MEDIAN_TOTAL];
@ -171,6 +315,41 @@ uint16_t roll_insert(uint16_t val) {
return median_get(ROLL);
}
/*
* pool_insert:
* To insert the data into the median pool depending on type of the variable
*
* E.g.:
* throttle_value = pool_insert(THROTTLE);
*/
uint16_t pool_insert(uint8_t pool_type, uint16_t val) {
// Insert to the array...at the last of the array
for(int i = 1; i < MEDIAN_TOTAL; i++) {
// Shift to left
if(pool_type == THROTTLE) {
throttle_pool[i - 1] = throttle_pool[i];
} else if(pool_type == YAW) {
yaw_pool[i - 1] = yaw_pool[i];
} else if(pool_type == PITCH) {
pitch_pool[i - 1] = pitch_pool[i];
} else if(pool_type == ROLL) {
roll_pool[i - 1] = roll_pool[i];
}
}
// Find median....
if(pool_type == THROTTLE) {
throttle_pool[MEDIAN_TOTAL - 1] = val;
} else if(pool_type == YAW) {
yaw_pool[MEDIAN_TOTAL - 1] = val;
} else if(pool_type == ROLL) {
roll_pool[MEDIAN_TOTAL - 1] = val;
} else if(pool_type == PITCH) {
pitch_pool[MEDIAN_TOTAL - 1] = val;
}
return median_get(pool_type);
}
void intro() {
for(int i = 0; i < 2; i++) {
digitalWrite(BUZZER_PIN, HIGH);
@ -187,10 +366,10 @@ void read_all_voltage() {
pitch_raw = analogRead(PITCH_PIN);
roll_raw = analogRead(ROLL_PIN);
throttle_value = throttle_insert(throttle_raw);
yaw_value = yaw_insert(yaw_raw);
pitch_value = pitch_insert(pitch_raw);
roll_value = roll_insert(roll_raw);
throttle_value = pool_insert(THROTTLE, throttle_raw);
yaw_value = pool_insert(YAW, yaw_raw);
pitch_value = pool_insert(PITCH, pitch_raw);
roll_value = pool_insert(ROLL, roll_raw);
}
@ -200,16 +379,50 @@ void setup() {
// PIN Initialization
pinMode(BUZZER_PIN, OUTPUT);
// Display Setup
u8g2.begin();
u8g2.setFont(u8g2_font_6x12_tr);
median_initialize();
// Startup Sound
intro();
// intro();
// LoRA Setup
// setup LoRa transceiver module
LoRa.setPins(SS, RST, DIO0);
// Replace the LoRa.begin(---E-) argument with your location's frequency
// 433E6 for Asia
// 866E6 for Europe
// 915E6 for North America
/*
while (!LoRa.begin(923E6)) {
Serial.println(".");
delay(500);
}
// Change sync word (0xF3) to match the receiver
// The sync word assures you don't get LoRa messages from other LoRa transceivers
// ranges from 0-0xFF
LoRa.setSyncWord(0xA0);
// Set to the highest PA Level
LoRa.setTxPower(20);
LoRa.setSpreadingFactor(7);
LoRa.setSignalBandwidth(125E3);
// LoRa.setSignalBandwidth(250E3);
// LoRa.setCodingRate4(5);
// LoRa.setSignalBandwidth(15.6E3);
// LoRa.setSpreadingFactor(6);
Serial.println("LoRa Initializing OK!");
*/
}
void loop() {
read_all_voltage();
/*
// Serial.println(throttle_raw + " : " + yaw_raw);
Serial.print("T [");
Serial.print(throttle_raw);
@ -218,7 +431,83 @@ void loop() {
Serial.print("] P[");
Serial.print(pitch_raw);
Serial.print("] R[");
Serial.print(roll_raw);
Serial.print(roll_value);
Serial.println("]");
if(millis() > last_update) {
// Determine stick position
if(millis() > last_menu_stick_read) {
if(roll_value > MENU_STICK_ROLL_MAX) {
stick_navigation_position = MENU_RIGHT;
} else if(roll_value < MENU_STICK_ROLL_MIN) {
stick_navigation_position = MENU_LEFT;
} else if(pitch_value > MENU_STICK_PITCH_MAX) {
stick_navigation_position = MENU_OK;
} else if(pitch_value < MENU_STICK_PITCH_MIN) {
stick_navigation_position = MENU_BACK;
} else {
stick_navigation_position = MENU_NONE;
}
// Next reading...
last_menu_stick_read = millis() + 250;
} else {
stick_navigation_position = MENU_NONE;
}
if(
!menu_entry_alpha_selected
) {
// Determine the menu position
if(stick_navigation_position == MENU_RIGHT) {
to_right(&destination_alpha_state);
} else if(stick_navigation_position == MENU_LEFT) {
to_left(&destination_alpha_state);
} else if(stick_navigation_position == MENU_OK) {
menu_entry_alpha_selected = true;
}
u8g2.firstPage();
draw_menu(&current_alpha_state);
u8g2.setFont(u8g2_font_helvB10_tr);
u8g2.setCursor((u8g2.getDisplayWidth()-u8g2.getStrWidth(menu_entry_alpha_list[destination_alpha_state.position].name))/2, u8g2.getDisplayHeight()-5);
u8g2.print(menu_entry_alpha_list[destination_alpha_state.position].name);
u8g2.nextPage();
towards(&current_alpha_state, &destination_alpha_state);
} else {
if(stick_navigation_position == MENU_BACK) {
menu_entry_alpha_selected = false;
} else {
u8g2.clearBuffer();
u8g2.setFontMode(1);
u8g2.setFont(u8g2_font_helvB10_tr);
u8g2.setCursor(0,15);
u8g2.print(F("Selected:"));
u8g2.setCursor(0,30);
u8g2.print(F(menu_entry_alpha_list[destination_alpha_state.position].name));
u8g2.sendBuffer();
}
}
last_update = millis() + 10;
}
/*
//if(millis() - last_update >= 2) {
// Send LoRa packet to receiver
//while(true) {
LoRa.setTxPower(20);
LoRa.beginPacket();
// LoRa.print("hello ");
LoRa.print(counter);
LoRa.endPacket();
counter++;
//delay(100);
// delayMicroseconds(1500);
// }
last_update = millis();
//}
*/
}
Loading…
Cancel
Save