Home | Projects | Notes > Embedded Systems Design using UML State Machines > Exercise 1: Changing Intensity of an LED
Connect the LED to any one of the PWM pins on the Arduino Uno board.
Modify the duty cycle of the PWM wave using the Arduino API's analogWrite()
function.
With the Arduino Uno board, the analogWrite()
API is not related to internal analog peripherals. Instead, it controls the ON/OFF period through the pin using a timer to achieve the desired duty cycle.
Language Reference: https://www.arduino.cc/reference/en/
Utilize the Arduino serial interface to transmit ON and OFF events from the host.
Arduino Uno board
1, 5mm LED
Jumper wires
Arduino Uno board PWM pins
Pin 3, 5, 6, 9, 10, 11 are PWM pins
On these pins Arudino Uno can generate PWM signals
PWM signal frequency:
490Hz on 3, 9, 10, 11
980Hz on 5 and 6
Arduino Uno board's secondary MCU acts as a USB-to-Serial converter which has a firmware that converts USB signal to UART signal and vice versa.
Thanks to this firmware, the Arduino Uno board can be enumerated as a Virtual COM Port on the host.
When uploading the program from the host to the Arduino board, the program is transferred via the USB cable, converted into UART signals, and then sent to the main MCU. The bootloader, located in the main MCU, writes the received program into the Flash memory.
xxxxxxxxxx
1331//==============================================================================
2// File : 01_LightControl_Mealy.ino
3// Brief : Light control application using the Mealy State Machine
4// Author : Kyungjae Lee
5// Date : Sep 27, 2023
6//==============================================================================
7
8// Macros
9
10
11
12
13
14
15// Enum for events
16typedef enum {
17 ON,
18 OFF
19} Event_Enum;
20
21// Enum for light states
22typedef enum {
23 LIGHT_OFF,
24 LIGHT_DIM,
25 LIGHT_MED,
26 LIGHT_FUL
27} LightState_Enum;
28
29// Function prototypes
30void light_state_machine(uint8_t event);
31void light_change_intensity(uint8_t pin, uint8_t intensity);
32
33// Global variables
34LightState_Enum light_state = LIGHT_OFF;
35
36void setup() {
37 // put your setup code here, to run once:
38
39 // 'Serial.begin()' takes care of all the necessary initialization of UART communication
40 Serial.begin(115200);
41 Serial.println("Light control application");
42 Serial.println("-------------------------");
43 Serial.println("Send 'x' or 'o'");
44}
45
46void loop() {
47 // put your main code here, to run repeatedly:
48
49 uint8_t event;
50
51 if (Serial.available() > 0)
52 {
53 event = Serial.read();
54 if (event == 'o')
55 {
56 light_state_machine(ON);
57 }
58 else if (event == 'x')
59 {
60 light_state_machine(OFF);
61 }
62 else
63 {
64 // Do nothing
65 }
66 }
67} // End of loop
68
69// Implementation of the Mealy State Machine for light control
70void light_state_machine(uint8_t event)
71{
72 switch (light_state)
73 {
74 case LIGHT_OFF: {
75 switch (event)
76 {
77 case ON:
78 light_change_intensity(PIN_LED, LIGHT_BRIGHT_DIM);
79 light_state = LIGHT_DIM;
80 break;
81 }
82 break;
83 }
84 case LIGHT_DIM: {
85 switch (event)
86 {
87 case ON:
88 light_change_intensity(PIN_LED, LIGHT_BRIGHT_MED);
89 light_state = LIGHT_MED;
90 break;
91 case OFF:
92 light_change_intensity(PIN_LED, LIGHT_BRIGHT_OFF);
93 light_state = LIGHT_OFF;
94 break;
95 }
96 break;
97 }
98 case LIGHT_MED: {
99 switch (event)
100 {
101 case ON:
102 light_change_intensity(PIN_LED, LIGHT_BRIGHT_FUL);
103 light_state = LIGHT_FUL;
104 break;
105 case OFF:
106 light_change_intensity(PIN_LED, LIGHT_BRIGHT_OFF);
107 light_state = LIGHT_OFF;
108 break;
109 }
110 break;
111 }
112 case LIGHT_FUL: {
113 switch (event)
114 {
115 case ON:
116 light_change_intensity(PIN_LED, LIGHT_BRIGHT_DIM);
117 light_state = LIGHT_DIM;
118 break;
119 case OFF:
120 light_change_intensity(PIN_LED, LIGHT_BRIGHT_OFF);
121 light_state = LIGHT_OFF;
122 break;
123 }
124 break;
125 }
126 }
127} // End of light_state_machine
128
129// Changes the light intensity
130void light_change_intensity(uint8_t pin, uint8_t intensity)
131{
132 analogWrite(pin, intensity);
133} // End of light_change_intensity
x1//==============================================================================
2// File : 02_LightControl_Moore.ino
3// Brief : Light control application using the Moore State Machine
4// Author : Kyungjae Lee
5// Date : Sep 27, 2023
6//==============================================================================
7
8// Macros
9
10
11
12
13
14
15// Enum for events
16typedef enum {
17 ON,
18 OFF
19} Event_Enum;
20
21// Enum for light states
22typedef enum {
23 LIGHT_OFF,
24 LIGHT_DIM,
25 LIGHT_MED,
26 LIGHT_FUL
27} LightState_Enum;
28
29// Function prototypes
30void light_init(void);
31void run_entry_action(LightState_Enum state);
32void light_state_machine(uint8_t event);
33void light_change_intensity(uint8_t pin, uint8_t intensity);
34
35// Global variables
36LightState_Enum curr_state;
37
38void setup() {
39 // put your setup code here, to run once:
40
41 // 'Serial.begin()' takes care of all the necessary initialization of UART communication
42 Serial.begin(115200);
43 Serial.println("Light control application");
44 Serial.println("-------------------------");
45 Serial.println("Send 'x' or 'o'");
46
47 light_init();
48} // End of setup
49
50void loop() {
51 // put your main code here, to run repeatedly:
52
53 uint8_t event;
54
55 if (Serial.available() > 0)
56 {
57 event = Serial.read();
58 if (event == 'o')
59 {
60 light_state_machine(ON);
61 }
62 else if (event == 'x')
63 {
64 light_state_machine(OFF);
65 }
66 else
67 {
68 // Do nothing
69 }
70 }
71} // End of loop
72
73// Initializes the light state
74void light_init(void)
75{
76 curr_state = LIGHT_OFF; // State
77 run_entry_action(LIGHT_OFF); // Action
78}
79
80// Implements the entry actions for each state
81void run_entry_action(LightState_Enum state)
82{
83 switch (state)
84 {
85 case LIGHT_OFF:
86 light_change_intensity(PIN_LED, LIGHT_BRIGHT_OFF);
87 break;
88 case LIGHT_DIM:
89 light_change_intensity(PIN_LED, LIGHT_BRIGHT_DIM);
90 break;
91 case LIGHT_MED:
92 light_change_intensity(PIN_LED, LIGHT_BRIGHT_MED);
93 break;
94 case LIGHT_FUL:
95 light_change_intensity(PIN_LED, LIGHT_BRIGHT_FUL);
96 break;
97 }
98} // End of run_entry_action
99
100// Implementation of Moore State Machine
101void light_state_machine(uint8_t event)
102{
103 LightState_Enum prev_state;
104
105 prev_state = curr_state;
106
107 switch (curr_state)
108 {
109 case LIGHT_OFF:
110 switch (event)
111 {
112 case ON:
113 curr_state = LIGHT_DIM;
114 break;
115 }
116 break;
117 case LIGHT_DIM:
118 switch (event)
119 {
120 case ON:
121 curr_state = LIGHT_MED;
122 break;
123 case OFF:
124 curr_state = LIGHT_OFF;
125 break;
126 }
127 break;
128 case LIGHT_MED:
129 switch (event)
130 {
131 case ON:
132 curr_state = LIGHT_FUL;
133 break;
134 case OFF:
135 curr_state = LIGHT_OFF;
136 break;
137 }
138 break;
139 case LIGHT_FUL:
140 switch (event)
141 {
142 case ON:
143 curr_state = LIGHT_DIM;
144 break;
145 case OFF:
146 curr_state = LIGHT_OFF;
147 break;
148 }
149 break;
150 }
151
152 // Check if there has been a state transition
153 if (prev_state != curr_state)
154 {
155 // There has been a state transition, so run appropriate entry action
156 // of the new state.
157 run_entry_action(curr_state);
158 }
159} // End of light_state_machine
160
161// Changes the light intensity
162void light_change_intensity(uint8_t pin, uint8_t intensity)
163{
164 analogWrite(pin, intensity);
165} // End of light_change_intensity