/* 3-floor Elevator Controller 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 #include #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[8]; char uplanternon[] = "55ff55"; char uplanternoff[] = "003300"; char downlanternon[] = "ff5555"; char downlanternoff[] = "330000"; 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,8); if (streq(channelbuf,"sensor1")) { sensor1state = (streq(msgbuf,"mesecon")); } else if (streq(channelbuf,"sensor2")) { sensor2state = (streq(msgbuf,"mesecon")); } else if (streq(channelbuf,"sensor3")) { sensor3state = (streq(msgbuf,"mesecon")); } 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"); digiline_send("lantern1up",uplanternoff); digiline_send("lantern2up",uplanternoff); digiline_send("lantern2down",downlanternoff); digiline_send("lantern3down",downlanternoff); 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; digiline_send("lantern1up",uplanternon); digiline_send("chime1","celevator_chime_up"); } 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"); digiline_send("lantern1up",uplanternoff); } 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"); digiline_send("lantern1up",uplanternoff); } 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"); digiline_send("lantern2up",uplanternoff); digiline_send("lantern2down",downlanternoff); } 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"); digiline_send("lantern2up",uplanternoff); digiline_send("lantern2down",downlanternoff); } } 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"); digiline_send("lantern2up",uplanternoff); digiline_send("lantern2down",downlanternoff); } 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"); digiline_send("lantern2up",uplanternoff); digiline_send("lantern2down",downlanternoff); } } 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"); digiline_send("lantern3down",downlanternoff); } 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"); digiline_send("lantern3down",downlanternoff); } 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"); digiline_send("lantern1up",uplanternon); digiline_send("chime1","celevator_chime_up"); 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"); if (direction == DIRECTION_UP) { digiline_send("lantern2up",uplanternon); digiline_send("chime2","celevator_chime_up"); } else { digiline_send("lantern2down",downlanternon); digiline_send("chime2","celevator_chime_down"); } 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"); digiline_send("lantern3down",downlanternon); digiline_send("chime3","celevator_chime_down"); 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); } } }