Last active
November 9, 2021 15:52
-
-
Save svavassori/431e78c2d9f1ff55adb63623408eb033 to your computer and use it in GitHub Desktop.
Bee counter that is based on state transition instead of elapsed time
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <string.h> | |
typedef enum { | |
EMPTY, | |
START_ENTERING, // bee is entering the gate from outside, so it's entering | |
MIDDLE_ENTERING, | |
END_ENTERING, // bee is almost all inside | |
START_EXITING, // bee is entering the gate from inside, so it's exiting | |
MIDDLE_EXITING, | |
END_EXITING, // bee is almost all outside | |
ERROR_STATE | |
} State; | |
typedef enum { | |
LOW, // there is no bee | |
HIGH // there is a bee | |
} Gate_Sensor; | |
const State transition_table[8][2][2] = { | |
[EMPTY][LOW][LOW] = EMPTY, | |
[EMPTY][LOW][HIGH] = START_ENTERING, | |
[EMPTY][HIGH][LOW] = START_EXITING, | |
[EMPTY][HIGH][HIGH] = ERROR_STATE, | |
// inbound pattern | |
[START_ENTERING][LOW][LOW] = EMPTY, | |
[START_ENTERING][LOW][HIGH] = START_ENTERING, | |
[START_ENTERING][HIGH][LOW] = ERROR_STATE, | |
[START_ENTERING][HIGH][HIGH] = MIDDLE_ENTERING, | |
[MIDDLE_ENTERING][LOW][LOW] = ERROR_STATE, | |
[MIDDLE_ENTERING][LOW][HIGH] = START_ENTERING, | |
[MIDDLE_ENTERING][HIGH][LOW] = END_ENTERING, | |
[MIDDLE_ENTERING][HIGH][HIGH] = MIDDLE_ENTERING, | |
[END_ENTERING][LOW][LOW] = EMPTY, // a bee has entered | |
[END_ENTERING][LOW][HIGH] = ERROR_STATE, | |
[END_ENTERING][HIGH][LOW] = END_ENTERING, | |
[END_ENTERING][HIGH][HIGH] = MIDDLE_ENTERING, | |
// outbound pattern | |
[START_EXITING][LOW][LOW] = EMPTY, | |
[START_EXITING][LOW][HIGH] = ERROR_STATE, | |
[START_EXITING][HIGH][LOW] = START_EXITING, | |
[START_EXITING][HIGH][HIGH] = MIDDLE_EXITING, | |
[MIDDLE_EXITING][LOW][LOW] = ERROR_STATE, | |
[MIDDLE_EXITING][LOW][HIGH] = END_EXITING, | |
[MIDDLE_EXITING][HIGH][LOW] = START_EXITING, | |
[MIDDLE_EXITING][HIGH][HIGH] = MIDDLE_EXITING, | |
[END_EXITING][LOW][LOW] = EMPTY, // a bee has exited | |
[END_EXITING][LOW][HIGH] = END_EXITING, | |
[END_EXITING][HIGH][LOW] = ERROR_STATE, | |
[END_EXITING][HIGH][HIGH] = MIDDLE_EXITING, | |
// Error state stays in Error state | |
[ERROR_STATE][LOW][LOW] = EMPTY, // gate is empty again, reset | |
[ERROR_STATE][LOW][HIGH] = ERROR_STATE, | |
[ERROR_STATE][HIGH][LOW] = ERROR_STATE, | |
[ERROR_STATE][HIGH][HIGH] = ERROR_STATE | |
}; | |
uint32_t entered = 0; | |
uint32_t exited = 0; | |
static State next_state(State current, uint8_t inner, uint8_t outer) | |
{ | |
State next = transition_table[current][inner][outer]; | |
if (next == EMPTY) { | |
if (current == END_ENTERING) { | |
entered++; | |
printf("A bee has entered\n"); | |
} else if (current == END_EXITING) { | |
exited++; | |
printf("A bee has exited\n"); | |
} | |
} else if (next == ERROR_STATE) { | |
// two bits are flipped at the same time (Hamming distance = 2), shouldn't happen | |
printf("Problem with transition on state %d: inner %d, outer %d\n", current, inner, outer); | |
} | |
return next; | |
} | |
int main(int argc, char *argv[]) { | |
// this is for one gate, just extend the array | |
State current[] = { EMPTY }; | |
// temporal sequence of a single gate | |
// e.g. entering bee: 00,01,11,10,00 | |
char *token = strtok(argv[1], ","); | |
while (token != NULL) { | |
uint8_t inner = *token == '0' ? 0 : 1; | |
uint8_t outer = *(token + 1) == '0' ? 0 : 1; | |
current[0] = next_state(current[0], inner, outer); | |
token = strtok(NULL, ","); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment