/*
Forum: https://forum.arduino.cc/t/two-limit-switches-and-a-gear-motor/1159503/21
Wokwi: https://wokwi.com/projects/373407825895140353
*/
// ********* Simulation Components Declarations *********
#include <Adafruit_NeoPixel.h>
constexpr byte simUpLimitPin = 8;
constexpr byte simDownLimitPin = 9;
constexpr byte simBarrierPin = 7;
const uint16_t NUMPIXELS1 = 16;
Adafruit_NeoPixel strip1(NUMPIXELS1, simBarrierPin, NEO_GRB + NEO_KHZ800);
int simPosition = 0;
// ********* End of Simulation Components Declarations *********
enum barrierStates {
UNKNOWN,
DOWN,
GOING_UP,
UP,
GOING_DOWN
};
enum barrierStates barrierState;
const uint8_t upLimitSwitchPin = 5; // UNO pin 5
const uint8_t downLimitSwitchPin = 6; // UNO pin 6
const uint8_t touchSwitchPin = 2; // UNO Pin 2
uint8_t upLimitSwitch;
uint8_t downLimitSwitch;
uint8_t touchSwitch;
uint8_t prevTouchSwitch;
#define AIN1 3
#define AIN2 4
void setup() {
// ******************Simulation Components Setup******************
strip1.begin();
strip1.clear();
strip1.setBrightness(255);
strip1.show();
pinMode(simUpLimitPin, OUTPUT);
pinMode(simDownLimitPin, OUTPUT);
digitalWrite(simUpLimitPin, HIGH);
digitalWrite(simDownLimitPin, HIGH);
randomSeed(analogRead(A0));
simPosition = random(0,16);
// ***************End of Simulation Components Setup******************
Serial.begin(9600);
pinMode( upLimitSwitchPin, INPUT_PULLUP );
pinMode( downLimitSwitchPin, INPUT_PULLUP );
pinMode( touchSwitchPin, INPUT_PULLUP );
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
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() {
// assume HIGH = switch touched
touchSwitch = digitalRead( touchSwitchPin );
// ******** Simulation of barrier by Neopixel Ring *********
barrierSimulation();
// ******** End of Simulation of barrier by Neopixel Ring ****
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;
}
// **************** Simulation functions ******************
//
// Reads motor control pins and
// controls simulation direction
void barrierSimulation() {
byte motorDown = digitalRead(AIN1);
byte motorUp = digitalRead(AIN2);
if (motorDown && motorUp) {
Serial.println("Error");
while (1);
}
if (motorDown) {
simGoing(-1);
}
if (motorUp) {
simGoing(1);
}
}
// Moves Led position every 500 msec right or left
// Turning Left -> simulates upwards
// Turning Right -> simulates downwards
void simGoing(int direction) {
static unsigned long lastMove;
if (millis() - lastMove >= 500) {
lastMove = millis();
strip1.setPixelColor(simPosition, 0, 0, 0);
simPosition += direction;
if (simPosition < 0) {
simPosition = 0;
}
if (simPosition > 15) {
simPosition = 15;
}
strip1.setPixelColor(simPosition, 255, 0, 0);
strip1.show();
}
switch (simPosition) {
case 0 : digitalWrite(simDownLimitPin, LOW); // Simulates Down Limit Switch Closed
break;
case 15 : digitalWrite(simUpLimitPin, LOW); // Simulates Up Limit Switch Closed
break;
default:
digitalWrite(simUpLimitPin, HIGH); // Simulates both limit Switches Open
digitalWrite(simDownLimitPin, HIGH);
}
}