Pulsante per incrementare valore + pulsante per decrementare valore

Ciao,
sto iniziando a fare un poi’ di esperimenti con una shield DMX.
Ciò che vorrei fare è che premendo il pulsante su D6 il canale DMX vada da 1 a 512 e premendo sul pulsante di D7 il canale DMX vada a ritroso ed invece di “sforare” su valori negativi come succede adesso, magari arrivato ad 1 riprenda da 512 a 1.

Ho scritto/scopiazzato questo sketch:

/* 03 FEBBRAIO 2014 V0.2

SHIELD PER CONTROLLO ATTUATORE DMX


Dal pin D3 di arduino esce il valore del DMX

A1 è usato da un potenziomentro per variare il valore del DMX da 0 a full (255)
D6 è usato per incrementare canale DMX con un pulsante
D7 è usato per decrementare canale DMX con un pulsante
*/
  
const int  BUTTON = 6;        // D6 INCREMENTO CANALE ASSEGNAZIONE DMX
int statoButton     = 0;      // stato del pulsante (inizialmente non premuto)  
int lastStatoButton = 0;      // ultimo stato del pulsante (per ora non premuto)  
int countButton     = 0;      // Conteggio del bottone

const int  BUTTONm = 7;        // D7 DECREMENTO CANALE ASSEGNAZIONE DMX
int statoButtonm     = 0;      // stato del pulsante (inizialmente non premuto)  
int lastStatoButtonm = 0;      // ultimo stato del pulsante (per ora non premuto)  
int countButtonm     = 0;      // Conteggio del bottone
#include <DmxSimple.h>
int pot1=analogRead(A1);
int ChDMX;
int DMXvalue;

void setup() {

  Serial.begin(9600);
   pinMode(BUTTON, INPUT);     // imposta il pin digitale come input
pinMode(BUTTONm, INPUT);     // imposta il pin digitale come input   
  DmxSimple.usePin(3);
  DmxSimple.maxChannel(4);
}

void loop() {
if(digitalRead(BUTTON)) 
  {  
    // Aspetto 200ms per far alzare il dito all'utente  
    delay(200);  
    // Cambio l'ultimo stato del bottone  
   if(lastStatoButton==0) lastStatoButton=1;  
   else lastStatoButton=0;  
    // Aumento il count del bottone  
   if(countButton<=511) countButton=countButton+1;  
   else countButton=1; 
   }
   if(digitalRead(BUTTONm)) 
  {  
    // Aspetto 200ms per far alzare il dito all'utente  
    delay(200);  
    // Cambio l'ultimo stato del bottone  
   if(lastStatoButtonm==0) lastStatoButtonm=1;  
   else lastStatoButtonm=0;  
    // Aumento il count del bottone  
   if(countButtonm>=1) countButtonm=countButtonm+1; 
   else countButtonm=1; 
   }
   int dmxchannel= (countButton-countButtonm);
  Serial.println(dmxchannel);
ChDMX=(dmxchannel); 
 pot1=analogRead(A1);             
DMXvalue=map(pot1,0,1023,1,255);   
Serial.println(DMXvalue); 
DmxSimple.write(ChDMX, DMXvalue);  
    delay(100);
  }

Come accennavo, però, premendo il pulsante si D7 e quindi decrementando il canale di assegnazione DMX, arrivato a 0, vado su valori negativi. Come posso fare per rimanere su valori positivi? Mi basterebbe si fermasse ad 1, meglio, appunto se riprendesse il “giro” da 512 a 1…

Grazie

E meglio se elimini l’else e crei due if differenti.
Alla pressione dei pulsanti metti solamente

countButton++;

o

countButton--;

e negli IF che seguono imposti le soglie.

if(countButton > 512 ) countButton = 1;

e

if(countButton < 1 ) countButton = 512;

Naturalmente devi inserire un sistema per il debounce: delay o controllo lettura precedente.

Grazie dei consigli. Ci provo.

Non ne esco!

Non riesco a farlo... :-(

Metti lo sketch modificato, quello che stai usando ora. E spiega cos'è che non va.

Quel “delay(200)” … non so … e se poi l’utente tiene premuto il pulsante per piu di 200mS ?

Se vuoi puoi provare una cosa tipo questa (io l’ho provata solo sulla Mega, non ne ho altre attive al momento, ma in teoria dovrebbe funzionare su tutti)

//devi definire 2 variabili globali, anche solo byte, per ogni pulsante da controllare
byte button1 = 0;
byte oldbutton1 = 0;
byte button2 = 0;
byte oldbutton2 = 0;
int miavariabile = 1:	//la variabile da incrementare-decrementare

void setup() ... ecc ...

void loop()
{
	//ciclo di controllo del pulsante che incrementa
	button1 = digitalRead(numeropin1); //legge lo stato del pulsante 1
	if ((button1 != oldbutton1) && (oldbutton1 == LOW) // il pulsante e' appena stato premuto
	{
		delay(50);		//debounce, non indispensabile se e' presente una rete RC
		oldbutton1 = button1; 	//porta oldbutton1 = button1 (previene cicli ripetitivi)
		tuavariabile++;
		if (tuavariabile > 512) {tuavariabile = 1;}
		//se hai dell'altro codice che deve essere eseguito una
		//volta sola quando il pulsante viene PREMUTO, va qui
		//al posto di questi commenti
	}
	if ((button1 != oldbutton1) && (oldbutton1 == HIGH) 	//il pulsante e' appena stato rilasciato
	{
		delay(50);		//debounce, non indispensabile se e' presente una rete RC
		oldbutton1 = button1; 	//porta oldbutton1 = button1 (previene cicli ripetitivi)
		//se hai altro codice che deve essere eseguito una volta
		//sola quando il pulsante viene RILASCIATO, va qui
		//al posto di questi commenti
	}
	//ciclo di controllo del pulsante che decrementa
	button2 = digitalRead(numeropin2); //legge lo stato del pulsante 2
	if ((button2 != oldbutton2) && (oldbutton2 == LOW) // il pulsante e' appena stato premuto
	{
		delay(50);		//debounce, non indispensabile se e' presente una rete RC
		oldbutton2 = button2; 	//porta oldbutton2 = button2 (previene cicli ripetitivi)
		tuavariabile--;
		if (tuavariabile >1) {tuavariabile = 512;}
		//se hai dell'altro codice che deve essere eseguito una
		//volta sola quando il pulsante viene PREMUTO, va qui
		//al posto di questi commenti
	}
	if ((button2 != oldbutton2) && (oldbutton2 == HIGH) 	//il pulsante e' appena stato rilasciato
	{
		delay(50);		//debounce, non indispensabile se e' presente una rete RC
		oldbutton2 = button2; 	//porta oldbutton2 = button2 (previene cicli ripetitivi)
		//se hai altro codice che deve essere eseguito una volta
		//sola quando il pulsante viene RILASCIATO, va qui
		//al posto di questi commenti
	}	
}

Questo l’ho provato con pulsanti collegati a massa ed il pullup, se hai pulsanti collegati al VCC con il pulldown, scambia semplicemente gli “HIGH” con i “LOW” nei cicli di controllo … reagisce solo ai cambi di stato del pulsante, quindi anche se uno continua a tenerlo premuto, non succede nulla finche’ non lo rilascia e ripreme un’altra volta … inoltre personalmente preferisco sempre mettere delle reti RC esterne per il debounce, cosi si possono anche eliminare le righe dei delay (o almeno ridurle di molto), ed il programma dovrebbe sveltirsi …

Le variabili preferisco definirle come globali, perche’ queste routine di controllo pulsanti le stavo studiando per usarle come funzioni condizionali, richiamabili in qualsiasi punto dello sketch … se le faccio locali, non si puo …

GRAZIE

:)

Ce l'ho fatta!!

Grazie ancora!!