Great, let me know if there are further doubts.
BTW: I fixed the copy/paste error in the yes/no menu example.
Oliver
Great, let me know if there are further doubts.
BTW: I fixed the copy/paste error in the yes/no menu example.
Oliver
I made great progress thanks to your last help. I have one more problem I can't seem to figure out.
I start the program displaying data from sensors. I want the menu to become active when I push a push button. With debugging statements, I can see the button press is seen by M2tklib, but the menu never shows, it just keeps displaying the data screen. On the reverse, if I start the program displaying the menu, when I exit the menu system, I just get a blank screen when I should get sensor data. I'm sure I'm missing something simple....
// Menu
M2tk m2(&m2_null_element, m2_es_arduino_rotary_encoder, m2_eh_4bd, m2_gh_u8g_bf);
M2_EXTERN_VLIST(el_main);
M2_EXTERN_HLIST(el_resetA);
M2_EXTERN_HLIST(el_resetB);
M2_EXTERN_VLIST(el_tz);
M2_EXTERN_VLIST(el_layout);
M2_EXTERN_VLIST(el_units);
M2_ROOT(main_el_top, "f0", NULL, &el_main);
M2_ROOT(main_el_reset_tripmeterA, "f0", "Reset trip A", &el_resetA);
M2_ROOT(main_el_reset_tripmeterB, "f0", "Reset trip B", &el_resetB);
M2_ROOT(main_el_set_timezone, "f0", "Set time zone", &el_tz);
M2_ROOT(main_el_set_layout, "f0", "Set layout", &el_layout);
M2_ROOT(main_el_set_units, "f0", "Set units", &el_units);
M2_ROOT(main_el_exit, "f0", "Exit menu", &m2_null_element);
// Cancel button
void fn_cancel(m2_el_fnarg_p fnarg) {
m2.setRoot(&el_main);
}
M2_BUTTON(button_cancel, "f0", "cancel", fn_cancel);
// Main menu
M2_LIST(main_list) = {
&main_el_reset_tripmeterA,
&main_el_reset_tripmeterB,
&main_el_set_timezone,
&main_el_set_layout,
&main_el_set_units,
&main_el_exit
};
M2_VLIST(el_main, "f0", main_list);
// Trip meter mennu
void fn_yesA(m2_el_fnarg_p fnarg) {
ResetTrip(0);
m2.setRoot(&main_el_top);
}
void fn_yesB(m2_el_fnarg_p fnarg) {
ResetTrip(1);
m2.setRoot(&main_el_top);
}
M2_BUTTON(button_yesA, "f0", "yes", fn_yesA );
M2_BUTTON(button_yesB, "f0", "yes", fn_yesB );
M2_LIST(list_resetA) = { &button_yesA, &button_cancel };
M2_HLIST(el_resetA, "f0", list_resetA);
M2_LIST(list_resetB) = { &button_yesB, &button_cancel };
M2_HLIST(el_resetB, "f0", list_resetB);
M2_LABEL(label_resetA, "f0", "Reset Trip A?");
M2_LABEL(label_resetB, "f0", "Reset Trip B?");
// Time zone menu
M2_LIST(list_tz) = { &button_cancel };
M2_VLIST(el_tz, "f0", list_tz);
// Layout menu
M2_LIST(list_layout) = { &button_cancel };
M2_VLIST(el_layout, "f0", list_layout);
// Units menu
M2_LIST(list_units) = { &button_cancel };
M2_VLIST(el_units, "f0", list_units);
void setup() {
m2_SetU8g(u8g.getU8g(), m2_u8g_box_icon);
m2.setFont(1, u8g_font_7x13r);
m2.setFont(0, u8g_font_profont11);
m2.setPin(M2_KEY_SELECT, SW1pin);
m2.setPin(M2_KEY_ROT_ENC_A, Knob0A);
m2.setPin(M2_KEY_ROT_ENC_B, Knob0B);
}
void loop() {
m2.checkKey();
if ( m2.getRoot() == &m2_null_element ) {
updateDisplay(layoutVer); // This does the u8g.firstPage() stuff inside the function
switch (m2.getKey()) {
case M2_KEY_NEXT:
SetBrightness(BrightStep);
break;
case M2_KEY_PREV:
SetBrightness(-BrightStep);
break;
case M2_KEY_SELECT:
Serial.println("MENU: button pressed");
m2.setRoot(&el_main);
break;
}
}
else {
if ( m2.handleKey() != 0 ) {
u8g.firstPage();
do {
m2.draw();
m2.checkKey();
}
while(u8g.nextPage());
}
}
}
Hi
You did not post the full code. Actually i have not seen a bug in the code above, but the problem might be in "updateDisplay".
I also would like to upload this on my Uno to see what exactly goes wrong.
Oliver
The full code is 83,556 bytes in 17 tabs. Here is the updateDisplay() code:
void updateDisplay(int layoutVer) {
u8g.firstPage();
do {
utc = now();
switch (layoutVer) {
case 1:
displaySpeed(53,42,9,u8g_font_fub25n);
displaySpeedUnit(54,54,u8g_font_tpssr);
displayAltitude(107,52,6,u8g_font_tpssr);
displayHeading(58,11,4,u8g_font_helvR10r);
displayLat(0,63,u8g_font_profont11);
displayLon(69,63,u8g_font_profont11);
displayTrip(98,26,6,1,valTripA,u8g_font_tpssr);
displayTrip(98,39,6,2,valTripB,u8g_font_tpssr);
displayTime((*tz).toLocal(utc),0,26,6,u8g_font_tpssr);
displayDate((*tz).toLocal(utc),0,39,6,u8g_font_tpssr);
displayTemp(0,11,8,u8g_font_helvB10r);
displayVoltage(89,11,29,u8g_font_helvB10r);
displaySDstatus(0,52,u8g_font_profont11);
break;
case 2:
displaySpeed(53,42,9,u8g_font_fub25n);
displaySpeedUnit(54,54,u8g_font_tpssr);
displayAltitude(107,52,6,u8g_font_tpssr);
displayHeading(58,11,4,u8g_font_helvR10r);
displayTrip(98,26,6,1,valTripA,u8g_font_tpssr);
displayTrip(98,39,6,2,valTripB,u8g_font_tpssr);
displayTime((*tz).toLocal(utc),0,26,6,u8g_font_tpssr);
displayDate((*tz).toLocal(utc),0,39,6,u8g_font_tpssr);
displayTemp(0,11,8,u8g_font_helvB10r);
displayVoltage(89,11,29,u8g_font_helvB10r);
displaySDstatus(0,52,u8g_font_profont11);
displayGPSstatus(55,63,u8g_font_profont11);
}
}
while(u8g.nextPage());
}
ok, i see, but i have not seen the problem in the code.
Best would be if i could see the problem on my board. Is it possible to cut down the code to one .ino file, but with the problem still appearing?
Oliver
olikraus:
ok, i see, but i have not seen the problem in the code.
Best would be if i could see the problem on my board. Is it possible to cut down the code to one .ino file, but with the problem still appearing?Oliver
I'll see what I can do. If I can't get to it tomorrow, it may be a week before I can do it. Thank you for all your help!
OK, here is a stripped down set of code that still has the problem. There is a bit of Teensy specific code in it, SPI and ADC stuff, but for an UNO you can use the regular SPI.h and strip the ADC stuff out, I think.
Edit: Slimmed down the code some more.
// SPI library - Teensy 3.x specific
#include <spi4teensy3.h>
//#include <SPI.h>
// Display library
#include <U8glib.h>
// ADC library
#include <ADC.h>
#include <ADC_Module.h>
#include <RingBuffer.h>
#include <RingBufferDMA.h>
// Menu library
#include <M2tk.h>
#include <utility/m2ghu8g.h>
#define DEBUG
U8GLIB_NHD27OLED_GR u8g(10, 15); // U8GLIB_NHD27OLED_GR(cs, a0 [, reset]) - Hardware SPI
// Analog pin definitions
const int TempPin = 16; // 16=A2 on Teensy 3.1 // Pin for input from TMP36
const int VMpin = 14; // 14=A0 on Teensy 3.1 // Pin for input from 0-30V after voltage divider - don't exceed 3.3V actual to pin
// Digital pin definitions
const int Knob0A = 3; // Rotary Encoder 0 Pin A
const int Knob0B = 2; // Rotary Encoder 0 Pin B
const int SW1pin = 20; // Push button SW1
// Voltmeter
float VMout;
// ADC
ADC *adc = new ADC();
// Thermometer
float DegF;
bool tempErr = false;
// Menu
//M2tk m2(&m2_null_element, m2_es_arduino_rotary_encoder, m2_eh_4bd, m2_gh_u8g_bf);
M2_EXTERN_VLIST(el_main);
M2tk m2(&el_main, m2_es_arduino_rotary_encoder, m2_eh_4bd, m2_gh_u8g_bf);
M2_EXTERN_HLIST(el_resetA);
M2_EXTERN_HLIST(el_resetB);
M2_EXTERN_VLIST(el_tz);
M2_EXTERN_VLIST(el_layout);
M2_EXTERN_VLIST(el_units);
M2_ROOT(main_el_top, "f0", NULL, &el_main);
M2_ROOT(main_el_reset_tripmeterA, "f0", "Reset trip A", &el_resetA);
M2_ROOT(main_el_reset_tripmeterB, "f0", "Reset trip B", &el_resetB);
M2_ROOT(main_el_set_timezone, "f0", "Set time zone", &el_tz);
M2_ROOT(main_el_set_layout, "f0", "Set layout", &el_layout);
M2_ROOT(main_el_set_units, "f0", "Set units", &el_units);
M2_ROOT(main_el_exit, "f0", "Exit menu", &m2_null_element);
// Cancel button
void fn_cancel(m2_el_fnarg_p fnarg) {
m2.setRoot(&el_main);
}
M2_BUTTON(button_cancel, "f0", "cancel", fn_cancel);
// Main menu
M2_LIST(main_list) = {
&main_el_reset_tripmeterA,
&main_el_reset_tripmeterB,
&main_el_set_timezone,
&main_el_set_layout,
&main_el_set_units,
&main_el_exit
};
M2_VLIST(el_main, "f0", main_list);
// Trip meter mennu
void fn_yesA(m2_el_fnarg_p fnarg) {
//ResetTrip(0);
m2.setRoot(&el_main);
}
void fn_yesB(m2_el_fnarg_p fnarg) {
//ResetTrip(1);
m2.setRoot(&el_main);
}
M2_BUTTON(button_yesA, "f0", "yes", fn_yesA );
M2_BUTTON(button_yesB, "f0", "yes", fn_yesB );
M2_LIST(list_resetA) = {
&button_yesA, &button_cancel };
M2_HLIST(el_resetA, "f0", list_resetA);
M2_LIST(list_resetB) = {
&button_yesB, &button_cancel };
M2_HLIST(el_resetB, "f0", list_resetB);
M2_LABEL(label_resetA, "f0", "Reset Trip A?");
M2_LABEL(label_resetB, "f0", "Reset Trip B?");
// Time zone menu
M2_LIST(list_tz) = {
&button_cancel };
M2_VLIST(el_tz, "f0", list_tz);
// Layout menu
M2_LIST(list_layout) = {
&button_cancel };
M2_VLIST(el_layout, "f0", list_layout);
// Units menu
M2_LIST(list_units) = {
&button_cancel };
M2_VLIST(el_units, "f0", list_units);
void setup() {
Serial.begin(115200);
Serial1.begin(19200); // GPS
#ifdef DEBUG
delay(2000); // startup delay
#endif
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Begin setup"));
#endif
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Display start"));
#endif
// Start the display
u8g.begin();
//u8g.setRot180(); // Rotate screen 180 deg
u8g.setColorIndex(15); // 15 = max intensity for GR display, 1 = on for BW
u8g.setContrast(200);
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Pin init"));
#endif
pinMode(VMpin, INPUT); // Input pin for voltmeter
pinMode(TempPin, INPUT); // Input pin for thermometer
//
// ADC setup
//
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Start ADC stuff"));
#endif
adc->setAveraging(16, ADC_0);
adc->setAveraging(16, ADC_1);
//
// Menu
//
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Menu setup"));
#endif
m2_SetU8g(u8g.getU8g(), m2_u8g_box_icon);
m2.setFont(1, u8g_font_7x13r);
m2.setFont(0, u8g_font_profont11);
m2.setPin(M2_KEY_SELECT, SW1pin);
m2.setPin(M2_KEY_ROT_ENC_A, Knob0A);
m2.setPin(M2_KEY_ROT_ENC_B, Knob0B);
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("End setup"));
#endif
} // End setup()
// Main body where we actually do stuff
void loop() {
CalculateVoltage();
CalculateTemp();
m2.checkKey();
if ( m2.getRoot() == &m2_null_element ) {
u8g.firstPage();
do {
displayTemp(0,11,8,u8g_font_helvB10r);
displayVoltage(89,11,29,u8g_font_helvB10r);
switch (m2.getKey()) {
case M2_KEY_NEXT:
#ifdef DEBUG
Serial.println("DISPLAY: Brightness up");
#endif
//SetBrightness(BrightStep);
break;
case M2_KEY_PREV:
#ifdef DEBUG
Serial.println("DISPLAY: Brightness down");
#endif
//SetBrightness(-BrightStep);
break;
case M2_KEY_SELECT:
#ifdef DEBUG
Serial.println("MENU: button pressed");
#endif
m2.setRoot(&el_main);
break;
}
}
while(u8g.nextPage());
}
else {
if ( m2.handleKey() != 0 ) {
u8g.firstPage();
do {
m2.draw();
m2.checkKey();
}
while(u8g.nextPage());
}
}
}
void displayVoltage(int posH, int posV, int inc, const unsigned char* font) {
u8g.setFont(font);
u8g.setPrintPos(posH, posV);
u8g.print(VMout,1); // Print the voltage with one decimal place
u8g.setPrintPos((posH + inc), posV); // Set the position for the following
u8g.print("V"); // Print V next to the voltage reading
}
void displayTemp(int posH, int posV, int inc, const unsigned char* font) {
u8g.setFont(font); // Set the font
if (tempErr == false) {
if ( DegF < 100.0f && DegF >= 10.0f ) { // adjust the print position depending on number of digits
u8g.setPrintPos((posH + inc), posV);
}
else if ( DegF < 10.0f && DegF >= 0.0f ) {
u8g.setPrintPos((posH + (inc * 2)), posV);
}
else {
u8g.setPrintPos(posH, posV);
}
u8g.print(DegF,0); // Print the temperature with no decimal fraction
}
else {
u8g.setFont(u8g_font_tpssr);
u8g.setPrintPos(posH, posV - 1);
u8g.print("ERR");
}
u8g.setPrintPos((posH + (inc * 3) + 1), posV);
u8g.setFont(font);
u8g.print("F"); // Print F next to the temp reading
}
void CalculateTemp() {
// Read the voltage from the LM34 and calcuate the temperature based on the voltage
float voltagein = adc->analogRead(TempPin, ADC_1); // Read the voltage using ADC_1
float tempVolt = voltagein / 310; // For 3.3v power
float DegC = (100 * tempVolt) - 50; // TMP36 voltage = temp in C with a 50 deg offset
tempErr = false;
DegF = (DegC * 9.0 / 5.0) + 32.0; // Convert to Farenheit
#ifdef DEBUGTEMP
Serial.print(F("TEMP: "));
Serial.print(F("Temp: "));
Serial.println(DegF);
#endif
}
void CalculateVoltage() {
float VMsum = adc->analogRead(VMpin); // Read the voltage
// Calculate the voltage
float VMvoltage = VMsum / 310.0; // For 3.3V system
// Send voltage for display - the number requires tweaking to suit your individual setup
// (voltage divider resistor value and variance, etc.)
VMout = VMvoltage * 11.0312;
#ifdef DEBUGVOLT
Serial.print(F("VOLT: "));
Serial.print(F("Volt: "));
Serial.println(VMout);
#endif
}
A little debugging shows that when in graphics mode, the M2_KEY_SELECT action is seen, however, the m2.setRoot(&el_main) does not take effect and the m2 root remains set to m2_null_element.
When in menu mode, and the menu option to exit back to graphics is selected, m2 root does change to m2_null_element but the low level graphics are not displayed.
Hi
I tracked down the problems.
if ( m2.getRoot() == &m2_null_element ) {
u8g.setDefaultForegroundColor();
u8g.firstPage();
case M2_KEY_SELECT:
#ifdef DEBUG
Serial.println("MENU: button pressed");
#endif
m2.setRoot(&el_main);
m2.handleKey(); // update internal menu
m2.setKey(M2_KEY_REFRESH); // force a refresh
Below you will find my test code.
Oliver
// SPI library - Teensy 3.x specific
//#include <spi4teensy3.h>
//#include <SPI.h>
// Display library
#include <U8glib.h>
// ADC library
//#include <ADC.h>
//#include <ADC_Module.h>
//#include <RingBuffer.h>
//#include <RingBufferDMA.h>
// Menu library
#include <M2tk.h>
#include <utility/m2ghu8g.h>
//#define DEBUG
//U8GLIB_NHD27OLED_GR u8g(10, 15); // U8GLIB_NHD27OLED_GR(cs, a0 [, reset]) - Hardware SPI
U8GLIB_DOGM128 u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
// Analog pin definitions
const int TempPin = 16; // 16=A2 on Teensy 3.1 // Pin for input from TMP36
const int VMpin = 14; // 14=A0 on Teensy 3.1 // Pin for input from 0-30V after voltage divider - don't exceed 3.3V actual to pin
// Digital pin definitions
const int Knob0A = 7; // Rotary Encoder 0 Pin A
const int Knob0B = 3; // Rotary Encoder 0 Pin B
const int SW1pin = 2; // Push button SW1
// Voltmeter
float VMout;
// ADC
//ADC *adc = new ADC();
// Thermometer
float DegF;
bool tempErr = false;
// Menu
//M2tk m2(&m2_null_element, m2_es_arduino_rotary_encoder, m2_eh_4bd, m2_gh_u8g_bf);
M2_EXTERN_VLIST(el_main);
M2tk m2(&el_main, m2_es_arduino_rotary_encoder, m2_eh_4bd, m2_gh_u8g_bf);
M2_EXTERN_HLIST(el_resetA);
M2_EXTERN_HLIST(el_resetB);
M2_EXTERN_VLIST(el_tz);
M2_EXTERN_VLIST(el_layout);
M2_EXTERN_VLIST(el_units);
M2_ROOT(main_el_top, "f0", NULL, &el_main);
M2_ROOT(main_el_reset_tripmeterA, "f0", "Reset trip A", &el_resetA);
M2_ROOT(main_el_reset_tripmeterB, "f0", "Reset trip B", &el_resetB);
M2_ROOT(main_el_set_timezone, "f0", "Set time zone", &el_tz);
M2_ROOT(main_el_set_layout, "f0", "Set layout", &el_layout);
M2_ROOT(main_el_set_units, "f0", "Set units", &el_units);
M2_ROOT(main_el_exit, "f0", "Exit menu", &m2_null_element);
// Cancel button
void fn_cancel(m2_el_fnarg_p fnarg) {
m2.setRoot(&el_main);
}
M2_BUTTON(button_cancel, "f0", "cancel", fn_cancel);
// Main menu
M2_LIST(main_list) = {
&main_el_reset_tripmeterA,
&main_el_reset_tripmeterB,
&main_el_set_timezone,
&main_el_set_layout,
&main_el_set_units,
&main_el_exit
};
M2_VLIST(el_main, "f0", main_list);
// Trip meter mennu
void fn_yesA(m2_el_fnarg_p fnarg) {
//ResetTrip(0);
m2.setRoot(&el_main);
}
void fn_yesB(m2_el_fnarg_p fnarg) {
//ResetTrip(1);
m2.setRoot(&el_main);
}
M2_BUTTON(button_yesA, "f0", "yes", fn_yesA );
M2_BUTTON(button_yesB, "f0", "yes", fn_yesB );
M2_LIST(list_resetA) = {
&button_yesA, &button_cancel };
M2_HLIST(el_resetA, "f0", list_resetA);
M2_LIST(list_resetB) = {
&button_yesB, &button_cancel };
M2_HLIST(el_resetB, "f0", list_resetB);
M2_LABEL(label_resetA, "f0", "Reset Trip A?");
M2_LABEL(label_resetB, "f0", "Reset Trip B?");
// Time zone menu
M2_LIST(list_tz) = {
&button_cancel };
M2_VLIST(el_tz, "f0", list_tz);
// Layout menu
M2_LIST(list_layout) = {
&button_cancel };
M2_VLIST(el_layout, "f0", list_layout);
// Units menu
M2_LIST(list_units) = {
&button_cancel };
M2_VLIST(el_units, "f0", list_units);
void setup() {
Serial.begin(115200);
//Serial1.begin(19200); // GPS
#ifdef DEBUG
delay(2000); // startup delay
#endif
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Begin setup"));
#endif
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Display start"));
#endif
// Start the display
u8g.begin();
//u8g.setRot180(); // Rotate screen 180 deg
//u8g.setColorIndex(15); // 15 = max intensity for GR display, 1 = on for BW
//u8g.setContrast(200);
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Pin init"));
#endif
pinMode(VMpin, INPUT); // Input pin for voltmeter
pinMode(TempPin, INPUT); // Input pin for thermometer
//
// ADC setup
//
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Start ADC stuff"));
#endif
//adc->setAveraging(16, ADC_0);
//adc->setAveraging(16, ADC_1);
//
// Menu
//
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("Menu setup"));
#endif
m2_SetU8g(u8g.getU8g(), m2_u8g_box_icon);
m2.setFont(1, u8g_font_7x13r);
m2.setFont(0, u8g_font_profont11);
m2.setPin(M2_KEY_SELECT, SW1pin);
m2.setPin(M2_KEY_NEXT, Knob0A);
m2.setPin(M2_KEY_PREV, Knob0B);
#ifdef DEBUG
Serial.print(F("DEBUG: "));
Serial.println(F("End setup"));
#endif
} // End setup()
// Main body where we actually do stuff
void loop() {
CalculateVoltage();
CalculateTemp();
m2.checkKey();
if ( m2.getRoot() == &m2_null_element ) {
u8g.setDefaultForegroundColor();
u8g.firstPage();
do {
m2.checkKey();
displayTemp(0,11,8,u8g_font_helvB10r);
displayVoltage(89,11,29,u8g_font_helvB10r);
}
while(u8g.nextPage());
switch (m2.getKey()) {
case M2_KEY_NEXT:
#ifdef DEBUG
Serial.println("DISPLAY: Brightness up");
#endif
//SetBrightness(BrightStep);
break;
case M2_KEY_PREV:
#ifdef DEBUG
Serial.println("DISPLAY: Brightness down");
#endif
//SetBrightness(-BrightStep);
break;
case M2_KEY_SELECT:
#ifdef DEBUG
Serial.println("MENU: button pressed");
#endif
m2.setRoot(&el_main);
m2.handleKey(); // update internal menu
m2.setKey(M2_KEY_REFRESH); // force a refresh
break;
}
}
else {
if ( m2.handleKey() != 0 ) {
u8g.firstPage();
do {
m2.draw();
m2.checkKey();
}
while(u8g.nextPage());
}
}
}
void displayVoltage(int posH, int posV, int inc, const unsigned char* font) {
u8g.setFont(font);
u8g.setPrintPos(posH, posV);
u8g.print(VMout,1); // Print the voltage with one decimal place
u8g.setPrintPos((posH + inc), posV); // Set the position for the following
u8g.print("V"); // Print V next to the voltage reading
}
void displayTemp(int posH, int posV, int inc, const unsigned char* font) {
u8g.setFont(font); // Set the font
if (tempErr == false) {
if ( DegF < 100.0f && DegF >= 10.0f ) { // adjust the print position depending on number of digits
u8g.setPrintPos((posH + inc), posV);
}
else if ( DegF < 10.0f && DegF >= 0.0f ) {
u8g.setPrintPos((posH + (inc * 2)), posV);
}
else {
u8g.setPrintPos(posH, posV);
}
u8g.print(DegF,0); // Print the temperature with no decimal fraction
}
else {
u8g.setFont(u8g_font_tpssr);
u8g.setPrintPos(posH, posV - 1);
u8g.print("ERR");
}
u8g.setPrintPos((posH + (inc * 3) + 1), posV);
u8g.setFont(font);
u8g.print("F"); // Print F next to the temp reading
}
void CalculateTemp() {
// Read the voltage from the LM34 and calcuate the temperature based on the voltage
float voltagein = 1023; // Read the voltage using ADC_1
float tempVolt = voltagein / 310; // For 3.3v power
float DegC = (100 * tempVolt) - 50; // TMP36 voltage = temp in C with a 50 deg offset
tempErr = false;
DegF = (DegC * 9.0 / 5.0) + 32.0; // Convert to Farenheit
#ifdef DEBUGTEMP
Serial.print(F("TEMP: "));
Serial.print(F("Temp: "));
Serial.println(DegF);
#endif
}
void CalculateVoltage() {
float VMsum = 888; // Read the voltage
// Calculate the voltage
float VMvoltage = VMsum / 310.0; // For 3.3V system
// Send voltage for display - the number requires tweaking to suit your individual setup
// (voltage divider resistor value and variance, etc.)
VMout = VMvoltage * 11.0312;
#ifdef DEBUGVOLT
Serial.print(F("VOLT: "));
Serial.print(F("Volt: "));
Serial.println(VMout);
#endif
}
Oliver,
Thank you, thank you, thank you! You have solved the last issues I was facing! I really appreciate your software and your assistance in debugging. Is there some way I can repay you?
Eric
I am glad to read, that the problems are solved. There is no need for "repay".
Oliver
olikraus:
I am glad to read, that the problems are solved. There is no need for "repay".Oliver
Do you have a Teensy 3.1 board? If not, can I send one to you?
Eric
Hi Eric
Thanks for the offer, but there is no need to send me a Teensy.
Is everything working? Do you have more questions on m2tklib?
Oliver
Everything is working at this point. I will need to implement a scroll list, but I think I can figure it out now from the tutorial.
One question I do have - is the button debounce interval configurable?
Eric
Hi Eric
in the file m2esarduino.c you can find these two definitions:
#define ROT_ENC_DEBOUNCE_VAL 3
#define ROT_ENC_EVENT_DIVISION 3
Try to reduce the values here for faster response of the rotary encoder.
Oliver
OK, I'm having an issue with a STRLIST. The vertical scroll bar is showing up below the strlist items. Here is what it looks like:
Here is the relevant code:
// Time zone menu
const char *selected = "";
const char *el_tzlist_tz(uint8_t idx, uint8_t msg) {
const char *tzone = "";
if ( idx == 0 )
tzone = "UTC";
else if ( idx == 1 )
tzone = "usET";
else if ( idx == 2 )
tzone = "usCT";
else if ( idx == 3 )
tzone = "usMT";
else if ( idx == 4 )
tzone = "usAZ";
else if ( idx == 5 )
tzone = "usPT";
else if ( idx == 6 )
tzone = "usAK";
if (msg == M2_STRLIST_MSG_GET_STR) {
/* nothing else todo, return the correct string */
} else if ( msg == M2_STRLIST_MSG_SELECT ) {
selected = tzone;
}
return tzone;
}
uint8_t el_tzlist_first = 0;
uint8_t el_tzlist_cnt = 7;
M2_STRLIST(el_tzlist, "l2w80", &el_tzlist_first, &el_tzlist_cnt, &el_tzlist_tz);
M2_SPACE(el_space, "w1h1");
M2_VSB(el_tzlist_vsb, "l2w5r1", &el_tzlist_first, &el_tzlist_cnt);
M2_LIST(list_tzlist_tz) = { &el_tzlist, &el_space, &el_tzlist_vsb };
M2_VLIST(el_tzlist_vlist, NULL, list_tzlist_tz);
M2_LABEL(el_label_tz,NULL, "Time zone: ");
M2_LABELPTR(el_labelptr_tz, NULL, &selected);
M2_LIST(list_label_tz) = { &el_label_tz, &el_labelptr_tz };
M2_VLIST(el_label_tz_vlist, NULL, list_label_tz);
M2_LIST(tzlist) = { &el_tzlist_vlist, &el_label_tz_vlist, &button_cancel };
M2_VLIST(el_tz_vlist, "f0", tzlist);
M2_ALIGN(top_el, "-1|1W64H64", &el_tz_vlist);
Also, I'd like to have the selected item (usPT in the example above) on the same line as "Time zone:".
Any pointers on how to resolve this are appreciated. I'm sure I'm missing something fairly simple...
Thanks!
I think you must use a HLIST instead of the VLIST for the first two container.
Oliver
M2_STRLIST(el_tzlist, "l2w80", &el_tzlist_first, &el_tzlist_cnt, &el_tzlist_tz);
M2_SPACE(el_space, "w1h1");
M2_VSB(el_tzlist_vsb, "l2w5r1", &el_tzlist_first, &el_tzlist_cnt);
M2_LIST(list_tzlist_tz) = { &el_tzlist, &el_space, &el_tzlist_vsb };
M2_HLIST(el_tzlist_vlist, NULL, list_tzlist_tz); // changed to HLIST
M2_LABEL(el_label_tz,NULL, "Time zone: ");
M2_LABELPTR(el_labelptr_tz, NULL, &selected);
M2_LIST(list_label_tz) = { &el_label_tz, &el_labelptr_tz };
M2_HLIST(el_label_tz_vlist, NULL, list_label_tz); // changed to HLIST
M2_LIST(tzlist) = { &el_tzlist_vlist, &el_label_tz_vlist, &button_cancel };
M2_VLIST(el_tz_vlist, "f0", tzlist);
M2_ALIGN(top_el, "-1|1W64H64", &el_tz_vlist);
That helped! Making progress:
Here's the updated code:
M2_STRLIST(el_tzlist, "l4w118", &el_tzlist_first, &el_tzlist_cnt, el_tzlist_tz);
M2_SPACE(el_space, "w1h1");
M2_VSB(el_tzlist_vsb, "l4w5r1", &el_tzlist_first, &el_tzlist_cnt);
M2_LIST(list_tzlist_tz) = { &el_tzlist, &el_space, &el_tzlist_vsb };
M2_HLIST(el_tzlist_vlist, NULL, list_tzlist_tz);
M2_ALIGN(top_el2, "-0|2", &el_tzlist);
M2_LABEL(el_label_tz,NULL, "Time zone: ");
M2_LABELPTR(el_labelptr_tz, NULL, &selected);
M2_LIST(list_label_tz) = { &el_label_tz, &el_labelptr_tz };
M2_HLIST(el_label_tz_vlist, NULL, list_label_tz);
M2_LIST(tzlist) = { &el_tzlist_vlist, &el_label_tz_vlist, &button_tz_use, &button_cancel };
M2_VLIST(el_tz_vlist, "f0", tzlist);
M2_ALIGN(top_el, "-1|1W64H64", &el_tz_vlist);
Now, I can't seem to get "Change?" and "cancel" on the same line.
I tried changing tzlist to a HLIST, but that really screwed up the display format.
As a side note, it doesn't appear that M2_ALIGN really does anything. I've tried changing that last entry to different formatting, to no avail.
I guess you need to put &button_tz_use and &button_cancel into another (third) HLIST. This HLIST has do be put into the VLIST, so finally the VLIST only contains three HLIST.
It looks, that your dialog box is larger than the screen. In such a case ALIGN can not do anything.
Oliver