Inhaltsverzeichnis:

Weihnachtsmusik Cheer Light - Gunook
Weihnachtsmusik Cheer Light - Gunook

Video: Weihnachtsmusik Cheer Light - Gunook

Video: Weihnachtsmusik Cheer Light - Gunook
Video: Iron Maiden - A Christmas Cheers 2024, November
Anonim
Weihnachtsmusik Cheer Light
Weihnachtsmusik Cheer Light

Frohe Weihnachten! Möchten Sie einen Weihnachtsbaum haben, der mit Ihnen interagieren kann?

Schritt 1: Dinge, die in diesem Projekt verwendet werden

Hardware-Komponenten

  • Seeeduino V4.2
  • Basisschild V2
  • Grove - Einstellbarer PIR-Bewegungssensor
  • Grove - Loudness-Sensor
  • Grove - WS2813 RGB LED-Streifen Wasserdicht - 60 LED/m - 1m

Software-Apps und Online-Dienste

Arduino-IDE

Schritt 2: Hardwareverbindung

Hardware-Verbindung
Hardware-Verbindung

Verbinden Sie den PIR-Sensor, den Loudness-Sensor und den LED-Streifen separat mit den Ports D2, A0 und D6 des Base Shield. Base Shield an Seeduino anschließen, fertig.

Schritt 3: Softwareprogrammierung

Die folgenden Bibliotheken müssen vor der Programmierung installiert werden. Bitte laden Sie sie herunter und importieren Sie sie manuell in Ihre Arduino IDE:

  • LED-Leiste
  • MsTimer2
  • Arduino_Vektor

Um den Code prägnanter zu gestalten, haben wir ihn gepackt. Die CheerLight-Klasse ist die Anwendungsklasse dieses Projekts.

Klassenanwendung::CheerLight

: öffentliche Anwendung::Schnittstelle::IApplication {öffentlich:void setup(void); Leere Schleife (Leere); Void setPIRSensorPin (uint8_t-Pin); Void setLoudnessSensorPin (uint8_t-Pin); Leere Messsensoren (void); void changeAnimation(void * args); void changeSpeed(void * args); void changeColor(void * args); statische Anwendung::CheerLight * getInstance(void); geschützt: Treiber::LEDStrip _ledStrip; Treiber::PIRSensor _pirSensor; Treiber::LoudnessSensor _loudnessSensor; uint8_t _animation; Middleware::Delegate _detectedDelegate; Middleware::Delegate _absoluteLoudnessDelegate; Middleware::Delegate _relativeLoudnessDelegate; CheerLight(leer); statische Anwendung::CheerLight _instance; };

Die CheerLight-Klasse wurde von Singleton Patterns entworfen, was bedeutet, dass es nur eine Instanz dafür gibt. Sie können CheerLight::getInstance() für diese Instanz aufrufen. Wenn sich die Verbindungen Ihrer Sensoren von der Hardwareverbindung unterscheiden, können Sie sie ändern, indem Sie die Methoden setPIRSensorPin() und setLoudnessSensorPin() aufrufen.

Bild
Bild

Wir empfehlen, die Methode measureSensors() im Timer-Interrupt aufzurufen, damit die Sensoren rechtzeitig gemessen werden, aber das manuelle Aufrufen der Methoden changeAnimation(), changeSpeed() oder changeColor() ist nicht erforderlich. Sie werden über Delegierte aufgerufen, wenn Sensoren gemessen werden.

Was ist ein Delegierter?

Wie wir alle wissen, können wir einen Funktionszeiger deklarieren und ihn auf eine Funktion in C zeigen lassen:

void func1(void);

void (*pFunc)(void) = func1;

und verwenden Sie es, um die Funktion aufzurufen, auf die es gezeigt hat

pFunc();

Aber es gibt Unterschiede in C++, wenn Sie versuchen, den Code wie folgt zu kompilieren:

Klasse a {

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

Der Compiler meldet einen Typkonvertierungsfehler, hier ist das richtige Beispiel:

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

Wenn wir versuchen, diese Methode zum Aufrufen dieser Methode zu verwenden, tritt erneut ein Fehler auf. Der Grund für diesen Fehler ist, dass eine Objektmethode von einem Objekt aufgerufen werden muss. Also erstellen wir ein Objekt, um es aufzurufen:

Aa;

a.*pFunc();

Diesmal kein Problem. Es gibt also die Delegate-Klasse in Delegate.h.

Vorlage

Klassen-Middleware::Delegate: öffentliche Middleware::interface::IDelegate { public: Delegate(T * Objekt, void (T::*method)(void *)); void invoke(void * args); geschützt: T * _Objekt; void (T::*_method)(void*); }; Template-Inline-Middleware::Delegate::Delegate(T * object, void (T::*method)(void *)): _object(object), _method(method) { } Template-Inline-Void-Middleware::Delegate::invoke(void * args) { (_object->*_method) (args); }

Da die Delegate-Klasse eine Vorlagenklasse ist, was bedeutet, dass Delegate ein Unterschied zu Delegate ist, wie kann man sie so einstellen, dass ein Zeiger denselben Typ hat? Die Antwort ist Schnittstelle, also gibt es IDelegate-Schnittstelle in IDelegate.h.

Klassen-Middleware::Schnittstelle::IDelegate {

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

In der Klasse von PIR Sensor und Loudness Sensor gibt es eine Variable namens _delegates, die verwendet wird, um Zeiger von Delegates zu speichern, und es gibt eine Methode namens invokeAllDelegates(), die verwendet wird, um alle Delegates in _delegates aufzurufen, sie wird in der Methode Measure() aufgerufen.

HINWEIS: Delegate-Methoden wie changeAnimation(), changeSpeed() und changeColor() werden im Timer2-Interrupt aufgerufen, verwenden Sie also NICHT delay() oder andere Interrupt-basierte Funktionen darin.

Empfohlen: