/*
Forum: https://forum.arduino.cc/t/two-limit-switches-and-a-gear-motor/1159503/21
Wokwi: https://wokwi.com/projects/374131876712793089
Changed the position sensing in the separate boolean functions
barrierIsDown()
barrierIsUp()
from limit switches to angle measurement
*/
// ********* Simulation Components Declarations *********
#include <Adafruit_NeoPixel.h>
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 touchSwitchPin = 2; // UNO Pin 2
/*
// This should be more appropriate for the real thing
constexpr int barrierDownValue = 512 - 1024.0/320*45; // middle value minus equivalent for 45 degrees
constexpr int barrierUpValue = 512 + 1024.0/320*45; // middle value plus equivalent for 45 degrees
*/
// Just to use the complete slider ...
constexpr int barrierDownValue = 0;
constexpr int barrierUpValue = 1023;
uint8_t touchSwitch;
uint8_t prevTouchSwitch;
#define AIN1 3
#define AIN2 4
void setup() {
// ********************************************************
// ***********Simulation Components Setup******************
simulationSetup();
// *******End of Simulation Components Setup **************
// ********************************************************
Serial.begin(9600);
pinMode( touchSwitchPin, INPUT_PULLUP );
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
delay(100);
touchSwitch = digitalRead( touchSwitchPin );
prevTouchSwitch = touchSwitch;
// determine the initial barrier position
if ( barrierIsUp() && barrierIsDown() ) {
Serial.println(F("ERROR - both limit switches activated"));
while (1);
}
else if ( !barrierIsUp() && !barrierIsDown() ) {
barrierState = UNKNOWN;
Serial.println(F("BARRIER POSITION UNKNOWN"));
Serial.println(F("Please move barrier (slider) upwards"));
}
else if ( barrierIsUp() ) {
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();
// ********************************************************
switch ( barrierState ) {
case UNKNOWN:
digitalWrite(AIN2, HIGH);
if ( barrierIsUp() ) {
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"));
Serial.println(F("Please move barrier (slider) upwards"));
barrierState = GOING_UP;
}
break;
case GOING_UP:
if ( barrierIsUp() ) {
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"));
Serial.println(F("Please move barrier (slider) downwards"));
barrierState = GOING_DOWN;
}
break;
case GOING_DOWN:
if ( barrierIsDown() ) {
digitalWrite(AIN1, LOW);
Serial.println(F("BARRIER DOWN"));
barrierState = DOWN;
}
break;
}
prevTouchSwitch = touchSwitch;
}
boolean barrierIsDown() {
return (barrierPosition() <= barrierDownValue);
// return !digitalRead( downLimitSwitchPin );
}
boolean barrierIsUp() {
return (barrierPosition() >= barrierUpValue);
// return !digitalRead( upLimitSwitchPin );
}
int barrierPosition(){
return analogRead(A0);
}
// ********************************************************
// **************** Simulation functions ******************
// ********************************************************
//
void simulationSetup() {
strip1.begin();
strip1.clear();
strip1.setBrightness(255);
strip1.show();
simPosition = getSimPosition();
}
int getSimPosition(){
int pos = barrierPosition();
if (pos <= barrierDownValue) {pos = barrierDownValue;};
if (pos >= barrierUpValue) {pos = barrierUpValue;};
return map(pos,barrierDownValue,barrierUpValue,0,15);
}
// Reads slide position only and
// controls barrier position
void barrierSimulation() {
simGoing();
}
// Moves Led position every 300 msec up or down
void simGoing() {
static unsigned long lastMove;
if (millis() - lastMove >= 300) {
lastMove = millis();
strip1.setPixelColor(simPosition, 0, 0, 0);
simPosition = getSimPosition();
strip1.setPixelColor(simPosition, 255, 0, 0);
strip1.show();
}
}