help using a rotary encoder to store a limit and turn off a relay and a LED on

My aim is to measure the rotations of a winch using a rotary encoder and use a toggle switch (or should i use a momentary switch) to set a limit at the current encoder reading. There will be 3 display LEDs red, green, and yellow which I would like to use as indicators. Green it is far away from the limit, yellow it is getting close, and at red it cuts a relay off that is running the winch so it wont be able to go past the set limit. I am using a 7 segment display to show the values of the encoder and that portion of the code works. Any help would be appreciated, when i run the code the green Led should come on and it doesn't, and the it seems to be really buggy.

/* Encoder-7 seg Display Program
 * This program is designed by Rip Martin on 11/8/2013
 * This program is proprietary and should not be used
 * or sold without the written consent of the creator.
 */
 
 #include <Encoder.h>              // Includes the Encoder library, need to download
 #include <SoftwareSerial.h>       // Includes the Software Serial library
 
 SoftwareSerial Serial7Segment(7, 8); // RX pin, TX pin
 Encoder myEnc(2, 3);                 // Pins 2,3
 
 int redLed = 4;                      // Red LED pin (output)
 int greLed = 5;                      // Green LED pin  (output)
 int topSwitch = 9;                   // Top limit toggle switch (input)
 int botSwitch = 10;                  // Bottom limit toggle switch (input)
 
 int limitTop = -5;                   // Top (Start) limit position
 int limitBot = 10000;                // Bottom (End) Limit position
 int saftey = 0;
 boolean tSwitch = false;
 boolean bSwitch = false;

void setup() {
   Serial.begin(9600);
  Serial.println("Basic Encoder Test:");
  
  pinMode(redLed, OUTPUT);
  pinMode(greLed, OUTPUT);
  pinMode(topSwitch, INPUT);
  pinMode(botSwitch, INPUT);  
  
  redLed = LOW;
  greLed = HIGH;
  
  Serial7Segment.begin(9600); // Talk to the Serial7Segment at 9600 bps
  Serial7Segment.write('v'); // Reset the display - this forces the cursor 
                             // to return to the beginning of the display
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read()/800;
  
  char tempString[10]; //Used for sprintf
  sprintf(tempString, "%4d", newPosition); // right adjusted
  
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
    Serial7Segment.print(tempString); //Send serial string out
  }
  
  if (digitalRead(topSwitch) == HIGH){
    if(tSwitch == false){
      tSwitch = !tSwitch;
      limitTop = myEnc.read();
      Serial.println("Top Limit Set At:");
      Serial.println(limitTop/800);
    }
  }
  else{
    tSwitch = false;
  }
  
   if (digitalRead(botSwitch) == HIGH){
    if(bSwitch == false){
      bSwitch = !bSwitch;
      limitBot = myEnc.read();
      Serial.println("Bottom Limit Set At:");
      Serial.println(limitBot/800);
    }
  }
  else{
    bSwitch = false;
  }
  
  if (digitalRead(topSwitch == HIGH) && digitalRead(botSwitch == HIGH)){
    saftey = myEnc.read();
   if (saftey >= limitTop && saftey <= limitBot){
     greLed = HIGH;
     redLed = LOW;
   }
   else if (saftey < limitTop || saftey > limitBot){ 
    greLed = LOW;
    redLed = HIGH;
   }
}

if (digitalRead(topSwitch == LOW) || digitalRead(botSwitch) == LOW){
  tSwitch = false;
  bSwitch = false;
}
}

Thesaint7811:
My aim is to measure the rotations of a wench using a rotary encoder ...

Is she attractive?

at red it cuts a relay off that is running the wench

She must hate that. :slight_smile:

Joking aside, how are these switches wired?

You have:

  if (digitalRead(topSwitch) == HIGH){
... //code to set top limit
  }
  
   if (digitalRead(botSwitch) == HIGH){
... //code to set bottom limit
  }
  
  if (digitalRead(topSwitch == HIGH) && digitalRead(botSwitch == HIGH)){
... // code for normal operation?
  }

I think two of the instances of HIGH in that code should be LOW instead. Which ones depends on how you have wired the switches.

I have both switches connected the same way, one side to the +5 rail on the bread board and the other side of the switch going to the appropriate pin so the when it is on it pulls the pin high

Do you have a resistor from the pin to ground, so as to pull the pin low when the switch is not activated?

sure do

Then surely you should execute the code that updates redLed and greLed when both switches read LOW, instead of when both switches read HIGH.

Also, instead of assigning new values to redLed and greLed, you need to digitalWrite the required value to those pins. Like this:

/* Encoder-7 seg Display Program
 * This program is designed by Rip Martin on 11/8/2013
 * This program is proprietary and should not be used
 * or sold without the written consent of the creator.
 */
 
 #include <Encoder.h>              // Includes the Encoder library, need to download
 #include <SoftwareSerial.h>       // Includes the Software Serial library
 
 SoftwareSerial Serial7Segment(7, 8); // RX pin, TX pin
 Encoder myEnc(2, 3);                 // Pins 2,3
 
//**************** added const to the followng 4 lines
const  int redLed = 4;                      // Red LED pin (output)
const int greLed = 5;                      // Green LED pin  (output)
const int topSwitch = 9;                   // Top limit toggle switch (input)
const int botSwitch = 10;                  // Bottom limit toggle switch (input)
 
 int limitTop = -5;                   // Top (Start) limit position
 int limitBot = 10000;                // Bottom (End) Limit position
 int saftey = 0;
 boolean tSwitch = false;
 boolean bSwitch = false;

void setup() {
   Serial.begin(9600);
  Serial.println("Basic Encoder Test:");
  
  pinMode(redLed, OUTPUT);
  pinMode(greLed, OUTPUT);
  pinMode(topSwitch, INPUT);
  pinMode(botSwitch, INPUT);  
  
//**************** changed the following 2 lines
  digitalWrite(redLed, LOW);
  digitalWrite(greLed, HIGH);
  
  Serial7Segment.begin(9600); // Talk to the Serial7Segment at 9600 bps
  Serial7Segment.write('v'); // Reset the display - this forces the cursor 
                             // to return to the beginning of the display
}

long oldPosition  = -999;

void loop() {
  long newPosition = myEnc.read()/800;
  
  char tempString[10]; //Used for sprintf
  sprintf(tempString, "%4d", newPosition); // right adjusted
  
  if (newPosition != oldPosition) {
    oldPosition = newPosition;
    Serial.println(newPosition);
    Serial7Segment.print(tempString); //Send serial string out
  }
  
  if (digitalRead(topSwitch) == HIGH){
    if(tSwitch == false){
      tSwitch = !tSwitch;
      limitTop = myEnc.read();
      Serial.println("Top Limit Set At:");
      Serial.println(limitTop/800);
    }
  }
  else{
    tSwitch = false;
  }
  
   if (digitalRead(botSwitch) == HIGH){
    if(bSwitch == false){
      bSwitch = !bSwitch;
      limitBot = myEnc.read();
      Serial.println("Bottom Limit Set At:");
      Serial.println(limitBot/800);
    }
  }
  else{
    bSwitch = false;
  }
  
//************** changed HIGH to LOW twice in the following line
  if (digitalRead(topSwitch == LOW) && digitalRead(botSwitch == LOW)){
    saftey = myEnc.read();
   if (saftey >= limitTop && saftey <= limitBot){
//*************** changed the following 2 lines
     digitalWrite(greLed, HIGH);
    digitalWrite( redLed, LOW);
   }
   else if (saftey < limitTop || saftey > limitBot){
//****************** changed the following 2 lines 
    digitalWrite(greLed, LOW);
    digitalWrite(redLed, HIGH);
   }
}

if (digitalRead(topSwitch == LOW) || digitalRead(botSwitch) == LOW){
  tSwitch = false;
  bSwitch = false;
}
}

btw it's more usual to wire switches between the input pin and ground, then you avoid carrying +5V to the switch and you can use the internal pullup resistor.

btw it's more usual to wire switches between the input pin and ground, then you avoid carrying +5V to the switch and you can use the internal pullup resistor.

Isnt there +5v at the switch either way?

I hope you are aware that such (simple) encoder can only indicate / count up / down rotation and by itself cannot give you absolute position, only relative to start.
So it really cannot "store a limit" per your specification.
But you could initialize it by always running to the start and let the limit switch at start reset the position to starting count.