polling with single encoder input?

i am trying to use this 720 count encoder to start counting at the Z index and when it gets to 720 start counting from 0 again. only need one way so i assume only one phase is needed?
right now it is reading either 0 or 1 on the serial monitor depending on position
the index does seem to be working good though on the start

const int encoder = 2;
const int index   = 3;
int timing;

void setup() {

    pinMode(encoder, INPUT_PULLUP);
    pinMode(index,   INPUT_PULLUP);
    Serial.begin(9600);
    while (digitalRead(index)==HIGH){};   //do nothing untill the index goes low
}

void loop() {

   timing=digitalRead(encoder);

   if (index==LOW   ) timing  =1;   //start
   if (encoder==LOW ) timing +=1;   //add 1 degree to timing
   if (encoder==HIGH){}             //do nothing
   if (index==LOW   ) timing  =0;   //when index is low then start counting from 1 again on timing

   Serial.print(timing);
   Serial.println(" degrees");
  
}

You are not reading the encoder input. You are comparing the pin number (3?) to LOW (0).

Try this way:

const byte EncoderDIPin = 2;
const byte IndexDIPin   = 3;
int timing = 0;


void setup()
{
  Serial.begin(1156200);
  while (!Serial) ; // Needed for Leonardo or Micro


  pinMode(EncoderDIPin, INPUT_PULLUP);
  pinMode(IndexDIPin,   INPUT_PULLUP);


  while (digitalRead(IndexDIPin) == HIGH) {}; //do nothing untill the index goes low
}


void loop()
{
  boolean encoderState = digitalRead(EncoderDIPin) == LOW;
  static byte oldEncoderState = true;


  boolean indexState = digitalRead(IndexDIPin) == LOW;
  static byte oldIndexState = HIGH;


  // If the 'index' signal has just gone active (LOW) reset the timer counter
  if (indexState != oldIndexState)
  {
    oldIndexState = indexState;
    if (indexState)
      timing = 0;
  }


  // If the encoder signal has just gone active (LOW) increment the timer counter
  if (encoderState != oldEncoderState)
  {
    oldEncoderState = encoderState;
    if (encoderState)
      timing++;
  }


  //  Display the position each second
  static unsigned long displayTimer = 0;
  if (millis() - displayTimer >= 1000)
  {
    displayTimer = millis();
    Serial.print(timing);
    Serial.println(" degrees");
  }
}

awesome! it works great
strangly i can get up to about 750 counts on a 720 encoder?
i wonder if this is reading some bounce on the counts at low (hand) speed
it would take a lot more code to input the B phase and only count one way?
time to study this ....

turbothis:
i wonder if this is reading some bounce on the counts at low (hand) speed

Probably so. With an encoder you can usually put a small cap (like 0.1uF plus or minus a huge window) across the pin and the center pin and filter out the bounce that way instead of having to code around it.

"across the pin and the center pin "

so on the A phase and where? lol

for learning sake
if there was a piece of code that was like

if A phase goes high, followed by B phase goes high
then do function

if A phase goes high, followed by B phase going low
then ignore function

this would make a one way counter right?

also is there a way to have the print function only print if something new happens? or is it always running?

turbothis:
"across the pin and the center pin "

so on the A phase and where? lol

You got three pins on the encoder. A pin, a B pin, and the third pin usually goes to ground. Sometimes it goes to hot, but usually goes to ground. So 99% chance I mean between the A pin and ground. And another on the B pin and ground if you want to read it.

turbothis:
for learning sake
if there was a piece of code that was like

if A phase goes high, followed by B phase goes high
then do function

if A phase goes high, followed by B phase going low
then ignore function

You could do that by recording the value from millis so at any transition you can see how long it has been since the last.

But you don't need to do that.

Look at how the gray code on an encoder looks. All you need to do is read the other pin. If the two pins match then you're going one way and if it doesn't then you're going the other way. A quick bit of experimentation with your particular encoder will help you determine which way is which. You just need to know if you are the leading or the lagging pin, and to do that all you need to know is if the other pin beat you to this state.

Adding debounce to the encoder signal:

void loop()
{
  unsigned long currentMillis = milis();
  
  boolean encoderState = digitalRead(EncoderDIPin) == LOW;
  static byte oldEncoderState = true;


  boolean indexState = digitalRead(IndexDIPin) == LOW;
  static byte oldIndexState = HIGH;


  // If the 'index' signal has just gone active (LOW) reset the timer counter
  if (indexState != oldIndexState)
  {
    oldIndexState = indexState;
    if (indexState)
      timing = 0;
  }


  // If the encoder signal has just gone active (LOW) increment the timer counter
  static unsigned long previousEncoderChangeTime = 0;
  if (encoderState != oldEncoderState && currentMillis - previousEncoderChangeTime > 10)
  {
    oldEncoderState = encoderState;
    previousEncoderChangeTime = currentTime;
    if (encoderState)
      timing++;
  }


  //  Display the position each second
  static unsigned long displayTimer = 0;
  if (mcurrentMillis - displayTimer >= 1000)
  {
    displayTimer = currentMillis;
    Serial.print(timing);
    Serial.println(" degrees");
  }
}

It looks like you want a readout of degrees, but your approach is prone to error if the input isn’t always moving in the positive direction.

I’d have thought just do full quadrature encoding. If you get back to Z and the count isn’t +360degrees or -360 degrees then you know there is a malfunction (ie you can have built in error spotting).

Also, I wonder if you should be using interrupts ?? I could be wrong here, but I think of interrupts allowing you to have other code doing stuff while making sure you don’t miss any encoder movement. Without interrupts you need a better understanding of the code timings to make sure it is reliable.

Here is some interrupt code for quadrature if you want to try it. Add you own code for Zero on Z, or check on Z.

edit: countA = countA % 1440; should be inside the interrupt routine if there is a danger of countA rolling over (ie if the dial is spinning and the main loop is slow )

// External Interrupts: See the attachInterrupt() function for details.

#define pinA1 1   //Roller A
#define pinA2 0   //Roller A

int oldA1=0, oldA2=0;
int countA=0;
int absdegrees=0;

void setup() {
  pinMode(pinA1, INPUT_PULLUP);
  pinMode(pinA2, INPUT_PULLUP);
  digitalWrite(pinA1, HIGH);
  digitalWrite(pinA2, HIGH);
  attachInterrupt(digitalPinToInterrupt(pinA1),doACount,CHANGE);
  attachInterrupt(digitalPinToInterrupt(pinA2),doACount,CHANGE);

  Serial.begin(9600); //This pipes to the serial monitor
}

void loop() {
  
  countA = countA % 1440;  //  for a 360ppr encoder ?
  absdegrees = countA / 4;  //  
  Serial.println( "degrees   " + String(absdegrees)); 
  delay(1000); // 

}

void doACount() {
  int newA1=digitalRead(pinA1);
  int newA2=digitalRead(pinA2);
    
   if((oldA1!=oldA2 && newA2!=oldA2)||(oldA1==oldA2 && newA1!=oldA1)) {
     countA = countA +1;
   } else {
     countA = countA -1;
   }
  oldA1=newA1;
  oldA2=newA2;
}

so i have spent some more hours learning some and trying some too
i think there are a couple things i am doing bad. lol

this looks to not be adding up "timing" properly or at all

it is running on now saying

fire 1
 fire 5
 fire 3
 fire 6
 fire 2
 fire 4
0 count

i would like to have it say

1
2
3
4
x
x
99
fire 1
101
102
x
x
218
219
fire 5
221
222
x
x
x
fire 3
fire 6
fire 2
fire 4

and so on as i run the encoder by hand

const byte EncoderDIPin = 2;       // encoder input
const byte IndexDIPin   = 3;       // index input
int COP1 = 4;                      // Digital Output Pins for turning on the COPs
int COP2 = 5;
int COP3 = 6;
int COP4 = 7;
int COP5 = 8;
int COP6 = 9;
int timing = 0;                    
unsigned long previousMillis = 0;
unsigned long COPdwell = 2;          
void setup() {
                                          
    Serial.begin(9600);                         // bunch of pins
   pinMode(EncoderDIPin, INPUT_PULLUP);
   pinMode(IndexDIPin,   INPUT_PULLUP);
   pinMode(COP1,         OUTPUT);
   pinMode(COP2,         OUTPUT);
   pinMode(COP3,         OUTPUT);
   pinMode(COP4,         OUTPUT);
   pinMode(COP5,         OUTPUT);
   pinMode(COP6,         OUTPUT);
                                          
   digitalWrite(COP1,LOW);                        // Make sure that the injectors are initially turned off
   digitalWrite(COP2,LOW);   
   digitalWrite(COP3,LOW);   
   digitalWrite(COP4,LOW);   
   digitalWrite(COP5,LOW);   
   digitalWrite(COP6,LOW);   
                                        
   while (digitalRead(IndexDIPin)==LOW) {}            // Wait for the index pulse to go high before starting the loop     
         
}   

void loop() {

                   ////////////////////////////////////////////////////////////  encoder and index input
                   
  boolean encoderState = digitalRead(EncoderDIPin) == LOW;              
  static byte oldEncoderState = true;

  boolean indexState   = digitalRead(IndexDIPin) == LOW;
  static byte oldIndexState =   HIGH;

  if (indexState != oldIndexState)            // If the 'index' signal has just gone active (LOW) reset the timer counter
  {
    oldIndexState = indexState;
    if (indexState) timing = 0;
  }
  
  if (encoderState != oldEncoderState)         // If the encoder signal has just gone active (LOW) increment the timer counter
  {
    oldEncoderState = encoderState;
    if (encoderState) timing++;   
  }    

                       /////////////////////////////////////////////////////////////    COP sequence   

   unsigned long currentMillis1 = millis();                   
   if (timing>=100)                                          
    digitalWrite(COP1,HIGH);  
    if (currentMillis1 - previousMillis >= COPdwell) {
        previousMillis = currentMillis1;
    digitalWrite(COP1,LOW);  
    while (COP1,LOW); {}
    Serial.println(" fire 1");

    }

    unsigned long currentMillis5 = millis();
   if (timing>=220) 
    digitalWrite(COP5,HIGH);
    if (currentMillis5 - previousMillis >= COPdwell) {
        previousMillis = currentMillis5;
    digitalWrite(COP5,LOW); 
    while (COP5,LOW); {}    
    Serial.println(" fire 5"); 
    } 

   unsigned long currentMillis3 = millis();
   if (timing>=340)
    digitalWrite(COP3,HIGH); 
    if (currentMillis3 - previousMillis >= COPdwell) {
        previousMillis = currentMillis3;
    digitalWrite(COP3,LOW); 
    while (COP3,LOW); {}  
    Serial.println(" fire 3");   
    }

   unsigned long currentMillis6 = millis();
   if (timing>=460)
    digitalWrite(COP6,HIGH); 
    if (currentMillis6 - previousMillis >= COPdwell) {
        previousMillis = currentMillis6;
    digitalWrite(COP6,LOW);  
    while (COP6,LOW); {} 
    Serial.println(" fire 6");   
    }

   unsigned long currentMillis2 = millis();
   if (timing>=580)
    digitalWrite(COP2,HIGH);
    if (currentMillis2 - previousMillis >= COPdwell) {
        previousMillis = currentMillis2;
    digitalWrite(COP2,LOW);  
    while (COP2,LOW); {}  
    Serial.println(" fire 2");  
    }

   unsigned long currentMillis4 = millis();
   if (timing>=700)
    digitalWrite(COP4,HIGH); 
    if (currentMillis4 - previousMillis >= COPdwell) {
        previousMillis = currentMillis4;
    digitalWrite(COP4,LOW);  
    while (COP4,LOW); {}  
    Serial.println(" fire 4");  
    }              

  Serial.print(timing);
  Serial.println(" count");

  Serial.println();                                 // space in between lines for easy reading
}