Luz de alegría de música navideña: 4 pasos
Luz de alegría de música navideña: 4 pasos
Anonim
Luz de alegría de música navideña
Luz de alegría de música navideña

¡Feliz Navidad! ¿Quieres tener un árbol de Navidad que pueda interactuar contigo?

Paso 1: Cosas utilizadas en este proyecto

Componentes de hardware

  • Seeeduino V4.2
  • Escudo base V2
  • Grove - Sensor de movimiento PIR ajustable
  • Grove - Sensor de sonoridad
  • Grove - WS2813 RGB LED Strip Impermeable - 60 LED / m - 1m

Aplicaciones de software y servicios en línea

IDE de Arduino

Paso 2: Conexión de hardware

Conexión de hardware
Conexión de hardware

Conecte el sensor PIR, el sensor de sonoridad y la tira de LED al puerto D2, A0 y D6 de Base Shield por separado. Conecte Base Shield a Seeduino, todo listo.

Paso 3: Programación de software

Las siguientes bibliotecas deben instalarse antes de la programación, descárguelas e impórtelas a su IDE de Arduino manualmente:

  • Tira llevada
  • MsTimer2
  • Arduino_Vector

Para hacer el código más conciso, lo hemos empaquetado. La clase CheerLight es la clase de aplicación de este proyecto.

aplicación de clase:: CheerLight

: aplicación pública:: interfaz:: IApplication {público: configuración void (void); bucle vacío (vacío); void setPIRSensorPin (pin uint8_t); void setLoudnessSensorPin (pin uint8_t); void MeasureSensors (void); void changeAnimation (void * args); void changeSpeed (void * args); void changeColor (void * args); aplicación estática:: CheerLight * getInstance (void); protegido: controlador:: LEDStrip _ledStrip; controlador:: PIRSensor _pirSensor; controlador:: LoudnessSensor _loudnessSensor; uint8_t _animation; middleware:: Delegate _detectedDelegate; middleware:: Delegate _absoluteLoudnessDelegate; middleware:: Delegate _relativeLoudnessDelegate; CheerLight (vacío); aplicación estática:: CheerLight _instance; };

La clase CheerLight fue diseñada por Singleton Patterns, lo que significa que solo hay una instancia para ella, puede llamar a CheerLight:: getInstance () a esa instancia. Si la conexión de sus sensores es diferente a la conexión de hardware, puede cambiarlos llamando a los métodos setPIRSensorPin () y setLoudnessSensorPin ().

Imagen
Imagen

Recomendamos llamar al método measureSensors () en la interrupción del temporizador para que los sensores se midan a tiempo, pero no es necesario llamar a los métodos changeAnimation (), changeSpeed () o changeColor () manualmente. Se les llamará a través de Delegados cuando se midan los sensores.

¿Qué es un delegado?

Como todos sabemos, podemos declarar un puntero de función y hacer que apunte a una función en C:

void func1 (vacío);

void (* pFunc) (void) = func1;

y utilícelo para llamar a la función a la que apuntó

pFunc ();

Pero hay diferencias en C ++, si intenta compilar el siguiente código:

clase A {

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

el compilador informará un error de conversión de tipo, aquí está el ejemplo correcto:

vacío (A:: * pFunc) (vacío) = & A:: func1;

Cuando intentamos usarlo para llamar a ese método, vuelve a producirse el error. La razón de ese error es que un objeto debe llamar a un método-objeto. Entonces creamos un objeto para llamarlo:

A a;

a. * pFunc ();

Esta vez no hay problema. Entonces hay una clase Delegate en Delegate.h.

plantilla

class middleware:: Delegate: public middleware:: interface:: IDelegate {public: Delegate (T * objeto, void (T:: * método) (void *)); void invoke (void * args); protegido: T * _object; void (método T:: * _) (void *); }; plantilla middleware en línea:: Delegate:: Delegate (T * objeto, void (T:: * método) (void *)): _object (objeto), _method (método) {} plantilla en línea void middleware:: Delegate:: invoke (void * args) {(_object -> * _ method) (args); }

Debido a que la clase Delegate es una clase de plantilla, lo que significa que Delegate es una diferencia con Delegate, ¿cómo hacer que el puntero los señale con el mismo tipo? La respuesta es la interfaz, por lo que hay una interfaz IDelegate en IDelegate.h.

clase middleware:: interfaz:: IDelegate {

público: invocación de vacío virtual (void * args) = 0; };

En la clase del sensor PIR y del sensor de sonoridad, hay una variable llamada _delegates que se usa para almacenar el puntero de los delegados, y hay un método llamado invokeAllDelegates () que se usa para invocar a todos los delegados en _delegates, se llamará en el método meter ().

NOTA: Los métodos delegados, como changeAnimation (), changeSpeed () y changeColor () se llamarán en la interrupción del timer2, así que NO use delay () u otra función basada en interrupciones.