Pages: [1]   Go Down
Author Topic: Gesitre Pin Input & Output  (Read 471 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buonasera, volevo avere un chiarimento.. In pratica ho la necessità di Gestire dei led ad infrarossi sia in Input che in Output, è possibile fare questo? E se si come? Spiego meglio in pratica son dei led IR, li gestisco in Input inquanto se vengono colpiti allora azionano una parte di codice, il fatto sta che Proprio quando vengono colpiti, ho la necessità che si "Disattivino" per 3 secondi, allora ho pensato di gestirli in output e.. Però ora che ci penso bene anche se li gestisco in output come farei a "Disattivarli" un digitalWrite(LEDIR, LOW) avrebbe effetto? Grazie per le risposte e per le eventuali proposte per risolvere questo problema smiley-wink
Logged

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

Non ho capito il senso della domanda....
Un "sensore" devi gestirlo in input. Ti deve dare un'informazione che proviene dall'esterno.
Puoi "ignorarlo" per 3 secondi, nel senso che una volta che ti ha dato l'impulso, non lo rileggi per il tempo stabilito.
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Boh, mi sto chiedendo anche io che demenziale domanda ho fatto. Il bello è che stavo anche per scrivere adesso tutta una spiegazione ma non reggeva per niente, bho, sarà l'ora xD Scusatemi tutti per il post un po inutile, ad ogni modo facciamo così, grazie del "Suggerimento" smiley-lol
Logged

BZ (I)
Offline Offline
Brattain Member
*****
Karma: 234
Posts: 20166
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

forse l' ora giovane del giorno ha portato a questi ragionameti.  smiley-wink smiley-wink

Ciao Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ehm, credo proprio che ieri sera abbia sdato troppo, in primis non mi sono spiegato molto bene nel primo post, e successivamente pensavo di aver sbagliato a scrivere come ho detto.. In realtà era giusto il mio primo post, ovvero quello in cui cercavo di spiegare bene il meccanismo, allora, lo rispiego in modo più semplice.

La necessità di gestire un pin sia in input che in output (Premetto che sto dicendo questo ma non so se è possibile gestirlo sia in input e in output) nasce dal fatto che io in questo progetto ho un IR, ora, usando un laser esterno al progetto.. Vorrei fare in modo che quando l'IR viene colpito dalla luce del laser questo azioni un codice [(CODICE1) (Tra il quale c'e anche un RITARDO di 3Secondi).. MA, il problema nasce dal fatto che se questo IR viene colpito in un lasso di tempo minore di 3 secondi da quando è stato colpito la prima volta, deve azionare un codice diverso da quello di prima (CODICE2).
Quindi il problema maggiore sta nel fatto che arduino deve riconoscere se in quei 3 secondi che è in "Pausa" viene nuovamente colpito, successivamente capire se lo colpisce per la prima volta o per la seconda volta, e poi agire di conseguenza..

Per quanto io possa cercare di capire come far funzionare questo codice, non riesco a venire a capo, il mio ragionamento è "Se lui è in "Pausa" per 3 secondi, allora come fa a capire se in quei 3 secondi viene colpito"?
Purtroppo a scuola abbiamo solo accennato ad un interrupt, credo che questa sia la soluzione perchè in diversi progetti alcuni compagni della mia classe che provenivano da una sezione in cui hanno fatto gli interrupt, Li usavano spesso.. Come ho detto noi però non abbiamo mai avuto modo di studiarli quindi so meno che 0, anche se credo che questa sia la giusta via per risolvere il problema.

Riporto in seguito la parte di codice interessata:
Code:
     if(ColpitoPremuto == HIGH){
              if(HP>0){
                HP = HP - 2;
                digitalWrite(LED_Colpito, HIGH);
                digitalWrite(LED_CorpettoColpito, HIGH);
                lcd.setCursor(1, 1);
                lcd.print("HP: ");  
                lcd.setCursor(4, 1);
                lcd.print(HP);  
                  if(HP<10){
                    lcd.setCursor(5,1);
                    lcd.print(" ");
                  }
            
              //EA Qua dovrei sviluppare quello che chiedo in questo post del forum..

              }
              else
                {
                digitalWrite(Riserva, HIGH);            
                Scarico = 0;    
                }
              }

Se non fosse ancora chiaro, il problema è che lui deve "MENTRE STA ASPETTANDO I 3 SECONDI" capire se appunto in quei 3 secondi che aspetta viene colpito un'altra volta. Tipo così:

Viene colpito per la prima volta?;
-------------------------------------------
    |delay(3000);                                         |          
    |CODICE1                                                 |
    |Controlla se viene colpito  dinuovo; |
     ---------------------------------------

Viene colpito per la seconda volta?;
-------------------------------------------
    |delay(3000);                                         |          
    |CODICE2                                                 |
    |Controlla se viene colpito  dinuovo; |
     -----------------------------------------                          
« Last Edit: January 19, 2013, 04:37:05 am by EnigmaAren92 » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

se ho capito bene vuoi gestire lo stesso pin sia in ingresso che in uscita...non credo sia possibile
dovrai usare uno per l'input e uno per output

evita il delay() e usa i millis() perchè quando funziona il delay arduino è come se fosse in pausa

per vedere se il laser lo ricolpisce in questi 3 secondi puoi fare un contatore

int contatore=0;

quando lo colpisce la prima volta contatore++ e lo posta a 1
se/quando lo colpisce la seconda volta contatore++ e lo posta a 2

poi fai il controllo
se contatore==1  esegui questa cosa
se contatore==2 esegui un'altra cosa

logicamente eseguite questa cose il contatore deve tornare a zero

forse non sarà la miglir cosa ma credo funzioni
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No non ci siamo.. non ho capito niente di tutto quello che mi vuoi dire ;(

Edito questo post: Ok ho capito che cosa mi vuoi dire, vorrei quindi fare in questo modo. Solo che essendo da poco nell'ambiente di arduino ancora non conosco la sintassi di tutti i comandi.
Mi potete le 2/3 righe di codice (Presumo siano così poche) Per creare avviare un conteggio?
cioè voglio dire tipo:

-int Conteggio=0
-Avvia la conta. (Conteggio=1, poi 2, poi 3, poi 4)

Si fa attraverso il comando millis a quanto pare, ma non ho capito come.. Grazie smiley-wink
« Last Edit: January 19, 2013, 05:32:34 am by EnigmaAren92 » Logged

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

Anche io non è che ho le idee chiare, leggendo l'ultimo post ti chiedi se è possibile usare un pin in input e output nello stesso istante, ovviamente non è possibile. Però è possibile impostare un pin in input leggere e impostarlo in output assegnando l'uscita per poi reipostarlo in input e così via. Se questo pin viene switchato rapidamente da input a output e viceversa, in base al vincolo temporale è possibile che appaia all'aplicazione come se ciò accadesse allo stesso tempo. Non funzionerebbe ad esempio se il tempo in cui il laser permane sul sensore è minore del tempo impiegato per passare da input a output e impostare il valore e ritornare in input.

Però, però, se si chiede una informazine lo si dovrebbe fare una cosa per volta e sopratutto sperando che sia quella la cosa che si vuole sapere.

In questo caso tu sei abbastanza confuso, allora ti consiglio di non pensare all'applicazione che devi realizzare ma di fare una pausa al fine di acquisire nuove informazioni e anche una flessibilità mentale che ti permetta di capire cosa ti serve e come raggiungerlo.

Al momento non sai cosa ti serve e ovviamente inutile pensare di raggiungerlo.

Cerca degli esempi che fanno uso di mills() potrebbe avvicinarsi di molto a quello che ti serve.

Il Delay non si usa quasi mai, specie con tempi lunghi e mai e poi mai quando l'applicazione deve rispondere in modo reattivo.
Certamente durante il Delay il microcontroller esegue codice in loop interno su cui non possiamo interaggire.

Gli interrupt potrebbero esserti di aiuto, e anche se l'applicazione si potesse fare senza interrupt conviene che vi lavori un po.

Usa le funzioni (credo si chiamino attachInterrupt ecc.) per attaccare ad una "funzione utente" ad un pin su cui è stato abilitato l'interrupt.
Un interrupt può scattare (trigger) sul fronte di salita, quello di discesa o entrambe.

Anche con l'interrupt non risolvi immediatamente. Una volta che viene eseguito codice della "funzione utente", questo viene usato per impostare una variabile di stato che indica soltanto che un pin a cambiato stato. Terminata la funzione utente nel loop devi controllare lo stato della variabile per un tempo di 3 secondi, quindi in loop o in while utente, se entro questo tempo la variabile cambia stato vuol dire che è stata chiamata la funzione utente e il laser che colpiva ora non c'è più, se il laser ritorna a colpire dopo 0.5 secondi la funzione utente viene chiamata un altra volta.

Se dentro la funzione utente metti un contatore che parte da zero e si incrementa puoi sapere sia quante volte il laser e andato via e tornato e anche lo stato del pin su cui c'è l'IR.

Non ho idea di quale siano i vincoli temporali da rispettare, sei tu che devi stabilirlo:
Il caso peggiore è ? non accadrà mai che il laser vada via e torni in un tempo inferiore a 200ms

Se fosse così devi fare attenzione a tutto il codice che impiega più di 200ms per essere esguito e se possibile spezzettare i pià di 200ms in 3 parti
es 250/3 = 83 ms, devi impegnare il micro per 83 ms in modo esclusivo, sospendere e riprendere al prossimo ciclo che sarà di 83ms e così via.

Primo obbiettivo sperimentare con mills() e micros o quello che è capiro nell'intimità.
Secondo obbiettivo sperimentare con gli interrupt.

Quando dico che bisogna capire nell'intimità mi riferisco ai side effect, cioè il rovescio della medaglio.
Es con gli interrupt il side effect e che la funzione utente monopolizza la cpu, pertanto in questo tempo altro codice non verrà eseguito neanche gli altri interrupt che sono disabilitati globalmente, e sono riabilitati quando la funzione utente termina.

Sono cosciente di averti confuso ancora di più, ma di averti anche dato una linea quida da seguire che in mancanza di una migliore che acquisirai con il tempo conviene prendere per buona.

Ciao.
Logged

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

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

@EnigmaAren92:

continuo a sostenere ciò che ti ho detto qui:
Puoi "ignorarlo" per 3 secondi, nel senso che una volta che ti ha dato l'impulso, non lo rileggi per il tempo stabilito.
A te serve questo.
La tua applicazione deve:
1) leggere un sensore collegato ad un pin. Lasciamo perdere che tipo sia: per ora pensiamo che sia un pin a cui arriva LOW o HIGH
2) nel caso arrivi il segnale voluto, attivi CODICE1 (lasciamo perdere anche qui che cosa sia) per 3 SECONDI
3) SE durante quei 3 secondi arriva un nuovo impulso, devi interrompere CODICE1 ed attivare CODICE2

E' giusto? Lo hai scritto qui:
Quote
La necessità di gestire un pin sia in input che in output (Premetto che sto dicendo questo ma non so se è possibile gestirlo sia in input e in output) nasce dal fatto che io in questo progetto ho un IR, ora, usando un laser esterno al progetto.. Vorrei fare in modo che quando l'IR viene colpito dalla luce del laser questo azioni un codice [(CODICE1) (Tra il quale c'e anche un RITARDO di 3Secondi).. MA, il problema nasce dal fatto che se questo IR viene colpito in un lasso di tempo minore di 3 secondi da quando è stato colpito la prima volta, deve azionare un codice diverso da quello di prima (CODICE2).
Quindi il problema maggiore sta nel fatto che arduino deve riconoscere se in quei 3 secondi che è in "Pausa" viene nuovamente colpito, successivamente capire se lo colpisce per la prima volta o per la seconda volta, e poi agire di conseguenza..
Io però NON vedo scritta la necessità di usare lo stesso pin come input e come output. Ricordati che normalmente NON puoi farlo a meno che il dispositivo a cui è collegato il pin non preveda espressamente di poter essere pilotato in questo modo. Se hai un sensore iR di RICEZIONE, mettendo il pin a cui è collegato in OUTPUT cosa ottieni, scusa?

Tornando al problema, devi strutturare il codice in modo tale che l'esecuzione di CODICE1 permetta un'uscita da esso prima del suo naturale termine.

Prova a trasportare in codice questo pseudo-codice:

Code:
void loop()  {
  if (digitalRead(SENSORE) == HIGH) { //presuppongo un segnale HIGH
    Codice1();
  }
}

void codice1() {
  unsigned long start = millis();
  boolean arrivatoImpulso = false;
  do {
    ....qui metti il tuo codice...
    if (digitalRead(SENSORE) == HIGH) {
      arrivatoImpulso = true;
    }
  } while ((millis() - start < 3000) && (!arrivatoImpulso));
  //ora controllo se è arrivato un secondo impulso prima dei 3 secondi
  if (arrivatoImpulso) {
    Codice2();
  }
}

void codice2() {
  ....il tuo codice..
}

Non l'ho provato ma dovrebbe funzionare
Logged


Offline Offline
Newbie
*
Karma: 0
Posts: 34
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@MauroTec

Ho letto tutto quello che hai scritto, effettivamente si lo trovo abbastanza complicato da leggere a primo impatto, spero che, in mancanza di una soluzione migliore riesca a trovare il modo di utilizzare tutti i tuoi consigli. Grazie davvero di tutto, per ora non posso altro che dirti molto sul codice, e sui consigli, proprio perche non ho ben capito le soluzioni che mi hai proposto.. Ma per come scrivi son sicuro che sia la miglior soluzione da adottare in questo specifico caso.
Ah dimenticavo di dire una cosa.. In realtà quello che voglio lo so solo che, come ho detto è da poco che mi sono cimentato nel mondo arduino, ma molte cose, mi sono già chiare a primo impatto inquanto proveniente da una realtà pressocchè uguale a quella del VB, quello che devo fare adesso è imparare per bene arduino xD.
Comunque no, 200 ms sono più che sufficienti.

@Leo72

Per quanto riguarda te, volevo solo dirti che mi trovo molto bene con le tue "Spiegazioni" cioè fino ad ora mi hai dato dei buoni consigli, che sono subito riuscito a comprendere, compreso quest'ultimo. Quando mi chiedi per quanto riguarda la necessità di usare un pin in imput in output, è prima importante capire che AVEVO bisogno di questo perchè:
-Gli IR si devono SPEGNERE, "Momentaneamente", e quindi li gestisco in output.
-Allo stesso tempo però devono rimanere Accesi, inquanto devono rilevare se viene poiettato per la seconda volta il laser sopra.
E quindi se scrivessi un codice in cui prima li gestisco in input, e successivamente in output credo il problema fosse risolto.

Ad ogni modo credo non ci sia più la necessità di questo stratagemma in quanto come suggerito da @Vinciolo basta usare un semplice contatore, e una variabile cont (Lo dico io lui non l'accenna) che mi indica se è stato premuto (1) o non è stato premuto (2).
Quindi, ricapitolando, la mia idea è questa:

-Faccio partire il conteggio. //1,2,3,4,5,6,7 <-- Ovviamente in millisecondi.
 Se conteggio < 3000 and Contatore = 1
      CODICE1;
      Contatore = 2;
 Else
 Se conteggio < 3000 and Contatore = 2
      CODICE2;
      Contatore = 1;
      Faccio ripartire il conteggio;

Siccome ci sono molti altri IF nel programma, ancora devo stabilire se questo Blocco di verità andrà all'inizio del Loop o in seguito ad un altra condizione verificata, e quindi apporterei delle modifiche sul dove inserire i Contatori=0,1 e 2 ma di queste ultime due righe non preoccupatevi perchè è solo una cosa futura, dettata dal mio potere decisionale.. Quindi non importa.

Lo pseudocodice di per se sopradescritto (Buttato giù ora in 10 minuti) credo possa andare bene.. Provo e vi faccio sapere smiley-wink
Logged

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

@Enigma:
sicuramente c'è un problema di comprensione del... problema da parte mia  smiley-sweat
Te senz'altro sai meglio di tutti noi cos'hai in testa. I suggerimenti te li abbiamo dati, vedo che ti sei fatto un'idea di come procedere.
Trasforma le idee in codice e provalo, se non ti funziona, pubblicalo che poi vediamo come andare avanti.
Logged


Pages: [1]   Go Up
Jump to: