Arduino Forum

International => Italiano => Software => Topic started by: maumari on Sep 12, 2016, 05:06 pm

Title: Istruzioni combinate tra contatto reed e keypad
Post by: maumari on Sep 12, 2016, 05:06 pm
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.
Code: [Select]

// 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à.
Code: [Select]
#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
Code: [Select]
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");
     }
   }
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 14, 2016, 06:43 pm
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.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: maumari on Sep 14, 2016, 07:04 pm
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
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 14, 2016, 07:22 pm
Comunque il problema è che non ti funziona il keypad?

Quote
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 ?
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Maurotec on Sep 14, 2016, 08:34 pm
Attenzione che: key = keypad.waitForKey(); è bloccante.
reference (http://playground.arduino.cc/Code/Keypad)

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:

Code: [Select]

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.



 
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: maumari on Sep 14, 2016, 10:15 pm
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
Code: [Select]

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

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

Code: [Select]

#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
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 14, 2016, 10:42 pm
Non so se è un refuso ma sembra che hai una parentesi in più.
Code: [Select]

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.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Maurotec on Sep 14, 2016, 11:20 pm
Quote
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.
Code: [Select]

   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.
 
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Maurotec on Sep 15, 2016, 12:10 am
In questo modo il loop non dovrebbe fermarsi in attesa di un tasto premuto.

Code: [Select]


#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.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 15, 2016, 12:16 am
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 ?

Code: [Select]

digitalWrite(relediscesaneg, LOW);
digitalWrite(relediscesapos, LOW);


Code: [Select]

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
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 15, 2016, 12:40 am
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.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: gpb01 on Sep 15, 2016, 06:41 am
>Victor795: Prima di dare suggerimenti usando l'interrupt ... sarebbe bene che IMPARASSI ad usare gli interrupt !  :smiley-evil:

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
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: gpb01 on Sep 15, 2016, 07:03 am
Regole fondamentali da rispettare in una ISR (© Nick Gammon  ;)) :

Quote
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 (http://gammon.com.au/interrupts) 

Guglielmo
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 15, 2016, 08:37 am
Regole fondamentali da rispettare in una ISR (© Nick Gammon  ;)) :

Per la trattazione dettagliata e completa dell'argomento (da STUDIARE) ... QUI (http://gammon.com.au/interrupts)

Guglielmo
Se ti riferisci alla serial, e solo un debug temporaneo. Non è un codice definitivo  ma uno spunto :)
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: gpb01 on Sep 15, 2016, 08:40 am
Non è un codice definitivo  ma uno spunto :)
Dare "spunti" diseducativi ed errati NON è lo scopo di questo forum ...  :smiley-evil:

Guglielmo
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: maumari on Sep 15, 2016, 08:49 am
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
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 15, 2016, 01:11 pm
Dare "spunti" diseducativi ed errati NON è lo scopo di questo forum ...  :smiley-evil:

Guglielmo
Mi adeguo al regolamento. Posto rivisto e corretto. ;)

ciao

Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Maurotec on Sep 15, 2016, 01:39 pm
@gpb01
Quote
Dare "spunti" diseducativi ed errati NON è lo scopo di questo forum ...  :smiley-evil:
Vero, però tutto sto veleno perché? Pensi sia educativo questo atteggiamento?

@Victor795
Quote
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.

Quote
Se ti riferisci alla serial, e solo un debug temporaneo. Non è un codice definitivo  ma uno spunto :)
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:
Code: [Select]

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.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: gpb01 on Sep 15, 2016, 02:10 pm
@gpb01
Vero, però tutto sto veleno perché? Pensi sia educativo questo atteggiamento?
Veleno ? ? ? ... se non distingui il "sarcasmo" dal "veleno" sei messo male ! :smiley-evil:

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
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Maurotec on Sep 15, 2016, 02:31 pm
Quote
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.

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

Ciao.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: gpb01 on Sep 15, 2016, 02:46 pm
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.
Ma dai, non è affatto vero ...
... anzi, oltre l'85% delle risposte e dei suggerimenti sono corrette ... poi c'è un circa 15% che ogni tanto ... le spara grosse senza avere quel minimo di nozioni che servono e, solo quelli ... "vanno riportati sulla giusta strada" ;)

Tutto qui. :)

Guglielmo
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: As_Needed on Sep 15, 2016, 03:26 pm
Se il loop è veloce, basta usare una flag dentro l'interrupt e poi metti quello che devi fare nell'interrupt, nel loop con un if :)
Ci devi contare MauroTec, che Guglielmo è Svizzero  :smiley-twist:  :smiley-mr-green:
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: gpb01 on Sep 15, 2016, 03:37 pm
Se il loop è veloce, basta usare una flag dentro l'interrupt e poi metti quello che devi fare nell'interrupt, nel loop con un if :)
E' infatti la forma più semplice ...
... la ISR alza una flag ... che viene controllata ad ogni giro del loop().

Ovvio che il loop() deve essere scritto in modo NON bloccante e deve girare velocemente, altrimenti occorre necessariamente strutturare diversamente il codice.

Guglielmo
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: As_Needed on Sep 15, 2016, 04:43 pm
Ovvio che il loop() deve essere scritto in modo NON bloccante e deve girare velocemente, altrimenti occorre necessariamente strutturare diversamente il codice.

Guglielmo
Ovvio, però un loop molto lungo può essere anche lento un paio di secondi.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: gpb01 on Sep 15, 2016, 04:46 pm
Ovvio, però un loop molto lungo può essere anche lento un paio di secondi.
... mi costringi ad auto-quotarmi ... :D

... deve girare velocemente, altrimenti occorre necessariamente strutturare diversamente il codice.
Guglielmo
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: As_Needed on Sep 15, 2016, 04:52 pm
... mi costringi ad auto-quotarmi ... :D
Guglielmo
Si lo so :D :D Mi è capitato di ristrutturare il codice all'infinito, però se fai tanta roba in un codice, a volte bisogna ristrutturare qualcosa a livello pure HW, ovvero ad esempio uno standalone che gestisca sensori che magari rallentano troppo e così fai diventare veloce il codice principale.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: maumari on Sep 15, 2016, 06:01 pm
Ragazzi,

sono felice di vedere che il "problema di facile soluzione" che ingenuamente a me sembrava... in realtà è una cosa da veri esperti.
Devo studiare ancora molto,  ma molto, anche se ho paura che mi manchino le basi, e che quindi sia un impresa ardua.
Non mi scoraggio però, perché se solo penso che fino a un anno fa le mie competenze erano a livello di -filo-interruttore-lampadina accesa-lampadina spenta...e che ora più o meno con Arduino, relè, Rfid, Pir, Ir, Keypad, Rtc e altro, qualche accrocchio ho messo in piedi e per ora sono moolto soddisfatto.
Ho imparato anche che la passione ti porta a fare cose che sembravano essere impossibili.
Sono veramente grato a tutti voi e aldilà di quello che riuscirò a fare con questo progettino, continuerò a leggere, studiare e sopratutto a seguirvi nelle vostre "discussioni".

Maurizio
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 15, 2016, 08:12 pm
@Victor795
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.
Il problema è che molto probabilmente lui non lo sa, e pensa si possa fare.
Hai colto nel segno.


Quote
Quote
Se ti riferisci alla serial, e solo un debug temporaneo. Non è un codice definitivo  ma uno spunto :)
Il problema è che molto probabilmente lui non lo sa
Quote
e pensa si possa fare.
Esatto.Questo è stato il mio errore.
Sono a conoscenza che gli isr debbano essere brevi,ma il mio era un tentativo di portare l'utente pian pianino a capire la soluzione proposta, correggendo tutto alla fine.
Un pò come accettare dei compromessi all'inizio e correggere il tiro stradafacendo ,anche perchè attraverso un forum è difficile spiegarsi.

Mi fa comunque piacere che ho rivitilizzato un topic al quale nessuno aveva risposto.

maumari sarebbe interessante vedere una soluzione funzionante dopo i consigli che hai ricevuto.


ciao

Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Maurotec on Sep 15, 2016, 11:21 pm
Quote
Sono a conoscenza che gli isr debbano essere brevi,ma il mio era un tentativo di portare l'utente pian pianino a capire la soluzione proposta, correggendo tutto alla fine.
Un pò come accettare dei compromessi all'inizio e correggere il tiro stradafacendo ,anche perchè attraverso un forum è difficile spiegarsi.
Alcuni utenti (io e molti altri) siamo qui da tanto tempo, ci siamo posti più volte il problema su come sia meglio relazionarsi con l'utente, specie se principiante. Colui che intende rispondere, prima dovrebbe cercare il post di presentazione dell'utente in questione; L'obbiettivo è di ricavare delle informazioni di massima sulle competenze che l'utente ha acquisito.

Ricavata questa informazione gli interventi potranno essere calibrati per lo specifico utente; per esperienza comune, consigliare interrupt, albero binario, buffer circolare ecc, a chi è alle prime armi si è rilevato essere  uno spreco di tempo  oltre che dannoso per l'utente.  

Quote
Mi fa comunque piacere che ho rivitilizzato un topic al quale nessuno aveva risposto.

maumari sarebbe interessante vedere una soluzione funzionante dopo i consigli che hai ricevuto.
Si sarebbe interessante, ma sai ormai io ci ho fatto il callo; la storia del forum è piena di post simili che si concludono in un
nulla di fatto, e non se ne conosce il motivo.

Sono tentato di spingermi oltre le comuni competenze fino a tirare in ballo IEEE 830-1998 che è stato sostituito da una nuova specifica. Questo documenta tutte le fasi da completare prima di iniziare a scrivere una riga di codice. Di questo documento però alcune parti a noi non tornano utili, questo perché noi siamo sia committenti che sviluppatori; inoltre svolgiamo anche l'analisi e ci occupiamo dello sviluppo hardware.

Sarebbe utile avere un documento simile, ma specifico per gli sviluppatore fai da te, che lo guidino lungo tutte le fasi.

@maumari
Vedi di rispondere alle domande dirette e indirette che ti sono state rivolte; ad esempio io ancora non so se tu hai capito cosa si intende per codice bloccante. Mi puoi fare un esempio di codice bloccante?


Ciao.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: maumari on Sep 16, 2016, 08:01 am
Ciao Victor

tu dici
Quote
maumari sarebbe interessante vedere una soluzione funzionante dopo i consigli che hai ricevuto
ok compatibilmente con gli impegni di lavoro e famiglia, sicuramente mi metterò a fare delle prove e speriamo che io me la cavo.

Mauro dice
Quote
la storia del forum è piena di post simili che si concludono in un nulla di fatto, e non se ne conosce il motivo.
Beh caro Mauro, io penso, ma forse mi sbaglio, se tanti post si concludono in un nulla di fatto può essere che nonostante tutti gli sforzi che uno possa fare, le competenze necessarie per risolvere certi problemi non si acquisiscono in due giorni, se no saremmo tutti Professori. Uno magari c prova e ci riprova, ma non ci arriva, ringrazia tutti, e alza le mani, probabilmente come capiterà a me.

A proposito di Professori, ma quando dici
Quote
Vedi di rispondere alle domande dirette e indirette che ti sono state rivolte; ad esempio io ancora non so se tu hai capito cosa si intende per codice bloccante. Mi puoi fare un esempio di codice bloccante?
ma il Prof lo fai di mestiere?

se è così chiedo scusa non sono preparato, negli ultimi tempi ho frequentato poco, anzi è dal giugno del '79 che non vengo a scuola.

ciao buona giornata a tutti


Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Maurotec on Sep 16, 2016, 12:58 pm
Quote
ma il Prof lo fai di mestiere?
No. Impossibile per me fare il professore di mestiere, l'ho anche detto tra le righe: Licenza scuola media inferiore.

Quote
Beh caro Mauro, io penso, ma forse mi sbaglio, se tanti post si concludono in un nulla di fatto può essere che nonostante tutti gli sforzi che uno possa fare, le competenze necessarie per risolvere certi problemi non si acquisiscono in due giorni, se no saremmo tutti Professori. Uno magari c prova e ci riprova, ma non ci arriva, ringrazia tutti, e alza le mani, probabilmente come capiterà a me.
Capire la differenza tra codice bloccante e non bloccante richiede circa 1 ora, se si hanno delle basi più o meno solide.
Mentre per l'analisi ci vuole molto più tempo ed è qui che io trovo le maggiori difficoltà; cioè io sono in difficoltà durante l'analisi del problema e sto studiando per affrontare questa fase tramite una metodologia che ancora non possiedo.

Ciao.
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: Victor795 on Sep 18, 2016, 12:03 pm
Maumari hai riprovato ? Puoi fare anche come dice MauroTec che forse è più semplice da comprendere rispetto all'interrupt.
Anche se non ti funziona , sottoponi il codice al forum
forza e coraggio  ;)
ciao
Title: Re: Istruzioni combinate tra contatto reed e keypad
Post by: maumari on Sep 21, 2016, 03:33 pm
Ciao Victor,

onestamente, non ci ho capito niente.
Penso che il problema sia per me insuperabile.
Sono ritornato al primo sketch dove la profondità a cui deve fermarsi
il sacchetto, è stabilita in base ai giri e circoneferenza ruota, cosicchè
intervenendo l'HIGH sui relè mi trovo alla posizione desiderata.
Tutto qui.
Ringrazio ancora tutti per l'aiuto.

ciao

Maurizio