Arduino basierte Quiz Box: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
(25 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 47: Zeile 47:
! ID  !! Inhalt !! Prio!! Ersteller !! Datum !! Geprüft von !! Datum
! ID  !! Inhalt !! Prio!! Ersteller !! Datum !! Geprüft von !! Datum
|-
|-
| 1  || Die Displays müssen veschiedene Zeichen zu verschiedenen Zeitpunkten ausgeben können. || hoch ||Anivesh Kumar || 10.10.24 || ||  
| 1  || Die Displays müssen veschiedene Zeichen zu verschiedenen Zeitpunkten ausgeben können. || hoch || Marius Hoffknecht, Anivesh Kumar || 10.10.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|-
|-
| 2  || Das Zusammenspiel zwischen LED, Display und Potentiometer muss zu jedem Zeitpunkt einwandfrei funktionieren. || hoch ||Anivesh Kumar || 10.10.24 || ||  
| 2  || Das Zusammenspiel zwischen LED, Display und Potentiometer muss zu jedem Zeitpunkt einwandfrei funktionieren. || hoch || Marius Hoffknecht, Anivesh Kumar || 10.10.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|-
|-
| 3  || Push Button für Neustarten muss funktionsfähig sein. || mittel ||Anivesh Kumar || 10.10.24 || ||  
| 3  || Push Button für Neustarten muss funktionsfähig sein. || mittel || Marius Hoffknecht, Anivesh Kumar || 10.10.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|-
|-
| 4  || Push Button muss über ein Interrupt entprellt werden. || niedrig ||Anivesh Kumar || 10.10.24 || ||  
| 4  || Push Button muss über ein Interrupt entprellt werden. || niedrig || Marius Hoffknecht, Anivesh Kumar || 10.10.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|-
|-
| 5  || Servo Motor muss nach Spielende den Deckel öffnen. || hoch || Marius Hoffknecht || 10.10.24 || ||  
| 5  || Servo Motor muss nach Spielende den Deckel öffnen. || hoch || Marius Hoffknecht, Anivesh Kumar || 10.10.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|-
|-
| 6  || RGB-LED muss hell beleuchtet sein. || mittel ||Anivesh Kumar || 10.10.24 || ||  
| 6  || RGB-LED muss hell beleuchtet sein. || mittel || Marius Hoffknecht, Anivesh Kumar || 10.10.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|-
|-
| 7  || Das Quiz Box muss in eine Schuhkarton passen. || mittel ||Anivesh Kumar || 11.10.24 || ||  
| 7  || Die Quiz Box muss in eine Schuhkarton passen. || mittel || Marius Hoffknecht, Anivesh Kumar || 11.10.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|-
|-
| 8  || Das Lösungsbox muss in eine Schuhkarton passen. || mittel ||Anivesh Kumar || 11.10.24 || ||  
| 8  || Die Lösungsbox muss in eine Schuhkarton passen. || mittel || Marius Hoffknecht, Anivesh Kumar || 11.10.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|-
|-
| 9  || RGB LED 1 und 2 müssen grün leuchten, wenn die richtige Antwort ausgewählt wurde. || hoch ||Marius Hoffknecht || 12.12.24 || ||  
| 9  || RGB LED 1 und 2 müssen grün leuchten, wenn die richtige Antwort ausgewählt wurde. || hoch || Marius Hoffknecht, Anivesh Kumar || 12.12.24 || Marius Hoffknecht, Anivesh Kumar || 14.01.25
|}
|}


Zeile 70: Zeile 70:




[[Datei:Layout QuizBox v2.jpg|mini|rechts|Abb. 01: Zeichnung Quiz Box]]
[[Datei:Layout QuizBox v2.jpg|mini|rechts|Abb. 01: Zeichnung Quiz Box[https://svn.hshl.de/usvn/project/Elektrotechnik_Fachpraktikum/show/trunk/Projekte/172-184/174_Arduino_basierte_Quiz_Box/Allgemeine_Planung/Layout_QuizBox_v2.jpg]]]
[[Datei:Funktionale Systementwurf QuizBox.jpg|mini|rechts|Abb. 02: Funktionaler Systementwurf]]
 
[[Datei:Technische Systementwurf v2.jpg|mini|rechts|Abb. 03: Technischer Systementwurf]]
[[Datei:Funktionale Systementwurf QuizBox.jpg|mini|rechts|Abb. 02: Funktionaler Systementwurf[https://svn.hshl.de/usvn/project/Elektrotechnik_Fachpraktikum/show/trunk/Projekte/172-184/174_Arduino_basierte_Quiz_Box/Allgemeine_Planung/Funktionale_Systementwurf_QuizBox.jpg]]]
 
[[Datei:Technische Systementwurf v2.jpg|mini|rechts|Abb. 03: Technischer Systementwurf[https://svn.hshl.de/usvn/project/Elektrotechnik_Fachpraktikum/show/trunk/Projekte/172-184/174_Arduino_basierte_Quiz_Box/Allgemeine_Planung/Technische_Systementwurf_v2.jpg]]]


Technischer Systementwurf:
Technischer Systementwurf:
Zeile 138: Zeile 140:


== Umsetzung (HW/SW) ==
== Umsetzung (HW/SW) ==
<big>'''Software(SW)'''</big>
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Programmablaufplan'''
[[Datei:Arduino basierte Quiz Box PAP v4.png|mini|links|Abb. 04: Projekt Ablauf Plan von Quiz Box]]
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Simulink-Modell'''
[[Datei:Hauptprogramm_Bild.jpg|mini|links|Abb. 05: Simulink Modell]]
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Simulink IO Device Builder Code'''
{| class="wikitable"
|-
Dieser Code würde in Arduino IDE getestet und weiter in Simulink Modell mithilfe der IO Device Builder erstellt und eingetragen.
{|
| <small><small>
{| class="wikitable"
|-
| <div style="width:800px; height:400px; overflow:scroll; border: hidden">
<syntaxhighlight lang="cpp" style="border: none; background-color: #EFF1C1; font-size:larger">
/********************************************************************************************************
                        Fachpraktikum Mechatronik WS2024/25
  Aufgabe      :      Arduino_Mega_Hauptprogramm.ino
  Betreuer      :      Marc Ebmeyer
  Autor        :      Anivesh Kumar && Marius Hoffknecht
  Datum        :      Lippstadt,den 27.12.2024
  Letzte Änderung:      Lippstadt,den 14.01.2025
  Software      :      MATLAB R2024b
  Hardware      :      Arduino Mega 2560
  Anmerkung      :    **Potis müssen langsam gedreht werden damit die werte bei dem übergang von hohere stellige Zahl zu eine Niedriger Stellige Zahl auf dem kleinere OLED Displays nicht überschreibt
                        , Dieses Programm wird teilweise in eine Simulink Modell Verwendet
                        , Dieses Programm dient als eine zweite Lösung wenn der Anwender kein Matlab/Simulink auf ihrem Rechner hat**
  Quellen        :    TFT_22_ILI9225.h bibliothek von Nkawu -> https://github.com/Nkawu/TFT_22_ILI9225
                      SSD1306Ascii.h && SSD1306AsciiWire.h bibliotheken von Bill Greiman -> https://github.com/greiman/SSD1306Ascii
                      Adafruit_NeoPixel.h bibliothek von Adafruit -> https://github.com/adafruit/Adafruit_NeoPixel
                      Servo.h bibliothek von Arduino, Michael Margolis -> https://github.com/arduino-libraries/Servo
  Status          :    Fertig
*******************************************************************************************************/
//Bibliothek wo die Cpp datei von diesem Simulink IO Device Builder block Gespeichert ist
#include "C:\Users\kumar\OneDrive\Desktop\Projekt_Relevant\HauptprogrammBibs\Arduino_Mega_Hauptprogramm.h"
//Einbindung Arduino bibliothek
#include "arduino.h"
int BRIGHTNESS = 255; //helligkeit von rgb led streife
//Bibliotheken AND GLOBALE Variablen
#include <Adafruit_NeoPixel.h> // einbindung Neopixel bibliothek
const int PIN_u16 = 9; // Pin für rgb led streife
const int NUMPIXELS_u16 = 8; // Max anzahl von rgb leds auf rgb led streife
Adafruit_NeoPixel pixels(NUMPIXELS_u16, PIN_u16, NEO_GRB + NEO_KHZ800); // objekt von rgb led streife
// Notwendige bibliotheken für alle displays
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include "SPI.h"
#include "TFT_22_ILI9225.h"
// oled displays objekte
SSD1306AsciiWire oled1;
SSD1306AsciiWire oled2;
// Pinbelegung von TFT display
const int TFT_RST = 28;
const int TFT_RS  = 22;
const int TFT_CS  = 36;  // SS
const int TFT_SDI = 51;  // MOSI
const int TFT_CLK = 52;  // SCK
const int TFT_LED = 0;  // 0 if wired to +5V directly
const int TFT_BRIGHTNESS = 200;  // display helligkeit auf 200
TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_LED, TFT_BRIGHTNESS); // TFT display objekt
// Variablen für Jede Abschnitt von Code
volatile int Task_u16 = 0;
volatile int Mini_Task_u16 = 0;
// Globale variablen für die Haupt Farben am RGB LEDs
int Rot_u16= 0;
int Gruen_u16 = 0;
int Blau_u16 = 0;
//int Text_Farbe = 0;
//Zusatzvariable für Displays zu Löschen
bool Clear_Display = 0;
// Notwendige FUNKTIONEN
// Funktion für RGBLED streife für player 1
void RGB_LED_PLATINE_Color_Set1(int R, int G, int B)
  {
    for(int i = 0; i<4; i++) // for loop
  {
   
    pixels.setPixelColor(i, pixels.Color(R, G, B)); // jede einzelne led mit farbe setzen
    pixels.show(); // led mit farbe anzeigen
  }
  }
// Funktion für RGBLED streife für player 2
void RGB_LED_PLATINE_Color_Set2(int r, int g, int b)
  {
    for(int j = 4; j<8; j++) // for loop
  {
   
    pixels.setPixelColor(j, pixels.Color(r, g, b)); // jede einzelne led mit farbe setzen
    pixels.show(); // led mit farbe anzeigen
  }
  }
// Funktion für die Schlauer Säuberung von OLED Display 1
void OLED1_Display_Output(int x, String y)
{
oled1.setCursor(2,1); //Cursor punkt einstellen
  if((x>7 && x<12)||(x>97 && x<102)||(x>997 && x<1003)) //Wenn diese werte trifft
  {
    oled1.print(y); //String anzeigen
    oled1.clear(); //Display aufräumen
  }
  else // sonst
  {
  oled1.print(y); //String anzeigen
  }
}
// Funktion für die Schlauer Säuberung von OLED Display 2
void OLED2_Display_Output(int x, String y)
{
oled2.setCursor(2,1); // Cursor punkt einstellen
  if((x>7 && x<12)||(x>97 && x<102)||(x>997 && x<1003)) // Wenn diese Werte Trifft
  {
    oled2.print(y); // String anzeigen
    oled2.clear(); //Display aufräumen
  }
  else // Sonst
  {
  oled2.print(y); //String anzeigen
  }
}
void Button_Reset() // Reset Button ISR
{
  Task_u16 = 0; // Programm ablauf auf 0 setzen
}
// SETUP SCHLEIFE
void setupFunctionArduino_Mega_Hauptprogramm()
{
  pixels.begin(); //initialisierung von RGB LED streife
  pixels.show();            // anzeige an alle einzelnen LEDs
  pixels.setBrightness(100); // Helligkeit einstellung
  pinMode(2,INPUT_PULLUP); // taster an Pin 2 pinmode einstellung
  attachInterrupt(digitalPinToInterrupt(2), Button_Reset, FALLING); // Reset button ISR einknupfen
 
  Wire.begin(); // I2C schnittstelle für OLED displays
  Wire.setClock(400000L); //I2C clock einstellung
  tft.begin(); //tft initialisieren
  oled1.begin(&Adafruit128x32, 0x3D); //OLED 1 einbindung an I2C adresse 0x3D
  oled2.begin(&Adafruit128x32, 0x3C); //OLED 2 einbindung an I2C adresse 0x3C
  oled1.setFont(System5x7); //Gleiche font einstellung für beide displays
  oled2.setFont(System5x7);
  //TFT Text orientation
  tft.setOrientation(1);
  tft.setFont(Terminal12x16); // TFT font einstellung
}
// RedOne uint16 [1,1]
// GreenOne uint16 [1,1]
// BlueOne uint16 [1,1]
// RedTwo uint16 [1,1]
// GreenTwo uint16 [1,1]
// BlueTwo uint16 [1,1]
// ServoWinkel uint16 [1,1]
// PotiOne uint16 [1,1]
// PotiTwo uint16 [1,1]
// PotiThree uint16 [1,1]
// LOOP FUNKTION
//Eingabe -> PotiOne, PotiTwo, PotiThree
//Ausgabe -> RedOne, GreenOne, BlueOne, RedTwo, GreenTwo, BlueTwo
void stepFunctionArduino_Mega_Hauptprogramm(uint16_T * RedOne,int size_vector_1,uint16_T * GreenOne,int size_vector_2,uint16_T * BlueOne,int size_vector_3,uint16_T * RedTwo,int size_vector_4,uint16_T * GreenTwo,int size_vector_5,uint16_T * BlueTwo,int size_vector_6,uint16_T * ServoWinkel,int size_vector_7,uint16_T PotiOne,int size_vector_a,uint16_T PotiTwo,int size_vector_b,uint16_T PotiThree,int size_vector_c)
{
  BRIGHTNESS = PotiOne;
  pixels.setBrightness(BRIGHTNESS); //RGB LED Streife helligkeit einstellen
  // Program ablaüfe gekennzeichnet mit Task_u16
  if (Task_u16 == 0) // bei 0 einführen
  {
   
    *ServoWinkel = 90; // Deckel geschlossen
      //Grün
      *RedOne = 0;*GreenOne = 255;*BlueOne = 0;
    //Grün
      *RedTwo = 0;*GreenTwo = 255;*BlueTwo = 0;
    Clear_Display = 1; // displays aufräumen
    tft.clear();
    oled1.clear();
    oled2.clear();
    Clear_Display = 0; //Gar nix mehr aufräumen
    //Strings für ausgang an Displays
    String D1_1 = "Arduino Basierte";
    String D1_2 = "";
    String D1_3 = "Quiz Box";
    String D1_4 = "";
    String D1_5 = "von Gruppe";
    String D1_6 = "";
    String D1_7 = "MTR_3";
    String D1_8 = "";
    String D2 = "LOS";
    String D3 = "GEHTS!!!";
    // Strings ausgang an TFT display
    tft.drawText(5, 10, D1_1.c_str(), COLOR_BLUE);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_BLUE);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_BLUE);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_BLUE);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_BLUE);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_BLUE);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_BLUE);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_BLUE);
   
   
    // Strings ausgang an OLED displays
    oled1.setCursor(1,1);
    oled2.setCursor(1,1);
    oled1.print(D2);
    oled2.print(D3);
    // farbe an RGB LED PLATine und 2 RGB LEDs
    RGB_LED_PLATINE_Color_Set1(255, 20 , 146);
    RGB_LED_PLATINE_Color_Set2(255, 20 , 146);
    //wenn Mini_Task = 1; 
    if(Mini_Task_u16 == 1)
    {
    delay(5000); // 5s warten
    Clear_Display = 1; // displays aufräumen
    tft.clear();
    oled1.clear();
    oled2.clear();
    Task_u16++; // Program ablauf erhöhen
    Mini_Task_u16 = 0; //minitask zurücksetzen
    }
    else if(Mini_Task_u16 == 0) //wenn minitask 0 ist
    {   
      Mini_Task_u16 = 1; // minitask erhöhen
    }
  }
  // Bei Program ablauf am 1
  else if (Task_u16 == 1)
  {
    *ServoWinkel = 90; //deckel schließen
    Clear_Display = 0; ///Displays nicht aufräumen
    // strings für ausgang am displays
    String D1_1 = "Raetsel 1: ";
    String D1_2 = "";
    String D1_3 = "fuer Rot";
    String D1_4 = "";
    String D1_5 = "230+5*e^x=y";
    String D1_6 = " ";
    String D1_7 = "Was ist y bei x=0";
    String D1_8 = " ";
    // ausgang am TFT
    tft.drawText(5, 10, D1_1.c_str(), COLOR_RED);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_RED);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_RED);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_RED);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_RED);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_RED);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_RED);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_RED);
    // werte an RGB LED streife und 2 RGB leds übergeben
    RGB_LED_PLATINE_Color_Set1(PotiTwo, 0 , 0);
    RGB_LED_PLATINE_Color_Set2(PotiThree, 0 , 0);
    //RGB LEDs farbe eintragen
      *RedOne = PotiTwo; *GreenOne = 0; *BlueOne = 0;
   
      *RedTwo = PotiThree; *GreenTwo = 0; *BlueTwo = 0;
      // strings und ausgang am OLED display
    String D2 = String(PotiTwo);
    String D3 = String(PotiThree);
    OLED1_Display_Output(PotiTwo, D2);
    OLED2_Display_Output(PotiThree, D3);
    //Wenn Linke Player schneller ist
    if (PotiTwo == 235)
    {
        *ServoWinkel = 90; //deckel schließen
      Clear_Display = 0; // nicht aufräumen
      // grün
        *RedOne = 0; *GreenOne = 255; *BlueOne = 0;
      // rot
        *RedTwo = 255; *GreenTwo = 0; *BlueTwo = 0;
      Rot_u16 = PotiTwo; //hauptfarbe speichern
      // Farbe an RGB LED streife
      RGB_LED_PLATINE_Color_Set1(Rot_u16, 0 , 0);
      RGB_LED_PLATINE_Color_Set2(Rot_u16, 0 , 0);
      //wenn minitask 1 ist
      if(Mini_Task_u16 == 1)
      {
      Clear_Display = 1; // dislpay aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
     
      Task_u16++; //program ablauf erhöhen
      Mini_Task_u16 = 0; //minitask zurücksetzen
      delay(1000); //1s delay
      }
      //wenn minitask 0 ist
      else if(Mini_Task_u16 == 0)
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }
    }
    // Wenn Rechte player Schneller ist
    else if (PotiThree == 235)
    {
        *ServoWinkel = 90; //deckel schließen
      Clear_Display = 0; //Nicht aufräumen
      //Grün
        *RedTwo = 0; *GreenTwo = 255; *BlueTwo = 0;
      //Rot
        *RedOne = 255; *GreenOne = 0; *BlueOne = 0;
      Rot_u16 = PotiThree; //Hauptfarbe speichern
      //Farbe an RGBLED Streife übergeben
      RGB_LED_PLATINE_Color_Set1(Rot_u16, 0 , 0);
      RGB_LED_PLATINE_Color_Set2(Rot_u16, 0 , 0);
      if(Mini_Task_u16 == 1) //Wenn minitask = 1 ist
      {
      Clear_Display = 1; //Aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000);  //1s delay
      Task_u16++; //Task erhöhen
      Mini_Task_u16 = 0; //minitask zurücksetzen
      }
      else if(Mini_Task_u16 == 0) //wenn minitask 0 ist
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }
    }
  }
 
  else if (Task_u16 == 2) //Wenn Program ablauf auf 2 ist
  {
    *ServoWinkel = 90; // deckel schließen
    Clear_Display = 0; //Nicht aufräumen
    //TFT relevante strings und ausgang
    String D1_1 = "Raetsel 2: ";
    String D1_2 = "";
    String D1_3 = "fuer Gruen";
    String D1_4 = "";
    String D1_5 = "(34+56+20+12+45+3)";
    String D1_6 = "/2 = x";
    String D1_7 = "";
    String D1_8 = "Was ist x ?";
    tft.drawText(5, 10, D1_1.c_str(), COLOR_GREEN);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_GREEN);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_GREEN);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_GREEN);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_GREEN);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_GREEN);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_GREEN);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_GREEN);
    //Werte an RGB LED Streife und LEDS übertragen
    RGB_LED_PLATINE_Color_Set1(Rot_u16, PotiTwo , 0);
    RGB_LED_PLATINE_Color_Set2(Rot_u16, PotiThree , 0);
   
      *RedOne = 0; *GreenOne = PotiTwo; *BlueOne = 0;
   
      *RedTwo = 0; *GreenTwo = PotiThree; *BlueTwo = 0;
    // Strings und ausgabe an OLED displays
    String D2 = String(PotiTwo);
    String D3 = String(PotiThree);
    OLED1_Display_Output(PotiTwo, D2);
    OLED2_Display_Output(PotiThree, D3);
    // wenn Player 1 schneller ist
    if (PotiTwo == 20)
    {
      *ServoWinkel = 90; //deckel schließen
      Clear_Display = 0; //Nicht aufräumen
      //grün
        *RedOne = 0; *GreenOne = 255; *BlueOne = 0;
      //rot
        *RedTwo = 255; *GreenTwo = 0; *BlueTwo = 0;
      Gruen_u16 = PotiTwo; //Hauptfarbe speichern und an RGBLED streife übergeben
      RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , 0);
      RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , 0);
      if(Mini_Task_u16 == 1) //wenn minitask 1 ist
      {
      Clear_Display = 1; //Display aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000); //1s warten
      Task_u16++; //Task erhöhen
      Mini_Task_u16 = 0; //Minitask zurücksetzen
      }
      else if(Mini_Task_u16 == 0) //wenn minitask 0 ist
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }
    }
    // wenn Palyer 2 schneller ist
    else if (PotiThree == 20)
    {
        *ServoWinkel = 90; //deckel schließen
      Clear_Display = 0; //Nicht aufräumen
      //grün
        *RedTwo = 0; *GreenTwo = 255; *BlueTwo = 0;
      //rot
        *RedOne = 255; *GreenOne = 0; *BlueOne = 0;
      Gruen_u16 = PotiThree; //haupt farbe speichern und an RGB LED sTreife übergeben
      RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , 0);
      RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , 0);
      if(Mini_Task_u16 == 1) //wenn minitask 1 ist
      {
      Clear_Display = 1; //Display aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000);  //delay 1s
      Task_u16++;  //task erhöhen
      Mini_Task_u16 = 0; //Minitask zurücksetzen
      }
      else if(Mini_Task_u16 == 0) //Wenn minitask 0 ist
      {
        Mini_Task_u16 = 1; //Minitask erhöhen
      }
    }
  }
  // Wenn Programm ablauf 3 ist
  else if (Task_u16 == 3)
  {
    *ServoWinkel = 90; //DEckel schließen
    Clear_Display = 0; //Display nicht aufräumen
    //TFT relevante Strings und Ausgabe
    String D1_1 = "Raetsel 3: ";
    String D1_2 = "";
    String D1_3 = "fuer Blau";
    String D1_4 = "";
    String D1_5 = "100 + x/2 =196";
    String D1_6 = " ";
    String D1_7 = " Was ist x ";
    String D1_8 = " ";
    tft.drawText(5, 10, D1_1.c_str(), COLOR_BLUE);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_BLUE);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_BLUE);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_BLUE);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_BLUE);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_BLUE);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_BLUE);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_BLUE);
    // werte an RGB LED streife und 2 RGB leds übergeben
    RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , PotiTwo);
    RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , PotiThree);
   
      *RedOne = 0; *GreenOne = 0; *BlueOne = PotiTwo;
   
      *RedTwo = 0; *GreenTwo = 0; *BlueTwo = PotiThree;
      //OLED Displays relevante Strings und Ausgabe
    String D2 = String(PotiTwo);
    String D3 = String(PotiThree);
    OLED1_Display_Output(PotiTwo, D2);
    OLED2_Display_Output(PotiThree, D3);
    // Wenn Player 1 schneller ist
    if (PotiTwo == 146)
    {
          *ServoWinkel = 90; //Deckel schließen
          Clear_Display = 0; //Nicht aufräumen
          //grün
            *RedOne = 0; *GreenOne = 255; *BlueOne = 0;
          //rot
            *RedTwo = 255; *GreenTwo = 0; *BlueTwo = 0;
          Blau_u16 = PotiTwo; //Hauptfarbe speichern und an RGB LED streife übergeben
          RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , Blau_u16);
          RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , Blau_u16);
          if(Mini_Task_u16 == 1) //Wenn Minitask 1 ist
      {
      Clear_Display = 1; //Displays aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000); //1s delay
      Task_u16++; //Task erhöhen
      Mini_Task_u16 = 0; //Minitask zurücksetzen
      }
      // Wenn Minitask 0 ist
      else if(Mini_Task_u16 == 0)
      {
        Mini_Task_u16 = 1; //Minitask erhöhen
      }
        }
        // Wenn Player 2 schneller ist
        else if (PotiThree == 146)
        {
          *ServoWinkel = 90; //deckel schließen
          Clear_Display = 0; //Nicht aufräumen
          //grün
            *RedTwo = 0; *GreenTwo = 255; *BlueTwo = 0;
          //rot
            *RedOne = 255; *GreenOne = 0; *BlueOne = 0;
          Blau_u16 = PotiThree; // Haupt farbe speichern und an RGB LED streife übergeben
          RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , Blau_u16);
          RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , Blau_u16);
          if(Mini_Task_u16 == 1) // wenn minitask 1 ist
      {
      Clear_Display = 1; //Display aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000); // 1s delay
      Task_u16++; //Task erhöhen
      Mini_Task_u16 = 0; //Minitask zurücksetzen
      }
      else if(Mini_Task_u16 == 0) //Wenn minitask 0 ist
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }
        }
  }
  // Wenn Programm Ablauf 4 ist
  else if (Task_u16 == 4)
  {
    *ServoWinkel = 90; //deckel schließen
    Clear_Display = 0; //nicht aufräumen
    // Hauptfarben an RGB LEDs anzeigen
      *RedTwo = 255; *GreenTwo = 20; *BlueTwo = 146;
      *RedOne = 255; *GreenOne = 20; *BlueOne = 146;
      // TFT Relevante Strings und Ausgabe 
    String D1_1 = "Farbkombination: ";
    String D1_2 = "";
    String D1_3 = "Rot: 255";
    String D1_4 = "";
    String D1_5 = "Gruen: 20";
    String D1_6 = " ";
    String D1_7 = " Blau: 146";
    String D1_8 = " ";
    tft.drawText(5, 10, D1_1.c_str(), COLOR_BLUE);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_BLUE);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_BLUE);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_BLUE);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_BLUE);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_BLUE);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_BLUE);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_BLUE);
    //OLED Display relevante Strings und Ausgabe
    String D2 = "SERVO WIRD";
    String D3 = "GEOEFFNET";
    OLED1_Display_Output(0, D2);
    OLED2_Display_Output(0, D3);
   
    //Deckel öffnen
    *ServoWinkel = 0;
      //Wenn minitask 1 ist
      if(Mini_Task_u16 == 1)
      {   
   
         
    delay(90000); // 1,5min delay
    Clear_Display = 1; //Displays aufräumen
    tft.clear();
    oled1.clear();
    oled2.clear();
    Task_u16 = 0; //Programm Ablauf auf 0 setzen
    Mini_Task_u16 = 0;  //Minitask auf 0 setzen   
      }
        //Wenn minitask 0 ist
      else if (Mini_Task_u16 == 0)
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }   
  }
}
</syntaxhighlight>
</small></small>
|}
|}
'''Tiefpassfilter'''
{| class="wikitable"
|-
Dieser Code würde in eine MATLAB function block geschreiben, und wird 3 mal in Simulink Modell verwendet.
{|
| <small><small>
{| class="wikitable"
|-
| <div style="width:800px; height:400px; overflow:scroll; border: hidden">
<syntaxhighlight lang="cpp" style="border: none; background-color: #EFF1C1; font-size:larger">
%****************************************************************
% Funktion        : Tiefpassfilter.m                          *
%                                                              *
% Datum          : 25.12.2024                                  *
%                                                              *
% Funktion        : Messwerte mit Tiefpass filter filtern      *
%                                                              *
% Implementation  : Matlab R2024b                              *
%                                                              *
% Author          : Anivesh Kumar && Marius Hoffknecht          *
%                                                              *
% Quellen        : DemoTiefpassFilter.ino von Prof.Dr.Schneider *
%                                                              *
%                                                              *
% Letzte Änderung : 14.01.2025                                  *
%                                                              *
%****************************************************************
function FW = Tiefpassfilter(Messwert)
% Persistente Variablen %
persistent Durchlauf;
persistent Alpha;
persistent Ergebnis;
persistent LetzteErgebnis;
if isempty(Durchlauf) % beim ersten ausführen prüfen %
    Alpha = 0.75;
    Ergebnis = 0;
    LetzteErgebnis = Messwert;
    Durchlauf = 1; % durchlauf anzahl als 1 speichern in funktion memory %
end
%a = Alpha;%
Ergebnis = Alpha * LetzteErgebnis + (1-Alpha) * Messwert; % Berechnung Tiefpass Wert %
LetzteErgebnis = Ergebnis; % LetzteErgebnis aktualisieren %
FW = Ergebnis; % als ausgabewert speichern %
end
</syntaxhighlight>
</small></small>
|}
|}
<big>'''Hardware(HW)'''</big>
'''Verdrahtungsplan'''
[[Datei:Verdrahtungsplan1.jpg|mini|links|Abb. 06: Verdrahtungsplan von Quiz Box]]
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Quizbox Top Platte'''
[[Datei:Quizbox Top new Pic.jpg|mini|links|Abb. 07: Quizbox Top Platte]]
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Quizbox Bottom Platte'''
[[Datei:Quizbox Bottom new Pic.jpg|mini|links|Abb. 08: Quizbox Bottom Platte]]
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Quizbox Baugruppe'''
[[Datei:Quizbox Baugruppe Pic.jpg|mini|links|Abb. 09: Quizbox Baugruppe in Solidworks]]
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Lösungsbox Deckel'''
[[Datei:Lösungsbox Deckel Pic.jpg|mini|links|Abb. 10: Lösungsbox Deckel]]
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Lösungsbox Gehäuse'''
[[Datei:Lösungsbox Gehäuse Pic.jpg|mini|links|Abb. 11: Lösungsbox Gehäuse]]
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
| links|left = left
| rechts|right = right
| #default = both
}};"></div></onlyinclude>
'''Lösungsbox Gehäuse'''


[[Datei:Verdrahtungsplan1.jpg|mini|links|Abb. 04: Verdrahtungsplan von Quiz Box]]
[[Datei:Lösungsbox Baugruppe Pic.jpg|mini|links|Abb. 12: Lösungsbox Baugruppe]]
<br>
<onlyinclude><div style="clear:{{{{{|safesubst:}}}#switch:{{{1}}}
<br>
| links|left = left
<br>
| rechts|right = right
<br>
| #default = both
<br>
}};"></div></onlyinclude>
<br>
<br>
<br>
<br>
<br>
[[Datei:Arduino basierte Quiz Box PAP v4.png|mini|links|Abb. 05: Projekt Ablauf Plan von Quiz Box]]
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>


== Komponententest ==
== Komponententest ==
Zeile 223: Zeile 960:
Die einzelnen Lösungswerte der Aufgaben sind im folgenden aufgeführt:
Die einzelnen Lösungswerte der Aufgaben sind im folgenden aufgeführt:


A1:  
Rot  - A1: x = 235


A2:
Grün - A2: x = 20


A3:
Blau - A3: x = 146


Am Ende wurden die Farben so gemischt, dass der RGB-LED Streifen pink leuchtet.
Am Ende wurden die Farben so gemischt, dass der RGB-LED Streifen pink leuchtet.


== Ergebnis ==
== Zusammenfassung ==
== Zusammenfassung ==
=== Lessons Learned ===
=== Lessons Learned ===
Das Projekt "Arduino basierte Quiz Box" hat viele Bereiche der Mechatronik vereint. Zuerst haben wir praktische Erfahrungen in der Projektplanung gesammelt. Dazu haben wir u.a. das Gantt-Diagramm genutzt, welches auch beim Projektmanagement ein essentielles Tool war. Weiterhin wurde der Umgang mit einer CAD-Software vertieft und zudem konnten wir Erfahrungen im 3D-Druck sammeln. Außerdem wurde unser Wissen im Bereich Mikrocontrollern, aber auch allgemein im Bereich Elektronik, durch den Aufbau und die Verkabelung unseres Projektes erweitert.Desweiteren konnten wir unsere Kenntnisse im Bereich der Informatik und MATLAB/Simulink ausbauen, indem wir erstmalig eine Software in dieser Größenordnung mit Simulink umgesetzt haben. Zudem haben wir kleinere Softwares zum Testen der Bauelemente in Arduino umgesetzt und dort auch unsere Kenntnisse vertieft.Anfangs kaum in seinem vollen Umfang gewürdigt, entfaltete die Bedeutung einer sorgfältigen Dokumentation ihre Klarheit erst im Zuge des Projektfortschritts. Sie erwies sich als unverzichtbares Werkzeug, das nicht nur das Verständnis des Projektes vertieft, sondern auch eine präzise Orientierung innerhalb der verschiedenen Entwicklungsphasen ermöglicht. Diese Erkenntnis beleuchtete die essentielle Rolle, die eine gewissenhafte Projektbegleitung durch Dokumentation spielt, und hob deren Wert für die strukturierte und nachvollziehbare Realisierung von Vorhaben hervor.


== Projektunterlagen ==
== Projektunterlagen ==

Version vom 14. Januar 2025, 16:31 Uhr

Autor: Anivesh Kumar und Marius Hoffknecht
Betreuer: Marc Ebmeyer


Einleitung

Zwei Spieler spielen gegeneinander und müssen 3 Rechenaufgaben lösen. Bei jeder Rechenaufgabe kommt eine Zahl zwischen 0 und 255 heraus. Die 3 Ergebniswerte werden dann am Ende für verwendet, um eine Farbe mithilfe einer RGB-LED anzuzeigen. Damit soll den Spielern die Funktionsweise einer RGB-LED nähergebracht werden und die Spieler können gleichzeitig gegeneinander ein mathematisches Quiz spielen. Wenn die Spieler alle 3 Aufgaben gelöst haben, wird Ihnen die Farbe angezeigt, die mit den Ergebnissen zusammengemischt wurde. Anschließend öffnet sich die Lösungsbox und die Spieler erhalten ihren Zahlencode.

1.Aufgabe

4 + 5 * e^x = y Was ist y, wenn x=0 ?

Ergebnis: Y = 9 -> Zahlenwert für Farbe Rot

2. Aufgabe

(34+56-20+30) / 2=x

Ergebnis: x = 50

3. Aufgabe

100 + x/2 = 150

Ergebnis: x= 100


Schwierigkeitslevel: einfach

Anforderungen

Tabelle 1: Anforderungen an die Arduino basierte Quiz Box
ID Inhalt Prio Ersteller Datum Geprüft von Datum
1 Die Displays müssen veschiedene Zeichen zu verschiedenen Zeitpunkten ausgeben können. hoch Marius Hoffknecht, Anivesh Kumar 10.10.24 Marius Hoffknecht, Anivesh Kumar 14.01.25
2 Das Zusammenspiel zwischen LED, Display und Potentiometer muss zu jedem Zeitpunkt einwandfrei funktionieren. hoch Marius Hoffknecht, Anivesh Kumar 10.10.24 Marius Hoffknecht, Anivesh Kumar 14.01.25
3 Push Button für Neustarten muss funktionsfähig sein. mittel Marius Hoffknecht, Anivesh Kumar 10.10.24 Marius Hoffknecht, Anivesh Kumar 14.01.25
4 Push Button muss über ein Interrupt entprellt werden. niedrig Marius Hoffknecht, Anivesh Kumar 10.10.24 Marius Hoffknecht, Anivesh Kumar 14.01.25
5 Servo Motor muss nach Spielende den Deckel öffnen. hoch Marius Hoffknecht, Anivesh Kumar 10.10.24 Marius Hoffknecht, Anivesh Kumar 14.01.25
6 RGB-LED muss hell beleuchtet sein. mittel Marius Hoffknecht, Anivesh Kumar 10.10.24 Marius Hoffknecht, Anivesh Kumar 14.01.25
7 Die Quiz Box muss in eine Schuhkarton passen. mittel Marius Hoffknecht, Anivesh Kumar 11.10.24 Marius Hoffknecht, Anivesh Kumar 14.01.25
8 Die Lösungsbox muss in eine Schuhkarton passen. mittel Marius Hoffknecht, Anivesh Kumar 11.10.24 Marius Hoffknecht, Anivesh Kumar 14.01.25
9 RGB LED 1 und 2 müssen grün leuchten, wenn die richtige Antwort ausgewählt wurde. hoch Marius Hoffknecht, Anivesh Kumar 12.12.24 Marius Hoffknecht, Anivesh Kumar 14.01.25

Funktionaler Systementwurf/Technischer Systementwurf

Abb. 01: Zeichnung Quiz Box[1]
Abb. 02: Funktionaler Systementwurf[2]
Abb. 03: Technischer Systementwurf[3]

Technischer Systementwurf:

Der Arduino Mega wird als Controller verwendet und vom Netzteil mit Spannung versorgt. Hier wird ein 2.2 Zoll TFT Display (D1) verwendet die über den SPI Bus angesteuert, und weitere 2x 0.96 Zoll OLED Displays (D2, D3) die über den I2C bus angesteuert werden. Zudem benötigen die Displays (D1,D2,D3) einen Anschluss an die Versorgungsspannung (VCC) und an Ground (GND). Die Display D1 hat 7 Anschlüsse die an der Arduino Mega verbunden müssen, Anschlüsse: MOSI, MISO, SCK, CS, DC, RST, LED, werden an jeweiligen Pins: 51, 50, 52, 11, 10, 9, 12 angeschlossen. Die RGB-LEDs werden mit einem Vorwiderstand von 200 Ohm direkt an die PWM-Digital-Pins des Arduino Megas 2-7 angeschlossen, RGB LED 1 an Pins: 2,3,4 und RGB LED 2 an Pins: 5,6,7. Die RGB-LED-Platine hat vier Anschlüsse. Zwei davon direkt auf Ground, einer an die Versorgungsspannung und ein Signalpin. Der Signalpin wird an den Digitalpin D3 des Arduino angeschlossen. Die Potentiometer haben drei Anschlüsse. Neben der Versorgungsspannung und Ground, werden die Analogpins am Arduino Mega angeschlossen, d.H Poti 1 an A0, Poti 2 an A1 und Poti 3 an A2. Der Servo Motor wird ebenfalls an die Versorgungsspannung und an Ground angeschlossen. Zudem wird der Signalanschluss an PWM Pin 10 des Arduino Mega verbunden. Der Push-Button wird an Digital Pin D8 des Arduinos angeschlossen und muss vor Benutzung entprellt werden.


Tabelle 2: Materialliste
Nr. Anz. Beschreibung Link
1 1 Arduino Mega 2560 https://funduinoshop.com/en/electronic-modules/other/microcontroller/funduino-mega-2560-r3-microcontroller-arduino-compatible
2 1 Push-Button https://funduinoshop.com/bauelemente/taster-und-schalter/taster/taster-mit-farbigem-knopf-12-12-6mm/12-12-9mm
3 2 RGB-LED https://funduinoshop.com/bauelemente/aktive-bauelemente/leds-und-leuchten/rgb-led-common-cathode
4 2 0,96 Zoll I2C OLED-Display (Addressierbar) https://funduinoshop.com/en/electronic-modules/displays/oled/oled-0.96-128x64px-i2c-with-jst-xh2.54-4p-socket
5 3 Potentiometer (10kOhm) https://www.reichelt.de/drehpotentiometer-mono-10-kohm-linear-6-mm-rk09k113-lin10k-p73815.html?PROVID=2788&gad_source=1&gclid=EAIaIQobChMIpq2p75eEiQMV062DBx1wpANgEAQYByABEgKisvD_BwE
6 2 Breadboard https://funduinoshop.com/bauelemente/steckbretter-und-platinen/steckbretter/breadboard-steckbrett-mit-830-kontakten
7 1 Spannungsversorgung/Netzteil 9V-2A https://www.reichelt.de/steckernetzteil-18-w-9-v-2-a-hnp-18-090v2-p298327.html?PROVID=2788&gad_source=1&gclid=CjwKCAjwpbi4BhByEiwAMC8JnVhx27iWHYBs7eWoPl3zBAQboPI9XpAuNrob9TcWDzpgbeIBAifPDBoCFi4QAvD_BwE
8 1 Servo Motor 5V, 180 Grad https://www.reichelt.de/servo-high-end-micro-analog-jamara-033212-p238316.html?&nbc=1
9 1 RGB-LED-Platine WS2812 -> Einzel addressierbar https://funduinoshop.com/bauelemente/aktive-bauelemente/leds-und-leuchten/rgb-led-platine-ws2812-vergleichbar-mit-neopixel-verschiedene-groessen
10 1 Quiz-Box Gehäuse ggf(3D-Druck) kein
11 1 Lösungsbox Gehäuse (3D-Druck) kein
12 6 Widerstände (200 Ohm) https://www.reichelt.de/de/de/widerstand-metallschicht-200-ohm-0207-0-6-w-1--metall-200-p11609.html?PROVID=2788&gad_source=1&gclid=CjwKCAjw9p24BhB_EiwA8ID5Bqu7fZkor6Goc2FLSAPN7G5r5AtZQqk35ApUG4aGrIu1iPSfapAK9RoCPhoQAvD_BwE&&r=1
13 1 Breadboard Netzteil https://funduinoshop.com/diy-werkstatt/stromversorgung/batteriefaecher-und-klemmen/stromversorgungsmodul-fuer-breadboards-typ-mb102-3.3v-5v
14 ? Jumper Kabel m/m https://www.reichelt.de/entwicklerboards-steckbrueckenkabel-40-pole-m-m-30-cm-debo-kabelset15-p282701.html?&nbc=1
15 ? Jumper Kabel f/m https://www.reichelt.de/entwicklerboards-steckbrueckenkabel-40-pole-f-m-15-cm-debo-kabelset10-p282696.html?&nbc=1
16 1 DC Hohlstecker Y-Verteiler https://www.berrybase.de/dc-hohlstecker-5-5-x-2-1mm-y-verteiler-1x-buchse-2x-stecker?number=DCY1Z2&utm_source=google&utm_medium=cpc&gad_source=1&gbraid=0AAAAADSQJK4hh8xVGUmdRw2V0lESwVKvG
17 1 2.2 Zoll TFT SPI Display https://www.reichelt.de/entwicklerboards-display-lcd-2-2-220-x-176-pixel-ili9225-debo-lcd-2-2-p282504.html?&nbc=1

Komponentenspezifikation

Im folgenden Absatz werden die Hauptkomponenten erklärt, die für die Umsetzung der Quizbox benötigt werden.

Hardware Board: Zur Umsetzung der Quizbox wurde ein Arduino Mega Microcontroller verwendet.

RGB-LEDs: Die RGB-LEDs wurden verwendet, um durch rotes oder grünes leuchten zu signalisieren, dass eine richtige Antwort eingegeben wurde. Zudem wurde ein RGB-LED Streifen verwendet, um verschiedene Helligkeitswerte an den RGB-LEDs einzustellen, diese zu vermischen und das Funktionsprinzip einer RGB-LED zu veranschaulichen.

Displays und Potentiometer: Die Displays wurden verwendet, um die Aufgaben anzuzeigen und die Zahlenwerte zur Lösung der Aufgaben anzuzeigen. Mit den Potentiometern können die Zahlenwerte verstellt werden.

Push-Button: Der Push-Button dient als Reset Schalter und verursacht bei Betätigung einen Neustart.

Umsetzung (HW/SW)

Software(SW)

Programmablaufplan

Abb. 04: Projekt Ablauf Plan von Quiz Box

Simulink-Modell

Abb. 05: Simulink Modell

Simulink IO Device Builder Code

Dieser Code würde in Arduino IDE getestet und weiter in Simulink Modell mithilfe der IO Device Builder erstellt und eingetragen.
/********************************************************************************************************
                        Fachpraktikum Mechatronik WS2024/25 

   Aufgabe       :       Arduino_Mega_Hauptprogramm.ino

   Betreuer      :       Marc Ebmeyer

   Autor         :       Anivesh Kumar && Marius Hoffknecht 

   Datum         :       Lippstadt,den 27.12.2024

   Letzte Änderung:       Lippstadt,den 14.01.2025

   Software       :       MATLAB R2024b

   Hardware       :       Arduino Mega 2560

   Anmerkung      :     **Potis müssen langsam gedreht werden damit die werte bei dem übergang von hohere stellige Zahl zu eine Niedriger Stellige Zahl auf dem kleinere OLED Displays nicht überschreibt
                        , Dieses Programm wird teilweise in eine Simulink Modell Verwendet
                        , Dieses Programm dient als eine zweite Lösung wenn der Anwender kein Matlab/Simulink auf ihrem Rechner hat**

   Quellen        :    TFT_22_ILI9225.h bibliothek von Nkawu -> https://github.com/Nkawu/TFT_22_ILI9225
                       SSD1306Ascii.h && SSD1306AsciiWire.h bibliotheken von Bill Greiman -> https://github.com/greiman/SSD1306Ascii
                       Adafruit_NeoPixel.h bibliothek von Adafruit -> https://github.com/adafruit/Adafruit_NeoPixel
                       Servo.h bibliothek von Arduino, Michael Margolis -> https://github.com/arduino-libraries/Servo

  Status          :     Fertig

 *******************************************************************************************************/

//Bibliothek wo die Cpp datei von diesem Simulink IO Device Builder block Gespeichert ist 
#include "C:\Users\kumar\OneDrive\Desktop\Projekt_Relevant\HauptprogrammBibs\Arduino_Mega_Hauptprogramm.h"
//Einbindung Arduino bibliothek
#include "arduino.h"
int BRIGHTNESS = 255; //helligkeit von rgb led streife


//Bibliotheken AND GLOBALE Variablen

#include <Adafruit_NeoPixel.h> // einbindung Neopixel bibliothek
const int PIN_u16 = 9; // Pin für rgb led streife

const int NUMPIXELS_u16 = 8; // Max anzahl von rgb leds auf rgb led streife

Adafruit_NeoPixel pixels(NUMPIXELS_u16, PIN_u16, NEO_GRB + NEO_KHZ800); // objekt von rgb led streife

// Notwendige bibliotheken für alle displays

#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include "SPI.h"
#include "TFT_22_ILI9225.h" 

// oled displays objekte
SSD1306AsciiWire oled1;
SSD1306AsciiWire oled2;

// Pinbelegung von TFT display

const int TFT_RST = 28;
const int TFT_RS  = 22;
const int TFT_CS  = 36;  // SS
const int TFT_SDI = 51;  // MOSI
const int TFT_CLK = 52;  // SCK
const int TFT_LED = 0;   // 0 if wired to +5V directly

const int TFT_BRIGHTNESS = 200;   // display helligkeit auf 200 

TFT_22_ILI9225 tft = TFT_22_ILI9225(TFT_RST, TFT_RS, TFT_CS, TFT_LED, TFT_BRIGHTNESS); // TFT display objekt

// Variablen für Jede Abschnitt von Code

volatile int Task_u16 = 0;
volatile int Mini_Task_u16 = 0;

// Globale variablen für die Haupt Farben am RGB LEDs

int Rot_u16= 0;
int Gruen_u16 = 0;
int Blau_u16 = 0;

//int Text_Farbe = 0;

//Zusatzvariable für Displays zu Löschen

bool Clear_Display = 0;


// Notwendige FUNKTIONEN


// Funktion für RGBLED streife für player 1
void RGB_LED_PLATINE_Color_Set1(int R, int G, int B)
  {
    for(int i = 0; i<4; i++) // for loop
  {
    
    pixels.setPixelColor(i, pixels.Color(R, G, B)); // jede einzelne led mit farbe setzen
    pixels.show(); // led mit farbe anzeigen 
  }
  }
// Funktion für RGBLED streife für player 2
void RGB_LED_PLATINE_Color_Set2(int r, int g, int b)
  {
    for(int j = 4; j<8; j++) // for loop
  {
    
    pixels.setPixelColor(j, pixels.Color(r, g, b)); // jede einzelne led mit farbe setzen 
    pixels.show(); // led mit farbe anzeigen 
  }
  }


// Funktion für die Schlauer Säuberung von OLED Display 1 
void OLED1_Display_Output(int x, String y)
{
 oled1.setCursor(2,1); //Cursor punkt einstellen
  if((x>7 && x<12)||(x>97 && x<102)||(x>997 && x<1003)) //Wenn diese werte trifft 
  { 

    oled1.print(y); //String anzeigen
    oled1.clear(); //Display aufräumen
  }
  else // sonst
  {
  oled1.print(y); //String anzeigen
  }
}
// Funktion für die Schlauer Säuberung von OLED Display 2
void OLED2_Display_Output(int x, String y)
{
 oled2.setCursor(2,1); // Cursor punkt einstellen
  if((x>7 && x<12)||(x>97 && x<102)||(x>997 && x<1003)) // Wenn diese Werte Trifft
  {
    oled2.print(y); // String anzeigen
    oled2.clear(); //Display aufräumen
  }
  else // Sonst
  {
  oled2.print(y); //String anzeigen
  }
}


void Button_Reset() // Reset Button ISR
{
  Task_u16 = 0; // Programm ablauf auf 0 setzen
}






// SETUP SCHLEIFE

void setupFunctionArduino_Mega_Hauptprogramm()
{
  pixels.begin(); //initialisierung von RGB LED streife
  pixels.show();            // anzeige an alle einzelnen LEDs
  pixels.setBrightness(100); // Helligkeit einstellung 

  pinMode(2,INPUT_PULLUP); // taster an Pin 2 pinmode einstellung 
  attachInterrupt(digitalPinToInterrupt(2), Button_Reset, FALLING); // Reset button ISR einknupfen

  

  Wire.begin(); // I2C schnittstelle für OLED displays 
  Wire.setClock(400000L); //I2C clock einstellung 

  tft.begin(); //tft initialisieren

  oled1.begin(&Adafruit128x32, 0x3D); //OLED 1 einbindung an I2C adresse 0x3D
  oled2.begin(&Adafruit128x32, 0x3C); //OLED 2 einbindung an I2C adresse 0x3C
  oled1.setFont(System5x7); //Gleiche font einstellung für beide displays
  oled2.setFont(System5x7);

  //TFT Text orientation
  tft.setOrientation(1);
  tft.setFont(Terminal12x16); // TFT font einstellung
}

// RedOne uint16 [1,1]
// GreenOne uint16 [1,1]
// BlueOne uint16 [1,1]
// RedTwo uint16 [1,1]
// GreenTwo uint16 [1,1]
// BlueTwo uint16 [1,1]
// ServoWinkel uint16 [1,1]
// PotiOne uint16 [1,1]
// PotiTwo uint16 [1,1]
// PotiThree uint16 [1,1]

// LOOP FUNKTION
//Eingabe -> PotiOne, PotiTwo, PotiThree
//Ausgabe -> RedOne, GreenOne, BlueOne, RedTwo, GreenTwo, BlueTwo
void stepFunctionArduino_Mega_Hauptprogramm(uint16_T * RedOne,int size_vector_1,uint16_T * GreenOne,int size_vector_2,uint16_T * BlueOne,int size_vector_3,uint16_T * RedTwo,int size_vector_4,uint16_T * GreenTwo,int size_vector_5,uint16_T * BlueTwo,int size_vector_6,uint16_T * ServoWinkel,int size_vector_7,uint16_T PotiOne,int size_vector_a,uint16_T PotiTwo,int size_vector_b,uint16_T PotiThree,int size_vector_c)
{
  BRIGHTNESS = PotiOne;
  pixels.setBrightness(BRIGHTNESS); //RGB LED Streife helligkeit einstellen


  // Program ablaüfe gekennzeichnet mit Task_u16
  if (Task_u16 == 0) // bei 0 einführen
  {
     
    *ServoWinkel = 90; // Deckel geschlossen 
      //Grün
      *RedOne = 0;*GreenOne = 255;*BlueOne = 0;
    //Grün
      *RedTwo = 0;*GreenTwo = 255;*BlueTwo = 0;
    Clear_Display = 1; // displays aufräumen
    tft.clear();
    oled1.clear();
    oled2.clear();
    Clear_Display = 0; //Gar nix mehr aufräumen 
    //Strings für ausgang an Displays 
    String D1_1 = "Arduino Basierte";
    String D1_2 = "";
    String D1_3 = "Quiz Box";
    String D1_4 = "";
    String D1_5 = "von Gruppe";
    String D1_6 = "";
    String D1_7 = "MTR_3";
    String D1_8 = "";
    String D2 = "LOS";
    String D3 = "GEHTS!!!";
    // Strings ausgang an TFT display 
    tft.drawText(5, 10, D1_1.c_str(), COLOR_BLUE);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_BLUE);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_BLUE);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_BLUE);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_BLUE);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_BLUE);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_BLUE);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_BLUE);
    
    
    // Strings ausgang an OLED displays 
    oled1.setCursor(1,1);
    oled2.setCursor(1,1);
    oled1.print(D2);
    oled2.print(D3);
    // farbe an RGB LED PLATine und 2 RGB LEDs
    RGB_LED_PLATINE_Color_Set1(255, 20 , 146);
    RGB_LED_PLATINE_Color_Set2(255, 20 , 146);
    //wenn Mini_Task = 1;  
    if(Mini_Task_u16 == 1)
    {
    delay(5000); // 5s warten
    Clear_Display = 1; // displays aufräumen
    tft.clear();
    oled1.clear();
    oled2.clear();
    Task_u16++; // Program ablauf erhöhen
    Mini_Task_u16 = 0; //minitask zurücksetzen
    }
    else if(Mini_Task_u16 == 0) //wenn minitask 0 ist
    {    
      Mini_Task_u16 = 1; // minitask erhöhen
    }
  }
  // Bei Program ablauf am 1
  else if (Task_u16 == 1)
  {
    *ServoWinkel = 90; //deckel schließen
    Clear_Display = 0; ///Displays nicht aufräumen 
    // strings für ausgang am displays
    String D1_1 = "Raetsel 1: ";
    String D1_2 = "";
    String D1_3 = "fuer Rot";
    String D1_4 = "";
    String D1_5 = "230+5*e^x=y";
    String D1_6 = " ";
    String D1_7 = "Was ist y bei x=0";
    String D1_8 = " ";
    // ausgang am TFT
    tft.drawText(5, 10, D1_1.c_str(), COLOR_RED);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_RED);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_RED);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_RED);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_RED);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_RED);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_RED);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_RED);
    // werte an RGB LED streife und 2 RGB leds übergeben 
    RGB_LED_PLATINE_Color_Set1(PotiTwo, 0 , 0);
    RGB_LED_PLATINE_Color_Set2(PotiThree, 0 , 0);
    //RGB LEDs farbe eintragen
      *RedOne = PotiTwo; *GreenOne = 0; *BlueOne = 0;
    
      *RedTwo = PotiThree; *GreenTwo = 0; *BlueTwo = 0;
      // strings und ausgang am OLED display 
    String D2 = String(PotiTwo);
    String D3 = String(PotiThree);
    OLED1_Display_Output(PotiTwo, D2);
    OLED2_Display_Output(PotiThree, D3);
    //Wenn Linke Player schneller ist
    if (PotiTwo == 235)
    {
        *ServoWinkel = 90; //deckel schließen
      Clear_Display = 0; // nicht aufräumen
      // grün
        *RedOne = 0; *GreenOne = 255; *BlueOne = 0;
      // rot
        *RedTwo = 255; *GreenTwo = 0; *BlueTwo = 0;
      Rot_u16 = PotiTwo; //hauptfarbe speichern
      // Farbe an RGB LED streife 
      RGB_LED_PLATINE_Color_Set1(Rot_u16, 0 , 0);
      RGB_LED_PLATINE_Color_Set2(Rot_u16, 0 , 0);
      //wenn minitask 1 ist
      if(Mini_Task_u16 == 1)
      {
      Clear_Display = 1; // dislpay aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
       
      Task_u16++; //program ablauf erhöhen
      Mini_Task_u16 = 0; //minitask zurücksetzen
      delay(1000); //1s delay
      }
      //wenn minitask 0 ist 
      else if(Mini_Task_u16 == 0)
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }
    }
    // Wenn Rechte player Schneller ist 
    else if (PotiThree == 235)
    {
        *ServoWinkel = 90; //deckel schließen
      Clear_Display = 0; //Nicht aufräumen 
      //Grün
        *RedTwo = 0; *GreenTwo = 255; *BlueTwo = 0;
      //Rot
        *RedOne = 255; *GreenOne = 0; *BlueOne = 0;
      Rot_u16 = PotiThree; //Hauptfarbe speichern
      //Farbe an RGBLED Streife übergeben
      RGB_LED_PLATINE_Color_Set1(Rot_u16, 0 , 0);
      RGB_LED_PLATINE_Color_Set2(Rot_u16, 0 , 0);
      if(Mini_Task_u16 == 1) //Wenn minitask = 1 ist 
      {
      Clear_Display = 1; //Aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000);  //1s delay 
      Task_u16++; //Task erhöhen
      Mini_Task_u16 = 0; //minitask zurücksetzen
      }
      else if(Mini_Task_u16 == 0) //wenn minitask 0 ist
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }
    }


  }

 
  
  else if (Task_u16 == 2) //Wenn Program ablauf auf 2 ist 
  {
    *ServoWinkel = 90; // deckel schließen
    Clear_Display = 0; //Nicht aufräumen
    //TFT relevante strings und ausgang
    String D1_1 = "Raetsel 2: ";
    String D1_2 = "";
    String D1_3 = "fuer Gruen";
    String D1_4 = "";
    String D1_5 = "(34+56+20+12+45+3)";
    String D1_6 = "/2 = x";
    String D1_7 = "";
    String D1_8 = "Was ist x ?";
    tft.drawText(5, 10, D1_1.c_str(), COLOR_GREEN);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_GREEN);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_GREEN);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_GREEN);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_GREEN);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_GREEN);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_GREEN);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_GREEN);
    //Werte an RGB LED Streife und LEDS übertragen
    RGB_LED_PLATINE_Color_Set1(Rot_u16, PotiTwo , 0);
    RGB_LED_PLATINE_Color_Set2(Rot_u16, PotiThree , 0);
    
      *RedOne = 0; *GreenOne = PotiTwo; *BlueOne = 0;
    
      *RedTwo = 0; *GreenTwo = PotiThree; *BlueTwo = 0;
    // Strings und ausgabe an OLED displays 
    String D2 = String(PotiTwo);
    String D3 = String(PotiThree);
    OLED1_Display_Output(PotiTwo, D2);
    OLED2_Display_Output(PotiThree, D3);
    // wenn Player 1 schneller ist 
    if (PotiTwo == 20)
    {
      *ServoWinkel = 90; //deckel schließen
      Clear_Display = 0; //Nicht aufräumen 
      //grün
        *RedOne = 0; *GreenOne = 255; *BlueOne = 0;
      //rot 
        *RedTwo = 255; *GreenTwo = 0; *BlueTwo = 0;
      Gruen_u16 = PotiTwo; //Hauptfarbe speichern und an RGBLED streife übergeben
      RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , 0);
      RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , 0);
      if(Mini_Task_u16 == 1) //wenn minitask 1 ist 
      {
      Clear_Display = 1; //Display aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000); //1s warten
      Task_u16++; //Task erhöhen
      Mini_Task_u16 = 0; //Minitask zurücksetzen
      }
      else if(Mini_Task_u16 == 0) //wenn minitask 0 ist 
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }
    }
    // wenn Palyer 2 schneller ist
    else if (PotiThree == 20)
    {
        *ServoWinkel = 90; //deckel schließen
      Clear_Display = 0; //Nicht aufräumen 
      //grün
        *RedTwo = 0; *GreenTwo = 255; *BlueTwo = 0;
      //rot
        *RedOne = 255; *GreenOne = 0; *BlueOne = 0;
      Gruen_u16 = PotiThree; //haupt farbe speichern und an RGB LED sTreife übergeben
      RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , 0);
      RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , 0);
      if(Mini_Task_u16 == 1) //wenn minitask 1 ist 
      {
      Clear_Display = 1; //Display aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000);  //delay 1s
      Task_u16++;  //task erhöhen 
      Mini_Task_u16 = 0; //Minitask zurücksetzen
      }
      else if(Mini_Task_u16 == 0) //Wenn minitask 0 ist 
      {
        Mini_Task_u16 = 1; //Minitask erhöhen
      }
    }
  }

  // Wenn Programm ablauf 3 ist 
  else if (Task_u16 == 3)
  {
    *ServoWinkel = 90; //DEckel schließen
    Clear_Display = 0; //Display nicht aufräumen
    //TFT relevante Strings und Ausgabe
    String D1_1 = "Raetsel 3: ";
    String D1_2 = "";
    String D1_3 = "fuer Blau";
    String D1_4 = "";
    String D1_5 = "100 + x/2 =196";
    String D1_6 = " ";
    String D1_7 = " Was ist x ";
    String D1_8 = " ";
    tft.drawText(5, 10, D1_1.c_str(), COLOR_BLUE);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_BLUE);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_BLUE);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_BLUE);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_BLUE);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_BLUE);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_BLUE);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_BLUE);
    // werte an RGB LED streife und 2 RGB leds übergeben 
    RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , PotiTwo);
    RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , PotiThree);
    
      *RedOne = 0; *GreenOne = 0; *BlueOne = PotiTwo;
    
      *RedTwo = 0; *GreenTwo = 0; *BlueTwo = PotiThree;
      //OLED Displays relevante Strings und Ausgabe
    String D2 = String(PotiTwo);
    String D3 = String(PotiThree);
    OLED1_Display_Output(PotiTwo, D2);
    OLED2_Display_Output(PotiThree, D3);
    // Wenn Player 1 schneller ist
    if (PotiTwo == 146)
    {
          *ServoWinkel = 90; //Deckel schließen
          Clear_Display = 0; //Nicht aufräumen 
          //grün
            *RedOne = 0; *GreenOne = 255; *BlueOne = 0;
          //rot
            *RedTwo = 255; *GreenTwo = 0; *BlueTwo = 0;
          Blau_u16 = PotiTwo; //Hauptfarbe speichern und an RGB LED streife übergeben
          RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , Blau_u16);
          RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , Blau_u16);
          if(Mini_Task_u16 == 1) //Wenn Minitask 1 ist 
      {
      Clear_Display = 1; //Displays aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000); //1s delay 
      Task_u16++; //Task erhöhen
      Mini_Task_u16 = 0; //Minitask zurücksetzen
      }
      // Wenn Minitask 0 ist 
      else if(Mini_Task_u16 == 0)
      {
        Mini_Task_u16 = 1; //Minitask erhöhen
      }
        }
        // Wenn Player 2 schneller ist 
        else if (PotiThree == 146)
        {
          *ServoWinkel = 90; //deckel schließen
          Clear_Display = 0; //Nicht aufräumen
          //grün
            *RedTwo = 0; *GreenTwo = 255; *BlueTwo = 0;
          //rot 
            *RedOne = 255; *GreenOne = 0; *BlueOne = 0;
          Blau_u16 = PotiThree; // Haupt farbe speichern und an RGB LED streife übergeben
          RGB_LED_PLATINE_Color_Set1(Rot_u16, Gruen_u16 , Blau_u16);
          RGB_LED_PLATINE_Color_Set2(Rot_u16, Gruen_u16 , Blau_u16);
          if(Mini_Task_u16 == 1) // wenn minitask 1 ist 
      {
      Clear_Display = 1; //Display aufräumen
      tft.clear();
      oled1.clear();
      oled2.clear();
      delay(1000); // 1s delay 
      Task_u16++; //Task erhöhen
      Mini_Task_u16 = 0; //Minitask zurücksetzen
      }
      else if(Mini_Task_u16 == 0) //Wenn minitask 0 ist 
      {
        Mini_Task_u16 = 1; //minitask erhöhen
      }
        }


  }

  // Wenn Programm Ablauf 4 ist 

   else if (Task_u16 == 4)
  {
    *ServoWinkel = 90; //deckel schließen
    Clear_Display = 0; //nicht aufräumen
    // Hauptfarben an RGB LEDs anzeigen
       *RedTwo = 255; *GreenTwo = 20; *BlueTwo = 146;
       *RedOne = 255; *GreenOne = 20; *BlueOne = 146;
       // TFT Relevante Strings und Ausgabe  
    String D1_1 = "Farbkombination: ";
    String D1_2 = "";
    String D1_3 = "Rot: 255";
    String D1_4 = "";
    String D1_5 = "Gruen: 20";
    String D1_6 = " ";
    String D1_7 = " Blau: 146";
    String D1_8 = " ";
    tft.drawText(5, 10, D1_1.c_str(), COLOR_BLUE);
    tft.drawText(5, 30, D1_2.c_str(), COLOR_BLUE);
    tft.drawText(5, 50, D1_3.c_str(), COLOR_BLUE);
    tft.drawText(5, 70, D1_4.c_str(), COLOR_BLUE);
    tft.drawText(5, 90, D1_5.c_str(), COLOR_BLUE);
    tft.drawText(5, 110, D1_6.c_str(), COLOR_BLUE);
    tft.drawText(5, 130, D1_7.c_str(), COLOR_BLUE);
    tft.drawText(5, 150, D1_8.c_str(), COLOR_BLUE);
    //OLED Display relevante Strings und Ausgabe
    String D2 = "SERVO WIRD";
    String D3 = "GEOEFFNET";
    OLED1_Display_Output(0, D2);
    OLED2_Display_Output(0, D3);

    
    //Deckel öffnen
    *ServoWinkel = 0;
      //Wenn minitask 1 ist 
       if(Mini_Task_u16 == 1)
       {    

    
           
    delay(90000); // 1,5min delay
    Clear_Display = 1; //Displays aufräumen
    tft.clear();
    oled1.clear();
    oled2.clear();
    Task_u16 = 0; //Programm Ablauf auf 0 setzen
    Mini_Task_u16 = 0;  //Minitask auf 0 setzen     
       }
        //Wenn minitask 0 ist 
       else if (Mini_Task_u16 == 0)
       {
        Mini_Task_u16 = 1; //minitask erhöhen
       }    

  }




}

Tiefpassfilter

Dieser Code würde in eine MATLAB function block geschreiben, und wird 3 mal in Simulink Modell verwendet.
%****************************************************************
% Funktion        : Tiefpassfilter.m                           *
%                                                               *
% Datum           : 25.12.2024                                  *
%                                                               *
% Funktion        : Messwerte mit Tiefpass filter filtern       *
%                                                               *
% Implementation  : Matlab R2024b                               *
%                                                               *
% Author          : Anivesh Kumar && Marius Hoffknecht          *
%                                                               *
% Quellen         : DemoTiefpassFilter.ino von Prof.Dr.Schneider *
%                                                              *
%                                                               *
% Letzte Änderung : 14.01.2025                                  *
%                                                               *
%****************************************************************


function FW = Tiefpassfilter(Messwert)
% Persistente Variablen %
persistent Durchlauf;
persistent Alpha;
persistent Ergebnis;
persistent LetzteErgebnis;

if isempty(Durchlauf) % beim ersten ausführen prüfen %
    Alpha = 0.75;
    Ergebnis = 0;
    LetzteErgebnis = Messwert;
    Durchlauf = 1; % durchlauf anzahl als 1 speichern in funktion memory %
end
%a = Alpha;%
Ergebnis = Alpha * LetzteErgebnis + (1-Alpha) * Messwert; % Berechnung Tiefpass Wert %
LetzteErgebnis = Ergebnis; % LetzteErgebnis aktualisieren %
FW = Ergebnis; % als ausgabewert speichern % 
end

Hardware(HW)


Verdrahtungsplan

Abb. 06: Verdrahtungsplan von Quiz Box

Quizbox Top Platte

Abb. 07: Quizbox Top Platte

Quizbox Bottom Platte

Abb. 08: Quizbox Bottom Platte

Quizbox Baugruppe

Abb. 09: Quizbox Baugruppe in Solidworks

Lösungsbox Deckel

Abb. 10: Lösungsbox Deckel

Lösungsbox Gehäuse

Abb. 11: Lösungsbox Gehäuse

Lösungsbox Gehäuse

Abb. 12: Lösungsbox Baugruppe

Komponententest

Nr. Anz. Beschreibung Link Teststatus
1 1 Arduino Mega 2560 https://funduinoshop.com/en/electronic-modules/other/microcontroller/funduino-mega-2560-r3-microcontroller-arduino-compatible getestet
2 1 Push-Button https://funduinoshop.com/bauelemente/taster-und-schalter/taster/taster-mit-farbigem-knopf-12-12-6mm/12-12-9mm getestet
3 2 RGB-LED https://funduinoshop.com/bauelemente/aktive-bauelemente/leds-und-leuchten/rgb-led-common-cathode getestet
4 2 0,96 Zoll I2C OLED-Display (Addressierbar) https://funduinoshop.com/en/electronic-modules/displays/oled/oled-0.96-128x64px-i2c-with-jst-xh2.54-4p-socket getestet
5 3 Potentiometer (10kOhm) https://www.reichelt.de/drehpotentiometer-mono-10-kohm-linear-6-mm-rk09k113-lin10k-p73815.html?PROVID=2788&gad_source=1&gclid=EAIaIQobChMIpq2p75eEiQMV062DBx1wpANgEAQYByABEgKisvD_BwE getestet
6 2 Breadboard https://funduinoshop.com/bauelemente/steckbretter-und-platinen/steckbretter/breadboard-steckbrett-mit-830-kontakten getestet
7 1 Spannungsversorgung/Netzteil 9V-2A https://www.reichelt.de/steckernetzteil-18-w-9-v-2-a-hnp-18-090v2-p298327.html?PROVID=2788&gad_source=1&gclid=CjwKCAjwpbi4BhByEiwAMC8JnVhx27iWHYBs7eWoPl3zBAQboPI9XpAuNrob9TcWDzpgbeIBAifPDBoCFi4QAvD_BwE getestet
8 1 Servo Motor 5V, 180 Grad https://www.reichelt.de/servo-high-end-micro-analog-jamara-033212-p238316.html?&nbc=1 getestet
9 1 RGB-LED-Platine WS2812 -> Einzel addressierbar https://funduinoshop.com/bauelemente/aktive-bauelemente/leds-und-leuchten/rgb-led-platine-ws2812-vergleichbar-mit-neopixel-verschiedene-groessen getestet
10 1 Quiz-Box Gehäuse ggf(3D-Druck) kein kein Test notwendig
11 1 Lösungsbox Gehäuse (3D-Druck) kein kein Test notwendig
12 6 Widerstände (200 Ohm) https://www.reichelt.de/de/de/widerstand-metallschicht-200-ohm-0207-0-6-w-1--metall-200-p11609.html?PROVID=2788&gad_source=1&gclid=CjwKCAjw9p24BhB_EiwA8ID5Bqu7fZkor6Goc2FLSAPN7G5r5AtZQqk35ApUG4aGrIu1iPSfapAK9RoCPhoQAvD_BwE&&r=1 getestet
13 1 Breadboard Netzteil https://funduinoshop.com/diy-werkstatt/stromversorgung/batteriefaecher-und-klemmen/stromversorgungsmodul-fuer-breadboards-typ-mb102-3.3v-5v getestet
14 ? Jumper Kabel m/m https://www.reichelt.de/entwicklerboards-steckbrueckenkabel-40-pole-m-m-30-cm-debo-kabelset15-p282701.html?&nbc=1 getestet
15 ? Jumper Kabel f/m https://www.reichelt.de/entwicklerboards-steckbrueckenkabel-40-pole-f-m-15-cm-debo-kabelset10-p282696.html?&nbc=1 getestet
16 1 DC Hohlstecker Y-Verteiler https://www.berrybase.de/dc-hohlstecker-5-5-x-2-1mm-y-verteiler-1x-buchse-2x-stecker?number=DCY1Z2&utm_source=google&utm_medium=cpc&gad_source=1&gbraid=0AAAAADSQJK4hh8xVGUmdRw2V0lESwVKvG getestet
17 1 2.2 Zoll TFT SPI Display https://www.reichelt.de/entwicklerboards-display-lcd-2-2-220-x-176-pixel-ili9225-debo-lcd-2-2-p282504.html?&nbc=1 getestet

Musterlösung

Die einzelnen Lösungswerte der Aufgaben sind im folgenden aufgeführt:

Rot - A1: x = 235

Grün - A2: x = 20

Blau - A3: x = 146

Am Ende wurden die Farben so gemischt, dass der RGB-LED Streifen pink leuchtet.

Ergebnis

Zusammenfassung

Lessons Learned

Das Projekt "Arduino basierte Quiz Box" hat viele Bereiche der Mechatronik vereint. Zuerst haben wir praktische Erfahrungen in der Projektplanung gesammelt. Dazu haben wir u.a. das Gantt-Diagramm genutzt, welches auch beim Projektmanagement ein essentielles Tool war. Weiterhin wurde der Umgang mit einer CAD-Software vertieft und zudem konnten wir Erfahrungen im 3D-Druck sammeln. Außerdem wurde unser Wissen im Bereich Mikrocontrollern, aber auch allgemein im Bereich Elektronik, durch den Aufbau und die Verkabelung unseres Projektes erweitert.Desweiteren konnten wir unsere Kenntnisse im Bereich der Informatik und MATLAB/Simulink ausbauen, indem wir erstmalig eine Software in dieser Größenordnung mit Simulink umgesetzt haben. Zudem haben wir kleinere Softwares zum Testen der Bauelemente in Arduino umgesetzt und dort auch unsere Kenntnisse vertieft.Anfangs kaum in seinem vollen Umfang gewürdigt, entfaltete die Bedeutung einer sorgfältigen Dokumentation ihre Klarheit erst im Zuge des Projektfortschritts. Sie erwies sich als unverzichtbares Werkzeug, das nicht nur das Verständnis des Projektes vertieft, sondern auch eine präzise Orientierung innerhalb der verschiedenen Entwicklungsphasen ermöglicht. Diese Erkenntnis beleuchtete die essentielle Rolle, die eine gewissenhafte Projektbegleitung durch Dokumentation spielt, und hob deren Wert für die strukturierte und nachvollziehbare Realisierung von Vorhaben hervor.

Projektunterlagen

Projektplan

Abbildung 04: Projektplanung mit Gantt

Hier ist die Projektplanung mit dem Programm GanttProject zu sehen. Alle verschiedenen Planungsschritte sind hier eingetragen und die Verfolgung der aktuellen Projektphase ist leicht nachvollziehbar. Die Datei wird immer aktuell gehalten, um jederzeit einen aktuellen Überblick zu gewährleisten.

Weblinks

Literatur


→ zurück zur Übersicht: WS 24/25: Escape Game