Go Down

Topic: [RISOLTO] con un encoder scrivere 3 variabili diverse (Read 6917 times) previous topic - next topic

elpapais

#15
Jan 14, 2014, 12:55 am Last Edit: Jan 14, 2014, 12:58 am by elpapais Reason: 1
Code: [Select]

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
www.infoportal.it support at infoportal.it

GINGARDU


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


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:
Code: [Select]
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.


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..

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;


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.

GINGARDU


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   ]:D

farstar1965

Azz, mea culpa, mi è scappato un uguale di troppo :smiley-red:. 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.

memedesimo

Vi ringrazio tutti tantissimo, mi scuso se ieri non ho risposto.
Ieri sera tardi ho letto i vostri post, ho provato le programmazioni postate..
Non funzionano  :~

Usando questo:
Code: [Select]
const int pulsante = 8;    // 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)== HIGH){ //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();
   }
 }  
}


Alla prima pressione dello switch il conteggio inizia e prosegue all'infinito... non si ferma mai.
Un mio amico programmatore mi ha dato un consiglio "volante" mi ha detto di usare un modulo..
Max

testato

vedi se ti aiuta questo:
http://forum.arduino.cc/index.php?topic=195650.0

- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

farstar1965

#22
Jan 16, 2014, 06:08 pm Last Edit: Jan 16, 2014, 08:03 pm by farstar1965 Reason: 1
Una cosa del genere potrebbe andare ?
Code: [Select]
const int pulsante = 8;    // Piedino dove collego il pulsante

int VariabileCheVoglioIncrementare = 0;

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() {
 while (digitalRead(pulsante) == LOW);
 {
   VariabileCheVoglioIncrementare++;
   if (VariabileCheVoglioIncrementare > 3 ) VariabileCheVoglioIncrementare = 1 ;
 }

}  


Non ho modo di provarlo ma non dovrebbero esserci grossi errori .

Grazie.

GINGARDU

#23
Jan 16, 2014, 09:52 pm Last Edit: Jan 16, 2014, 10:05 pm by gingardu Reason: 1

Vi ringrazio tutti tantissimo, mi scuso se ieri non ho risposto.
Ieri sera tardi ho letto i vostri post, ho provato le programmazioni postate..
Non funzionano  :~

Usando questo:
Code: [Select]
const int pulsante = 8;    // 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)== HIGH){ //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();
   }
 }  
}


Alla prima pressione dello switch il conteggio inizia e prosegue all'infinito... non si ferma mai.
Un mio amico programmatore mi ha dato un consiglio "volante" mi ha detto di usare un modulo..
Max


beh...   questo e ovvio     =(  se non metti te delle "briglie"    al pulsante premuto  continua a leggerlo premuto  e la velocita del micro e velocissima  rispetto a premere il pulsante con la mano  

questo che segue e un piccolo pezzo di codice che sto usando in un "progettino"

puls_encoder (e anche  conta_impulsi_pulsante)  e una variabile byte  e che parte con zero nel setup   byte puls_encoder = 0
e come "vedi"  non mi affido alla digitalRead  per incrementare   ma al cambiamento di stato di  puls_encoder == 1


if (digitalRead (7)== LOW) puls_encoder = 1;  
if (puls_encoder == 1) conta_impulsi_pulsante = conta_impulsi_pulsante +1,  puls_encoder=0,  delay (300);

if (conta_impulsi_pulsante  > 3)  conta_impulsi_pulsante  = 0 ;  // riga aggiunta per te

(ovviamente il "mio" pin 7   e messo "alto"  col pull up interno   e premendo il pulsante  lo metto a massa con una resistenza

memedesimo

#24
Jan 23, 2014, 07:50 pm Last Edit: Jan 23, 2014, 07:53 pm by memedesimo Reason: 1
Bene! Ci sono riuscito... Mi scuso a tutti per non aver più risposto, sono stato male e sinceramente non avevo voglia di mettermi al pc...
Ho provato le righe di codice che mi avete scritto, non funzionavano.
Posto la parte dello sketch che serve per il contatore nella speranza che possa servire a qualcuno nel futuro.
Code: [Select]
const int buttonPin = 8; //pin dello switch
int buttonState = 0;         // variable per la lettura delo stato del pushbutton
int puntatore = 1; //variabile per il puntatore
void setup() {
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop() {
 buttonState = digitalRead(buttonPin);
 Serial.println(puntatore);
 if (puntatore>=4) {
 puntatore=1;
 }
 if (buttonState == HIGH) {        
  puntatore++;
  delay(500);
 }
}


A seconda di ciò che si deve fare per ogni valore assunto dal puntatore ci vuole anche:
Code: [Select]
if (puntatore == 1){
}
if (puntatore == 2){
}
if (puntatore == 3){
}


Un ringraziamento a tutti.
Max

Go Up