[RISOLTO] con un encoder scrivere 3 variabili diverse

Ciao a tutti, premetto che non sono un programmatore esperto ma sono alle primissime armi e sto cercando di realizzare un progettino, inizialmente avevo 2 variabili da impostare e ho deciso di utilizzare 2 encoder, uno per ogni valore, adesso la cosa si è evoluta ed avrei bisogno di gestire momentaneamente 3 variabili ma più in la sicuramente di più…
Sto utilizzando un encoder con pulsante che se non erro dovrebbe essere: ALPS STEC12E07
Dovrei impostare che ogni qual volta premo il pulsante dell’encoder esso venga letto una variabile diversa, se non si capisse mi spiego meglio:
-alfa
-beta
-gamma

Inizialmente parto da alfa, ruotando l’encoder esso viene letto ed il suo valore attribuito solo ad alfa, alla pressione dello switch l’ecoder ruotando non dovra piu attribuire il suo valore a alfa ma questa volta a beta, successivamente lo switch mi fara attribuire variazioni a gamma e a seguire di nuovo in alfra.

Creata una variabile “posizione” alla quale attribuisco il valore da me voluto ad ogni pressione dello switch (1 → 2 → 3 → 1) ho impostato il cambiamento sotto degli IF e anche sotto FOR ma a quanto pare non vanno bene perchè quando ruoto l’encoder si muovono sempre tutte e 3 le variabili…
Sicuramente mi direte di usare un interrupt ma su arduinoUno ho gia entrambi gli interrupt occupati dai pin dell’encoder, come posso fare?
Con le altre funzioni posso “emulare” un interrupt?

Ecco il mio sketch, gentilmente datemi un opinione anche sullo sketch, non so se ci sono parti che posso alleggerire o se ci sono errori…

#include<Encoder.h>
#include<LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 6, 7);        //LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

Encoder encoder(2, 3);                           //pin dell'encoder
const int Switch = 8;                                //pin dello switch dell'encoder
int posizione = 0;                                      //valore per identificare la posizione della scrittura dell'encoder, puo assumere valori: 0,1,2; 0=Alfa 1=Beta 2=Gamma

void setup() {
 lcd.begin (20,4);
 pinMode(Switch, INPUT);
 lcd.setCursor(0,1);
 lcd.print("Alfa");
 lcd.setCursor(0,2);
 lcd.print("Beta");
 lcd.setCursor (0,3);
 lcd.print ("Gamma");
 }
 
 long oldAlfa = -999;
 long oldBeta = -999;
 long oldGamma = -999;
 long newAlfa = 0;
 long newBeta = 0;
 long newGamma = 0;
 
 void loop() {
   
    //lettura valore Alfa
   for(posizione=0; posizione=0; posizione++) {
          newAlfa = encoder.read();
          if (newAlfa != oldAlfa) {
          oldAlfa = newAlfa;
          //fase di cancellazione
          lcd.setCursor(6,1);
          lcd.print("        ");       
          //fase di printing
          lcd.setCursor(6,1);
          lcd.print(newAlfa/4);
          while(digitalRead(Switch) == HIGH) {
          delay(50);    //debounce per la pressione del tasto
          posizione = 1;
           }
          }
   }  
   //lettura valore Beta
   for(posizione=1; posizione=1; posizione++) {
          newBeta = encoder.read();
          if (newBeta != oldBeta) {
          oldBeta = newBeta;
          //fase di cancellazione
          lcd.setCursor(6,2);
          lcd.print ("            ");   
          //fase di printing
          lcd.setCursor(6,2);
          lcd.print(newBeta/4);
          lcd.print (" secondi");
          while(digitalRead(Switch) == HIGH) {
          delay(50);    //debounce per la pressione del tasto
          posizione = 2;
           }
          }
   }   
    //lettura valore Gamma
   for(posizione=2; posizione=2; posizione=1) {
          newGamma = encoder.read();
          if (newGamma != oldGamma) {
          oldGamma = newGamma;
          //fase di cancellazione
          lcd.setCursor(6,3);
          lcd.print("        ");       
          //fase di printing
          lcd.setCursor(6,3);
          lcd.print(newGamma/4);
          if(digitalRead(Switch) == HIGH) {
          delay(50);    //debounce per la pressione del tasto
          posizione = 0;
           }
          }
          
   }
}

La libreria aggiunta è la seguente: http://www.pjrc.com/teensy/td_libs_Encoder.html

Ringrazio anticipatamente
Max

Ciao,

sbagli ad usare i for, come li hai messi tu non dovrebbero mai partire, mi suona strano che cmq ti si cambino le variabili

for (posizione = 0; posizione = 0; posizione++)

Sostituiscili con uno switch, dove i case sono le tre posizioni.

Grazie della risposta, ho già provato anche con SWITCH, non funzionava ugualmente…
Ieri sera tardi purtroppo ho cancellato lo sketch con la funzione SWITCH altrimenti postavo anche quella.
Tu sei sicuro che con SWITCH debba funzionare? Ora mi metto a riscriverla e poi la posto per vedere se ci sono degli errori.
Qualcuno ha altre idee?
Max

edit:
Ho corretto come da te consigliatomi, diciamo che funziona e non funziona…
Inizia partendo da Alfa, ruoto l’encoder e cambia il valore, tutto ok, alla pressione dello switch dovrei passare in “case 2”, l’encoder e non succede nulla… cosi a gusto suo dopo un attesa che può durare dai 2 ai 10 secondi il valore si aggiorna, premendo di nuovo lo switch succede la medesima cosa per gamma, poi da gamma non passa in “case 1” e si perde chissà dove, dopo svariate pressioni del tasto ritorna magicamente a cambiare il valore di Alfa ma insieme a questo si muove anche Beta…

#include<Encoder.h>
#include<LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 6, 7);        //LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

Encoder encoder(2, 3);                           //pin dell'encoder
const int Switch = 8;                                //pin dello switch dell'encoder
int posizione = 1;                                      //valore per identificare la posizione della scrittura dell'encoder, puo assumere valori: 0,1,2; 0=Alfa 1=Beta 2=Gamma

void setup() {
 lcd.begin (20,4);
 pinMode(Switch, INPUT);
 lcd.setCursor(0,1);
 lcd.print("Alfa");
 lcd.setCursor(0,2);
 lcd.print("Beta");
 lcd.setCursor (0,3);
 lcd.print ("Gamma");
 }
 
 long oldAlfa = -999;
 long oldBeta = -999;
 long oldGamma = -999;
 long newAlfa = 0;
 long newBeta = 0;
 long newGamma = 0;
 
 void loop() {
   
    //lettura valore Alfa
  switch (posizione) {
     case 1:
          newAlfa = encoder.read();
          if (newAlfa != oldAlfa) {
          oldAlfa = newAlfa;
          //fase di cancellazione
          lcd.setCursor(6,1);
          lcd.print("        ");       
          //fase di printing
          lcd.setCursor(6,1);
          lcd.print(newAlfa/4);
          while(digitalRead(Switch) == HIGH) {
          delay(50);    //debounce per la pressione del tasto
          posizione = 2;
           }
          }
          break;
     
     //lettura valore Beta
     case 2:
          newBeta = encoder.read();
          if (newBeta != oldBeta) {
          oldBeta = newBeta;
          //fase di cancellazione
          lcd.setCursor(6,2);
          lcd.print ("            ");   
          //fase di printing
          lcd.setCursor(6,2);
          lcd.print(newBeta/4);
          lcd.print (" secondi");
          while(digitalRead(Switch) == HIGH) {
          delay(50);    //debounce per la pressione del tasto
          posizione = 3;
           }
          }
          break;
          
    //lettura valore Gamma
   case 3: {
          newGamma = encoder.read();
          if (newGamma != oldGamma) {
          oldGamma = newGamma;
          //fase di cancellazione
          lcd.setCursor(6,3);
          lcd.print("        ");       
          //fase di printing
          lcd.setCursor(6,3);
          lcd.print(newGamma/4);
          if(digitalRead(Switch) == HIGH) {
          delay(50);    //debounce per la pressione del tasto
          posizione = 1;
           }
          }
          break;
   }
  }
 }

Dove sbaglio?
Max

ci siamo quasi :)

la variabile "posizione" non devi settarla internamente allo switch, cioe' intendo alla fine di ogni case togli l'assegnazione a posizione. la variabile posizione, sulla quale fai funzionare poi lo switch, deve incrementare autonomamente ed esternamente agli switch.

Fai un contatore sequenziale che premendo il tasto centrale faccia 1-2-3-1-2-3-ecc

Sinceramente non l’ho mai fatto un contatore sequenziale e mi sono rivolto a google…
Ho trovato questo: http://linuxmx.it/forum/viewtopic.php?f=16&t=721
usando il primo sketch ripulendolo dal secondo testo e dalle scritte iniziali:

#include <LiquidCrystal.h>
int in=8;
int b = 0;
int c= 0;
LiquidCrystal lcd(12, 11, 5, 4, 6, 7);

void setup() {
  pinMode(in,INPUT);
  lcd.begin(20, 4);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Valori:");
  lcd.setCursor(0, 1);
  lcd.print("P1="); 
}

void loop() {
  c=digitalRead(in);
  if ( c== 1){b=b+1; delay(500);}    
  lcd.setCursor(4, 1);
  lcd.print(a);
  lcd.setCursor(14, 1);  
  lcd.print(b);   
}

Non funziona, appena premo lo switch dell’encoder inizia a contare di continuo… si ferma un po quando dice lui, poi lo ripremo e riparte, alcune volte funziona bene ed altre invece inizia a contare da solo…
Come posso fare? Dove sbaglio?

Max

Io avevo fatto in questo modo: A ogni pressione del tasto dell'encoder incrementavo una variabile che mi definiva quale contatore variare e poi con un wile bloccavo tutto perchè senò ogni volta che premi il tasto arduino te lo legge diecimila volte e non sai mai dove finisci, dopo di chè rilasciando il tasto puoi andare a sommare il valore dell'encoder al contatore che hai selezionato.

Grazie.

farstar1965: Io avevo fatto in questo modo: A ogni pressione del tasto dell'encoder incrementavo una variabile che mi definiva quale contatore variare e poi con un wile bloccavo tutto perchè senò ogni volta che premi il tasto arduino te lo legge diecimila volte e non sai mai dove finisci, dopo di chè rilasciando il tasto puoi andare a sommare il valore dell'encoder al contatore che hai selezionato.

Ti ringrazio parecchio per la tua risposta, gentilmente mi spieghi meglio dove mettevi il "while"? mi fai uno sketch di esempio? Come incrementavi la variabile alla pressione dell'encoder? Usavi un interrupt oppure lo facevi senza? Come? Grazie Max

edit: Giuro sono preso dallo sconforto.. alla fine ho provato per scrupolo a farlo con un interrupt.. Ho scritto cosi:

int pos = 1;

void setup() {
 lcd.begin (20,4);
 }
void loop() {
    attachInterrupt(0, posizione, RISING);
}
void posizione() {
      pos = pos+1;
      lcd.setCursor(0,0);
      lcd.print(pos);
      if (pos==4) {
        pos = 1;
        lcd.setCursor(0,0);
        lcd.print(pos);
      }
}

Il conteggio riesce solo alcune volte, nel senso, sembra come se fosse lento nell'elaborare il comando.. Ho sbagliato qualche sintassi? Ho appesantito qualcosa nello sketch? Giuro non ho più idee, ci sto combattendo da questa mattina per non dire da ieri... Help me Max

mah… mi sa che la vuoi fare troppo semplice ]:smiley:
che vuol dire 3 variabili ? vuoi star li a girare l’encoder 3/4 d’ora ?
IMHO devi cambiare “strategia” con es: ad ogni premuta pulsante fai lampeggiare una sola cifra di una variabile e regoli solo quella se bastano tre cifre alla prima pressione regoli le unita alla seconda, decine alla terza le centinaia e alla quarta pressione regoli la “barretta” del negativo,
alla quinta pressione regoli le unita della seconda variabile etc…

Purtroppo non essendo in grado di fare magheggi mi devo accontentare di usare quello che offre arduino di standard e non avendo altri interrupt vado a leggere lo stato dello switch dell’encoder nel normale ciclo di loop.
Un pezzo del codice che avevo usato è questo:

 while (digitalRead(SwitcEncodePin) == LOW); // finchè è premuto resto fermo
               while ((digitalRead(SwitcEncodePin) == HIGH) && (time < 3000))//usco dal menu se non faccio niente per un tot
                     {
                     time++ ;
                     lcd.setCursor(0, 0);
                     lcd.print("Circolatore Caldaia ");
                     lcd.setCursor(0, 1);
                     lcd.print("Set Temperatura     ");
                     lcd.setCursor(16, 1);
                     lcd.print(SetBoilerTemp);
                     lcd.setCursor(0, 3);
                     lcd.print("Premere per uscire");
                     if (encoder0Pos < 1) encoder0Pos = 1 ;
                     if (encoder0Pos > 100) encoder0Pos = 100 ;
                     SetBoilerTemp = encoder0Pos;//aggiungo alla variabile il valore dellencoder che essendo letto da interrupt viene aggiornato sempre
                     }

Sono assolutamente un principiante spero di essermi spiegato

Scusate, mentre avete postato ho fatto un edit del 6° post, se non l'avete notato ho scritto un altro sketch provando ad usare un interrupt, che non funziona per giunta...

gingardu: mah.. mi sa che la vuoi fare troppo semplice ]:D che vuol dire 3 variabili ? vuoi star li a girare l'encoder 3/4 d'ora ? IMHO devi cambiare "strategia" con es: ad ogni premuta pulsante fai lampeggiare una sola cifra di una variabile e regoli solo quella se bastano tre cifre alla prima pressione regoli le unita alla seconda, decine alla terza le centinaia e alla quarta pressione regoli la "barretta" del negativo, alla quinta pressione regoli le unita della seconda variabile etc...

Vabbe per iniziare questo progettino ho deciso di iniziare a fare le cose semplici, già incontro parecchie difficoltà nel cambiare la posizione della scrittura scrittura di una lettura di un encoder figuriamoci cosa succederebbe se mi avventurassi direttamente in una cosa complessa come mi suggerisci, sono perfettamente d'accordo, prima o poi farò così come dici tu ma per il momento faccio un passetto alla volta altrimenti potrebbe sembrare che voglia la pappa pronta da qualcun altro senza metterci nemmeno un po di impegno.

Non per demoralizzarti o darti contro memedesimo ma hai scelto una delle cose complicata per iniziare... l'encoder a quadratura e' oggetto ancor oggi di numerosi dibattiti.... Forse non sai che: l'encoder da 4 impulsi a scatto. l'encoder per gestirlo bene e che sia reattivo devi per forza di cose usare DUE IRQ, con un IRQ va gia' meglio ma.... senza IRQ vai a caso.... per capirci....: tu fai un giro orario e conta 100 avanti poi fai un giro antiorario e conta 23 indietro poi giri uno orario e conta 43 avanti un'altro antiorario e conta 75 indietro ma tu giravi un giro avanti e uno indietro preciso preciso....

memedesimo: Scusate, mentre avete postato ho fatto un edit del 6° post, se non l'avete notato ho scritto un altro sketch provando ad usare un interrupt, che non funziona per giunta...

gingardu: mah.. mi sa che la vuoi fare troppo semplice ]:D che vuol dire 3 variabili ? vuoi star li a girare l'encoder 3/4 d'ora ? IMHO devi cambiare "strategia" con es: ad ogni premuta pulsante fai lampeggiare una sola cifra di una variabile e regoli solo quella se bastano tre cifre alla prima pressione regoli le unita alla seconda, decine alla terza le centinaia e alla quarta pressione regoli la "barretta" del negativo, alla quinta pressione regoli le unita della seconda variabile etc...

Vabbe per iniziare questo progettino ho deciso di iniziare a fare le cose semplici, già incontro parecchie difficoltà nel cambiare la posizione della scrittura scrittura di una lettura di un encoder figuriamoci cosa succederebbe se mi avventurassi direttamente in una cosa complessa come mi suggerisci, sono perfettamente d'accordo, prima o poi farò così come dici tu ma per il momento faccio un passetto alla volta altrimenti potrebbe sembrare che voglia la pappa pronta da qualcun altro senza metterci nemmeno un po di impegno.

forse e più complicato come vuoi fare tu comunque tutto dipende dAL NUMERO di cifre delle variabili

prova con una (x) da 3 cifre all'inizio magari fai 3 byte (a b c) uno per cifra poi moltiplichi la prima di sinistra per 100 la seconda per 10 e la prima per 1 x = (a*100 + b*10 + c*1)

oppure puoi anche provare di moltiplicare per 10 o per 100 il valore dell'encoder ogni volta che premi il pulsante

ti consiglio questi sistemi perché sono gli unici che funzionano (secondo me )

Lo state portando fuori strada.

Il pulsante dell encoder è un semplice pulsante, lasciano stare l encoder, quello viene dopo, lui per ora deve fare in modo di selezionare le 3 variabili. Fai le prove con un pulsante normale, e fai anche il debounce, Quando avrai risolto questa cosa, cioe ptemendo il pulsante fai 1.2.3, e ritorni ad 1 solo dopo integra la parte encoder

Prima di tutto vi ringrazio per le numerose risposte ed attenzioni al mio problema.

elpapais: Non per demoralizzarti o darti contro memedesimo ma hai scelto una delle cose complicata per iniziare... l'encoder a quadratura e' oggetto ancor oggi di numerosi dibattiti.... Forse non sai che: l'encoder da 4 impulsi a scatto. l'encoder per gestirlo bene e che sia reattivo devi per forza di cose usare DUE IRQ, con un IRQ va gia' meglio ma.... senza IRQ vai a caso.... per capirci....: tu fai un giro orario e conta 100 avanti poi fai un giro antiorario e conta 23 indietro poi giri uno orario e conta 43 avanti un'altro antiorario e conta 75 indietro ma tu giravi un giro avanti e uno indietro preciso preciso....

Sinceramente non ho proprio capito bene ciò che intendi, comunque mi pare di aver capito che tu ti stia preoccupando del fatto della lettura dell'encoder, che si fa in quadratura, se è per quello mi affido a una libreria: http://www.pjrc.com/teensy/td_libs_Encoder.html funziona molto bene, se non l'avete mai usata ve la consiglio, certo non che ne abbia provate parecchie però mi pare molto ben fatta, se per gli ingressi uso i due pin di interrupt posso ruotare l'econder molto velocemente in ambedue i sensi e il valore di lettura risponde molto bene.

gingardu: forse e più complicato come vuoi fare tu comunque tutto dipende dAL NUMERO di cifre delle variabili prova con una (x) da 3 cifre all'inizio magari fai 3 byte (a b c) uno per cifra poi moltiplichi la prima di sinistra per 100 la seconda per 10 e la prima per 1 x = (a*100 + b*10 + c*1) oppure puoi anche provare di moltiplicare per 10 o per 100 il valore dell'encoder ogni volta che premi il pulsante ti consiglio questi sistemi perché sono gli unici che funzionano (secondo me )

Mi ero chiesto come poter far funzionare le 3 variabili (centinaia, decine, unita) con la formula: x = (a*100 + b*10 + c*1) hai risposto ad una domanda che avrei quasi sicuramente posto tra qualche giorno, ti ringrazio ;)

Attualmente il mio problema forse non l'ho spiegato bene, ci riprovo: Devo spostare il cursore sull'LCD, e ruotando l'encoder devo variare ad esempio una variabile A, successivamente alla pressione dello switch sull'encoder il cursore si deve portare nella posizione della variabile B e ruotando l'encoder devo variare il valore di B lasciando inalterato il valore di A. Prima di riscrivere ed editare tutto il programma ho pensato bene di fare delle prove su questo funzionamento, infatti, gli ultimi sketch che ho postato in linea teorica dovrebbero contare le pressioni dello switch dell'encoder e scriverle su LCD in modo tale che io possa controllare l'avvenuto cambiamento della variabile (numero di pressioni dello switch) fatto cio ho continuato ponendo un limite alla numerazione, nel senso che il numero delle pressioni dello switch deve essere sempre un numero compreso tra 1 e 3, infatti, nell'ultimo sketch (quello del post editato) nel void loop() c'è un if (pos==4) { pos = 1; } che secondo logica dovrebbe riportare la variabile "pos" ad un valore di 1 nel caso in cui gli venga attribuito un valore di 4.

Qui è l'inghippo, dove sbaglio? Come fareste voi? Non riesco a programmare una funzione che mi "sposti" la lettura dell'encoder da una variabile all'altra, nel caso in cui venga premuto lo switch..

Testato: Il pulsante dell encoder è un semplice pulsante, lasciano stare l encoder, quello viene dopo, lui per ora deve fare in modo di selezionare le 3 variabili. Fai le prove con un pulsante normale, e fai anche il debounce, Quando avrai risolto questa cosa, cioe ptemendo il pulsante fai 1.2.3, e ritorni ad 1 solo dopo integra la parte encoder

Esatto, attualmente sto cercando di creare la sequenza 1-2-3 ma non ci riesco.. Quando premo sullo switch il valore non cambia subito, ci mette un pò.. come se l'istruzione da me fornita fosse difficoltosa da elaborare.. Mi aiuti?

Max

per evitare l'antirimbalzo e il multiconteggio devi usare il debounce. negli esempi di base lo trovi nella sezione digital.

//Variabili fisse
const int buttonPin = 2;    // pin dov'e' collegaro il pulsante
const int ledPin = 13;      // numero pin dov'e' collegato il led

//variabili che cambiano in continuazione
int ledState = HIGH;         // stato corrente dell'uscita 
int buttonState;             // Lettura corrente dello stato del pulsante
int lastButtonState = LOW;   // lettura precedente dello stato del pulsante

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);

  // set initial LED state
  digitalWrite(ledPin, ledState);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button 
  // (i.e. the input went from LOW to HIGH),  and you've waited 
  // long enough since the last press to ignore any noise:  

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  } 
  
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        ledState = !ledState;
      }
    }
  }
  
  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;
}

logicamente al posto di accendere il led incrementa la variabile tua....

const int pulsante = 22;    // Piedino dove collego il pulsante

int VariabileCheVoglioIncrementare = 0;
unsigned long LetturaAttuale; // Variabile che continua a incrementarsi a ogni ciclo di loop
unsigned long PrecedenteLettura;  // verificare se da blocco per overflow
unsigned long TempoPressionePulsante = 1000;    // Tempo di attesa per pulsante premuto(lo devo tener premuto 1000 millisecondi ovvero 1 secondo)

void setup() {
  pinMode(pulsante, INPUT); /// modo del piedino dove ho collegato il pulsante (ingresso)
  Serial.begin(9600); // avvio la seriale per poter vedere sul monitor se il programma funziona
}

void loop() {
  LetturaAttuale=millis();
  if(digitalRead(pulsante)== LOW){ //se premo il pulsante dell'encoder eseguo altro if(LOW perche' io ho i comuni dell'encoder collegato a massa) 
   if(LetturaAttuale>PrecedenteLettura+TempoPressionePulsante){
      VariabileCheVoglioIncrementare++;
      Serial.println(VariabileCheVoglioIncrementare);
      PrecedenteLettura=millis();
    }
  }
}

Spero sia chiaro e utile a qualcuno

memedesimo: Prima di tutto vi ringrazio per le numerose risposte ed attenzioni al mio problema.

elpapais: Non per demoralizzarti o darti contro memedesimo ma hai scelto una delle cose complicata per iniziare... l'encoder a quadratura e' oggetto ancor oggi di numerosi dibattiti.... Forse non sai che: l'encoder da 4 impulsi a scatto. l'encoder per gestirlo bene e che sia reattivo devi per forza di cose usare DUE IRQ, con un IRQ va gia' meglio ma.... senza IRQ vai a caso.... per capirci....: tu fai un giro orario e conta 100 avanti poi fai un giro antiorario e conta 23 indietro poi giri uno orario e conta 43 avanti un'altro antiorario e conta 75 indietro ma tu giravi un giro avanti e uno indietro preciso preciso....

Sinceramente non ho proprio capito bene ciò che intendi, comunque mi pare di aver capito che tu ti stia preoccupando del fatto della lettura dell'encoder, che si fa in quadratura, se è per quello mi affido a una libreria: http://www.pjrc.com/teensy/td_libs_Encoder.html funziona molto bene, se non l'avete mai usata ve la consiglio, certo non che ne abbia provate parecchie però mi pare molto ben fatta, se per gli ingressi uso i due pin di interrupt posso ruotare l'econder molto velocemente in ambedue i sensi e il valore di lettura risponde molto bene.

gingardu: forse e più complicato come vuoi fare tu comunque tutto dipende dAL NUMERO di cifre delle variabili prova con una (x) da 3 cifre all'inizio magari fai 3 byte (a b c) uno per cifra poi moltiplichi la prima di sinistra per 100 la seconda per 10 e la prima per 1 x = (a*100 + b*10 + c*1) oppure puoi anche provare di moltiplicare per 10 o per 100 il valore dell'encoder ogni volta che premi il pulsante ti consiglio questi sistemi perché sono gli unici che funzionano (secondo me )

Mi ero chiesto come poter far funzionare le 3 variabili (centinaia, decine, unita) con la formula: x = (a*100 + b*10 + c*1) hai risposto ad una domanda che avrei quasi sicuramente posto tra qualche giorno, ti ringrazio ;)

Attualmente il mio problema forse non l'ho spiegato bene, ci riprovo: Devo spostare il cursore sull'LCD, e ruotando l'encoder devo variare ad esempio una variabile A, successivamente alla pressione dello switch sull'encoder il cursore si deve portare nella posizione della variabile B e ruotando l'encoder devo variare il valore di B lasciando inalterato il valore di A. Prima di riscrivere ed editare tutto il programma ho pensato bene di fare delle prove su questo funzionamento, infatti, gli ultimi sketch che ho postato in linea teorica dovrebbero contare le pressioni dello switch dell'encoder e scriverle su LCD in modo tale che io possa controllare l'avvenuto cambiamento della variabile (numero di pressioni dello switch) fatto cio ho continuato ponendo un limite alla numerazione, nel senso che il numero delle pressioni dello switch deve essere sempre un numero compreso tra 1 e 3, infatti, nell'ultimo sketch (quello del post editato) nel void loop() c'è un if (pos==4) { pos = 1; } che secondo logica dovrebbe riportare la variabile "pos" ad un valore di 1 nel caso in cui gli venga attribuito un valore di 4.

Qui è l'inghippo, dove sbaglio? Come fareste voi? Non riesco a programmare una funzione che mi "sposti" la lettura dell'encoder da una variabile all'altra, nel caso in cui venga premuto lo switch..

Testato: Il pulsante dell encoder è un semplice pulsante, lasciano stare l encoder, quello viene dopo, lui per ora deve fare in modo di selezionare le 3 variabili. Fai le prove con un pulsante normale, e fai anche il debounce, Quando avrai risolto questa cosa, cioe ptemendo il pulsante fai 1.2.3, e ritorni ad 1 solo dopo integra la parte encoder

Esatto, attualmente sto cercando di creare la sequenza 1-2-3 ma non ci riesco.. Quando premo sullo switch il valore non cambia subito, ci mette un pò.. come se l'istruzione da me fornita fosse difficoltosa da elaborare.. Mi aiuti?

Max

premesso che l'invio della scrittura dati al display sia nel loop e che c'è un refresh senza troppi ritardi bastano 3 if

if (pulsante==1) variabile_1 = lettura_encoder; if (pulsante==2) variabile_2 = lettura_encoder; if (pulsante==3) variabile_3 = lettura_encoder; if (pulsante => 4) pulsante = 0;

Allora stò perdendo il filo, mi sembra che il problema sia assegnare un valore a pulsante, quindi:
Premesso che ci vuole un antirimbalzo ( software o elettrico), se premo il pulsante vado in while (mi stoppa fino a quando e premuto) per non leggerlo migliaia di volte, faccio pulsante++ e poi torno a verificare se il pulsante è premuto.
Poi se pulsante > 3 pulsante ==3 e viceversa se < 1 pulsante ==1 >3 pulsante==1 .

Grazie.

farstar1965:
Allora stò perdendo il filo, mi sembra che il problema sia assegnare un valore a pulsante, quindi:
Premesso che ci vuole un antirimbalzo ( software o elettrico), se premo il pulsante vado in while (mi stoppa fino a quando e premuto) per non leggerlo migliaia di volte, faccio pulsante++ e poi torno a verificare se il pulsante è premuto.
Poi se pulsante > 3 pulsante ==3 e viceversa se < 1 pulsante ==1 >3 pulsante==1 .

Grazie.

c’è molta differenza tra mettere un uguale e metterne due ]:smiley:

Azz, mea culpa, mi è scappato un uguale di troppo :blush:. Intendevo (inutile dirlo) se premo una volta assegna 1 se premo due asseggna 2 se premo tre volte assegna tre e la quarta volta che premo ritorna a 1.

Grazie.