Istruzioni combinate tra contatto reed e keypad

salve a tutti,

sto cercando di realizzare un affondatore per pastura in sacchetti di rete dalla barca. La parte meccanica è gia stata completata, realizzata con un motorino da tergicristallo. La parte elettronica consiste in un Arduino Mega, un display LCD 16x2, una scheda 4 relè, un keypad a membrana 3 x4. il funzionamento è semplice, premendo in combinazione due tasti il motorino fa scendere il cavetto alla profondità desiderata. Premendo i tasti per la risalita, il motorino parte e si ferma prima con un finecorsa, e poi dopo i secondi del delay. I metri della discesa sono stabiliti con un delay che tiene i relè LOW in base ai giri del motore e alla circonferenza della bobina su cui è avvolto il cavetto. Fin qui tutto bene, questa è una parte del codice, funziona, ma chiedo venia per gli errori che eventualmente ci saranno.

// AMBROGINO DA AMBROGIO DEI ROCHER E ARDUINO.
// AIUTANTE ADDETTO AL SACCHETTO DELLA PASTURA.
// MOTORE 42 GG/min - BOBINA RECUPERA 10,433 MT IN 10 SEC. = 1,0433 AL MILLISECONDO = 1 MT = 958 MSECONDI
#include <Keypad.h>
#include <LiquidCrystal.h>
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
 {'1','2','3'},
 {'4','5','6'},
 {'7','8','9'},
 {'#','0','*'}
};
byte rowPins[ROWS] = {26, 28, 30, 32}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {34, 36, 38}; //connect to the column pinouts of the keypad
//int j = 0;
//int x = 0;
char code [2]; 
char key;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

int relediscesaneg = 62; // SU IN1 
int relediscesapos = 63; // SU IN2
int relesalitapos = 64; // SU IN3 
int relesalitaneg= 65; // SU IN4 

int stato_relediscesaneg = 0;
int stato_relediscesapos = 0;
int stato_relesalitapos = 0;
int stato_relesalitaneg = 0;


void setup()
{
Serial.begin(9600);
 pinMode(relediscesapos, OUTPUT);    
 digitalWrite(relediscesapos, HIGH);
 pinMode(relediscesaneg, OUTPUT);    
 digitalWrite(relediscesaneg, HIGH);
 pinMode(relesalitapos, OUTPUT);    
 digitalWrite(relesalitapos, HIGH);
 pinMode(relesalitaneg, OUTPUT);    
 digitalWrite(relesalitaneg, HIGH);

lcd.begin(16, 2);
lcd.print(" Ambrogino Lift ");
lcd.setCursor(0,2);
lcd.print("Ins. Prof.2 Num.");

}
void loop()
{
   if (key != NO_KEY)
 Serial.println(key);
        
 key = keypad.waitForKey();
  code
= key;

    
 key = keypad.waitForKey();
  code [1] = key;
 
 
 // =============INIZIO BLOCCO CINQUE DIECI ============
}
 if ((code[0] == '0') && (code[1] == '5')) {  
 lcd.setCursor(0,2);
 lcd.print("Discesa 5 metri ");
 digitalWrite(relediscesaneg, LOW);
 digitalWrite(relediscesapos, LOW);
 delay(5*958); // 4790
 digitalWrite(relediscesaneg, HIGH);
 digitalWrite(relediscesapos, HIGH);
 lcd.setCursor(0,2);
 lcd.print("Pastura  a  5 mt ");
}

Volendo diminuire la velocità di discesa e se occorre aumentare la velocità di risalita, ho usato un variatore di velocità. Sorge ora la necessità di contare i giri della ruota, e ho tentato con questa altra parte di codice, che mi sembra funzioni, conta il numero di giri e lo divide per tre (il diametro è 10,6 cm) e mi restituisce i metri di profondità.

#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
int RELE = 64;

const int ContattoReed = A0; 
int Contagiri = 0;   
int Stato = 0;        
int UltimoStato = 0;    

int Profondita = 0;
int Metri = 0;     
void setup() 
  { 
 pinMode(ContattoReed, INPUT);
 pinMode(RELE, OUTPUT);
 digitalWrite(RELE, HIGH);
 lcd.begin(16, 2);
 lcd.print(" Reed Contagiri");
 lcd.setCursor(0,2);
 lcd.print("contametri      ");
}
     
 void loop() 
    
   { 
     // digitalWrite(RELE, LOW);
   // read the pushbutton input pin:
 Stato = digitalRead(ContattoReed);
 if (Stato != UltimoStato) {
 if (Stato == HIGH)
 {
 delay(200);
 Contagiri++;
 float Metri=(Contagiri/3);
   lcd.setCursor(0,2);
 lcd.print("Profondita  -   ");
 lcd.setCursor(13,2);
 lcd.print(Metri,0);
   } 
 }
 
 UltimoStato = Stato;
// Profondita = Metri;
 if (Contagiri == 3*4) {
   digitalWrite(RELE, LOW);
 } 
   if (Contagiri == 3*11) {
   digitalWrite(RELE, HIGH);
   //(Contagiri = 0);
   lcd.setCursor(0,2);
   //lcd.print("                ");
   lcd.setCursor(0,2);
   lcd.print("Arrivo a -");
   lcd.setCursor(11,2);
   lcd.print(Metri,0);
   lcd.setCursor(13,2);
   lcd.print(" Mt");
} 
  }

[
Ho cercato di unire i due codici, con l'intenzione per esempio, premendo 05 sul keypad, i relè discesa vanno in LOW, dopo 5 metri, contati dal reed, i relè vanno HIGH.
Non riesco a far funzionare questa parte di codice, chiedo aiuto , umilmente, se possibile.
Grazie

if ((code[0] == '0') && (code[1] == '3')){  
  {
  lcd.setCursor(0,2);
  lcd.print("Discesa 3 metri ");
  delay(2000);
  digitalWrite(relediscesaneg, LOW);
  digitalWrite(relediscesapos, LOW); 
    {   
     Stato = digitalRead(ContattoReed);
     if (Stato != UltimoStato)
      { if (Stato == HIGH)
       {
       delay(200);
       Contagiri++;
       float Metri=(Contagiri/3);
       lcd.setCursor(0,2);
       lcd.print("Profondita  -   ");
       lcd.setCursor(13,2);
       lcd.print(Metri,0);
      }  
     UltimoStato = Stato;  
            
       
         if (Contagiri == 3*3) {
         digitalWrite(relediscesaneg, LOW);
         digitalWrite(relediscesapos, LOW);
         //(Contagiri = 0);
         lcd.setCursor(0,2);
         //lcd.print("                ");
         lcd.setCursor(0,2);
         lcd.print("Arrivo a -");
         lcd.setCursor(11,2);
         lcd.print(Metri,0);
         //lcd.setCursor(13,2);
         //lcd.print(" Mt");
     } 
   }

Dovresti ripostare il codice "unito" (l'ultimo modificato) e dettagliare meglio con parole tue cosa non funziona. Isola la parte di codice che ti sembra non funzionare con la tag 'code'

Ho risposto io , ma sia chiaro io non sono esperto.

Ok Victor,

stasera mi ci metto e cerco di essere più chiaro,
mi rendo conto che forse la cosa non è così semplice come pensavo.

Grazie

Comunque il problema è che non ti funziona il keypad?

Premendo i tasti per la risalita, il motorino parte e si ferma prima con un finecorsa, e poi dopo i secondi del delay

quante volte si ferma ?

Attenzione che: key = keypad.waitForKey(); è bloccante.
reference

Non so se questo metodo sia adatto, se lo ritieni adatto non considerare quanto segue:

Bloccante in questo caso vuol dire che tutto il resto del codice non verrà eseguito fino al momento che non si preme un tasto. Una volta premuto il tasto il resto del codice viene eseguito fino ad incontrare nuovamente waitForKey().

Il metodo che userei è il seguente:boolean keyStateChanged()
Il metodo keyStateChanged() restituisce un valore true se lo stato della tastiera è stato modificato, diversamente restituisce false.

Lo stato della tastiera può essere uno dei seguenti:IDLE, PRESSED, RELEASED and HOLD.

Ad esempio se premi e mantieni premuto un tasto, lo stato della tastiera passa ad HOLD, quando lo rilasci dovrebbe passare a RELEASED o IDLE(non ho la lib per guardarci dentro).

keyStateChanged() restituisce true quando:
da IDLE passa a HOLD
dal HOLD passa a IDLE
da ecc,

In sostanza quando lo stato interno si modifica a seguito della interazione utente.

Quindi nel loop inserirei:

if ( keypad.keyStateChanged() {
    switch( keypad.getKey() ) {
    case 1:
         // fai le tuo operazioni
         break;
    case 2:
         // fai le tuo operazioni
         break; 
    // case ecc
    }

}

Anche: KeyState getState() è interessante, essa restituisce uno dei precedenti stati elencati.

Ciao.

Grazie Mauro,

non so se posso risolvere con lo switch case, o almeno non riesco io a capire come fare.
Per Victor, con il keypad, con la combinazione di due tasti, 02, 03, 12, etc riesco a far attivare i relè, far girare la ruota per tot giri e fermarmi a x metri di profondità con questo codice

#include <Keypad.h>
#include <LiquidCrystal.h>
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'#','0','*'}
};
byte rowPins[ROWS] = {26, 28, 30, 32}; 
byte colPins[COLS] = {34, 36, 38}; 
char code [2]; 
char key;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

int relediscesaneg = 62; // SU IN1 
int relediscesapos = 63; // SU IN2
int stato_relediscesaneg = 0;
int stato_relediscesapos = 0;

void setup()
{
  pinMode(relediscesapos, OUTPUT);    
  digitalWrite(relediscesapos, HIGH);
  pinMode(relediscesaneg, OUTPUT);    
  digitalWrite(relediscesaneg, HIGH);
  
lcd.begin(16, 2);
lcd.print(" Ambrogino Lift ");
lcd.setCursor(0,2);
lcd.print("Ins. Prof.2 Num.");

}
void loop()
{
    if (key != NO_KEY)
  Serial.println(key);
         
  key = keypad.waitForKey();
   code [0] = key;
     
  key = keypad.waitForKey();
   code [1] = key;
  
  if ((code[0] == '0') && (code[1] == '3')) {  
  lcd.setCursor(0,2);
  lcd.print("Discesa 3 metri ");
  digitalWrite(relediscesaneg, LOW);
  digitalWrite(relediscesapos, LOW);
  delay(3*958); // 4790
  digitalWrite(relediscesaneg, HIGH);
  digitalWrite(relediscesapos, HIGH);
  lcd.setCursor(0,2);
  lcd.print("Pastura  a  3 mt ");
 } 
}

Ho provato a inserire un contatto reed normalmente aperto, girando manualmnte la ruota segna sul display la profondità crescente in metri, attiva e disattiva i relè alle profondità desiderate, con questo codice

#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

int relediscesaneg = 62; // SU IN1 
int relediscesapos = 63; // SU IN2

int stato_relediscesaneg = 0;
int stato_relediscesapos = 0;
 
const int ContattoReed = A0; //pin di imput contatto reed
int Contagiri = 0;   // counter for the number of button presses
int Stato = 0;         // current state of the button
int UltimoStato = 0;     // previous state of the button

int Profondita = 0;
int Metri = 0;     
 void setup() 
   { 
  pinMode(ContattoReed, INPUT);
  pinMode(ContattoReed, INPUT);
  pinMode(relediscesapos, OUTPUT);    
  digitalWrite(relediscesapos, HIGH);
  pinMode(relediscesaneg, OUTPUT);    
  digitalWrite(relediscesaneg, HIGH);
  lcd.begin(16, 2);
  lcd.print(" Reed Contagiri");
  lcd.setCursor(0,2);
  lcd.print("  Contametri  ");
 }
      
  void loop() 
     
    { 
   Stato = digitalRead(ContattoReed);
  if (Stato != UltimoStato) {
  if (Stato == HIGH)
  {
  delay(200);
  Contagiri++;
  float Metri=(Contagiri/3);
    lcd.setCursor(0,2);
  lcd.print("Profondita  -   ");
  lcd.setCursor(13,2);
  lcd.print(Metri,0);
    } 
  }
  
  UltimoStato = Stato;
  if (Contagiri == 3*1) //CORRISPONDE A 1 MT
  {
    digitalWrite(relediscesaneg, LOW);
    digitalWrite(relediscesapos, LOW); 
  } 
    if (Contagiri == 3*3) {
    digitalWrite(relediscesaneg, HIGH);
    digitalWrite(relediscesapos, HIGH); 
    lcd.setCursor(0,2);
    lcd.setCursor(0,2);
    lcd.print("Arrivo a ");
    lcd.setCursor(11,2);
    lcd.print(Metri,0);
    lcd.setCursor(13,2);
    lcd.print(" Mt");
     } 
   }

Cio che non riesco a capire, è come poter fare ad attivare i relè da tastiera, la ruota gira, il cavetto scente, e far fermare la ruota disattivando i relè dopo tot giri. Ho provato questo codice, si attivano i relè, la ruota gira ma non si attiva il reed, non segna i metri e non si disattivano mai i relè.

#include <Keypad.h>
#include <LiquidCrystal.h>

//blocco reed
const int ContattoReed = A0; 
int Contagiri = 0;   
int Stato = 0;        
int UltimoStato = 0;    
int Profondita = 0;
int Metri = 0;     
//fine blocco reed

const byte ROWS = 4; 
const byte COLS = 3; 
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'#','0','*'}
};
byte rowPins[ROWS] = {26, 28, 30, 32}; 
byte colPins[COLS] = {34, 36, 38}; 

char code [2]; 
char key;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

int relediscesaneg = 62; // SU IN1 
int relediscesapos = 63; // SU IN2

int stato_relediscesaneg = 0;
int stato_relediscesapos = 0;


void setup()
{
  pinMode(ContattoReed, INPUT);
  pinMode(relediscesapos, OUTPUT);    
  digitalWrite(relediscesapos, HIGH);
  pinMode(relediscesaneg, OUTPUT);    
  digitalWrite(relediscesaneg, HIGH);
  
lcd.begin(16, 2);
lcd.print("AmbReed 11091027");
lcd.setCursor(0,2);
lcd.print("contametri");

}
void loop()
{
    if (key != NO_KEY)
  Serial.println(key);
         
 key = keypad.waitForKey();
   code [0] = key;
     
  key = keypad.waitForKey();
   code [1] = key;

//======INIZIO BLOCCO PROVA TASTIERA E REED ===============
           
  if ((code[0] == '0') && (code[1] == '3'))  
  {
  lcd.setCursor(0,2);
  lcd.print("Discesa 3 metri ");
  delay(2000);
  digitalWrite(relediscesaneg, LOW);
  digitalWrite(relediscesapos, LOW); 
    {   
     Stato = digitalRead(ContattoReed);
     if (Stato != UltimoStato)
      { if (Stato == HIGH)
       {
       delay(200);
       Contagiri++;
       float Metri=(Contagiri/3);
       lcd.setCursor(0,2);
       lcd.print("Profondita  -   ");
       lcd.setCursor(13,2);
       lcd.print(Metri,0);
      }  
     UltimoStato = Stato;  
             
         if (Contagiri == 3*3) {
         digitalWrite(relediscesaneg, LOW);
         digitalWrite(relediscesapos, LOW);
         //(Contagiri = 0);
         lcd.setCursor(0,2);
         //lcd.print("                ");
         lcd.setCursor(0,2);
         lcd.print("Arrivo a -");
         lcd.setCursor(11,2);
         lcd.print(Metri,0);
         //lcd.setCursor(13,2);
         //lcd.print(" Mt");
         } 
       }
     }
   }
 }
 //======FINE BLOCCO PROVA TASTIERA E REED ===============

Sono ad un punto morto.

Grazie a tutti

ciao

Maurizio

Non so se è un refuso ma sembra che hai una parentesi in più.

if ((code[0] == '0') && (code[1] == '3')) 
  {
  lcd.setCursor(0,2);
  lcd.print("Discesa 3 metri ");
  delay(2000);
  digitalWrite(relediscesaneg, LOW);
  digitalWrite(relediscesapos, LOW);
    {   <--------------- ????
     Stato = digitalRead(ContattoReed);

Finisco di leggerlo.

I delay sembrano un problema .

Lo sono, ma anche key = keypad.waitForKey(); crea lo stesso problema o, almeno gli stessi effetti di delay ma molto più netti.

Credo che @maumari non abbia chiaro il concetto di funzione bloccante, perché diversamente avrebbe già individuato il/i problema/i, magari non saprebbe come risolverli, ma li avrebbe individuati.

Se potessi formattare il codice usando l'opzione offerta dall'ide io forse riuscirei a leggere meglio il codice.

Tu non ti rendi conto che questo pezzo di codice viene eseguito due volte.

   if (key != NO_KEY)
  Serial.println(key);
         
  key = keypad.waitForKey();
   code [0] = key;
     
  key = keypad.waitForKey();
   code [1] = key;

La prima volta dopo che il display stampa [Ins. Prof.2 Num.].
La seconda volta quando la funzione loop() termina e ciò si verifica alla riga dove c'è la parentesi graffa di chiusura, la quale delimita una porzione di codice legata ad una funzione. Quando la funzione loop() termina restituisce il controllo alla codice arduino che chiama nuovamente la funzione loop().

Quindi il codice nel loop in effetti viene eseguito una sola volta, perché al secondo ciclo il codice poco sopra viene eseguito ed attende quindi l'inserimento dei due dati.

Di soluzioni c'è ne sono tante, molte però richiedono l'uso di codice che farai fatica a comprendere, esempio sai cosa è in C una union?

Tieni duro che ad una soluzione che puoi comprendere prima o poi ci si arriva. Avrei anche bisogno di sapere se per te
è più importante questa applicazione o è più importante imparare a creare applicazioni embedded.

Ciao.

In questo modo il loop non dovrebbe fermarsi in attesa di un tasto premuto.

#include <Keypad.h>
#include <LiquidCrystal.h>

//blocco reed
const int ContattoReed = A0;
int Contagiri = 0;   
int Stato = 0;       
int UltimoStato = 0;   
int Profondita = 0;
int Metri = 0;     
//fine blocco reed

const byte ROWS = 4;
const byte COLS = 3;
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'#','0','*'}
};
byte rowPins[ROWS] = {26, 28, 30, 32};
byte colPins[COLS] = {34, 36, 38};

char code [2];
char key;

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);

int relediscesaneg = 62; // SU IN1
int relediscesapos = 63; // SU IN2

int stato_relediscesaneg = 0;
int stato_relediscesapos = 0;


void setup()
{
  pinMode(ContattoReed, INPUT);
  pinMode(relediscesapos, OUTPUT);   
  digitalWrite(relediscesapos, HIGH);
  pinMode(relediscesaneg, OUTPUT);   
  digitalWrite(relediscesaneg, HIGH);
 
lcd.begin(16, 2);
lcd.print("AmbReed 11091027");
lcd.setCursor(0,2);
lcd.print("contametri");

}

byte keyCounter = 0;
void loop()
{
    if ( keypad.keyStateChanged() ) {
         key = keypad.getKey();
        
        if (key != NO_KEY) {
            if (keyCounter == 0 ) {
                code [0] = key;
                keyCounter = 1;
            } else if ( keyCounter == 1 ) {
                 code [1] = key;
                 keyCounter = 0;
            }
        }
   }

//======INIZIO BLOCCO PROVA TASTIERA E REED ===============
           
  if ((code[0] == '0') && (code[1] == '3')) 
  {
  lcd.setCursor(0,2);
  lcd.print("Discesa 3 metri ");
  delay(2000);
  digitalWrite(relediscesaneg, LOW);
  digitalWrite(relediscesapos, LOW);
    {   
     Stato = digitalRead(ContattoReed);
     if (Stato != UltimoStato)
      { if (Stato == HIGH)
       {
       delay(200);
       Contagiri++;
       float Metri=(Contagiri/3);
       lcd.setCursor(0,2);
       lcd.print("Profondita  -   ");
       lcd.setCursor(13,2);
       lcd.print(Metri,0);
      } 
     UltimoStato = Stato; 
             
         if (Contagiri == 3*3) {
         digitalWrite(relediscesaneg, LOW);
         digitalWrite(relediscesapos, LOW);
         //(Contagiri = 0);
         lcd.setCursor(0,2);
         //lcd.print("                ");
         lcd.setCursor(0,2);
         lcd.print("Arrivo a -");
         lcd.setCursor(11,2);
         lcd.print(Metri,0);
         //lcd.setCursor(13,2);
         //lcd.print(" Mt");
         }
       }
     }
   }
 }
 //======FINE BLOCCO PROVA TASTIERA E REED ===============

Ci sono sempre i delay da rimuovere e ciò comporta un poco di stravolgimento.

Ciao.

MauroTec:
Lo sono, ma anche key = keypad.waitForKey(); crea lo stesso problema o, almeno gli stessi effetti di delay ma molto più netti...

Si esatto è bloccante

Maumari hai scritto due volte questo codice, anche quanto " contagiri = 3*3".
Con questo codice spegni o accendi il motore?Credo tu voglia spegnerlo quindi probabilmente sarà HIGH,

confermi ?

digitalWrite(relediscesaneg, LOW);
digitalWrite(relediscesapos, LOW);
if (Contagiri == 3*3)
        {
            digitalWrite(relediscesaneg, LOW);
            digitalWrite(relediscesapos, LOW);

Chiedo non perchè credo sia il problema principale , ma dopo ti chiederò un'altra cosa

Un soluzione potrebbe essere questa ma dipende dalle tue esigenze.

Il contagiri, invece di leggerlo nel main , lo leggi su un interrupt così ti svincoli dal main.

Edit:
Su google troverai tanti esempi.

Victor795: Prima di dare suggerimenti usando l'interrupt ... sarebbe bene che IMPARASSI ad usare gli interrupt ! :smiling_imp:

Una ISR DEVE essere la più veloce possibile e quindi, ad esempio, alzare una flag, incrementare un contatore, ma NON di certo fare tutto quello che tu ci hai infilato, senza tenere inoltre conto che, in una ISR, gli interrupt sono disabilitati e quindi non si devono usare altre funzioni che ... usano gli interrupt.

Quindi ... quel tuo codice è diseducativo, da NON usare e ... da riscrivere !

Guglielmo

Regole fondamentali da rispettare in una ISR (© Nick Gammon :wink:) :

When writing an Interrupt Service Routine (ISR):

• Keep it short
• Don't use delay ()
• Don't do serial prints
• Make variables shared with the main code volatile
• Variables shared with main code may need to be protected by "critical sections"
• Don't try to turn interrupts off or on

Warning: Since interrupts are disabled inside an ISR, and since the latest version of the Arduino IDE uses interrupts for Serial reading and writing, and also for incrementing the counter used by "millis" and "delay" you should not attempt to use those functions inside an ISR.

Per la trattazione dettagliata e completa dell'argomento (da STUDIARE) ... QUI

Guglielmo

gpb01:
Regole fondamentali da rispettare in una ISR (© Nick Gammon :wink:) :

Per la trattazione dettagliata e completa dell'argomento (da STUDIARE) ... QUI

Guglielmo

Se ti riferisci alla serial, e solo un debug temporaneo. Non è un codice definitivo ma uno spunto :slight_smile:

Victor795:
Non è un codice definitivo ma uno spunto :slight_smile:

Dare "spunti" diseducativi ed errati NON è lo scopo di questo forum ... :smiling_imp:

Guglielmo

Buongiorno,

sono fuori casa per lavoro, stasera proverò a combinare qualcosa,
intanto vi ringrazio tutti per l'aiuto.

Grazie ancora a Guglielmo, a cui in particolare chiedo scusa
per le parole di ieri, purtroppo a me capita ogni tanto
di far trasparire in faccende che niente hanno a vedere,
l'irritazione causata da altre situazioni.

Un saluto a tutti

gpb01:
Dare "spunti" diseducativi ed errati NON è lo scopo di questo forum ... :smiling_imp:

Guglielmo

Mi adeguo al regolamento. Posto rivisto e corretto. :wink:

ciao

@gpb01

Dare "spunti" diseducativi ed errati NON è lo scopo di questo forum ... :smiling_imp:

Vero, però tutto sto veleno perché? Pensi sia educativo questo atteggiamento?

@Victor795

Ti consiglio prima di puntare a far funzionare il contagiri con l'interrupt

Introdurre l'uso di interrupt per contare eventi è sicuramente un buon consiglio, tuttavia io ho evitato di introdurre cose complesse perché @maumari ha limitate competenze; potrebbe pensare bene di usare delay(2000) dentro la funzione utente attaccata all'interrupt, senza sapere che come recita @Nick Gammon è una cosa da evitare.

Sicuramente potrebbe creare un altro progetto separato dove impiega gli interrupt per contare eventi; con l'intento di capire come funzionano e come usarli. Poi dopo avere acquisito maggiori competenze può decidere di introdurre il conteggio tramite interrupt nel codice dell'applicazione che sta sviluppando.

Se ti riferisci alla serial, e solo un debug temporaneo. Non è un codice definitivo ma uno spunto :slight_smile:

Il problema è che molto probabilmente lui non lo sa, e pensa si possa fare.

@maumari
Purtroppo come avrai intuito il tuo programma deve essere rivisto pesantemente; il codice non è la risultante di analisi del problema, oppure l'analisi è errata.

Valido invece è il modo di usare la tastiera, il primo byte seleziona l'operazione, il secondo fornisce l'argomento.
Ad esempio a rigor di logica se inserisco 00 equivale a non fare nulla. In seguito quando avrai più esperienza potrai usare
il display e la tastiera in modo più ingegnoso, ad esempio userai la libreria Menu o MENWIZ per rendere l'applicazione interattiva.

L'analisi mi appare errata
Mi pare errata per vari motivi, ma al momento per semplificare mi concentro sul fatto seguente:
Dopo avere acquisito comando e argomento da tastiera, il codice impiegherà un certo tempo per compiere l'azione richiesta, durante questo tempo l'interazione con l'utente tramite tastiera deve essere limitata o completamente disabilitata, in quest'ultimo caso, durante il tempo necessario a compiere l'azione richiesta (azionare il motore fino a raggiungere tot metri) lo stato dell'applicazione dovrebbe essere BUSY (impegnata), per poi passare a IDLE quando tot metri sono stati raggiunti.

Questo meccanismo può essere implementato tramite un flag boolean come da esempio:

boolean appState = 0;  // 0 significa IDLE
if ( appState == 0 ) {
   enableUserInteration();  // abilita l'interazione utente al fine di inserire dei dati tramite tastiera
} else {
   // esegue [i]comando[/i] e [i]argomento[/i] inseriti in modo IDLE
   appState = 1;   // 1 significa BUSY, quindi impegnata a compiere un'azione
   // Controlla se l'azione è stata completata, se si cambia stato ad appState
   // if ( actionCompleted() )
   //     appState = 0; 
}

Il codice sopra serve solo come supporto all'analisi e quindi non va inserito nell'ide.

Ciao.

[Edit: Cavolo @Victor795 hai postato prima di me, io nel mio post faccio riferimento ai tuoi suggerimenti, che però hai modificato.

MauroTec:
@gpb01
Vero, però tutto sto veleno perché? Pensi sia educativo questo atteggiamento?

Veleno ? ? ? ... se non distingui il "sarcasmo" dal "veleno" sei messo male ! :smiling_imp:

E comunque ribadisco (... e non sono il solo qui) che i cosigli si dovrebbero dare quando si conosce esattamente ciò di cui si parla, altrimenti si dovrebbe evitare, dato che informazioni errate sono più dannose che benefiche.

Guglielmo

E comunque ribadisco (... e non sono il solo qui) che i cosigli si dovrebbero dare quando si conosce esattamente ciò di cui si parla, altrimenti si dovrebbe evitare, dato che informazioni errate sono più dannose che benefiche.

Si ok, ma così finisce che le risposte arrivano solo da pochi eletti e questo non è un problema da sottovalutare; è questo che che vogliamo ottenere? Non penso.

Siamo entrambi in sintonia piena nella lotta alla informazione distorta, ma non si può arrivare a bacchettare tutti quelli che hanno la volontà di ricambiare l'aiuto ricevuto, ma non hanno una competenza estrema (che solo pochi eletti possiedono).

Su questo punto forse se lo ritieni opportuno se ne può discutere in altro posto per approfondire senza inquinare il post attuale, ovviamente sempre se altri utenti (da sempre presenti) hanno interesse a discuterne.

Veleno ? ? ? ... se non distingui il "sarcasmo" dal "veleno" sei messo male !

;D

Ciao.