384 lines
8.9 KiB
C++
384 lines
8.9 KiB
C++
/*
|
|
* Menu.cpp
|
|
*
|
|
* Created on: Jun 8, 2024
|
|
* Author: Carst
|
|
*/
|
|
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
#include <cinttypes>
|
|
#include "Menu.hpp"
|
|
#include "Display.hpp"
|
|
#include "Button.hpp"
|
|
#include "Timer.hpp"
|
|
#include "ElektronischeLast.hpp"
|
|
#include "STM32G071KBT6.hpp"
|
|
|
|
namespace ElektronischeLast
|
|
{
|
|
static Timer timer = Timer();
|
|
static Button ok = Button();
|
|
static Button up = Button();
|
|
static Button down = Button();
|
|
static Display lcd = Display();
|
|
static const uint8_t degreeSymbol[] = { 0x0E, 0x0A, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
|
static const uint8_t arrowUp[] = { 0x04, 0x0E, 0x1F, 0x04, 0x04, 0x04, 0x04, 0x04 };
|
|
static const uint8_t arrowDown[] = { 0x04, 0x04, 0x04, 0x04, 0x04, 0x1F, 0x0E, 0x04 };
|
|
|
|
void Menu::init()
|
|
{
|
|
timer.start(500U);
|
|
ok.init(GPIOA, LL_GPIO_PIN_7);
|
|
up.init(GPIOA, LL_GPIO_PIN_9);
|
|
down.init(GPIOA, LL_GPIO_PIN_8);
|
|
|
|
lcd.init();
|
|
|
|
while(lcd.ready_for_data() == false)
|
|
{
|
|
lcd.run();
|
|
}
|
|
|
|
lcd.lcd_set_user_chars(Display::FirstSign, arrowUp);
|
|
while(lcd.ready_for_data() == false)
|
|
{
|
|
lcd.run();
|
|
}
|
|
lcd.lcd_set_user_chars(Display::ThirdSign, arrowDown);
|
|
while(lcd.ready_for_data() == false)
|
|
{
|
|
lcd.run();
|
|
}
|
|
lcd.lcd_set_user_chars(Display::SecondSign, degreeSymbol);
|
|
while(lcd.ready_for_data() == false)
|
|
{
|
|
lcd.run();
|
|
}
|
|
lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOff, Display::eCursorBlinkOff);
|
|
lcd.print(Display::Line1, "Elektronische Last");
|
|
|
|
up.cyclic();
|
|
down.cyclic();
|
|
if(up.isPressed() && down.isPressed())
|
|
{
|
|
menu_level = MenuLevel_Call;
|
|
}
|
|
}
|
|
|
|
void Menu::set_measurements(uint32_t spannung, uint32_t strom, uint32_t temperatur, uint32_t geschwindigkeit)
|
|
{
|
|
this->spannung = spannung;
|
|
this->strom = strom;
|
|
this->temperatur = temperatur;
|
|
this->geschwindigkeit = geschwindigkeit;
|
|
}
|
|
|
|
void Menu::run()
|
|
{
|
|
ok.cyclic();
|
|
up.cyclic();
|
|
down.cyclic();
|
|
|
|
switch(menu_level)
|
|
{
|
|
case MenuLevel_Call:
|
|
menu_call();
|
|
break;
|
|
case MenuLevel_ICallInit:
|
|
menu_icall_init();
|
|
break;
|
|
case MenuLevel_ICall:
|
|
menu_icall();
|
|
break;
|
|
case MenuLevel_UCallInit:
|
|
menu_ucall_init();
|
|
break;
|
|
case MenuLevel_UCall:
|
|
menu_ucall();
|
|
break;
|
|
case MenuLevel_ISoll:
|
|
menu_isoll();
|
|
break;
|
|
case MenuLevel_Main:
|
|
default:
|
|
menu_main();
|
|
break;
|
|
}
|
|
lcd.run();
|
|
}
|
|
|
|
void Menu::menu_main(void)
|
|
{
|
|
if(timer.elapsed())
|
|
{
|
|
if(lcd.ready_for_data())
|
|
{
|
|
timer.start(500U);
|
|
|
|
char data[17U];
|
|
|
|
int32_t len = snprintf(data, sizeof(data) - 1, "%2" PRIu32 ".%02" PRIu32 "V",
|
|
spannung / 1000U, spannung % 1000U / 10U);
|
|
std::memset(&data[len], (int)' ', 16U - len);
|
|
snprintf(&data[12], sizeof(data) - 12, "%2" PRIu32 "%cC", temperatur, 0x1);
|
|
data[16] = '\0';
|
|
lcd.print(Display::Line1, data);
|
|
|
|
if(strom < 1000UL)
|
|
{
|
|
len = snprintf(data, sizeof(data) - 1, "%3" PRIu32 "mA", strom);
|
|
}
|
|
else
|
|
{
|
|
len = snprintf(data, sizeof(data) - 1, "%" PRIu32 ".%02" PRIu32 "A",
|
|
strom / 1000U, strom % 1000U / 10U);
|
|
}
|
|
std::memset(&data[len], (int)' ', 16U - len);
|
|
snprintf(&data[9], sizeof(data) - 9, "%4" PRIu32 "RPM", geschwindigkeit);
|
|
data[16] = '\0';
|
|
lcd.print(Display::Line2, data);
|
|
}
|
|
}
|
|
|
|
if(ok.isReleased())
|
|
{
|
|
this->menu_level = MenuLevel_ISoll;
|
|
this->configurations = 0UL;
|
|
}
|
|
}
|
|
|
|
void Menu::menu_call(void)
|
|
{
|
|
if(lcd.ready_for_data())
|
|
{
|
|
switch(this->configurations)
|
|
{
|
|
case 0UL:
|
|
lcd.print(Display::Line1, "Kalibrierung: I");
|
|
lcd.print(Display::Line2, "Kalibrierung: U");
|
|
this->configurations++;
|
|
break;
|
|
case 1UL:
|
|
lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOn, Display::eCursorBlinkOn);
|
|
this->configurations++;
|
|
break;
|
|
case 2UL:
|
|
lcd.set_cursor(Display::Line1, 15U);
|
|
this->configurations++;
|
|
this->cursor = 1UL;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(ok.isReleased())
|
|
{
|
|
if(this->cursor == 1UL)
|
|
{
|
|
this->menu_level = MenuLevel_ICallInit;
|
|
}
|
|
else if(this->cursor == 2UL)
|
|
{
|
|
this->menu_level = MenuLevel_UCallInit;
|
|
}
|
|
this->configurations = 0UL;
|
|
}
|
|
else if(up.isReleased())
|
|
{
|
|
if(this->cursor == 1UL)
|
|
{
|
|
this->cursor = 2UL;
|
|
lcd.set_cursor(Display::Line2, 15U);
|
|
}
|
|
else if(this->cursor == 2UL)
|
|
{
|
|
this->cursor = 1UL;
|
|
lcd.set_cursor(Display::Line1, 15U);
|
|
}
|
|
}
|
|
else if(down.isReleased())
|
|
{
|
|
if(this->cursor == 1UL)
|
|
{
|
|
this->cursor = 2UL;
|
|
lcd.set_cursor(Display::Line2, 15U);
|
|
}
|
|
else if(this->cursor == 2UL)
|
|
{
|
|
this->cursor = 1UL;
|
|
lcd.set_cursor(Display::Line1, 15U);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Menu::menu_icall_init(void)
|
|
{
|
|
char data[17U];
|
|
if(lcd.ready_for_data())
|
|
{
|
|
switch(this->configurations)
|
|
{
|
|
case 0UL:
|
|
set_new_sollstrom(1000UL);
|
|
soll = get_current_sollstrom();
|
|
snprintf(data, sizeof(data), "iSoll: %5" PRIu32 "mA", soll);
|
|
lcd.print(Display::Line1, "Stelle 1A ein ");
|
|
lcd.print(Display::Line2, data);
|
|
this->configurations++;
|
|
break;
|
|
case 1UL:
|
|
lcd.set_cursor(Display::Line2, 13UL);
|
|
this->configurations++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(ok.isReleased())
|
|
{
|
|
this->menu_level = MenuLevel_ICall;
|
|
this->configurations = 0UL;
|
|
}
|
|
else if(down.isReleased())
|
|
{
|
|
soll--;
|
|
set_new_sollstrom(soll);
|
|
snprintf(data, sizeof(data), "iSoll: %5" PRIu32 "mA", soll);
|
|
lcd.print(Display::Line2, data);
|
|
this->configurations = 1UL;
|
|
}
|
|
else if(up.isReleased())
|
|
{
|
|
soll++;
|
|
set_new_sollstrom(soll);
|
|
snprintf(data, sizeof(data), "iSoll: %5" PRIu32 "mA", soll);
|
|
lcd.print(Display::Line2, data);
|
|
this->configurations = 1UL;
|
|
}
|
|
}
|
|
|
|
void Menu::menu_icall(void)
|
|
{
|
|
if(this->configurations == 0UL)
|
|
{
|
|
start_icall();
|
|
lcd.print(Display::Line1, "Kalibrierung... ");
|
|
lcd.print(Display::Line2, " ");
|
|
this->configurations++;
|
|
}
|
|
}
|
|
|
|
void Menu::menu_ucall_init(void)
|
|
{
|
|
if(this->configurations == 0UL)
|
|
{
|
|
set_new_sollstrom(0UL);
|
|
lcd.print(Display::Line1, "Lege 15V an ");
|
|
lcd.print(Display::Line2, " ");
|
|
this->configurations++;
|
|
}
|
|
|
|
if(ok.isReleased())
|
|
{
|
|
this->menu_level = MenuLevel_UCall;
|
|
this->configurations = 0UL;
|
|
}
|
|
}
|
|
|
|
void Menu::menu_ucall(void)
|
|
{
|
|
if(this->configurations == 0UL)
|
|
{
|
|
start_ucall();
|
|
lcd.print(Display::Line1, "Kalibrierung... ");
|
|
lcd.print(Display::Line2, " ");
|
|
this->configurations++;
|
|
}
|
|
}
|
|
|
|
void Menu::menu_isoll(void)
|
|
{
|
|
const char *header = "Sollstrom: ";
|
|
char data[17U];
|
|
int32_t len;
|
|
bool changed = false;
|
|
|
|
if(lcd.ready_for_data())
|
|
{
|
|
switch(this->configurations)
|
|
{
|
|
case 0UL:
|
|
cursor = 0U;
|
|
soll = get_current_sollstrom();
|
|
len = snprintf(data, sizeof(data) - 1, "%05" PRIu32 "mA", soll);
|
|
std::memset(&data[len], (int)' ', 16U - len);
|
|
data[16] = '\0';
|
|
lcd.print(Display::Line1, header);
|
|
lcd.print(Display::Line2, data);
|
|
this->configurations++;
|
|
break;
|
|
case 1UL:
|
|
lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOn, Display::eCursorBlinkOn);
|
|
this->configurations++;
|
|
break;
|
|
case 2UL:
|
|
lcd.set_cursor(Display::Line2, cursor);
|
|
this->configurations++;
|
|
break;
|
|
default:
|
|
if(ok.isReleased())
|
|
{
|
|
cursor++;
|
|
if(cursor > 3U)
|
|
{
|
|
menu_level = MenuLevel_Main;
|
|
set_new_sollstrom(soll);
|
|
lcd.lcd_set_display(Display::eDispalyOn, Display::eCursorOff, Display::eCursorBlinkOff);
|
|
}
|
|
else
|
|
{
|
|
lcd.set_cursor(Display::Line2, cursor);
|
|
}
|
|
}
|
|
else if(up.isReleased())
|
|
{
|
|
uint32_t step = 10000UL;
|
|
uint32_t i = 0U;
|
|
while(i < cursor)
|
|
{
|
|
step /= 10UL;
|
|
i++;
|
|
}
|
|
this->soll = (this->soll + step) % 11000UL;
|
|
changed = true;
|
|
}
|
|
else if(down.isReleased())
|
|
{
|
|
uint32_t step = 10000UL;
|
|
uint32_t i = 0U;
|
|
while(i < cursor)
|
|
{
|
|
step /= 10UL;
|
|
i++;
|
|
}
|
|
this->soll = (this->soll - step) % 11000UL;
|
|
changed = true;
|
|
}
|
|
if(changed)
|
|
{
|
|
len = snprintf(data, sizeof(data) - 1, "%05" PRIu32 "mA", this->soll);
|
|
std::memset(&data[len], (int)' ', 16U - len);
|
|
data[16] = '\0';
|
|
lcd.print(Display::Line2, data);
|
|
this->configurations = 2U;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|