/********************************************************************************************************
Fachpraktikum Mechatronik WS2024/25
Aufgabe : Hauptprogramm_Arduino_IDE_Basiert_v2.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 == 9 || x == 10 || x == 99|| x == 100|| x == 999 || x == 1000) //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 == 9 || x == 10 || x == 99|| x == 100|| x == 999 || x == 1000) // 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(3);
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
}
}
}