Encoder per misurare spostamento [ RISOLTO ]

Salve, ho adattato uno sketch per convertire la rotazione dell’encoder in una misura lineare,
tutto funziona bene ma non riesco a resettare il valore letto tramite il pulsante SW dell’encoder.
Sicuramente mi sto perdendo in un bicchiere d’acqua, mi aiutate a capire dove sbaglio?

Metto qui sotto il codice ( necessita di “MsTimer2.h”) ed è OK sia su seriale che LCD :

/*
 *      rotary_sm.ino   --  State machine implementation of rotary encoder driver
 *                          Interrupt driven; supports 2 types of interrupts:
 *                            * Polled interrupts; enable by defining TIMER2INT
 *                            * Pin change interrupts: enalbe by defining PINCHANGEINT
 *                              (Do NOT enable both at the same time)
 *
 *          This program is developed from the code at: 
 *              http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html
 *          Since this code was in the form of an arduino library, and I had unresolvable
 *          references that I could not figure out, I just modified it as a single sketch.
 *          The only library support required is if you want to use interrupt polling,
 *          and then the MsTimer2 library needs to be installed.
 */


#include <Wire.h> 
#include <LiquidCrystal_I2C.h> // Libreria LCD I2C

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);//Inizializzo LCD



/* Define PINCHANGEINT if you want to interrupt on any encoder pin change */
//#define PINCHANGEINT
/* --- OR --- */
/* Define TIMER2INT if you want to use periodic interrupts to poll the encoder */
#define TIMER2INT

/* Define ENABLEPULLUPS if there are no external pull-ups on encoder AB pins */
//#define ENABLEPULLUPS

/* Define to enable the ISR debug flag */
#define ISRFLAG


/* You may need to install this library (MsTimer2) from the arduino site */
#ifdef TIMER2INT
#include    <MsTimer2.h>
#endif


#define DIR_NONE 0x00           // No complete step yet.
#define DIR_CW   0x10           // Clockwise step.
#define DIR_CCW  0x20           // Anti-clockwise step.

unsigned int state;
unsigned int A = 2;             // pins connected to the encoder (digital_pin 2)
unsigned int B = 3;             //              "                (digital_pin 3)
unsigned int ISRflag = 5;       //              "                (digital_pin 3)
         int count = 0;         // count each indent
         int old_count = 0;     // check for count changed

unsigned int PinSW = 4;
float lettura ;

/*
 * The below state table has, for each state (row), the new state
 * to set based on the next encoder output. From left to right in,
 * the table, the encoder outputs are 00, 01, 10, 11, and the value
 * in that position is the new state to set.
 */

// State definitions state table (emits a code at 00 only)
// states are: (NAB) N = 0: clockwise;  N = 1: counterclockwiswe
#define R_START     0x3
#define R_CW_BEGIN  0x1
#define R_CW_NEXT   0x0
#define R_CW_FINAL  0x2
#define R_CCW_BEGIN 0x6
#define R_CCW_NEXT  0x4
#define R_CCW_FINAL 0x5

 

const unsigned char ttable[8][4] = {
    {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},                // R_CW_NEXT
    {R_CW_NEXT,  R_CW_BEGIN,  R_CW_BEGIN,  R_START},                // R_CW_BEGIN
    {R_CW_NEXT,  R_CW_FINAL,  R_CW_FINAL,  R_START | DIR_CW},       // R_CW_FINAL
    {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},                // R_START
    {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},                // R_CCW_NEXT
    {R_CCW_NEXT, R_CCW_FINAL, R_CCW_FINAL, R_START | DIR_CCW},      // R_CCW_FINAL
    {R_CCW_NEXT, R_CCW_BEGIN, R_CCW_BEGIN, R_START},                // R_CCW_BEGIN
    {R_START,    R_START,     R_START,     R_START}                 // ILLEGAL
};

void setup( ) {
    pinMode( A, INPUT );
    pinMode( B, INPUT );
    pinMode(PinSW, INPUT);
    
#ifdef ENABLEPULLUPS
    digitalWrite( A, HIGH );                // set pullups
    digitalWrite( B, HIGH );                //      "
    digitalWrite( PinSW, HIGH );
#endif

#ifdef TIMER2INT
    MsTimer2::set( 1, T2_isr );             // interrupt polling:
    MsTimer2::start( );
#endif

#ifdef PINCHANGEINT
    attachInterrupt( 0, AB_isr, CHANGE );   // pin-change interrupts: 
    attachInterrupt( 1, AB_isr, CHANGE );
#endif

#ifdef ISRFLAG
    pinMode( ISRflag, OUTPUT );             // time the ISR
    digitalWrite( ISRflag, HIGH );          // set pull-up ON
#endif

    state = (digitalRead( A ) << 1) | digitalRead( B );     // Initialise state.
    old_count = 0;

    Serial.begin( 9600 );
    Serial.println( "Rotary Encoder Tests" );
    
    lcd.begin(16,2);
    lcd.clear();
}


#ifdef PINCHANGEINT
void AB_isr( ) {
    // Grab state of input pins.
    unsigned char pinstate = (digitalRead( A ) << 1) | digitalRead( B );

    // Determine new state from the pins and state table.
    state = ttable[state & 0x07][pinstate];

    if( state & DIR_CW )    count++;
    if( state & DIR_CCW )   count--;
}
#endif


#ifdef TIMER2INT
void T2_isr( ) {

#ifdef ISRFLAG
    digitalWrite( ISRflag, HIGH );
#endif

    // Grab state of input pins.
    unsigned char pinstate = (digitalRead( A ) << 1) | digitalRead( B );

    // Determine new state from the pins and state table.
    state = ttable[state & 0x07][pinstate];

    if( state & DIR_CW )    count++;        // count up for clockwise
    if( state & DIR_CCW )   count--;        // count down for counterclockwise

#ifdef ISRFLAG
    digitalWrite( ISRflag, LOW );
#endif
}
#endif


void loop( ) {
    
  if( old_count != count ) {
        
        old_count = count;
    
        lettura = (count * 0.15); // Ad ogni Step assegno 0,15mm che corrispondono a 3mm giro
        
        lcd.setCursor(0,0);
        lcd.print("X= ");
        lcd.print( lettura );
        lcd.print(" mm  ");
        
        lcd.setCursor(0,1);
        lcd.print( count );
        lcd.print("     ");
        
        Serial.print (lettura);
        Serial.print (" mm  Posizione Encoder ");  
        Serial.println( count );
    
    }
    
    
    if( PinSW == LOW ) {    // Reset contatore
        
        count = 0;
    }
    
    
    
    
}

Con l’ultima istruzione pensavo di resettare il contatore, ma non funziona…dove sto sbagliando?

Abbiate pietà, sono un niubbo :confused:

forse se fai una lettura della porta dov'e' collegato il pulsante, funziona meglio

if( digitalRead (PinSW) == LOW )

Ciao Brunello, grazie per la risposta, sinceramente avevo provato anche io come mi hai suggerito,
ma mi capitava una cosa strana.

In pratica la lettura era sempre a 0 ( sia con il pin SW collegato e sia scollegato), questo mi aveva mandato in confusione.

Dopo il Tuo suggerimento però mi è venuto il dubbio che il problema fosse hardware e non software, perchè con il pin scollegato doveva per forza fare la lettura invece di resettarsi continuamente.

In pratica si è bruciato qualcosa e l'arduino funzionava perfettamente ma non portava a PULLUP
il pin 4 ( pensare che avevo provato anche il 5), per cui leggendo sempre "LOW" si resettava in continuazione.

Ora o scoperto che escluso i pin 4 e 5 negli altri pin digitali lo sketch funziona perfettamente.

Grazie ancora.