This is my code:
- TFT task manager
//#define TFT_IRQ_PIN 36 // using esp32 devkit-v1
#define TFT_IRQ_PIN PB2 // using stm32 blackpill
//void IRAM_ATTR tft_irq_isr(void);
void tft_irq_isr(void);
void tft_start_setting(void){
tft_irq.page_index = HOME_PAGE;
tft_irq.button_index = NOT_SELECTED;
tft_irq.page_update = false;
tft_irq.button_update = false;
tft_irq.tftTouchLock = false;
// tft isr setting
pinMode(TFT_IRQ_PIN, INPUT);
attachInterrupt(TFT_IRQ_PIN, tft_irq_isr, FALLING);
}
//void IRAM_ATTR tft_irq_isr(void) {
void tft_irq_isr(void) {
if(!tft_irq.tftTouchLock){
tft_irq.buttonTimer = millis();
tft_irq.tftTouchLock = 1;
tft_irq.irq_request_count++;
}
}
void tft_task_manager(void){
print_pages();
perform_actions();
read_buttons();
if(tft_irq.tftTouchLock){
if(millis() - tft_irq.buttonTimer >= 300){
tft_irq.tftTouchLock = 0;
}
}
}
- Main TFT control functions. There are 3 main functions:
print_pages
, read_buttons
and perform_actions
:
#include "system_variables.h"
/////////////////////////////////////// MAIN PAGE ////////////////////////////////////////////
// pages and headings
// main ///////////////////////////////////
text t_main_page = {CENTERED_MAIN, 20, TFT_WHITE, TFT_BLACK, "System Menu", CENTERED};
button p_motor = {40, 60, 250, 30, TFT_BLUE, TFT_WHITE, "MOTOR CONTROL", MOTOR_PAGE};
button p_electrical = {40, 110, 250, 30, TFT_BLUE, TFT_WHITE, "ELECTRICAL CONTROL", ELECTRICAL_PAGE};
button p_weather = {40, 160, 250, 30, TFT_BLUE, TFT_WHITE, "WEATHER MONITOR", WEATHER_PAGE};
button p_led_control = {40, 210, 250, 30, TFT_BLUE, TFT_WHITE, "LED CONTROL", LED_CONTROL_PAGE};
button p_new = {40, 260, 250, 30, TFT_BLUE, TFT_WHITE, "NEW CONTROL", NEW_CONTROL_PAGE};
// electrical /////////////////////////////
text t_main_electrical = {CENTERED_MAIN, 20, TFT_WHITE, TFT_BLACK, "Electrical Type Control", CENTERED};
data_output d_voltage = {120, 80, 50, 30, TFT_YELLOW, TFT_BLACK, TFT_YELLOW, 0, "VOLTAGE", 40, "", 0, 0};
data_output d_current = {120, 130, 50, 30, TFT_YELLOW, TFT_BLACK, TFT_YELLOW, 0, "CURRENT", 40, "", 0, 0};
data_output d_power = {120, 180, 50, 30, TFT_YELLOW, TFT_BLACK, TFT_YELLOW, 0, "POWER", 40, "", 0, 0};
// weather ////////////////////////////////
text t_main_weather = {CENTERED_MAIN, 20, TFT_WHITE, TFT_BLACK, "Weather Monitor", CENTERED};
slide s_fan_speed = {150, 170, 130, 30, TFT_RED, TFT_YELLOW, 0, 0, 0, 0, 0};
// motor //////////////////////////////////
text t_main_motor = {CENTERED_MAIN, 20, TFT_WHITE, TFT_BLACK, "Motor Type Control", CENTERED};
// constant home/sub-home pages
button p_main_page = {40, 440, 250, 30, TFT_ORANGE, TFT_BLACK, "HOME PAGE", HOME_PAGE};
button p_motors_main_page = {40, 390, 250, 30, TFT_ORANGE, TFT_BLACK, "MOTORS MENU", MOTOR_PAGE};
text t_stepper_main = {CENTERED_MAIN, 20, TFT_ORANGE, TFT_BLACK, "Stepper Motor", CENTERED};
text t_servo_main = {CENTERED_MAIN, 20, TFT_WHITE, TFT_BLACK, "Servo Motor", CENTERED};
text t_dc_main = {CENTERED_MAIN, 20, TFT_WHITE, TFT_BLACK, "DC Motor", CENTERED};
button p_servo = {40, 60, 250, 30, TFT_GREEN, TFT_DARKGREEN, "SERVO MOTOR CONTROL", SERVO_MOTOR_PAGE};
button p_dc = {40, 110, 250, 30, TFT_GREEN, TFT_DARKGREEN, "DC MOTOR CONTROL", DC_MOTOR_PAGE};
button p_stepper = {40, 160, 250, 30, TFT_GREEN, TFT_DARKGREEN, "STEPPER MOTOR CONTROL", STEPPER_MOTOR_PAGE};
// general motor itmes
text t_motor_mode = {THREE_COL_1, 80, TFT_GREEN, TFT_BLACK, "Mode", NOT_CENTERED};
text t_motor_direction = {THREE_COL_1, 130, TFT_GREEN, TFT_BLACK, "Direction", NOT_CENTERED};
text t_motor_speed = {THREE_COL_1, 190, TFT_GREEN, TFT_BLACK, "Speed", NOT_CENTERED};
button_toggle b_motor_mode = {THREE_COL_2, 60, 50, 30, 20, TFT_GREEN, TFT_BLUE, TFT_BLACK, "AT", "MT", 0, 0, 0, 0, 0, 0, 0};
button_toggle b_motor_direction = {THREE_COL_2, 110, 50, 30, 20, TFT_GREEN, TFT_BLUE, TFT_BLACK, "CW", "CCW", 0, 0, 0, 0, 0, 0, 0};
button_toggle b_motor_start_stop = {CENTERED_COL, 250, 80, 60, 20, TFT_RED, TFT_GREEN, TFT_BLACK, "RUN", "STOP", 0, 0, 0, 0, 0, 0, 0};
slide s_motor_speed = {150, 170, 130, 30, TFT_RED, TFT_YELLOW, 0, 0, 0, 0, 0};
// servo tools
text t_servo_angle = {THREE_COL_1, 190, TFT_GREEN, TFT_BLACK, "Servo Angle", NOT_CENTERED};
slide s_servo_pos = {150, 170, 130, 30, TFT_RED, TFT_YELLOW, SERVO_MOTOR_CONTROL, PCA9685_0, 0, 0, 0};
// stepper tools
button_toggle b_stepper_mode = {THREE_COL_2, 60, 50, 30, 20, TFT_GREEN, TFT_BLUE, TFT_BLACK, "FULL STEP", "HALF STEP", 0, 0, 0, 0, 0, 0, 0};
button_toggle b_stepper_direction = {THREE_COL_2, 60, 50, 30, 20, TFT_GREEN, TFT_BLUE, TFT_BLACK, "CW", "CCW", 0, 0, 0, 0, 0, 0, 0};
stepper_4_wires_obj_t stepper1_obj_arduino = {
PB12, PB13, PB14, PB15, STEPPER_START_STEP, STEPPER_360_DEG, STEPPER_CW, MOVE_TO, STEPPER_HALF_STEP, 0, micros(), 2000};
// led control
text t_led_control_main = {CENTERED_MAIN, 20, TFT_WHITE, TFT_BLACK, "LED CONTROL", CENTERED};
button_toggle b_led_pb8 = {CENTERED_COL, 160, 90, 40, 20, TFT_RED, TFT_GREEN, TFT_BLACK, "LED ON", "LED OFF", LOGIC_CONTROL, PB8, HIGH, LOW, 0, 0, 0};
button_toggle b_led_pb9 = {CENTERED_COL, 210, 90, 40, 20, TFT_RED, TFT_GREEN, TFT_BLACK, "LED ON", "LED OFF", LOGIC_CONTROL, PB9, HIGH, LOW, 0, 0, 0};
slide s_led_brightness = {150, 110, 130, 30, TFT_RED, TFT_YELLOW, PWM_CONTROL, PB9, 0, 0, 0};
// new control
text t_new_control_main = {CENTERED_MAIN, 20, TFT_ORANGE, TFT_BLACK, "NEW CONTROL", CENTERED};
button_toggle b_tgl_btn = {CENTERED_COL, 160, 90, 40, 20, TFT_RED, TFT_GREEN, TFT_BLACK, "ON", "OFF", 0, 0, 0, 0, 0, 0, 0};
slide s_brightness = {150, 110, 130, 30, TFT_RED, TFT_YELLOW, 0, 0, 0, 0, 0};
void main_menu_page(void) {
tft.fillScreen(TFT_BLACK);
draw_text(t_main_page);
draw_button(p_motor);
draw_button(p_electrical);
draw_button(p_weather);
draw_button(p_led_control);
draw_button(p_new);
}
void motors_page(void){
tft.fillScreen(TFT_BLACK);
draw_text(t_main_motor);
draw_button(p_servo);
draw_button(p_dc);
draw_button(p_stepper);
draw_button(p_main_page);
}
void electrical_page(void){
tft.fillScreen(TFT_BLACK);
draw_text(t_main_electrical);
draw_button(p_main_page);
draw_data_output(d_voltage);
draw_data_output(d_current);
draw_data_output(d_power);
}
void weather_page(void){
tft.fillScreen(TFT_BLACK);
draw_text(t_main_weather);
draw_slide(s_fan_speed);
draw_button(p_main_page);
}
void led_control_page(void){
tft.fillScreen(TFT_BLACK);
draw_text(t_led_control_main);
draw_button_toggle(b_led_pb9);
draw_button_toggle(b_led_pb8);
draw_slide(s_led_brightness);
draw_button(p_main_page);
}
void new_control_page(void){
tft.fillScreen(TFT_DARKGREEN);
draw_text(t_new_control_main);
draw_button_toggle(b_tgl_btn);
draw_slide(s_brightness);
draw_button(p_main_page);
}
void stepper_motor_page(void){
tft.fillScreen(TFT_BLACK);
draw_text(t_stepper_main);
draw_text(t_motor_mode);
draw_button_toggle(b_stepper_mode);
draw_text(t_motor_direction);
draw_button_toggle(b_motor_direction);
draw_text(t_motor_speed);
draw_slide(s_motor_speed);
draw_button_toggle(b_motor_start_stop);
draw_button(p_motors_main_page);
draw_button(p_main_page);
}
void servo_motor_page(void){
tft.fillScreen(TFT_BLACK);
draw_text(t_servo_main);
draw_text(t_servo_angle);
draw_slide(s_servo_pos);
draw_button(p_motors_main_page);
draw_button(p_main_page);
}
void dc_motor_page(void){
tft.fillScreen(TFT_BLACK);
draw_text(t_dc_main);
draw_text(t_motor_mode);
draw_text(t_motor_direction);
draw_button_toggle(b_motor_direction);
draw_text(t_motor_speed);
draw_slide(s_motor_speed);
draw_button_toggle(b_motor_start_stop);
draw_button(p_motors_main_page);
draw_button(p_main_page);
}
//////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// BUTTON READ / PROCESS ////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
void read_buttons(void){
if(tft_irq.tft_task_state == READ_BUTTON && tft_irq.page_update == true){
if(tft_irq.page_index == HOME_PAGE){
tft_irq.button_index |= read_button(p_motor);
tft_irq.button_index |= read_button(p_electrical);
tft_irq.button_index |= read_button(p_weather);
tft_irq.button_index |= read_button(p_led_control);
tft_irq.button_index |= read_button(p_new);
}
else if(tft_irq.page_index == MOTOR_PAGE){
tft_irq.button_index |= read_button(p_servo);
tft_irq.button_index |= read_button(p_dc);
tft_irq.button_index |= read_button(p_stepper);
tft_irq.button_index |= read_button(p_main_page);
}
else if(tft_irq.page_index == STEPPER_MOTOR_PAGE){
tft_irq.button_index |= read_button_toggle(b_stepper_mode);
tft_irq.button_index |= read_button_toggle(b_motor_direction);
tft_irq.button_index |= read_button_toggle(b_motor_start_stop);
// tft_irq.button_index |= // --> not connected to pin/output
update_slide(s_motor_speed);
tft_irq.button_index |= read_button(p_motors_main_page);
tft_irq.button_index |= read_button(p_main_page);
}
else if(tft_irq.page_index == DC_MOTOR_PAGE){
tft_irq.button_index |= read_button_toggle(b_motor_mode);
tft_irq.button_index |= read_button_toggle(b_motor_direction);
// tft_irq.button_index |= // --> not connected to pin/output
update_slide(s_motor_speed);
tft_irq.button_index |= read_button(p_motors_main_page);
tft_irq.button_index |= read_button(p_main_page);
}
else if(tft_irq.page_index == SERVO_MOTOR_PAGE){
tft_irq.button_index |= update_slide(s_servo_pos);
tft_irq.button_index |= read_button(p_motors_main_page);
tft_irq.button_index |= read_button(p_main_page);
}
else if(tft_irq.page_index == ELECTRICAL_PAGE){
tft_irq.button_index |= read_button(p_main_page);
update_data_output(d_voltage);
update_data_output(d_current);
update_data_output(d_power);
}
else if(tft_irq.page_index == WEATHER_PAGE){
update_slide(s_fan_speed);
tft_irq.button_index |= read_button(p_main_page);
}
else if(tft_irq.page_index == LED_CONTROL_PAGE){
tft_irq.button_index |= read_button_toggle(b_led_pb8);
tft_irq.button_index |= read_button_toggle(b_led_pb9);
tft_irq.button_index |= update_slide(s_led_brightness);
tft_irq.button_index |= read_button(p_main_page);
}
else if(tft_irq.page_index == NEW_CONTROL_PAGE){
tft_irq.button_index |= read_button_toggle(b_tgl_btn);
tft_irq.button_index |= update_slide(s_brightness);
tft_irq.button_index |= read_button(p_main_page);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
if(tft_irq.button_index){
if(tft_irq.button_index < PAGE_END_INDEX && tft_irq.button_index > PAGE_START_INDEX){
tft_irq.tft_task_state = PRINT_PAGE;
tft_irq.page_index = tft_irq.button_index;
tft_irq.page_update = false;
}
// execute button actions
else if(tft_irq.button_index > ACTION_START_INDEX && tft_irq.button_index < ACTION_END_INDEX){
tft_irq.tft_task_state = PERFORM_ACTION;
tft_irq.button_update = true;
}
// else if(tft_irq.button_index > ACTIONS_START_INDEX && tft_irq.button_index < ACTIONS_END_INDEX){
// tft_irq.tft_task_state = PERFORM_ACTION;
// tft_irq.button_update = true;
// }
}
}
}
void perform_actions(void){
if(tft_irq.tft_task_state == PERFORM_ACTION && tft_irq.button_update == true){
switch(tft_irq.button_index){
case LOGIC_CONTROL:
pinMode(tft_irq.mcu_task_pin, OUTPUT);
digitalWrite(tft_irq.mcu_task_pin, tft_irq.mcu_task_action);
break;
case PWM_CONTROL:
analogWrite(tft_irq.mcu_task_pin, tft_irq.mcu_task_action);
break;
case SERVO_MOTOR_CONTROL:
pwm.setPWM(tft_irq.mcu_task_pin, 0, tft_irq.mcu_task_action);
break;
case STEPPER_MOTOR_CONTROL:
stepper_4_wires_init(stepper1_obj_arduino);
stepper_4_wires_step_run(stepper1_obj_arduino);
break;
case READ_INPUT_DIGITAL:
tft_irq.mcu_task_action = digitalRead(tft_irq.mcu_task_pin);
break;
case READ_INPUT_ANALOG:
tft_irq.mcu_task_action = analogRead(tft_irq.mcu_task_pin);
break;
}
tft_irq.tft_task_state = READ_BUTTON;
tft_irq.button_index = NOT_SELECTED;
tft_irq.button_update = false;
tft_irq.mcu_task_pin = NOT_SELECTED;
tft_irq.mcu_task_action = NOT_SELECTED;
}
}
void print_pages(void) {
if(tft_irq.tft_task_state == PRINT_PAGE && tft_irq.page_update == false){
switch (tft_irq.page_index) {
//////////////////////////////////// home page
case HOME_PAGE:
main_menu_page();
break;
//////////////////////////////////// main pages
case MOTOR_PAGE:
motors_page();
break;
case WEATHER_PAGE:
weather_page();
break;
case ELECTRICAL_PAGE:
electrical_page();
break;
case LED_CONTROL_PAGE:
led_control_page();
break;
case NEW_CONTROL_PAGE:
new_control_page();
break;
//////////////////////////////////// motor pages
case SERVO_MOTOR_PAGE:
servo_motor_page();
break;
case DC_MOTOR_PAGE:
dc_motor_page();
break;
case STEPPER_MOTOR_PAGE:
stepper_motor_page();
break;
//////////////////////////////////// ... pages
}
tft_irq.tft_task_state = READ_BUTTON;
tft_irq.button_index = NOT_SELECTED;
tft_irq.page_update = true;
}
}