Go Down

Topic: Aiuto per codice (Read 9891 times) previous topic - next topic

ARDURINO

Anch'io ho visto il video. Qui non  si vuole solo accendere le luci di una gradinata, ma creare anche un effetto scenografico dove i led si accendo in sequenza a seconda della direzione salita o discesa .... bell'idea devo dire complimenti, però a quanto sembra dal video il programma è sempre lo stesso sia nella prima fase che nella seconda fase del test dove il comportamento per qualche motivo cambia, quindi sono fattori esterni al software che modificano i risultati.  I pir non si comportano sempre come vorremmo senza un adeguato software di calcolo, ti consiglio di elaborare meglio le tempistiche di ingresso dei segnali.

ciao
Pablos avevi ragione . Il problema era nei rilevatori PIR .
Dopo tanto penare ho cambiato i sensori inizialmente con dei comuni pulsanti (just a proof of concept) e successivante con dei fotodiodi IR. Ora il sistema funziona egregiamente.

Un'ultima cosa che vorrei implementare nello sketch e' un timer in modo che se qualcuno aziona uno dei due sensori ( salendo o scendendo ) , qualora non sale o scende le scale ma torna indietro (senza quindi azionare il secondo sensore) , i LEDs dovrebbero spegenrsi dopo un certo numero di secondi.

Qualcuno puo' aiutarmi in questo ?

Grazie


Code: [Select]



#include <ShiftRegister74HC595.h>
ShiftRegister74HC595 sr (1,4, 6, 5);
int del = 80;

#define Interruttore_SOPRA 12  // il pin 2 è usato per il sensore SUPERIORE
#define Interruttore_SOTTO 11

// Variabili
int INTERRUTTORE_A = 0;
int INTERRUTTORE_B = 0;
int bAccesiA = false;  
int bAccesiB = false;


void AccendiA()
{                           // accensione LEDs


  for (int i = 0; i < 8; i++) {

    sr.set(i, HIGH); // set single pin HIGH
    delay(del);

  }

}

void AccendiB()
{                   // accensione LED 1

  for (int i = 8; i >=0; i--) {

    sr.set(i, HIGH); // set single pin HIGH
    delay(del);
  }
}

void SpegniA ()
{                           // spegni LEDs sequenza  1 a 7

  for (int i = 0; i <= 8; i++) {


    sr.set(i, LOW); // set single pin LOW
    delay(del);
  }
}

void SpegniB ()
{                 // spegni LEDs sequenza 7 a 1


  for (int i = 8; i >=0; i--) {


    sr.set(i, LOW); // set single pin LOW
    delay(del);
    
  }
}

void setup() {


  pinMode(Interruttore_SOPRA, INPUT_PULLUP);
  pinMode(Interruttore_SOTTO, INPUT_PULLUP);

  Serial.begin(9600);
  Serial.println("avvio");

}
void loop()
{
  INTERRUTTORE_A = digitalRead(Interruttore_SOPRA);
  INTERRUTTORE_B = digitalRead(Interruttore_SOTTO);


  if (INTERRUTTORE_A == LOW)
  {
    if (bAccesiB==false)
    {
      bAccesiA=true ;
      AccendiA ();
    }
    else // (bAccesiB==true)
    {
      bAccesiB=false;
      SpegniB ();
    }
  }
  if (INTERRUTTORE_B  == LOW)  // sensore inferiore attivato
  {
    if (bAccesiA==false)
    {
      bAccesiB=true;
      AccendiB();
    }  
    else  // (bAccesiA==false)
    {
      bAccesiA = false;
      SpegniA ();

    }
  }
/*  Serial.print("INTERRUTTORE_A = ");
  Serial.println(INTERRUTTORE_A);
  Serial.print("INTERRUTTORE_B = ");
  Serial.println(INTERRUTTORE_B);
  Serial.print("bAccesiA = ");
  Serial.println(bAccesiA);
  Serial.print("bAccesiB = ");
  Serial.println(bAccesiB);
  Serial.println(" ");
  delay (0);
*/

}



vbextreme

#31
Jun 08, 2015, 03:13 pm Last Edit: Jun 08, 2015, 03:14 pm by vbextreme
a occhio e croce scriverei cosi:
Code: [Select]

#include <ShiftRegister74HC595.h>

ShiftRegister74HC595 luci (1,4, 6, 5);
#define LUCI_DELAY 450

#define PID_SOPRA  12
#define PID_SOTTO  11
#define PID_BOUNCE 100

#define LUCI_ON  HIGH
#define LUCI_OFF LOW
#define MODE_SOTTOSOPRA 0
#define MODE_SOPRASOTTO 1

#define TEMPO_MINIMO 1000
#define TEMPO_ON     5000

byte stato = 0;

unsigned long collision = 0;

void Luci(byte onoff, byte mode)
{
    if (onoff ) onoff = 1;
    static byte OF = 0;
    if ( onoff == OF ) return;
    OF = onoff;
   
    char i;
    if ( mode ) mode = 7;
   
    for (i=0; i < 8; ++i)
    {
        luci.set( mode - i, onoff); // set single pin HIGH
        delay(LUCI_DELAY);
    }
}

byte Pid(byte pid)
{
    if ( !digitalRead(pid) ) return 0;
    delay(PID_BOUNCE);
    return digitalRead(pid);
}
       
byte Direction()
{
    byte ret = 0;
    if ( Pid(PID_SOTTO) ) ret |= 0x01;
    if ( Pid(PID_SOPRA) ) ret |= 0x02;
    return ret;
}

void setup()
{
    pinMode(PID_SOPRA, INPUT_PULLUP);
    pinMode(PID_SOTTO, INPUT_PULLUP);
}

void loop()
{
    byte collide = 0;
    byte d;
    d = Direction();
     
    switch (d)
    {
        case 0x01:
            if ( !stato )
            {
               Luci( LUCI_ON, MODE_SOTTOSOPRA);
               collision = millis();
            }
            else
            {
               if ( (millis() - collision) < TEMPO_MINIMO ) { collide = MODE_SOPRASOTTO; break;}
               Luci( LUCI_OFF, MODE_SOPRASOTTO);
            }
            stato = !stato;
        break;
       
        case 0x02:
            if ( !stato )
            {
               Luci( LUCI_ON, MODE_SOPRASOTTO);
               collision = millis();
            }
            else
            {
               if ( (millis() - collision) < TEMPO_MINIMO ) { collide = MODE_SOTTOSOPRA; break;}
               Luci( LUCI_OFF, MODE_SOTTOSOPRA);
            }
            stato = !stato;
        break;
       
        case 0x03:
            Luci(LUCI_ON, MODE_SOPRASOTTO);
            stato = !stato;
            collision = millis();
            collide = MODE_SOTTOSOPRA;
        break;
    }
   
    if ( collide )
    {
        delay(TEMPO_ON);
        Luci(LUCI_OFF,collide);
        stato = 0;
    }
}


In questo modo se viene rilevato qualcosa che non dovrebbe accadere entro TEMPO_MIN lui lascia le luci accese per TEMPO_ON.
L' ho scritto dal phone quindi non garantisco che funzioni correttamente...
Easy framework linguaggio C: https://github.com/vbextreme/EasyFramework
Hack your life: http://vbextreme.netai.net/
Unoffical Telegram group: https://telegram.me/joinchat/ALRu8ACkdTdXyz-2P7v13A

ARDURINO

VBex , ho provato lo sketch.
Ma i leds continuano a lampeggire alternativamente in sequenza senza che io abbia azioni le fotocellule.  :(


Non so da cosa possa dipendere ????

Franky


vbextreme

#33
Jun 12, 2015, 05:09 pm Last Edit: Jun 12, 2015, 05:10 pm by vbextreme
come dicevo l'ho scritta al phone......
probabilmente il problema è nella funzione Pid() che ritorna anche se il pid non si è diseccitato e rientra che il pid è ancora eccitato cosi facendo manda in banana tutto il programma, me ne sono accorto adesso  :)
potresti ad esempio modificarlo cosi:
Code: [Select]

byte Pid(byte pid)
{
    if ( !digitalRead(pid) ) return 0;
    delay(PID_BOUNCE);
    if ( digitalRead(pid) )
    {
        while ( digitalRead(pid) ) ;
        return 1;
    }
    return 0;
}


oppure potresti scrivere cosi:
Code: [Select]

#include <ShiftRegister74HC595.h>

ShiftRegister74HC595 luci (1,4, 6, 5);
#define LUCI_DELAY 450

#define PID_SOPRA  12
#define PID_SOTTO  11
#define PID_BOUNCE 100

#define LUCI_ON  HIGH
#define LUCI_OFF LOW
#define MODE_SOTTOSOPRA 0
#define MODE_SOPRASOTTO 1

#define TEMPO_MINIMO 1000
#define TEMPO_ON     5000

byte stato = 0;

unsigned long collision = 0;

void Luci(byte onoff, byte mode)
{
    if (onoff ) onoff = 1;
    static byte OF = 0;
    if ( onoff == OF ) return;
    OF = onoff;
   
    char i;
    if ( mode ) mode = 7;
   
    for (i=0; i < 8; ++i)
    {
        luci.set( mode - i, onoff); // set single pin HIGH
        delay(LUCI_DELAY);
    }
}

byte Pid(byte pid)
{
    if ( !digitalRead(pid) ) return 0;
    delay(PID_BOUNCE);
    return digitalRead(pid);
}
       
byte Direction()
{
    byte ret = 0;
    if ( Pid(PID_SOTTO) ) ret |= 0x01;
    if ( Pid(PID_SOPRA) ) ret |= 0x02;
    return ret;
}

void setup()
{
    pinMode(PID_SOPRA, INPUT_PULLUP);
    pinMode(PID_SOTTO, INPUT_PULLUP);
}

void loop()
{
    byte d = Direction();
     
    if ( stato == 0 )
    {
        if ( d == 0x03 )
        {
            stato = 3;
        }
        else if ( d & 0x01 )
        {
            Luci( LUCI_ON, MODE_SOTTOSOPRA);
            collision = millis();
            stato = 1;
        }
        else if ( d & 0x02 )
        {
            Luci( LUCI_ON, MODE_SOPRASOTTO);
            collision = millis();
            stato = 2;
        }       
    }
    else if ( stato == 1 )
    {
        if ( d & 0x02  )
        {
            if ( (millis() < (collision + TEMPO_MINIMO)) || (d & 0x01) )
            {
                stato = 3;
            }
            else
            {
                Luci( LUCI_OFF, MODE_SOTTOSOPRA);
                stato = 0;
            }
        }
        else if ( d & 0x01 )
        {
            collision = millis();
        }
    }
    else if ( stato == 2 )
    {
        if ( d & 0x01  )
        {
            if ( (millis() < (collision + TEMPO_MINIMO)) || (d & 0x02) )
            {
                stato = 3;
            }
            else
            {
                Luci( LUCI_OFF, MODE_SOPRASOTTO);
                stato = 0;
            }
        }
        else if ( d & 0x02 )
        {
            collision = millis();
        }
    }
    else if ( stato == 3 )
    {
        delay(TEMPO_ON);
        Luci(LUCI_OFF,MODE_SOPRASOTTO);
        stato = 0;
    }
}


la macchina a stati di solito funziona... :)
Easy framework linguaggio C: https://github.com/vbextreme/EasyFramework
Hack your life: http://vbextreme.netai.net/
Unoffical Telegram group: https://telegram.me/joinchat/ALRu8ACkdTdXyz-2P7v13A

ARDURINO

Vbex,

quello che succede e' che stimolando uno dei due sensori i led si accendono tutti in nsequenza, mentre stimolando l'altro sensore si accende solo un led.

Si accendono e spengono correttamente stimolado prima un sensore e poi l'altro indipendentemente dal numero dei led accesi ( uno solo o otto), ma quello che non accade e che i led una volta accesi dopo aver stimolato un sensore , e passati 5000 millisec senza stimolare l'altro sensore , non si spengono, rimangono accesi.

 :-\

?????

P.M. : ho sostituito i sensori PIR ( che hanno un tempo di risposta  - delay time - molto ampio) , con un light gate formato da sensori IR ( fotodiodo) molto piu' rapidi .
 Forse il #define PID_BOUNCE 100 line del codice non serve piu'. Ho dovuito anche modificare il pinMode(PID_SOPRA, INPUT_PULLUP) con pinMode(PID_SOPRA, INPUT) questo per il modo in cui funzionano i sensori IR .

vbextreme

il mio voleva essere un codice di esempio non una soluzione, i led devono accendersi con un sensore e spegnersi con l'altro i 5000 è in caso avvengano situazioni particolari, ovvero legge il basso ma subito dopo legge l'alto prima di un tempo minimo ed allora entro in stato 3 che lascio acceso indistintamente per il tempo che l'omarello dovrebbe impiegare a salire le scale.
Quindi lavora correttamente, mi fa piacere, il problema relativo all'accensione dei led dovrebbe essere un problema nella funzione LED, quale dei due modi accende solo un led? MODE_SOTTOSOPRA o MODE_SOPRASOTTO?
un po di BOUNCE serve sempre....
Easy framework linguaggio C: https://github.com/vbextreme/EasyFramework
Hack your life: http://vbextreme.netai.net/
Unoffical Telegram group: https://telegram.me/joinchat/ALRu8ACkdTdXyz-2P7v13A

ARDURINO

Vbex,

ho postato un video di prova caricando il tuo sketch su ARDUINO .
Forse ti potrai rendere meglio conto di quello che succede !

https://www.youtube.com/watch?v=CqTGmA5tIW4&feature=youtu.be

vbextreme

Si ok avevo capito, ripeto non si deve spegnere dopo 5 secondi, fai cosi:
tocca un sensore e subito dopo l'altro ora conta fino a 5 e vedrai che si spegne.
Quella è solo una sicurezza in caso che uno scenda mentre l'altro sale, ovvero arduino dice " è passato solo un secondo come ha fatto Pinco a fare 12 rampe di scale? bho io aspetto x tempo cosi sono sicuro"

Quello che non capisco è perchè si accende solo un led! mi spieghi in quale dei due eventi accade? quando tocchi il sensore al pin 12 o al pin 11?
Easy framework linguaggio C: https://github.com/vbextreme/EasyFramework
Hack your life: http://vbextreme.netai.net/
Unoffical Telegram group: https://telegram.me/joinchat/ALRu8ACkdTdXyz-2P7v13A

vbextreme

fai cosi;

Code: [Select]


void Luci(byte onoff, byte mode)
{
    if (onoff ) onoff = 1;
    static byte OF = 0;
    if ( onoff == OF ) return;
    OF = onoff;
   
    char i;
    if ( mode )
    {
        for (i=0; i < 8; ++i)
        {
            luci.set( 7 - i, onoff); // set single pin HIGH
            delay(LUCI_DELAY);
        }
    }
    else
    {
        for (i=0; i < 8; ++i)
        {
            luci.set( i, onoff); // set single pin HIGH
            delay(LUCI_DELAY);
        }
    }
}



è brutto come codice ma dovrebbe andare
Easy framework linguaggio C: https://github.com/vbextreme/EasyFramework
Hack your life: http://vbextreme.netai.net/
Unoffical Telegram group: https://telegram.me/joinchat/ALRu8ACkdTdXyz-2P7v13A

ARDURINO

Si ok avevo capito, ripeto non si deve spegnere dopo 5 secondi, fai cosi:
tocca un sensore e subito dopo l'altro ora conta fino a 5 e vedrai che si spegne.
Quella è solo una sicurezza in caso che uno scenda mentre l'altro sale, ovvero arduino dice " è passato solo un secondo come ha fatto Pinco a fare 12 rampe di scale? bho io aspetto x tempo cosi sono sicuro"

Quello che non capisco è perchè si accende solo un led! mi spieghi in quale dei due eventi accade? quando tocchi il sensore al pin 12 o al pin 11?

Scusa Vbex,

non mi sono spiegato bene nella funzione che vorrei implementare nel codice...

Se per esempio salgo le scale attivando il primo sensore e mi squilla il telefono e sono costretto a scendere prima di completare la salita ed attivare il secondo sensore ( o viceversa) , vorrei che i led accesi si spengano dopo un certo numero di sceondi .

Non so se sono stato chiaro  :smiley-confuse:


Il PIN che non funziona bene corrisponde al PIN 11.

Franky

vbextreme

ok,vanno i led modificando la funzione come ti ho detto?
ora hai una macchina a stati
stato 0: aspetti evento
stato 1: sensore1 attivo
stato 2: sensore2 attivo
stato 3: confuso.

per semplificare il codice devi modificare la funzione pid come ti avevo suggerito prima, ovvero legge e attende di essere disinpegnata per proseguire, una volta fatto ciò dentro a stato 1 e d & 0x01 hai l' evento che desideri, ovvero togli la riga millis()=... e ci puoi mettere stato = 3, poi fai uguale con stato 2 e d&0x02.

posta il codice e ne discutiamo
Easy framework linguaggio C: https://github.com/vbextreme/EasyFramework
Hack your life: http://vbextreme.netai.net/
Unoffical Telegram group: https://telegram.me/joinchat/ALRu8ACkdTdXyz-2P7v13A

ARDURINO

Hurra !!!

Addesso i LEDs funzionano egregiamente.

Per il resto del codice devo capire ancora la LOGICA dei blocchi.

Ti faro' sapere quanto prima .

Franky

andres26

#42
Jun 13, 2015, 11:02 am Last Edit: Jun 13, 2015, 11:16 am by andres26
Posso aggiungere la mia...  :) ,

ho letto il thread perche' sono interessato anch'io a fare qualcosa di simile e secondo me manca una cosa indispensabile se vuoi che i led funzionino perfettamente in ogni caso :
con 2 soli sensori non sei in grado di capire se qualcuno entra nelle scale o esce dalle scale, indipendentemente sopra che sotto. Per fare cio' ti servono 4 sensori, meglio delle barriere come nel video, 2 sopra e 2 sotto.
Con questa configurazione, se qualcuno ENTRA nelle scale, cioe' si interrompe PRIMA il sensore 1 e POI il sensore 2 (ripeto indifferentemente in cima o in fondo alle scale), ACCENDI le luci con il bell' effetto che si vede nel video (anzi... volendo potresti fare in modo che se entra uno di sotto scorre in senso mentre se entra uno di sopra nell'altro :)  ).
Mentre accendi le luci INCREMENTI anche una variabile, la chiamerei PERSONE_SULLE_SCALE, ponendola ad 1.
A questo punto, Se qualcun'altro ENTRA nelle scale, devi SOLO incrementare PERSONE_SULLE_SCALE, perche' le luci sono gia' accese.
Adesso e' semplice... Se qualcuno ESCE, cioe' interrompe PRIMA il sensore 2 e POI l'1 (dimenticavo... poniamo i sensori 2 quelli piu' vicini alle scale e gli 1 quelli piu' luntani), devi diminuire la variabile PERSONE_SULLE_SCALE, infine, se il valore raggiunto e 0, SPEGNI le luci   :D   

pep123456

Avete risolto il problema? ?

gpb01

#44
Nov 01, 2016, 06:18 pm Last Edit: Nov 01, 2016, 06:19 pm by gpb01
Avete risolto il problema? ?
Hai visto che è una discussione di 1 anno e mezzo fa ? ? ? :o  Non so se  qualcuno ancora risponde ... ::)

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

Go Up