Musica natalizia allegria: 4 passaggi
Musica natalizia allegria: 4 passaggi
Anonim
Luce di allegria di musica di Natale
Luce di allegria di musica di Natale

Buon Natale! Vuoi avere un albero di Natale che possa interagire con te?

Passaggio 1: cose utilizzate in questo progetto

Componenti hardware

  • Seeeduino V4.2
  • Scudo base V2
  • Grove - Sensore di movimento PIR regolabile
  • Grove - Sensore di rumorosità
  • Grove - Striscia LED RGB impermeabile WS2813 - 60 LED/m - 1m

App software e servizi online

Arduino IDE

Passaggio 2: connessione hardware

Connessione hardware
Connessione hardware

Collegare il sensore PIR, il sensore di rumorosità e la striscia LED alla porta D2, A0 e D6 di Base Shield separatamente. Collega Base Shield a Seeduino, tutto fatto.

Passaggio 3: programmazione del software

Le librerie seguenti devono essere installate prima della programmazione, scaricale e importale manualmente nel tuo IDE Arduino:

  • Striscia_Led
  • MsTimer2
  • Arduino_Vector

Per rendere il codice più conciso, lo abbiamo impacchettato. La classe CheerLight è la classe applicativa di questo progetto.

applicazione di classe::CheerLight

: public application::interface::IApplication { public: void setup(void); ciclo vuoto(vuoto); void setPIRSensorPin(uint8_t pin); void setLoudnessSensorPin(uint8_t pin); void misuraSensori(void); void changeAnimation(void * args); void changeSpeed(void * args); void changeColor(void * args); applicazione statica::CheerLight * getInstance(void); protetto: driver::LEDStrip _ledStrip; driver::PIRSensor _pirSensor; driver::LoudnessSensor _loudnessSensor; uint8_t _animazione; middleware::Delegate _detectedDelegate; middleware::Delegate _absoluteLoudnessDelegate; middleware::Delegate _relativeLoudnessDelegate; CheerLight (vuoto); applicazione statica::CheerLight _instance; };

La classe CheerLight è stata progettata da Singleton Patterns, il che significa che esiste solo un'istanza, puoi chiamare CheerLight::getInstance() a quell'istanza. Se la connessione dei tuoi sensori è diversa dalla connessione hardware, puoi cambiarli chiamando i metodi setPIRSensorPin() e setLoudnessSensorPin().

Immagine
Immagine

Si consiglia di chiamare il metodo measureSensors() nell'interruzione del timer per fare in modo che i sensori vengano misurati tempestivamente, ma non è necessario chiamare manualmente i metodi changeAnimation(), changeSpeed() o changeColor(). Saranno chiamati tramite i Delegati quando i sensori saranno misurati.

Che cos'è un delegato?

Come tutti sappiamo, possiamo dichiarare un puntatore a funzione e farlo puntare a una funzione in C:

void func1(void);

void (*pFunc)(void) = func1;

e usalo per chiamare la funzione a cui punta

pFunc();

Ma ci sono differenze in C++, se provi a compilare il codice seguente:

classe A {

public: void func1(void); }; void (*pFunc)(void) = &A::func1;

il compilatore segnalerà un errore di conversione del tipo, ecco l'esempio giusto:

void (A::*pFunc)(void) = &A::func1;

Quando proviamo a usarlo per chiamare quel metodo, errore di nuovo. La ragione di quell'errore è che un oggetto-metodo deve essere chiamato da un oggetto. Quindi creiamo un oggetto per chiamarlo:

Aa;

a.*pFunc();

Questa volta nessun problema. Quindi c'è la classe Delegate in Delegate.h.

modello

class middleware::Delegate: public middleware::interface::IDelegate { public: Delegate(T * oggetto, void (T::*method)(void *)); void invoke(void * argomenti); protetto: T * _oggetto; void (T::*_method)(void *); }; middleware inline template::Delegate::Delegate(T * oggetto, void (T::*method)(void *)): _object(oggetto), _method(method) { } middleware void template inline::Delegate::invoke(void * args) { (_object->*_method)(args); }

Poiché la classe Delegate è una classe modello, il che significa che Delegate è diverso da Delegate, come farle puntare dal puntatore con lo stesso tipo? La risposta è l'interfaccia, quindi c'è l'interfaccia IDelegate in IDelegate.h.

middleware di classe::interfaccia::IDelegate {

public: virtual void invoke(void * args) = 0; };

Nella classe PIR Sensor e Loudness Sensor, è presente una variabile denominata _delegates utilizzata per memorizzare il puntatore dei delegati e un metodo denominato invokeAllDelegates() utilizzato per richiamare tutti i delegati in _delegates, verrà chiamato nel metodo measure().

NOTA: i metodi delegati, come changeAnimation(), changeSpeed() e changeColor() verranno chiamati nell'interrupt timer2, quindi NON utilizzare delay() o altre funzioni basate su interrupt.

Consigliato: