summaryrefslogtreecommitdiff
path: root/c/elevator/elevator.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/elevator/elevator.c')
-rw-r--r--c/elevator/elevator.c230
1 files changed, 230 insertions, 0 deletions
diff --git a/c/elevator/elevator.c b/c/elevator/elevator.c
new file mode 100644
index 0000000..845a57e
--- /dev/null
+++ b/c/elevator/elevator.c
@@ -0,0 +1,230 @@
+/* Conway's Game of Life for RVController
+ * A product of Advanced Mesecons Devices, a Cheapie Systems company
+ * This is free and unencumbered software released into the public domain.
+ * See http://unlicense.org/ for more information */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "rvcontroller-ecalls.h"
+#include "states.h"
+
+int state = STATE_INIT;
+bool sensor1state = false;
+bool sensor2state = false;
+bool sensor3state = false;
+bool call1state = false;
+bool call2state = false;
+bool call3state = false;
+int direction = DIRECTION_UP;
+int timer;
+
+char channelbuf[16];
+char msgbuf[64];
+
+bool streq(char *a, char *b) {
+ for (int i=0;a[i] != 0 || b[i] != 0;i++) {
+ if (a[i] != b[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void sleep(uint32_t delay) {
+ //This will start having problems after about 130 years
+ //of uptime, but that's probably acceptable
+ uint32_t endtime = rdtime() + delay;
+ while (rdtime() < endtime) {}
+ return;
+}
+
+void sendSensorGetMessages(void) {
+ digiline_send("sensor1","GET");
+ digiline_send("sensor2","GET");
+ digiline_send("sensor3","GET");
+}
+
+void processDigilinesMessages(void) {
+ while (digiline_bufferlevel() > 0) {
+ digiline_receive(channelbuf,16,msgbuf,64);
+ if (streq(channelbuf,"sensor1")) {
+ sensor1state = (streq(msgbuf,"mesecons_movestones:movestone_vertical"));
+ } else if (streq(channelbuf,"sensor2")) {
+ sensor2state = (streq(msgbuf,"mesecons_movestones:movestone_vertical"));
+ } else if (streq(channelbuf,"sensor3")) {
+ sensor3state = (streq(msgbuf,"mesecons_movestones:movestone_vertical"));
+ } else if (streq(channelbuf,"button1") && (state != STATE_TIMING_1) && (state != STATE_IDLE_1)) {
+ call1state = true;
+ digiline_send("button1","light_on");
+ } else if (streq(channelbuf,"button2") && (state != STATE_TIMING_2) && (state != STATE_IDLE_2)) {
+ call2state = true;
+ digiline_send("button2","light_on");
+ } else if (streq(channelbuf,"button3") && (state != STATE_TIMING_3) && (state != STATE_IDLE_3)) {
+ call3state = true;
+ digiline_send("button3","light_on");
+ }
+ }
+}
+
+void main(void) {
+ while (true) {
+ sendSensorGetMessages();
+ processDigilinesMessages();
+ switch (state) {
+ case STATE_INIT:
+ printstr("\nElevator Controller\nfor RVController\nInitializing");
+ digiline_send("door1","extend");
+ digiline_send("door2","extend");
+ digiline_send("door3","extend");
+ digiline_send("sel","extend");
+ digiline_send("down","extend");
+ digiline_send("up","retract_sticky");
+ digiline_send("button1","light_off");
+ digiline_send("button2","light_off");
+ digiline_send("button3","light_off");
+ printstr("\nBottom Floor Demand");
+ state = STATE_BOTTOM_FLOOR_DEMAND;
+ break;
+ case STATE_BOTTOM_FLOOR_DEMAND:
+ if (sensor1state) {
+ printstr("\nBFD Complete");
+ digiline_send("down","retract_sticky");
+ digiline_send("door1","retract_sticky");
+ state = STATE_TIMING_1;
+ timer = 5;
+ }
+ break;
+ case STATE_TIMING_1:
+ timer--;
+ if (timer <= 0) {
+ printstr("\nIdle at 1");
+ state = STATE_IDLE_1;
+ }
+ break;
+ case STATE_TIMING_2:
+ timer--;
+ if (timer <= 0) {
+ printstr("\nIdle at 2");
+ state = STATE_IDLE_2;
+ }
+ break;
+ case STATE_TIMING_3:
+ timer--;
+ if (timer <= 0) {
+ printstr("\nIdle at 3");
+ state = STATE_IDLE_3;
+ }
+ break;
+ case STATE_IDLE_1:
+ if (call2state) {
+ direction = DIRECTION_UP;
+ printstr("\nMoving to 2");
+ state = STATE_MOVING_2;
+ digiline_send("door1","extend");
+ digiline_send("sel","retract_sticky");
+ digiline_send("up","extend");
+ } else if (call3state) {
+ direction = DIRECTION_UP;
+ printstr("\nMoving to 3");
+ state = STATE_MOVING_3;
+ digiline_send("door1","extend");
+ digiline_send("sel","extend");
+ digiline_send("up","extend");
+ }
+ break;
+ case STATE_IDLE_2:
+ if (direction == DIRECTION_UP) {
+ if (call3state) {
+ direction = DIRECTION_UP;
+ printstr("\nMoving to 3");
+ state = STATE_MOVING_3;
+ digiline_send("door2","extend");
+ digiline_send("sel","extend");
+ digiline_send("up","extend");
+ } else if (call1state) {
+ direction = DIRECTION_DOWN;
+ printstr("\nMoving to 1");
+ state = STATE_MOVING_1;
+ digiline_send("door2","extend");
+ digiline_send("sel","extend");
+ digiline_send("down","extend");
+ }
+ } else {
+ if (call1state) {
+ direction = DIRECTION_DOWN;
+ printstr("\nMoving to 1");
+ state = STATE_MOVING_1;
+ digiline_send("door2","extend");
+ digiline_send("sel","extend");
+ digiline_send("down","extend");
+ } else if (call3state) {
+ direction = DIRECTION_UP;
+ printstr("\nMoving to 3");
+ state = STATE_MOVING_3;
+ digiline_send("door2","extend");
+ digiline_send("sel","extend");
+ digiline_send("up","extend");
+ }
+ }
+ break;
+ case STATE_IDLE_3:
+ if (call2state) {
+ direction = DIRECTION_DOWN;
+ printstr("\nMoving to 2");
+ state = STATE_MOVING_2;
+ digiline_send("door3","extend");
+ digiline_send("sel","retract_sticky");
+ digiline_send("down","extend");
+ } else if (call1state) {
+ direction = DIRECTION_DOWN;
+ printstr("\nMoving to 1");
+ state = STATE_MOVING_1;
+ digiline_send("door3","extend");
+ digiline_send("sel","extend");
+ digiline_send("down","extend");
+ }
+ break;
+ case STATE_MOVING_1:
+ if (sensor1state) {
+ printstr("\nArrived at 1");
+ digiline_send("button1","light_off");
+ direction = DIRECTION_UP;
+ digiline_send("down","retract_sticky");
+ digiline_send("door1","retract_sticky");
+ timer = 5;
+ state = STATE_TIMING_1;
+ call1state = false;
+ }
+ break;
+ case STATE_MOVING_2:
+ if (sensor2state) {
+ printstr("\nArrived at 2");
+ digiline_send("button2","light_off");
+ digiline_send("up","retract_sticky");
+ digiline_send("down","retract_sticky");
+ digiline_send("door2","retract_sticky");
+ timer = 5;
+ state = STATE_TIMING_2;
+ call2state = false;
+ }
+ break;
+ case STATE_MOVING_3:
+ if (sensor3state) {
+ printstr("\nArrived at 3");
+ digiline_send("button3","light_off");
+ direction = DIRECTION_DOWN;
+ digiline_send("up","retract_sticky");
+ digiline_send("door3","retract_sticky");
+ timer = 5;
+ state = STATE_TIMING_3;
+ call3state = false;
+ }
+ break;
+ }
+ if ((state == STATE_IDLE_1) || (state == STATE_IDLE_2) || (state == STATE_IDLE_3)) {
+ lightweight_mode(1);
+ sleep(1);
+ lightweight_mode(0);
+ }
+ }
+}