Reputation: 19
I am trying to create a state machine but am a little lost. Please go easy on me, i've only been coding 4 months.
Im using a pic16f18325 and coding in mplab
So i think im pretty much there, i know what i want it to do, i have written diagrams etc and think i have set it up correctly. My question is how to i switch between the states? How do i change an event?
If for example i was in the maincode and i wanted to trigger the ENTER event by press of a button. Would i just write:
if (button == 0){ // (button has been defined already)
event = ENTER;
}
void ENTER (void){
// do some stuff
}
mplab is not liking the word "event" im getting a fair few errors that i dont understand:
main.c:33:6: error: redefinition of 'ENTER' as different kind of symbol
void ENTER (void);
^
main.c:26:5: note: previous definition is here
int ENTER; // for entering programming from maincode
^
main.c:34:6: error: redefinition of 'EXIT' as different kind of symbol
void EXIT (void);
^
main.c:27:5: note: previous definition is here
int EXIT; // for exiting programming and returning to maincode
^
main.c:35:6: error: redefinition of 'Reset' as different kind of symbol
void Reset (void);
^
main.c:28:5: note: previous definition is here
int Reset; // to reset the speed and return to main code
^
main.c:36:6: error: redefinition of 'INCREASE' as different kind of symbol
void INCREASE (void);
^
main.c:29:5: note: previous definition is here
int INCREASE; // to increase the speed while in programming
^
main.c:37:6: error: redefinition of 'DECREASE' as different kind of symbol
void DECREASE (void);
^
main.c:30:5: note: previous definition is here
int DECREASE; // to decrease the speed while in programming
^
main.c:110:36: error: function definition is not allowed here
void step_state(enum events event) { // not sure what to write here, will work it out
^
main.c:145:18: error: function definition is not allowed here
void ENTER (void){
^
main.c:148:17: error: function definition is not allowed here
void EXIT (void){
^
main.c:151:18: error: function definition is not allowed here
void Reset (void){
^
main.c:154:21: error: function definition is not allowed here
void INCREASE (void){
^
main.c:157:21: error: function definition is not allowed here
void DECREASE (void){
^
11 errors generated.
Heres my state machine coding:
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/device_config.h"
int ENTER; // for entering programming from maincode
int EXIT; // for exiting programming and returning to maincode
int Reset; // to reset the speed and return to main code
int INCREASE; // to increase the speed while in programming
int DECREASE; // to decrease the speed while in programming
int events;
void ENTER (void);
void EXIT (void);
void Reset (void);
void INCREASE (void);
void DECREASE (void);
void main(void) {
enum states { // this state machine will have 2 states
MAINCODE, // main code where it will sit most of the time
PROGRAMMING, // and then programming which is used to change the speed
} state;
enum events { // we will have 5 events
ENTER, // for entering programming from maincode
EXIT, // for exiting programming and returning to maincode
RESET, // to reset the speed and return to main code
INCREASE, // to increase the speed while in programming
DECREASE, // to decrease the speed while in programming
};
void step_state(enum events event) { // not sure what to write here??? what is step_state? why enum events event?
switch(state) { // the switch is done by a change of state
case MAINCODE: // while in maincode
switch(event) { // and the enter event is initiated
case ENTER: // enter programming
state = PROGRAMMING; // to do this we change the state
break; // break to jump into that state
default: // if something messes up, the default instruction
state = MAINCODE; // is to go back into the maincode
break;
}
break;
case PROGRAMMING: // while in programming state
switch(event) { // and an event is triggered
case EXIT: // which happens to be exit
state = MAINCODE; // enter maincode
break;
case RESET:
// add code to revert default speed value
state = MAINCODE; // then enter maincode
break;
case INCREASE:
// add code for increasing speed
break;
case DECREASE:
// add code for decreasing speed
break;
default:
state = MAINCODE;
break;
}
break;
}
}
if (button == 0){
event = ENTER;
}
void ENTER (void){
state = PROGRAMMING;
}
if (button == 0){
event = EXIT;
}
void EXIT (void){
state = MAINCODE;
}
if (button == 0 && but1 == 0){
event = Reset;
}
void Reset (void){
value = default;
state = MAINCODE;
}
if (but1 == 0){
event = INCREASE;
}
void INCREASE (void){
// add code to increase speed
}
if (but2 == 0){
event = DECREASE;
}
void DECREASE (void){
// add code to decrease speed
}
while (1)
{
}
}
Upvotes: 0
Views: 247
Reputation: 61
I am not seeing an error regarding your "events" variable, and I am not aware of it being a keyword. As for the other errors, you have a few namespace issues going on. When a enum is defined, it tells the compiler to use the specified key words in place for a number to help make your source code more maintainable. The enum implicitly sets the type of these keywords to "int" making the following lines unnecessary and causes a name collision.
int ENTER; // for entering programming from maincode
int EXIT; // for exiting programming and returning to maincode
int Reset; // to reset the speed and return to main code
int INCREASE; // to increase the speed while in programming
int DECREASE; // to decrease the speed while in programming
Even with these lines removed, the compiler is getting confused because your state functions are sharing the same name as your states in your "events" enumeration. If instead you rename your state functions INCREASE_func(), DECREASE_func(), etc. it will resolve the issue. here is a good source of implemented state machine code in C.
Upvotes: 1
Reputation: 93466
So i think im pretty much there, [...] My question is how to i switch between the states? How do i change an event?
Surely your question is why am I getting all these errors?! You are clearly a lot further from "pretty much there" than you think. Get valid code that compiles (i.e. learn to write valid C code) first - then ask about how to make the state machine work if it does not. Otherwise all these other errors are just a distraction - you are not even close to "pretty much there" is it does not compile so you can run, test and debug it. In fact so much so I am going to ignore your question and address the code validity. When you get the build working, ask a new question if necessary about how to make it work - or better use your debugger and figure it out for yourself.
The error messages seem pretty clear:
main.c:33:6: error: redefinition of 'ENTER' as different kind of symbol
void ENTER (void);
^
main.c:26:5: note: previous definition is here
int ENTER; // for entering programming from maincode
Line 33 has a definition for a function called ENTER
, but ENTER
is previously defined as an int
variable at line 26. It is telling you not to use the same name twice (at least not in the same scope).
In fact the symbol ENTER
(for example - the same error for other symbols) is defined three times for different things:
An integer variable:
int ENTER; // for entering programming from maincode
A function:
void ENTER (void);
An enum constant:
enum events { // we will have 5 events
ENTER, // for entering programming from maincode
It is generally a bad idea to us the same symbol name for multiple purposes and in most cases it is ambiguous so the compiler cannot determine which to use.
In this case you should use lower or CamelCase for the function names - conventionally upper case is used for constants. Somewhat inconsistently you already have a Reset()
function - you used a different naming convention elsewhere. Caution however because exit()
is the name of a function in the standard library.
The variable int ENTER;
and the other similarly declared variables do not appear to be used and can probably be deleted - that then removes the ambiguity with the enum
constants.
Apart from that, the code posted is not the code that generated the errors posted - it has numerous other issues and the line number references in the diagnostics do not align with the code posted. Specifically:
button
, event
, but1
, but2
and value
(a particularly poor name for a variable BTW - they are all "values").event = Reset;
is invalid, event
is undefined, but context suggests that it should be an enum events
object, in which case perhaps RESET
was intended?value = default ;
is invalid because default
is a reserved keyword for a switch case label. It is not clear what you might have intended here, because value
is undefined and this is the only place you have referenced it.Upvotes: 3
Reputation: 127
You're trying to redefine an already used symbol, like ENTER.. You can't name your variables the same as the methods, because the compiler is getting confused and it also doesn't make much sense for anyone
You could also use a enum type to create your state machine
enum EventType {
EVENT_NONE,
EVENT_EXAMPLE
};
struct State {
enum EventType last_event;
};
int main(void) {
struct State state = { .last_event = EVENT_NONE }
// do what you want to do....
{
if (state.last_event == EVENT_EXAMPLE) {
// do what you want
}
}
}
Upvotes: 0