Contatore up douw

Buona giornata a tutti cortesemente ho bisogno del vostro aiuto, come da titolo sto sto facendo un contattore con due sensori hall, con 4 display a 7 segmenti, il mio problema ora e di far incrementare il cunter "variabile del contatore" di una unita, ovviamente con la semplice lettura del pin questo continua ad incrementare in continuazione, o cercato una soluzione in rete, o trovato qui questa discussione https://forum.arduino.cc/index.php?topic=352346.0 ma non mi funziona, forse son tonto non capisco, posto una parte del codice di controllo dei sensori

Valbuton_1 = digitalRead(buton_1);
    if((Valbuton_1 != Statbuton_1) && (Statbuton_1 == 1)){

        cunter++;
        Statbuton_1 = Valbuton_1;
    }
    if((Valbuton_1 != Statbuton_1) && (Statbuton_1 == 0)){
        Statbuton_1 = Valbuton_1;
    }

per cortesia qualcuno mi potrebbe aiutare a capire dove sbaglio mille grazie a chi mi può aiutare

In che senso non ti va?

Devo do me quel codice incrementa il contatore ( conter partirooo, su butun che io lo sooooo)

scusa l'intermezzo canterino...

Dicevo incrementa il contatore tutte le volte che il sensore viene impegnato e poi liberato, quando viene liberato intendo...

Cosa ti fa?

Non conta? Conta troppo? Non torna indietro?

Se capisco il problema magari ti posso aiutare....

Come hai connesso i sensori ? ... se chiudono verso massa o se chiudono verso VCC, la logica dei controlli e' invertita ...

milefori: il mio problema ora e di far incrementare il cunter "variabile del contatore" di una unita, ovviamente con la semplice lettura del pin questo continua ad incrementare in continuazione,

Se vorresti incrementare il contatore ed il programma te lo incrementa, scusa, ma quale sarebbe il problema? ;D

PS: non è obbligatorio dare alle variabili nomi in inglese ;) puoi anche chiamarle "contatore" o "conta", visto che in inglese "cunt" è un'altra cosa, e non mi pare il caso... :D

È il caso, invece, secondo me

Dal m io punto di vista quel contatore deve essere sempre saturo....

intanto mille grazie per avermi risposto,

docsavage

In che senso non ti va?

proprio non conta,passo il magnete sul sensore ma non conta

Etemenanki questo e il datasheet del sensore, e cosi io l'ho collegato con una resistenza da 10K al positivo http://pdf1.alldatasheet.com/datasheet-pdf/view/149127/ANACHIP/AH337.html

la logica dei controlli e' invertita

ed e questo che non capisco come posso fare per invertire i controlli, mi puoi dare qualche suggerimento per risolvere il problema?

docdoc

ovviamente con la semplice lettura del pin questo continua ad incrementare in continuazione,

intendevo dire che al passaggio del magnete sul sensore mi incrementa più di un unita, ed invece quello che io voglio che incrementi di una solo unita

ovviamente se vi servono altre informazioni son ben lieto di darle

milefori: docsavage proprio non conta,passo il magnete sul sensore ma non conta

docdoc intendevo dire che al passaggio del magnete sul sensore mi incrementa più di un unita, ed invece quello che io voglio che incrementi di una solo unita

Beh queste due frasi sono in apparente contrasto... :o Passi il magnete e non conta, o passi il magnete e conta anche troppo? 8)

Se è la prima, potrebbe essere un problema di cablaggi o di come tu intercetti il cambiamento (usi interrupt? come è configurato?). Postare lo schema dei collegamenti e possibilmente anche l'intero sketch potrebbe aiutare a capire meglio.

Ma anche se è la seconda, credo che la cosa migliore sia postare il tuo intero sketch.

In generale, posso dirti che sono quelle if() a non andare bene, in linea di massima (dò per scontato che tu stia nel loop()) ti scrivo i miei commenti (assumendo che Statbuton tu lo inizializzi a 0):

// qui leggi il valore del bottone ossia del sensore
Valbuton_1 = digitalRead(buton_1);
// quindi se il valore corrente è diverso dal precedente e Statbuton è uguale ad 1
if((Valbuton_1 != Statbuton_1) && (Statbuton_1 == 1)){
  // incrementi il contatore
  cunter++;
  // metti in Statbuton il valore corrente
  Statbuton_1 = Valbuton_1;
}
// quindi verifichi di nuovo se il valore è diverso dal precedente (se è entrato nella 
// if precedente qui non entrerà mai!!!) e se Statbuton è 0 (che è poi il valore 
// precedente appena letto!)
if((Valbuton_1 != Statbuton_1) && (Statbuton_1 == 0)){
  Statbuton_1 = Valbuton_1; // qui ci entra sempre fino a che non si attiva l'input
}

Lo "stato precedente" devi aggiornarlo solo quando è diverso dal precedente ed indipendentemente dal test, incrementando solo se il valore attuale è diverso dal precedente e non rifare il controllo una seconda volta. Per cui semplificherei il tutto in questo modo (ti sto scrivendo "al volo", ma in pratica è la classica gestione anche dei pulsanti):

Valbuton_1 = digitalRead(buton_1);
// quindi se il valore corrente è diverso dal precedente
if (Valbuton_1 != Statbuton_1) {
  // Se il valore corrente è 1
  if (Valbuton_1 == 1) {
    // incrementi il contatore
    cunter++;
  }
  // metti in Statbuton il valore corrente, per la prossima iterazione
  Statbuton_1 = Valbuton_1;
}

Prova e fammi sapere. Ma posta tutto lo sketch se vuoi altri consigli!

Chiude verso massa, quindi dovrebbe andare bene ... domanda scontata, ma ... stai usando il magnete nel senso giusto ? ... quei sensori sono "unipolari", quindi il magnete viene letto solo se passa con il polo corretto davanti al sensore ... per quelli SMD, il nord dalla parte della scritta, oppure il sud dalla parte opposta, per quelli passanti, l'opposto, come c'e' sul disegno del datasheet ...

Poi, hai provato con un pulsante collegato al posto del sensore (fra massa e pin, con la resistenza fra pin e VCC), a vedere se magari lo sketch funziona, e che non sia il sensore che non va ?

Stessa domanda che avrei fatto io

Isola il problema

Conta con un pulsante?

Sente i rimbalzi?

Il sensore provato con un tester, va?

allora prima di collegare i sensori o provato con i pulsanti, stessa cosa,
posto lo sketch

#include <Arduino.h>

#define buton_1 14

int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int f = 6;
int g = 7;
int p = 8;

int displayU = 8;
int displayD = 9;
int displayC = 10;
int displayM = 11;

long cunter = 0;
int x = 100;
int del = 55;  

byte Valbuton_1 = 0;
byte Statbuton_1 = 0;

void pickDigit(int x);
void pickNumber(int x);
void clearLEDs(void);
void zero(void);
void one(void);
void two(void);
void three(void);
void four(void);
void five(void);
void six(void);
void seven(void);
void eight(void);
void nine(void);

void setup()
{
 
 pinMode(buton_1, INPUT_PULLUP);
 digitalWrite(buton_1, HIGH);
 
 pinMode(displayM, OUTPUT);
 pinMode(displayC, OUTPUT);
 pinMode(displayD, OUTPUT);
 pinMode(displayU, OUTPUT);
 
 pinMode(a, OUTPUT);
 pinMode(b, OUTPUT);
 pinMode(c, OUTPUT);
 pinMode(d, OUTPUT);
 pinMode(e, OUTPUT);
 pinMode(f, OUTPUT);
 pinMode(g, OUTPUT);
 pinMode(p, OUTPUT);
}

void loop()
{
 
 Valbuton_1 = digitalRead(buton_1);
 if((Valbuton_1 != Statbuton_1) && (Statbuton_1 == 1)){
 
 cunter++;
 Statbuton_1 = Valbuton_1;
 }
 if((Valbuton_1 != Statbuton_1) && (Statbuton_1 == 0)){
 Statbuton_1 = Valbuton_1;
 }
 
 clearLEDs();
 pickDigit(1);
 pickNumber((cunter/x/1000)%10);
 delayMicroseconds(del);
 
 clearLEDs();
 pickDigit(2);
 pickNumber((cunter/x/100)%10);
 delayMicroseconds(del);
 
 clearLEDs();
 pickDigit(3);
 pickNumber((cunter/x/10)%10);
 delayMicroseconds(del);
 
 clearLEDs();
 pickDigit(4);
 pickNumber(cunter/x%10);
 delayMicroseconds(del);
 
 if (digitalRead(13) == HIGH)
 {
 cunter = 0;
 }
}

void pickDigit(int x) 
{
 digitalWrite(displayM, LOW);
 digitalWrite(displayC, LOW);
 digitalWrite(displayD, LOW);
 digitalWrite(displayU, LOW);
 
 switch(x)
 {
 case 1:
 digitalWrite(displayM, HIGH);
 break;
 case 2:
 digitalWrite(displayC, HIGH);
 break;
 case 3:
 digitalWrite(displayD, HIGH);
 break;
 default:
 digitalWrite(displayU, HIGH);
 break;
 }
}

void pickNumber(int x) 
{
 switch(x)
 {
 default:
 zero();
 break;
 case 1:
 one();
 break;
 case 2:
 two();
 break;
 case 3:
 three();
 break;
 case 4:
 four();
 break;
 case 5:
 five();
 break;
 case 6:
 six();
 break;
 case 7:
 seven();
 break;
 case 8:
 eight();
 break;
 case 9:
 nine();
 break;
 }
}

void clearLEDs()  
{
 digitalWrite(a, LOW);
 digitalWrite(b, LOW);
 digitalWrite(c, LOW);
 digitalWrite(d, LOW);
 digitalWrite(e, LOW);
 digitalWrite(f, LOW);
 digitalWrite(g, LOW);
 digitalWrite(p, LOW);
}

void zero() 
{
 digitalWrite(a, HIGH);
 digitalWrite(b, HIGH);
 digitalWrite(c, HIGH);
 digitalWrite(d, HIGH);
 digitalWrite(e, HIGH);
 digitalWrite(f, HIGH);
 digitalWrite(g, LOW);
}

void one() 
{
 digitalWrite(a, LOW);
 digitalWrite(b, HIGH);
 digitalWrite(c, HIGH);
 digitalWrite(d, LOW);
 digitalWrite(e, LOW);
 digitalWrite(f, LOW);
 digitalWrite(g, LOW);
}

void two() 
{
 digitalWrite(a, HIGH);
 digitalWrite(b, HIGH);
 digitalWrite(c, LOW);
 digitalWrite(d, HIGH);
 digitalWrite(e, HIGH);
 digitalWrite(f, LOW);
 digitalWrite(g, HIGH);
}

void three() 
{
 digitalWrite(a, HIGH);
 digitalWrite(b, HIGH);
 digitalWrite(c, HIGH);
 digitalWrite(d, HIGH);
 digitalWrite(e, LOW);
 digitalWrite(f, LOW);
 digitalWrite(g, HIGH);
}

void four() 
{
 digitalWrite(a, LOW);
 digitalWrite(b, HIGH);
 digitalWrite(c, HIGH);
 digitalWrite(d, LOW);
 digitalWrite(e, LOW);
 digitalWrite(f, HIGH);
 digitalWrite(g, HIGH);
}

void five() 
{
 digitalWrite(a, HIGH);
 digitalWrite(b, LOW);
 digitalWrite(c, HIGH);
 digitalWrite(d, HIGH);
 digitalWrite(e, LOW);
 digitalWrite(f, HIGH);
 digitalWrite(g, HIGH);
}

void six() 
{
 digitalWrite(a, HIGH);
 digitalWrite(b, LOW);
 digitalWrite(c, HIGH);
 digitalWrite(d, HIGH);
 digitalWrite(e, HIGH);
 digitalWrite(f, HIGH);
 digitalWrite(g, HIGH);
}

void seven() 
{
 digitalWrite(a, HIGH);
 digitalWrite(b, HIGH);
 digitalWrite(c, HIGH);
 digitalWrite(d, LOW);
 digitalWrite(e, LOW);
 digitalWrite(f, LOW);
 digitalWrite(g, LOW);
}

void eight() 
{
 digitalWrite(a, HIGH);
 digitalWrite(b, HIGH);
 digitalWrite(c, HIGH);
 digitalWrite(d, HIGH);
 digitalWrite(e, HIGH);
 digitalWrite(f, HIGH);
 digitalWrite(g, HIGH);
}

void nine() 
{
 digitalWrite(a, HIGH);
 digitalWrite(b, HIGH);
 digitalWrite(c, HIGH);
 digitalWrite(d, HIGH);
 digitalWrite(e, LOW);
 digitalWrite(f, HIGH);
 digitalWrite(g, HIGH);
}

i sensori funzionano, perché se sostituisco quei if con

if(Valbuton_1 ==  0){
cunter++
}

incrementa ma più di un unita,
per lo schema di collegamento dei sensori e cosi semplice che non lo neanche fatto,
ma se volete velo faccio
il magnete e nel senso giusto, perché se cambio gli if conta

Ma scusa, cosa dovrebbe fare il programma

Dal tablet mi sono perso tre volte tentando di capirlo

Prova a semplificare gli if

Valbuton_1 = digitalRead(buton_1);
 if((Valbuton_1 != Statbuton_1) && (Statbuton_1)){

 cunter++;

 }

 Statbuton_1 = Valbuton_1;

La seconda if è inutile La condizione == 1 basta mettere il nome della variabili La statbuton uguale alla valbuton la fai sempre, non serve metterla in if

Non sarà risolutivo, ma semplifica

Le due variabili valbuton e statbuton le dovresti mettere ad 1, non a 0, nella dichiarazione iniziale, perche' parti con l'ingresso tenuto ad 1 dalla resistenza (ma non e' molto influente, al massimo ti fa un conteggio indesiderato all'inizio e poi si portano ad 1) ... e non ho capito bene perche' fai un digitalWrite su buton_1 subito dopo averlo dichiarato come ingresso ... a parte questo, il ciclo di lettura dovrebbe funzionare, almeno in teoria ...

Se fai quella sostituzione, e' ovvio che ti incrementi piu di una unita', perche' la condizione viene controllata ad ogni ciclo del loop, e siccome ogni volta che la controlla e' vera, aggiunge un'altra unita', e questo per tutto il tempo che tieni premuto ... siccome il loop e' molto veloce, anche una pressione breve ti incrementa parecchie unita' ...

docsavage: ... La seconda if è inutile ...

No, non lo e' ... nel suo caso particolare, serve semplicemente a dire allo sketch di ignorare il pulsante per tutto il tempo che rimane premuto, dopo aver eseguito il comando della prima if (e ad azzerare la flag Statbuton quando rilascia il pulsante per dire allo sketch di leggerlo di nuovo se viene ripremuto ... se non la metti, la flag non viene piu azzerata, quindi le pressioni del pulsante successive alla prima verrebbero ignorate) ... con poche modifiche si puo usare anche per eseguire differenti istruzioni solo al rilascio del pulsante, o per eseguire due (o piu, volendo) set diversi di istruzioni in base al tempo in cui il pulsante e' rimasto premuto (anche se questi non sono i suoi casi di utilizzo) ... ;)

Dissento

La statbuton segue la valbuton in ritardo di un passo

Questo grazie all'assegnazione dopo la if

Pertanto il test di differenza fra le due viene superato solo al primo ciclo dopo un cambio di stato

Se il test è superato e input (alto è sottinteso) allora incrementa

Statbuton, in questo caso, e' solo una flag temporanea ... nel primo if, stat e val sono diverse solo nel momento in cui il pulsante viene premuto, quindi il primo if lo esegui solo se stat e' diverso da val E val e' 0 ... qui incrementa, poi porta stat uguale a val, per cui anche se il pulsante rimane premuto, i successivi cicli del loop non lo eseguono, quindi non continuano ad incrementare il contatore ad ogni ciclo (come invece gli succede se sostituisce gli if con un semplice controllo) ... quando rilasci il pulsante, viene eseguito il secondo if (stat diverso da val e pulsante rilasciato), che non fa altro che rimettere stat uguale a val, per consentire di rilevare una nuova pressione del tasto ... senza quello, stat rimarrebbe settato a zero, ed il primo if non verrebbe piu eseguito neppure alla successiva pressione del tasto (perche' avresti o stat diverso da val e val = 1, o stat uguale a val e val = 0, nessuna delle due combinazioni incrementerebbe piu il contatore dopo la prima volta)

Allora o fatto le modifiche suggeritemi da Etemenanki, cioè settate a 1 le due variabili, e commentato digitalWrite su buton_1, a questo punto programmato il micro, il contattore non conta, ovviamente passando il magnete sui sensori alta prova: tolgo il commento a digitalWrite su buton_1 programmo, niente come sopra,

non so se e importante o se sia questo il problema, non sto usando l'IDE di Arduino ma Studio7 e programmo con Atmel ICE

Sarà

Statbuton è globale, mantiene il suo valore Valbuton viene aggiornata uguale allo input ogni ciclo

Prima che statbuton venga posta uguale a valbuton

Sottolineo prima

Viene eseguito il test

Che quindi vale vero solo al primo ciclo dopo un cambio di stato

Io sono in ferie, ho solo tablet e cellulare, ma ieri sera ho scoperto che mio figlio si è portato dietro pc e una uno

Magari nel pomeriggio faccio prova

Anche se sarebbe meglio che la prova la facesse milefori.....

io non sono certamente bravo con il c++, vorrei se mi aiutate a capire una cosa, o cercato in rete cosa fa l'operatore !, mi sembra di capire che:

if(Stat != Val){
codice da eseguire
}

ora se Stat = 0, e Val = 0, la condizione e falsa di conseguenza non viene eseguito il codice sottostane, ditemi, sto sbagliando?

E' un operatore di comparazione, != significa NON uguale, così come == signiica uguale. Studiali nel reference.

Guglielmo

Come dice Guglielmo ... in particolare, nell'esempio, il primo if viene eseguito solo SE (abbrevio) stat e val sono diverse E contemporaneamente val e' 0 (cioe' nel momento in cui il pulsante passa da 1 a 0) ... a questo punto stat viene posto uguale a val, per cui per tutti i successivi cicli del loop, finche' il pulsante rimarra' premuto, l'if NON viene piu eseguito (in modo da incrementare il contatore una sola volta per ogni pressione del tasto) ... il secondo if viene eseguito SOLO nel momento in cui stat e' di nuovo diverso da val E val e' 1 (cioe' nell'istante in cui il pulsante viene rilasciato), e serve solo a resettare stat, in modo che alla prossima pressione del tasto il primo if venga di nuovo eseguito ... se non lo si facesse, il primo if non verrebbe mai piu eseguito, dopo la prima volta che si preme il tasto ...

Se si usano dei pulsanti sarebbe meglio metterci una rete RC di debounce, con i sensori reed non dovrebbe servire, perche' contrariamente ai pulsanti non hanno rimbalzi ...