// https://wokwi.com/projects/373410350749940737
// https://forum.arduino.cc/t/two-limit-switches-and-a-gear-motor/1159503
enum barrierStates {
UNKNOWN,
DOWN,
GOING_UP,
UP,
GOING_DOWN
};
enum barrierStates barrierState;
const uint8_t upLimitSwitchPin = 5; // UNO pin 4
const uint8_t downLimitSwitchPin = 6; // UNO pin 5
const uint8_t touchSwitchPin = 2; // UNO Pin 6
uint8_t upLimitSwitch;
uint8_t downLimitSwitch;
uint8_t touchSwitch;
uint8_t prevTouchSwitch;
#define AIN1 3
#define AIN2 4
void setup() {
Serial.begin(9600);
pinMode( upLimitSwitchPin, INPUT_PULLUP );
pinMode( downLimitSwitchPin, INPUT_PULLUP );
pinMode( touchSwitchPin, INPUT_PULLUP );
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
setupSimulatedDoor();
runSimulatedDoor(); // step the machine so inouts and outpus make sense
delay(100);
touchSwitch = digitalRead( touchSwitchPin );
prevTouchSwitch = touchSwitch;
// a HIGH here means the limit switch is open
upLimitSwitch = digitalRead( upLimitSwitchPin );
downLimitSwitch = digitalRead( downLimitSwitchPin );
// determine the initial barrier position
if ( upLimitSwitch == LOW && downLimitSwitch == LOW ) {
Serial.println(F("ERROR - both limit switches activated"));
while (1);
}
else if ( upLimitSwitch == HIGH && downLimitSwitch == HIGH ) {
barrierState = UNKNOWN;
Serial.println(F("BARRIER POSITION UNKNOWN"));
}
else if ( upLimitSwitch == LOW ) {
Serial.println(F("BARRIER UP"));
barrierState = UP;
}
else {
Serial.println(F("BARRIER DOWN"));
barrierState = DOWN;
}
}
void loop() {
runSimulatedDoor();
// assume HIGH = switch touched
touchSwitch = digitalRead( touchSwitchPin );
switch ( barrierState ) {
case UNKNOWN:
digitalWrite(AIN2,HIGH);
upLimitSwitch = digitalRead( upLimitSwitchPin );
if ( upLimitSwitch == LOW ) {
digitalWrite(AIN2,LOW);
Serial.println(F("BARRIER UP"));
barrierState = UP;
}
break;
case DOWN:
if (( touchSwitch != prevTouchSwitch ) && ( touchSwitch == HIGH ) ) {
digitalWrite(AIN2,HIGH);
Serial.println(F("BARRIER GOING UP"));
barrierState = GOING_UP;
}
break;
case GOING_UP:
upLimitSwitch = digitalRead( upLimitSwitchPin );
if ( upLimitSwitch == LOW ) {
digitalWrite(AIN2,LOW);
Serial.println(F("BARRIER UP"));
barrierState = UP;
}
break;
case UP:
if (( touchSwitch != prevTouchSwitch ) && ( touchSwitch == HIGH ) ) {
digitalWrite(AIN1,HIGH);
Serial.println(F("BARRIER GOING DOWN"));
barrierState = GOING_DOWN;
}
break;
case GOING_DOWN:
downLimitSwitch = digitalRead( downLimitSwitchPin );
if ( downLimitSwitch == LOW ) {
digitalWrite(AIN1,LOW);
Serial.println(F("BARRIER DOWN"));
barrierState = DOWN;
}
break;
}
prevTouchSwitch = touchSwitch;
}
// the only software connection between the control program and the dor simulator
// void setupSimulatedDoor(){} // initilise door sim hardware and variables
// void runSimulatedDoor(){} // step the door according to inputs and position, mimic limit switches at extremes
// below here finds itself the door simulation machinery
# define sDoorDown A1
# define sDoorUp A2
# define doorX A0
# define sDoorDownMotorPin A3
# define sDoorUpMotorPin A4
# define door
# include <Adafruit_NeoPixel.h>
# define PIN 8 // the pin
# define NPIXELS 17 // number of LEDs on strip
Adafruit_NeoPixel doorBar(NPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int lPosition = 6; // sim door starts at 6
unsigned char dir = 1; // moving up. or is true down?
void setupSimulatedDoor()
{
pinMode(sDoorDown, OUTPUT);
pinMode(sDoorUp, OUTPUT);
pinMode(sDoorDownMotorPin, INPUT);
pinMode(sDoorUpMotorPin, INPUT);
doorBar.begin();
doorBar.setPixelColor(2, 0xff0000);
doorBar.show();
delay(777);
}
void runSimulatedDoor()
{
// int doorPosition = analogRead(A0);
// delay(20);
// digitalWrite(sDoorDown, doorPosition < 100 ? LOW : HIGH); // active low
// digitalWrite(sDoorUp, doorPosition > 923 ? LOW : HIGH);
static unsigned long lastTime;
if (millis() - lastTime < 733) return;
lastTime = millis();
if (0) { // test - door will just cycle up and down all by itself
lPosition += dir ? -1 : 1;
if ((lPosition == -1) || (lPosition == NPIXELS)) dir = !dir;
}
else { // read the main code outputs and run the door if
if (digitalRead(sDoorDownMotorPin)) lPosition--;
if (digitalRead(sDoorUpMotorPin)) lPosition++;
}
if (lPosition == -1) lPosition = 0;
if (lPosition == NPIXELS) lPosition = NPIXELS - 1;
// argh! Serial.println(lPosition); delay(777);
digitalWrite(sDoorDown, lPosition == 0 ? LOW : HIGH);
digitalWrite(sDoorUp, lPosition == NPIXELS - 1 ? LOW : HIGH);
// moved the output section here to keep everything in phase:
doorBar.clear();
doorBar.setPixelColor(lPosition, 0xff0000);
doorBar.show();
}
/* was actually higher in the source code
void runSimulatedDoorNew()
{
static int lPosition = 7;
int doorPosition = analogRead(A0);
// delay(20);
digitalWrite(sDoorDown, lPosition <= 1 ? LOW : HIGH); // active low
digitalWrite(sDoorUp, lPosition >= 13 ? LOW : HIGH);
static unsigned long lastTime;
if (millis() - lastTime < 100) return;
lastTime = millis();
static unsigned char dir;
doorBar.clear();
doorBar.setPixelColor(lPosition, 0xff0000);
doorBar.show();
if (0) {
lPosition += dir ? -1 : 1;
if ((lPosition == -1) || (lPosition == NPIXELS)) dir = !dir;
}
else {
if (digitalRead(doorDownMotorPin)) lPosition--;
if (digitalRead(doorUpMotorPin)) lPosition++;
}
if (lPosition == -1) lPosition = 0;
if (lPosition == NPIXELS) lPosition = NPIXELS - 1;
}
*/
UP LIMIT
DOWN LIMIT
MOTOR UP
MOTOR DOWN