t08 - olikraus/m2tklib GitHub Wiki
Tutorial 8: Software Design for User Forms
The discussed questions are:
- How to transfer information from and to M2tklib?
- How to process user input?
This tutorial will:
- Suggest a simple concept for the design of user input forms.
- Apply this concept to a more complex example (PWM Pin List)
Theory
Background: Most M2tklib elements just get the address of a variable. Here is M2_U8NUM
M2_U8NUM(el_u8_field, NULL, 0, 255, &my_variable);
The value of my_variable
can be modified by the user. Such a variable is called a "menu variable".
The suggestion in this tutorial is to write two procedures:
- Collect information and store the information in the "menu variables" (
prepare_user_input
procedure). - Collect values from the "menu variables", apply these values to the hardware and/or store these values (
apply_user_input procedure
).
Example
This example is available as PWMPinList
in the Arduino IDE.
Specification
- The user can select one of the PWM pins (six for the Arduino Uno).
- The user can modify the output state of each pin.
- Output states are: Low, high, duty cycle time of 25%, 50% and 75%
Pin Array
The user can select a pin:
The output state will be stored in the array pwm_duty_array
:
// array with all the information
#define PWM_PIN_CNT 6
uint8_t pwm_duty_array[PWM_PIN_CNT] = { 0,0,0,0,0,0 };
uint8_t pwm_pin_array[PWM_PIN_CNT] = { 3,5,6,9,10,11 };
An internal number from 0 to 4 will be mapped to the intended output state:
void pwm_value_to_str(uint8_t value, char *dest) {
switch(value) {
case 0: strcpy(dest, "low"); break;
case 1: strcpy(dest, "25%"); break;
case 2: strcpy(dest, "50%"); break;
case 3: strcpy(dest, "75%"); break;
case 4: strcpy(dest, "high"); break;
}
}
Menu Variables
The user menu for one pwm pin will look like this:
The values of two variables are visible:
uint8_t pwm_menu_pin = 0; // pin number
uint8_t pwm_menu_duty = 0; // output state
As suggested, there are two procedures to transfer data from and to the menu:
// get pin and value pair from the global array and store them in the menu variables
void pwm_prepare_user_input(void) {
pwm_menu_duty = pwm_duty_array[pwm_menu_current_index];
pwm_menu_pin = pwm_pin_array[pwm_menu_current_index];
}
// write user input back to the array and to the analog pin
void pwm_apply_user_input(void) {
// write user input into array
pwm_duty_array[pwm_menu_current_index] = pwm_menu_duty;
pwm_pin_array[pwm_menu_current_index] = pwm_menu_pin;
// apply user input to the hardware
// analogWrite(pwm_menu_pin, pwm_value_to_analog(pwm_menu_value));
}
Program Flow
To jump from the list of pwm pins to the user dialog, use the following sequence:
// transfer values from the array to the menu variables
pwm_prepare_user_input();
// give control to the pwm dialog
m2.setRoot(&el_top_pwm_menu);
The "ok" button of the dialog menu for one pwm pin will jump back to the pin list. The callback procedure for the "ok" button will look like this:
// this procedure is called by the "ok" button
void pwm_fn_ok(m2_el_fnarg_p fnarg) {
// finish user entry
pwm_apply_user_input();
// go back to parent menu
m2.setRoot(&top_el_pin_list);
}
Conclusion
- Use one procedure to setup the variables of your dialog menu.
- Use one procedure to apply values from the user input to the rest of the software.
Links
- Previous Tutorial: Arduino Serial Monitor
- Next Tutorial: Incremental Rotary Encoder
- Wiki Start Page