Skip to content

Instantly share code, notes, and snippets.

@svavassori
Last active November 9, 2021 15:52
Show Gist options
  • Save svavassori/431e78c2d9f1ff55adb63623408eb033 to your computer and use it in GitHub Desktop.
Save svavassori/431e78c2d9f1ff55adb63623408eb033 to your computer and use it in GitHub Desktop.
Bee counter that is based on state transition instead of elapsed time
#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