Pages: [1] 2   Go Down
Author Topic: Uscita impulsiva per 3 secondi  (Read 1609 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi trovo a smanettare con arduino1 e shield I/O con 6 ingressi e 6 uscite a relè...

Volevo integrare allo sketch seguente una funzione che pi pemette di attivare una uscita pin per secondi in maniera impulsiva se il carattere ricevuto dalla seriale IDE è per esempio "J1"...

Mi spiego meglio :

Carattere ricevuto  "O1"   ------  attivo uscita 1 equivalente a Pin7
Carattere ricevuto  "O1"   ------  disattivo uscita 1 equivalente a Pin7  modalità PASSO-PASSO

Carattere ricevuto  "J1"   ------  attivo uscita 1 equivalente a Pin7 per 3 secondi e poi si spegne

Carattere ricevuto  "I1"   ------  leggo stato-ingresso 1 equivalente a Pin2

Lo sketch è il seguente :

Code:

// Variables will change:
int in=0;             
int out=0;
int an=0;
int inByte=0;

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
 
    // start serial port at 9600 bps:
  Serial.begin(9600);


  // set the digital pin as output:
  for (int out=8; out<=13; out++){
    pinMode(out, OUTPUT);     
  }
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
 
  if (Serial.available() > 0) {
    protocollo();
  }
 
     
}


void protocollo()
{
  inByte = Serial.read();
    switch (inByte)
    {
        case 79: //O  out
         
         
          Serial.println("Out number? (1 to 6)");   // send an initial string
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            out = Serial.read()-48;
            Serial.println("ricevuto ");
            Serial.print(out);
            if (out>=1&&out<=6)
            {
              out=out+7;
              if (!digitalRead(out))
                digitalWrite(out, HIGH);
              else
                digitalWrite(out, LOW);
               
              Serial.print("Out ");
              Serial.print(out-7);
              Serial.print(" = ");
              Serial.println(digitalRead(out));
            }
         
          break;
         
        case 73: //I
          //input
         
          Serial.println("In number? (1 to 6)");   // send an initial string
       
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            in = Serial.read()-48;
            if (in>=1&&in<=6){
            in=in+1;
           
            Serial.print("In ");
            Serial.print(in-1);
            Serial.print(" = ");
            Serial.println(digitalRead(in));
            }
          break;
         
          case 65: //A
          //analog
         
          Serial.println("Analog number? (1 to 6)");   // send an initial string
       
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            an = Serial.read()-48;
            if (an>=1&&an<=6){
            an=an-1;
           

            Serial.print("Analog ");
            Serial.print(an+1);
            Serial.print(" = ");
            Serial.println(analogRead(an));
            }
          break;

         
        //default:
          // if nothing else matches, do the default
          // default is optional
     
    }
 
   
}


Ora allego la modifica chiaramente con il blocco di codice mancante legato alla funzione dell'uscita impulsiva che ho realizzato con i Delay ma non mi soddisfa in quanto mi blocca il codice e ho provato con millis ma senza nessun risultato valido...un aiuto di cuore a chi volesse aiutarmi....grazie...

Code:

// Variables will change:
int in=0;             
int out=0;
int an=0;
int inByte=0;

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
 
    // start serial port at 9600 bps:
  Serial.begin(9600);


  // set the digital pin as output:
  for (int out=8; out<=13; out++){
    pinMode(out, OUTPUT);     
  }
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
 
  if (Serial.available() > 0) {
    protocollo();
  }
 
     
}


void protocollo()
{
  inByte = Serial.read();
    switch (inByte)
    {
        case 79: //O  out
         
         
          Serial.println("Out number? (1 to 6)");   // send an initial string
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            out = Serial.read()-48;
            Serial.println("ricevuto ");
            Serial.print(out);
            if (out>=1&&out<=6)
            {
              out=out+7;
              if (!digitalRead(out))
                digitalWrite(out, HIGH);
              else
                digitalWrite(out, LOW);
               
              Serial.print("Out ");
              Serial.print(out-7);
              Serial.print(" = ");
              Serial.println(digitalRead(out));
            }
         
          break;
         
        case 73: //I
          //input
         
          Serial.println("In number? (1 to 6)");   // send an initial string
       
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            in = Serial.read()-48;
            if (in>=1&&in<=6){
            in=in+1;
           
            Serial.print("In ");
            Serial.print(in-1);
            Serial.print(" = ");
            Serial.println(digitalRead(in));
            }
          break;

         
           case 74: //J  out IMPULSIVA
         
         
          Serial.println("Out number? (1 to 6)");   // send an initial string
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            out = Serial.read()-48;
            Serial.println("ricevuto ");
            Serial.print(out);
            if (out>=1&&out<=6)
            {
              out=out+7;
              if (!digitalRead(out))
                digitalWrite(out, HIGH);
           
                 delay(3000);        // uscita impulsiva a 3 secondi ma non multitasking...vorrei realizzarla col     
                                          // millis ma non sono riuscito...

                digitalWrite(out, LOW);
               
              Serial.print("Out ");
              Serial.print(out-7);
              Serial.print(" = ");
              Serial.println(digitalRead(out));
            }
         
          break;
         

         
          case 65: //A
          //analog
         
          Serial.println("Analog number? (1 to 6)");   // send an initial string
       
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            an = Serial.read()-48;
            if (an>=1&&an<=6){
            an=an-1;
           

            Serial.print("Analog ");
            Serial.print(an+1);
            Serial.print(" = ");
            Serial.println(analogRead(an));
            }
          break;

         
        //default:
          // if nothing else matches, do the default
          // default is optional
     
    }
 
   
}


Grazie...
Logged

0
Offline Offline
Faraday Member
**
Karma: 31
Posts: 2908
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hai provato con le librerie di classi create da leo72?

C'è il leOS, SecTimer o simile, cerca un suo post e trovi i link alle librerie, puoi anche cercare nel playground.

Oggi di leggere codice proprio non ci riesco, mi girano gli occhi.

Ciao.
Logged

AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Per rispondere a Maurotec non ho provato le librerie esterne perchè volevo realizzare il tutto con un semplice millis() ma quello che sembra strano è proprio che realizzare una uscita impulsiva sembra facile ma non lo è per niente....
Ad esempio ho provato un semplice sketch dove premo un pulsante e piloto un led pin on-off per 3 secondi ma ripeto senza il delay vado in tilt...

Se qualcuno mi può aiutare con un esempio di uscita impulsiva realizzato con millis ne sarei veramente riconoscente...poi capito il concetto provo anche a buttarmi con le librerie secTimer e LeOs...
Grazie...
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 333
Posts: 23015
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ad esempio ho provato un semplice sketch dove premo un pulsante e piloto un led pin on-off per 3 secondi ma ripeto senza il delay vado in tilt...
Che intendi per impulsivo? Cioè tenere un'uscita alta per 3 secondi da quando premi un pulsante?

Senza una variabile di stato non lo puoi fare.
Code:
byte stato = false;
byte pulsante = 2;
byte led = 13;
unsigned long myMillis;

void setup() {
    pinMode(led, OUTPUT);
    pinMode(pulsante, INPUT_PULLUP);
}

void loop() {
  if (!digitalRead(pulsante)) {
    delay(30); //debounce
    if (!digitalRead(pulsante)) {
      digitalWrite(led, HIGH);
      stato = true;
      myMillis = millis();
    }
  }
  if (stato) {
    if (millis() - myMillis > 3000) {
      digitalWrite(led, LOW);
      stato = false;
    }
  }
}

Come funziona il codice?
Ogni volta che premi il pulsante (uso la logica del LOW come premuto, il pulsante è tenuto alto con la pull-up interna) viene messo a TRUE il flag che controlla lo stato del led, questo viene acceso e poi viene salvato il valore attuale di millis.
Si controlla poi se lo stato del flag. Se è TRUE, si guarda se è trascorso l'intervallo voluto, 3 secondi. Se sì, si spenge il led e si rimette a FALSE lo stato.
Logged


Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie Leo per il codice...non ancora ho modo di provare il codice ma penso che hai trovato la souzione...

Una sola domanda a scopo didattico se mi permetti ...cosa significa il punto esclamativo ??

Code:
if (!digitalRead(pulsante))

Penso che debba significare "se leggi la pressione del pulsante" ma non conoscevo l'espressione con il "!"...
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 115
Posts: 5998
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...
Una sola domanda a scopo didattico se mi permetti ...cosa significa il punto esclamativo ??
...

E' l'operatore booleano di NEGAZIONE : http://arduino.cc/en/Reference/Boolean

In pratica, se la digitalRead ritorna "vero" il "!" lo inverte in "falso" e viceversa smiley-wink

Guglielmo

P.S. : Leo ti ha specificato che usa la logica del LOW per indicare pulsante premuto, quindi tu, nell'IF, devi rilevare la condizione di LOW
« Last Edit: March 28, 2013, 08:25:37 am by gpb01 » Logged

Search is Your friend ... or I am Your enemy !

Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ne approfitto per un'altra domanda didattica...siccome non ho avuto ancora modo di verificare il codice mi pare strana l'espressione:

Code:
if (stato)
{  }

In pratica con la condizione "if(stato)"  cosa si esprime ??!!
Logged

Switzerland
Offline Offline
Faraday Member
**
Karma: 115
Posts: 5998
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

...
In pratica con la condizione "if(stato)"  cosa si esprime ??!!

L'operatore IF è utilizzato per verificare se una certa condizione è vera e, in tal caso, eseguire quello che è specificato ... qui il riferimento : http://arduino.cc/en/Reference/If

In pratica tu hai

Code:
if (condizione_da_verificare) {

   cosa_fare_se_la_condizione_è_vera
}
else {
   cosa_fare_se_la_condizione_è_falsa
}

la parte dell' else è opzionale.

Credo comunque che sarebbe bene se dedicassi un po' di tempo alla lettura almeno di un semplice manuale di "C" e del "reference" http://arduino.cc/en/Reference/HomePage smiley-wink

Guglielmo
Logged

Search is Your friend ... or I am Your enemy !

Switzerland
Offline Offline
Faraday Member
**
Karma: 115
Posts: 5998
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Scusa, forse ho frainteso io la domanda ... forse non avevi capito proprio cosa intendesse Leo con quell' IF ?

In tal caso ...
... "stato" come vedi è una variabile di tipo "byte" che Leo dichiara inizialmente "false" e che, se si verificano certe condizioni, mette invece a "true".

Nel successivo IF (stato) non fa altro che controllare se quella variabile è ancora a "false" (e quindi le condizioni non si sono verificate) o a "true" .... in tal caso esegue quello che c'è nell'IF ...

Altri dubbi ? smiley

Guglielmo
Logged

Search is Your friend ... or I am Your enemy !

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 333
Posts: 23015
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Guglielmo ti ha spiegato la logica che ho adoperato.
Sono tutte delle contrazioni per ridurre il quantitativo di codice da scrivere.

Bisogna conoscere Arduino e cosa fa per poi poterlo usare, ma è anche utile conoscere il suo codice per poterlo usare.
false e true sono 2 costanti predefinite che valgono rispettivamente 0 e 1.
Avrei potuto utilizzare un tipo bool (booleano) per memorizzare false e true ma posso lo stesso usare un tipo byte che contiene un valore numerico, tanto devo metterci dentro solo 0 o 1, anche se sotto mentite spoglie (false e true, appunto).

Nei confronti, come gli if, una condizione è vera quando ha un valore diverso da 0, altrimenti è falsa. Quindi
fare
Code:
if (stato == true)
if (stato == 1)
if (stato)
è perfettamente equivalente. L'ultima, anzi, è una forma contratta dato che avendo stato appunto un valore di 0 o 1, può solo essere o falso o vero.

Anche per la lettura del pin ho usato le stesse abbreviazioni.
Ho precisato che uso la logica del LOW per premuto, per cui se l'utente preme un pulsante, significa che viene letto LOW.
Il test "lungo" sarebbe quindi:

Code:
if (digitalWrite(pin) == LOW)
Ora, in Arduino LOW vale 0 e HIGH vale 1.
Quindi il precedente test è equivalente a:
Code:
if (digitalWrite(pin) == 0)

Ma riprendendo quanto detto prima, lo 0 vale sempre false nei test.
Se però io inverto il risultato di un false ottengo che il test è vero quando è falso, giusto?
Quindi
Code:
if (!digitalRead(pin))
significa appunto
Code:
se (inverti(digitalRead(pin))
digitalRead(pin) è falso quando il pin restituisce LOW, cioè 0.
Invertendo 0 ottengo 1, per cui l'if esterno diventa vero quando il pin è inverti(0).
Logged


Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Scusa, forse ho frainteso io la domanda ... forse non avevi capito proprio cosa intendesse Leo con quell' IF ?

Non ti preoccupare infatti io non avevo capito proprio l'espressione usata da Leo in questo caso...

Quote
if (stato == true)
if (stato == 1)
if (stato)
è perfettamente equivalente.

Grazie Leo per le apprezzabili delucidazioni...e anche a "gpb01 " ...ora è tutto chiaro ...voi siete i maestri e noi piano piano cerchiamo d'imparare...
E' evidente che chi sa masticare il C come voi usate delle scorciatoie per scrivere il codice...io purtroppo mi attengo alle formule più note e quelle che vedo già un pò diverse dalle altre per me sono "errori di forma" e invece sono chicche di saggezza...grazie a tutti...ora provo a concludere lo sketch che avevo postato all'inizio in modo tale da poterlo condividere con chi ne può avere bisogno...
Logged

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 333
Posts: 23015
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sicuramente Guglielmo sa masticare il C visto quel che ha fatto in tutti questi anni, io di sicuro no perché programmo in C da 2 anni e mezzo.  smiley-sweat
Solitamente non uso queste contrazioni quando scrivo codice per principianti proprio per evitare di incasinare ulteriormente l'utente che già di problemi ne ha di suo  smiley-wink
Però stamani andavo di fretta ed ho scritto contratto per far prima. Manca anche la definizione di costante "const" messa davanti alla variabile del pin, così come ho usato un "byte" al posto di un "bool" perché avevo in mente una cosa e poi ne ho fatta un'altra  smiley-yell
Logged


Switzerland
Offline Offline
Faraday Member
**
Karma: 115
Posts: 5998
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sicuramente Guglielmo sa masticare il C visto quel che ha fatto in tutti questi anni, io di sicuro no perché programmo in C da 2 anni e mezzo.  smiley-sweat
...

Leo non fare il modesto ... che sappiamo bene di cosa sei capace ... smiley smiley smiley

Guglielmo
Logged

Search is Your friend ... or I am Your enemy !

Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Come promesso carico il codice e spiego il funzionamento...

Chiaramente lo sketch inizialmente è stato preso dagli esempi di futura elettronica da dove ho acquistato la simpatica shield 6IN/6OUT/6Analog e l'ho manipolato:

La scheda è in continuo ascolto sulla seriale e in base ai caratteri ricevuti compie delle azioni,ad esempio:

se digito sulla serile monitor dell'IDE arduino 1.03  :

"O1"  arduino accende il relè n.1 sulla scheda ma bensì relativo al pin7
"O2"  arduino accende il relè n.2 sulla scheda ma bensì relativo al pin8 ...etc..etc fino al relè n.6

"I1"   arduino controlla lo stato dell'ingresso fisico n.1 sulla scheda ma bensì relativo al pin 2 digitale
"I2"   arduino controlla lo stato dell'ingresso fisico n.2 sulla scheda ma bensì relativo al pin 3 digitale

Io ho cercato di implementare grazie all'aiuto di Leo e gpb01 un'altra funzione ovvero :

"J1"  arduino accende il rele n.1 sulla scheda per 2 secondi e poi la spegne
"J2"  arduino accende il rele n.2 sulla scheda per 2 secondi e poi la spegne   etc..etc..

Ora ho incontrato un problema...ovvero se invio due comandi consecutivi tipo "J1 J2" il sistema non risponde in multitasking bensì accende prima il Relè 1,dopo due secondi spegne il Relè 1,
poi accende il relè 2,dopo due secondi spegne il Relè 2...

Io volevo usare millis() proprio per evitare i ritardi nel codice...come posso fare ???
Il problema potrebbe essere legato ai Switch-Case creati ??

Grazie se avete ancora la pazienza di seguirmi...vi ringrazio già in anticipo...

Logged

Offline Offline
Full Member
***
Karma: 2
Posts: 105
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi ero dimenticato di caricare il codice...eccolo

Code:

// Variables will change:
int in=0;             
int out=0;
int an=0;
int inByte=0;

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long interval = 1000;           // interval at which to blink (milliseconds)

void setup() {
 
    // start serial port at 9600 bps:
  Serial.begin(9600);


  // set the digital pin as output:
  for (int out=8; out<=13; out++){
    pinMode(out, OUTPUT);     
  }
}

void loop()
{
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the
  // difference between the current time and last time you blinked
  // the LED is bigger than the interval at which you want to
  // blink the LED.
 
  if (Serial.available() > 0) {
    protocollo();
  }
 
     
}


void protocollo()
{
  inByte = Serial.read();
    switch (inByte)
    {
        case 79: //O  out
         
         
          Serial.println("Out number? (1 to 6)");   // send an initial string
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            out = Serial.read()-48;
            Serial.println("ricevuto ");
            Serial.print(out);
            if (out>=1&&out<=6)
            {
              out=out+7;
              if (!digitalRead(out))
                digitalWrite(out, HIGH);
              else
                digitalWrite(out, LOW);
               
              Serial.print("Out ");
              Serial.print(out-7);
              Serial.print(" = ");
              Serial.println(digitalRead(out));
            }
         
          break;
         
        case 73: //I
          //input
         
          Serial.println("In number? (1 to 6)");   // send an initial string
       
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            in = Serial.read()-48;
            if (in>=1&&in<=6){
            in=in+1;
           
            Serial.print("In ");
            Serial.print(in-1);
            Serial.print(" = ");
            Serial.println(digitalRead(in));
            }
          break;
         
          case 65: //A
          //analog
         
          Serial.println("Analog number? (1 to 6)");   // send an initial string
       
            while (Serial.available() <= 0)
            {
              delay(300);
            }
           
            an = Serial.read()-48;
            if (an>=1&&an<=6){
            an=an-1;
           

            Serial.print("Analog ");
            Serial.print(an+1);
            Serial.print(" = ");
            Serial.println(analogRead(an));
            }
          break;

         
        //default:
          // if nothing else matches, do the default
          // default is optional
     
    }
 
   
}


Forse l'errore stà che dovrei specificare un millis per ogni uscita,quindi unsigned long myMillis1,unsigned long myMillis2...etc..etc  spero di averci azzeccato...
Logged

Pages: [1] 2   Go Up
Jump to: