Il mio "problema" con arduino

Salve a tutti, inizzio subito con il dire che sono nuovo qui nel forum anche se vi seguo da un paio di mesi. Mi chiamo luca e ho 23 anni.
Da grande appassionato di elettronica e programmazione mi sono imbattuto in arduino. Premetto però che sono abbastanza inetto nella programmazione.

Veniamo al dunque, sto tentando di creare una specie di relay elettronico via software. In poche parole, premendo un pulsate (normalmente basso) si deve accendere un led e rimanere acceso, quando lo ripremo, il led si deve spegnere.
Ho provato in vari modi ma nessuno ha funziona, vi posto qui sotto il lo script con il quale mi sono avvicinato maggiormante al mio fine.

const int button_pin = 2;
const int led_pin = 13;

int button_state = 0;
int a;

void setup() {
pinMode(led_pin, OUTPUT);
pinMode(button_pin, INPUT);
}

void loop(){

button_state = digitalRead(button_pin);

if ((button_state == HIGH)&&(a==0)) {
digitalWrite(led_pin, HIGH);
}

if ((button_state == LOW)&&(a==0)){
a=1;
}

if ((button_state == HIGH)&&(a==1)) {
digitalWrite(led_pin, LOW);
a=0;
}

if ((button_state == LOW)&&(a==1)){
a=0;
}
}

Se qualche buona anima mi può aiutare. Qualsiasi aiuto è gradito, cerco qualcunoche abbia un infinita pazienza anche nel spiegarmi dove e come ho sbagliato.
Vi ringrazzio in anticipo saluti Luca!

boolean statoLed=false;

void setup() {
....
digitalWrite(pinLed, statoLed); //LOW=FALSE=0
}

void loop() {
if (digitalRead(button)==HIGH) {
delay(50); //debounce
if (digitalRead(button)==HIGH) {
statoLed^=1; //XOR logico: 1 xor 1=0 // 0 xor 1=1
digitalWrite(pinLed, statoLed);
}
}
}

Tieni 1 variabile, che è lo stato del led1. Ad ogni pressione del pulsante, ne cambi lo stato con uno XOR. 1 xor 1 dà 0, 0 xor 1 dà 1, quindi tu ne inverti lo stato ogni volta, senza preoccuparti dello stato che aveva in precedenza (eviti if in cascata).
Ho messoun piccolo debounce per evitare false letture sul pulsantino

Ciao! Credo che il problema sia nel pulsante: devi aggiungere qualche di riga per il debouncing del segnale http://arduino.cc/it/Tutorial/Debounce, in questo modo una singola pressione non viene letta come più cambiamenti di stato del segnale e tutto dovrebbe funzionare

Questo codice é scritto per un pulsante collegato tra entarata Arduino e massa e la resistenza pullup interna attivata.

const int button_pin = 2;     
const int led_pin =  13;     

int button_state = 0;         
int a =0;

void setup() {
 pinMode(led_pin, OUTPUT);     
 pinMode(button_pin, INPUT);     
 digitalWrite(button_pin,HIGH); // attiva la resistenza Pullup interna
 digitalWrite(led_pin, LOW); 
 }

void loop(){
    button_state = digitalRead(button_pin);
    delay (10); // qua eve anndare un debounce in mancanza va bene anche un delay

   if ((button_state == LOW)&&(a==0)) {    // viene premuto il pusante e acceso il led
    digitalWrite(led_pin, HIGH); 
    a=1;
  }
 
  if ((button_state == HIGH)&&(a==1)){  // viene rilasciato l' interuttore dopo aver acceso il LED
   a=2;
  }
 
  if ((button_state == LOW)&&(a==2)) {  // viene premuto il pusante e spento il led
    digitalWrite(led_pin, LOW);
   a=3;
  }
 
   if ((button_state ==HIGH)&&(a==3)){  // viene rilasciato l' interuttore dopo aver spento il LED
   a=0;
  }

if(a>3) a=0; // non dovrebbe essere necessario perché non arriva a questi valori ma meglio che ci sia.
if (a<0) a=0;
}

Il codice non genera errori in compilazione ma non l'ho testato se funziona su un arduino.
Ciao Uwe

leo72:
boolean statoLed=false;

void setup() {
....
digitalWrite(pinLed, statoLed); //LOW=FALSE=0
}

void loop() {
if (digitalRead(button)==HIGH) {
delay(50); //debounce
if (digitalRead(button)==HIGH) {
statoLed^=1; //XOR logico: 1 xor 1=0 // 0 xor 1=1
digitalWrite(pinLed, statoLed);
}
}
}

Tieni 1 variabile, che è lo stato del led1. Ad ogni pressione del pulsante, ne cambi lo stato con uno XOR. 1 xor 1 dà 0, 0 xor 1 dà 1, quindi tu ne inverti lo stato ogni volta, senza preoccuparti dello stato che aveva in precedenza (eviti if in cascata).
Ho messoun piccolo debounce per evitare false letture sul pulsantino

Leo il tuo esempio fa accendere e spegnere il LED di continuo finche tieni premuto il pulsante.
Ciao Uwe

@Uwe:
ops, è vero. L'ho scritto tra una nausea e l'altra... =(

Basta mettere un check per uscire solo al rilascio del pulsante.
if (digitalRead(button)==HIGH) {
delay(50); //debounce
if (digitalRead(button)==HIGH) {
statoLed^=1; //XOR logico: 1 xor 1=0 // 0 xor 1=1
digitalWrite(pinLed, statoLed);
while (digitalRead(button)==HIGH) {}
}
}

Con lo XOR è pulitissimo, grazie Leo, non lo avevo mai usato prima :blush: ... che niubbo...

Comunque a me è venuta fuori una cosa del genere che funge perfettamente:

const int buttonPin = 6;
const int ledPin =  13;

boolean ledState = false;
int buttonState; 
int lastButtonState = LOW;

long lastDebounceTime = 0;
long debounceDelay = 50;

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

void loop() {
  buttonState=digitalRead(buttonPin);
  if ((buttonState!=lastButtonState)&&(millis()-lastDebounceTime>debounceDelay)){
    if (buttonState==HIGH){
      ledState^=1;
      digitalWrite(ledPin, ledState);
    }
    lastDebounceTime=millis();
    lastButtonState=buttonState;
  }
}

E' tutto in inglese perché son partito dall'esempio debounce per far prima, però mi sembra molto pulito, mi piace

ora prova questo con un condensatore ceramico in parallelo al pulsante ridotto ancora più pulito senza debounce :slight_smile:

const int buttonPin = 6;
const int ledPin =  13;

boolean ledState = false;
int buttonState; 
int lastButtonState = LOW;

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

void loop() {
  buttonState=digitalRead(buttonPin);
  if ((buttonState!=lastButtonState))
  {
    if (buttonState==HIGH){
      ledState^=1;
      digitalWrite(ledPin, ledState);
    }
    lastButtonState=buttonState;
  }
}

pablos:
ora prova questo con un condensatore ceramico in parallelo al pulsante ridotto ancora più pulito senza debounce :slight_smile:

Giusto! Dopo fisica 2 e elettrotecnica dovrei saperle queste cose, invece... :blush: Comunque grazie, proverò. Ciao

Grazie ragazzi, ho provato tutti i modi che mi avete postato. Anche se ad essere sincero quello di Uwe per il mio livello è quello più comprensibile, pur essendo che gli altri due sono molto meno articolati!!
Ho sbagliato quasi completamente l'utilizzo della variabile "a". Con questo esempio ho imparato ad usare la resistenza di pull-up interna di cui ero totalmente allo scuro, ora sorge una domanda, ma è possibile avere anche resistenze di pull-down interne??
Grazie ancora!!

Pullup Resistors

Often it is useful to steer an input pin to a known state if no input is present. This can be done by adding a pullup resistor (to +5V), or a pulldown resistor (resistor to ground) on the input, with 10K being a common value.

There are also convenient 20K pullup resistors built into the Atmega chip that can be accessed from software. These built-in pullup resistors are accessed in the following manner.

pinMode(pin, INPUT); // set pin to input
digitalWrite(pin, HIGH); // turn on pullup resistors

il pull_down ce lo devi mettere tu esternamente

ciao