Thanks Tom! The Mosfet Driver was exatly what im searching for.
I replaced the Transistors by this Mosfet drivers, now the basic function are working.
To prevent failures because of induction of the coils Ive used Diodes.
Two things are left, I really would appreciate it if you guys also have good Input.
First, i want to reduce the Injector Voltage at "void opentest1" to 8V. The injector should be switched on with 8V Voltage, then switched off etc.
The PWM Ports of my MEGA2560 are all used by the TFT Touch. My first Idea was, to realize the Voltage drop by using the PWM library. ATM the Voltage is still 12V without drop, also if i use 10% PWM Duty cycle.
Do you have an idea, if the error occurs bcs. of mistakes codewise or bcs. of hardwarewise problems?
Second, Im willed to switch 4 injectors on for 3 milliseconds by function "void dynamicmatching". The injectors should be switched on one after each after. For better understanding, switch injectors on like:
Injector 1: 0-3ms
Injector 2: 3-6ms
...
Injector 4: 9-12ms
This procedure should be runned 1000 times, then it should stop. Running the procedure one time means every single injector is switched on one time.
The current code works, but works very poorly, means that the timing for opening and closing is very inaccurate. It seems like the Arduino is not fast enough to open and close the injectors at the correct point of time. The serial Port also shows, that the timing is incorrect.
Do you see any mistakes at the code, which lead to this error?
#include <SoftPWM.h> //library for using non pwm pin as pwm pins
#include <SoftPWM_timer.h> //library for using non pwm pin as pwm pins
#include "TouchScreen.h" //touch library
#include "LCDWIKI_GUI.h" //Core graphics library
#include "LCDWIKI_KBV.h" //Hardware-specific library
LCDWIKI_KBV my_lcd(ILI9486, A3, A2, A1, A0, A4); //model,cs,cd,wr,rd,reset
// making digital pins to pwm pins and declaring them
#define PIN1_PWM 31
#define PIN2_PWM 33
#define PIN3_PWM 35
#define PIN4_PWM 37
//snippet for turn on injectors repeatedly with lower voltage (PWM)
const uint8_t PWMPins[4] = { PIN1_PWM, PIN2_PWM, PIN3_PWM, PIN4_PWM};
const uint8_t lastPWMIndex = sizeof(PWMPins) - 1;
const uint16_t openDuration_opentest1 = 250; //time period for void open test 1
const uint16_t openDuration_opentest2 = 500; //time period for open test 2
uint32_t lastopen;
uint8_t currPWM = lastPWMIndex;
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define YP A3 // must be an analog pin, use "An" notation!
#define XM A2 // must be an analog pin, use "An" notation!
#define YM 9 // can be a digital pin
#define XP 8 // can be a digital pin
//touch sensitivity for X
#define TS_MINX 906
#define TS_MAXX 116
//touch sensitivity for Y
#define TS_MINY 92
#define TS_MAXY 952
#define MINPRESSURE 10
#define MAXPRESSURE 1000
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
// declaration for grafics
void show_string(uint8_t *str, int16_t x, int16_t y, uint8_t csize, uint16_t fc, uint16_t bc, boolean mode)
{
my_lcd.Set_Text_Mode(mode);
my_lcd.Set_Text_Size(csize);
my_lcd.Set_Text_colour(fc);
my_lcd.Set_Text_Back_colour(bc);
my_lcd.Print_String(str, x, y);
}
boolean is_pressed(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t px, int16_t py)
{
if ((px > x1 && px < x2) && (py > y1 && py < y2))
{
return true;
}
else
{
return false;
}
}
char currentpage;
unsigned long previousMillis;
unsigned long currentMillis;
unsigned long ventilateMillis;
// snippet for ventilation, putting on one injector after another repeatedly
const uint8_t ledPins[4] = { 31, 33, 35, 37 };
const uint8_t lastIndex = sizeof(ledPins) - 1;
const uint16_t blinkDuration = 200; //time period for void ventilation
uint32_t lastBlink;
uint8_t currLed = lastIndex;
//declarate matching parameters
int matchtime = 0;
int dynamicmatchtime = 0;
int vmax = 0;
int vmin = 0;
int vmindyn = 0;
int vmaxdyn = 0;
int buttonleakcheckstate = LOW;
int buttonventilatestate = LOW;
int buttonopentest1state = LOW;
int buttonopentest2state = LOW;
//int dynamicmatchstate = 0;
int dynamicmatchruns = 0;
int previousdynamicmatchruns = 0;
void setup() {
my_lcd.Init_LCD();
my_lcd.Fill_Screen(WHITE);
drawhomescreen();
currentpage = '0';
pinMode(31, OUTPUT);
pinMode(33, OUTPUT);
pinMode(35, OUTPUT);
pinMode(37, OUTPUT);
SoftPWMBegin(); // starting pwm functionality of non pwm pins
for (auto pin : ledPins) { // functionality for ventilation function
pinMode(pin, OUTPUT);
}
for (auto pin : PWMPins) { // functionality for ventilation function
pinMode(pin, OUTPUT);
}
pinMode(31, OUTPUT);
pinMode(33, OUTPUT);
pinMode(35, OUTPUT);
pinMode(37, OUTPUT);
Serial.begin(115200);
Serial.println("hallo");
}
void loop() {
digitalWrite(13, HIGH);
TSPoint p = ts.getPoint();
digitalWrite(13, LOW);
pinMode(XM, OUTPUT);
pinMode(YP, OUTPUT);
////////////// general functionality of pages ////////////////////////////////
if (currentpage == '0') {
if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
{
p.x = map(p.x, TS_MINX, TS_MAXX, my_lcd.Get_Display_Width(), 0);
p.y = map(p.y, TS_MINY, TS_MAXY, my_lcd.Get_Display_Height(), 0);
if (is_pressed(10, 50, 310, 100, p.x, p.y)) //400 ccm clicked
{
matchtime = 6000; // 5s static matching time for this type
dynamicmatchtime = 3; // 30ms danymic matching time
vmin = 20; // min static volume for this type
vmax = 23; // max static volumen for this type
vmindyn = 5; //min dyn. volumen for this type
vmaxdyn = 8; //max dyn. volumen for this type
currentpage = '1';
drawventilate(); // display next page
currentMillis = millis();
previousMillis = currentMillis;
}
if (is_pressed(10, 150, 310, 200, p.x, p.y)) //470 ccm clicked
{
matchtime = 5000; // 5s static matching time for this type
dynamicmatchtime = 3; // 30ms danymic matching time
vmin = 20; // min static volume for this type
vmax = 23; // max static volumen for this type
vmindyn = 5; //min dyn. volumen for this type
vmaxdyn = 8; //max dyn. volumen for this type
currentpage = '1';
drawventilate(); // display next page
currentMillis = millis();
previousMillis = currentMillis;
}
if (is_pressed(10, 250, 310, 300, p.x, p.y)) //600 ccm clicked
{
matchtime = 4000; // 5s static matching time for this type
dynamicmatchtime = 3; // 30ms danymic matching time
vmin = 20; // min static volume for this type
vmax = 23; // max static volumen for this type
vmindyn = 5; //min dyn. volumen for this type
vmaxdyn = 8; //max dyn. volumen for this type
currentpage = '1';
drawventilate(); // display next page
currentMillis = millis();
previousMillis = currentMillis;
}
if (is_pressed(10, 350, 310, 400, p.x, p.y)) //900 ccm clicked
{
matchtime = 3000; // 5s static matching time for this type
dynamicmatchtime = 3; // 3ms danymic matching time
vmin = 20; // min static volume for this type
vmax = 23; // max static volumen for this type
vmindyn = 5; //min dyn. volumen for this type
vmaxdyn = 8; //max dyn. volumen for this type
currentpage = '1';
drawventilate(); // display next page
currentMillis = millis();
ventilateMillis = currentMillis;
}
}
}
if (currentpage == '1') {
startventilate();
currentMillis = millis();
if ((buttonventilatestate == LOW) && (currentMillis - ventilateMillis > 5000)) {
button_ventilate();
}
if ((p.z > MINPRESSURE && p.z < MAXPRESSURE) && (buttonventilatestate == HIGH))
{
p.x = map(p.x, TS_MINX, TS_MAXX, my_lcd.Get_Display_Width(), 0);
p.y = map(p.y, TS_MINY, TS_MAXY, my_lcd.Get_Display_Height(), 0);
if (is_pressed(10, 420, 310, 470, p.x, p.y)) //fertig button clicked
{
digitalWrite(31, LOW);
digitalWrite(33, LOW);
digitalWrite(35, LOW);
digitalWrite(37, LOW);
currentpage = '2';
leakcheck(); // display screen "start leak check"
currentMillis = millis();
previousMillis = currentMillis;
}
}
}
if (currentpage == '2') {
currentMillis = millis();
if ((buttonleakcheckstate == LOW) && (currentMillis - previousMillis > 8000)) {
button_leakcheck();
}
if ((p.z > MINPRESSURE && p.z < MAXPRESSURE) && (buttonleakcheckstate == HIGH))
{
p.x = map(p.x, TS_MINX, TS_MAXX, my_lcd.Get_Display_Width(), 0);
p.y = map(p.y, TS_MINY, TS_MAXY, my_lcd.Get_Display_Height(), 0);
if (is_pressed(10, 420, 310, 470, p.x, p.y)) //leak check ok button clicked
{
currentpage = '3';
drawmatching();
currentMillis = millis();
previousMillis = currentMillis;
}
if (is_pressed(10, 350, 310, 400, p.x, p.y)) //leak check Nok button clicked
{
my_lcd.Fill_Screen(WHITE);
drawhomescreen();
currentpage = '0';
}
}
}
if (currentpage == '3') {
matching(matchtime);
}
if (currentpage == '4') {
if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
{
p.x = map(p.x, TS_MINX, TS_MAXX, my_lcd.Get_Display_Width(), 0);
p.y = map(p.y, TS_MINY, TS_MAXY, my_lcd.Get_Display_Height(), 0);
if (is_pressed(10, 420, 310, 470, p.x, p.y)) //fertig button clicked
{
my_lcd.Fill_Screen(WHITE);
drawdynamicmatching();
dynamicmatchruns = 0;
previousdynamicmatchruns = 0;
currentMillis = millis();
previousMillis = currentMillis;
currentpage = '5';
}
}
}
if (currentpage == '5') {
dynamicmatching(dynamicmatchtime);
}
if (currentpage == '6') { // page for evalutating dynamic match results
if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
{
p.x = map(p.x, TS_MINX, TS_MAXX, my_lcd.Get_Display_Width(), 0);
p.y = map(p.y, TS_MINY, TS_MAXY, my_lcd.Get_Display_Height(), 0);
if (is_pressed(10, 420, 310, 470, p.x, p.y)) //fertig button clicked
{
my_lcd.Fill_Screen(WHITE);
drawopentest1();
currentMillis = millis();
previousMillis = currentMillis;
currentpage = '7';
}
}
}
if (currentpage == '7') {
opentest1();
currentMillis = millis();
if ((buttonopentest1state == LOW) && (currentMillis - previousMillis > 8000)) { // wait 8 seconds till showing up button for open test
button_opentest1();
}
if ((p.z > MINPRESSURE && p.z < MAXPRESSURE) && (buttonopentest1state == HIGH)) //enable touch function to let machine guy start the next step
{
p.x = map(p.x, TS_MINX, TS_MAXX, my_lcd.Get_Display_Width(), 0);
p.y = map(p.y, TS_MINY, TS_MAXY, my_lcd.Get_Display_Height(), 0);
if (is_pressed(10, 420, 310, 470, p.x, p.y)) //fertig button clicked
{
currentpage = '8';
turnallinjoff();
my_lcd.Fill_Screen(WHITE);
drawopentest2();
currentMillis = millis();
previousMillis = currentMillis;
}
}
}
if (currentpage == '8') {
opentest2();
currentMillis = millis();
if ((buttonopentest2state == LOW) && (currentMillis - previousMillis > 8000)) { // wait 8 seconds till showing up button for open test
button_opentest2();
}
if ((p.z > MINPRESSURE && p.z < MAXPRESSURE) && (buttonopentest2state == HIGH)) //enable touch function to let machine guy start the next step
{
p.x = map(p.x, TS_MINX, TS_MAXX, my_lcd.Get_Display_Width(), 0);
p.y = map(p.y, TS_MINY, TS_MAXY, my_lcd.Get_Display_Height(), 0);
if (is_pressed(10, 420, 310, 470, p.x, p.y)) //fertig button clicked
{
currentpage = '0';
turnallinjoff();
my_lcd.Fill_Screen(WHITE);
drawhomescreen();
}
}
}
}
///////////////////////////functions///////////////////////////
void startventilate() { //code for ventilate injectors for fuel rail air evacuation
uint32_t topLoop = millis();
if (topLoop - lastBlink >= blinkDuration) {
lastBlink = topLoop;
digitalWrite(ledPins[currLed], LOW); // switch off last injector
if (++currLed > lastIndex) {
currLed = 0;
}
digitalWrite(ledPins[currLed], HIGH); // turn next injector on
}
}
void leakcheck() {
my_lcd.Fill_Screen(WHITE);
show_string("DICHTHEITSPRUEFUNG!", 10, 10, 2, BLACK, BLACK, 1);
show_string("KEINE DUESE TROPFT", 10, 100, 2, RED, BLACK, 1);
show_string("VENTIL SCHLIESSEN", 10, 200, 2, RED, BLACK, 1);
}
void matching(int matchtime) {
currentMillis = millis();//starts timer for matching
if (currentMillis - previousMillis <= matchtime) {
digitalWrite(31, HIGH);
}
if (currentMillis - previousMillis <= 2 * matchtime && currentMillis - previousMillis > matchtime ) {
digitalWrite(31, LOW);
digitalWrite(33, HIGH);
}
if (currentMillis - previousMillis <= 3 * matchtime && currentMillis - previousMillis > 2 * matchtime ) {
digitalWrite(33, LOW);
digitalWrite(35, HIGH);
}
if (currentMillis - previousMillis <= 4 * matchtime && currentMillis - previousMillis > 3 * matchtime) {
digitalWrite(35, LOW);
digitalWrite(37, HIGH);
}
if (currentMillis - previousMillis > 4 * matchtime) {
digitalWrite(37, LOW);
currentpage = '4'; // nach matching automatisch auf folgeseite weiterleiten
drawresults();// nach matching automatisch auf folgeseite weiterleiten
}
}
void dynamicmatching(int dynamicmatchtime) {
if (dynamicmatchruns <= 1000) {
previousdynamicmatchruns = dynamicmatchruns;
currentMillis = millis();
Serial.println("lauf nummer = ");
Serial.println(dynamicmatchruns);
if (currentMillis - previousMillis <= dynamicmatchtime) {
digitalWrite(31, HIGH);
Serial.println("Düse 1 an");
}
if (currentMillis - previousMillis <= 2 * dynamicmatchtime && currentMillis - previousMillis > dynamicmatchtime ) {
digitalWrite(31, LOW);
digitalWrite(33, HIGH);
Serial.println("Düse 2 an");
}
if (currentMillis - previousMillis <= 3 * dynamicmatchtime && currentMillis - previousMillis > 2 * dynamicmatchtime ) {
digitalWrite(33, LOW);
digitalWrite(35, HIGH);
Serial.println("Düse 3 an");
}
if (currentMillis - previousMillis <= 4 * dynamicmatchtime && currentMillis - previousMillis > 3 * dynamicmatchtime) {
digitalWrite(35, LOW);
digitalWrite(37, HIGH);
Serial.println("Düse 4 an");
}
if (currentMillis - previousMillis > 4 * dynamicmatchtime) {
digitalWrite(37, LOW);
Serial.println(">4 erreicht, alle düsen aus");
dynamicmatchruns = previousdynamicmatchruns + 1;
Serial.println("pm +1 erhöt");
previousMillis = currentMillis;
}
}
if (dynamicmatchruns > 1000) {
Serial.println("dynamic beendet");
turnallinjoff();
currentpage = '6';
drawdynamicresults();
}
}
void opentest1() { // code for test proper injector opening at engine start conditions (8V voltage, 3 Bar pressure, 2.5ms opening pulsewidth)
uint32_t topLoop = millis();
if (topLoop - lastopen >= openDuration_opentest1) {
lastopen = topLoop;
SoftPWMSetPercent(PWMPins[currPWM], 0); // switch off last injector
if (++currPWM > lastPWMIndex) {
currPWM = 0;
delay(100); // not very sexy, but works
}
SoftPWMSetPercent(PWMPins[currPWM], 10); // set outputpin to 10% of source voltage (dont forget transistor characteristik)
}
}
void opentest2() { // code for test proper injector opening at full power conditions (13V voltage, 7 Bar pressure, 5ms opening pulsewidth)
uint32_t topLoop = millis();
if (topLoop - lastopen >= openDuration_opentest2) {
lastopen = topLoop;
SoftPWMSetPercent(PWMPins[currPWM], 0); // switch off last injector
if (++currPWM > lastPWMIndex) {
currPWM = 0;
delay(100); // not very sexy, but works
}
SoftPWMSetPercent(PWMPins[currPWM], 10); // set outputpin to 10% of source voltage (dont forget transistor characteristik)
}
}
///////////////////////////grafical setup buttons///////////////////////////
void button_leakcheck() {
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 420, 310, 470);
show_string("ALLE DICHT", 100, 435, 3, WHITE, BLACK, 1);
my_lcd.Set_Draw_color(RED);
my_lcd.Fill_Rectangle(10, 350, 310, 400);
show_string("UNDICHT", 100, 365, 3, WHITE, BLACK, 1);
buttonleakcheckstate = HIGH;
}
void button_ventilate() {
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 420, 310, 470);
show_string("FERTIG", 100, 435, 3, WHITE, BLACK, 1);
buttonventilatestate = HIGH;
}
void button_opentest1() {
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 420, 310, 470);
show_string("FERTIG", 100, 435, 3, WHITE, BLACK, 1);
buttonopentest1state = HIGH;
}
void button_opentest2() {
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 420, 310, 470);
show_string("FERTIG", 100, 435, 3, WHITE, BLACK, 1);
buttonopentest2state = HIGH;
}
///////////////////////////grafical setup pages///////////////////////////
void drawhomescreen()
{
my_lcd.Set_Draw_color(BLACK);
show_string("Duesengroesse waehlen!", 10, 11, 2, BLACK, BLACK, 1);
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 50, 310, 100);
show_string("400 ccm", 100, 65, 3, WHITE, BLACK, 1);
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 150, 310, 200);
show_string("470 ccm", 100 , 165, 3, WHITE, BLACK, 1);
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 250, 310, 300);
show_string("600 ccm", 100, 265, 3, WHITE, BLACK, 1);
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 350, 310, 400);
show_string("900 ccm", 100, 365, 3, WHITE, BLACK, 1);
buttonleakcheckstate = LOW;
buttonventilatestate = LOW;
buttonopentest1state = LOW;
buttonopentest2state = LOW;
dynamicmatchruns = 0;
}
void drawventilate() {
my_lcd.Fill_Screen(WHITE);
show_string("STARTE PUMPE & EINSTELLEN!", 10, 10, 2, BLACK, BLACK, 1);
show_string("3,0 BAR", 30, 100, 3, RED, BLACK, 1);
}
void drawmatching() {
my_lcd.Fill_Screen(WHITE);
show_string("DRUCK PRUEFEN & EINSTELLEN!", 10, 10, 2, BLACK, BLACK, 1); // ggf ladezeichen o.ä. einfügen, so das konstante arbeit klar wird
show_string("3,0 BAR", 10, 100, 2, RED, BLACK, 1);
show_string("...", 10, 150, 2, RED, BLACK, 1);
}
void drawdynamicmatching() {
my_lcd.Fill_Screen(WHITE);
show_string("DRUCK PRUEFEN & EINSTELLEN!", 10, 10, 2, BLACK, BLACK, 1); // ggf ladezeichen o.ä. einfügen, so das konstante arbeit klar wird
show_string("3,0 BAR", 10, 100, 2, RED, BLACK, 1);
show_string("...", 10, 150, 2, RED, BLACK, 1);
}
void drawopentest1() {
my_lcd.Fill_Screen(WHITE);
show_string("DRUCK !", 10, 10, 2, BLACK, BLACK, 1); // ggf ladezeichen o.ä. einfügen, so das konstante arbeit klar wird
show_string("3,0 BAR", 10, 100, 2, RED, BLACK, 1);
show_string("Alle DUESEN", 10, 150, 2, RED, BLACK, 1);
show_string("MUESSEN RICHTIG OEFFNEN", 10, 200, 2, RED, BLACK, 1);
}
void drawopentest2() {
my_lcd.Fill_Screen(WHITE);
show_string("DRUCK STEIGERN AUF!", 10, 10, 2, BLACK, BLACK, 1); // ggf ladezeichen o.ä. einfügen, so das konstante arbeit klar wird
show_string("7,0 BAR", 10, 100, 2, RED, BLACK, 1);
show_string("Alle DUESEN", 10, 150, 2, RED, BLACK, 1);
show_string("MUESSEN RICHTIG OEFFNEN", 10, 200, 2, RED, BLACK, 1);
show_string("ERGEBNISSE NOTIEREN", 10, 200, 2, BLACK, BLACK, 1);
show_string("PUMPE ABSTELLEN", 10, 200, 2, RED, BLACK, 1);
}
void drawresults() { // shows matching reference values for the machine users decision, if tolerance is okay
my_lcd.Fill_Screen(WHITE);
show_string("WERTE PRUEFEN & EINTRAGEN!", 10, 10, 2, BLACK, BLACK, 1);
show_string("MINIMUM:", 30, 100, 3, BLACK, BLACK, 1);
show_string("20", 180, 100, 3, BLACK, BLACK, 1); //use arguments for better program
show_string("MAXIMUM:", 30, 200, 3, BLACK, BLACK, 1);
show_string("23", 180, 200, 3, BLACK, BLACK, 1); //use arguments for better program
show_string("NACH EINTRAGEN:", 30, 250, 2, BLACK, BLACK, 1);
show_string("VENTIL OEFFNEN", 30, 300, 2, BLACK, BLACK, 1);
show_string("ROEHREN LEEREN", 30, 350, 2, BLACK, BLACK, 1);
show_string("VENTIL SCHLIESSEN", 30, 400, 2, BLACK, BLACK, 1);
//fertig button
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 420, 310, 470);
show_string("FERTIG", 100, 435, 3, WHITE, BLACK, 1);
}
void drawdynamicresults() { // shows matching reference values for the machine users decision, if tolerance is okay
my_lcd.Fill_Screen(WHITE);
show_string("WERTE PRUEFEN UND EINTRAGEN!", 10, 10, 2, BLACK, BLACK, 1);
show_string("MINIMUM:", 30, 100, 3, BLACK, BLACK, 1);
show_string("10", 180, 100, 3, BLACK, BLACK, 1); //use arguments for better program
show_string("MAXIMUM:", 30, 200, 3, BLACK, BLACK, 1);
show_string("14", 180, 200, 3, BLACK, BLACK, 1); //use arguments for better program
show_string("NACH EINTRAGEN:", 30, 250, 2, BLACK, BLACK, 1);
show_string("VENTIL OEFFNEN", 30, 300, 2, BLACK, BLACK, 1);
show_string("ROEHREN LEEREN", 30, 350, 2, BLACK, BLACK, 1);
show_string("VENTIL SCHLIESSEN", 30, 400, 2, BLACK, BLACK, 1);
//fertig button
my_lcd.Set_Draw_color(BLUE);
my_lcd.Fill_Rectangle(10, 420, 310, 470);
show_string("FERTIG", 100, 435, 3, WHITE, BLACK, 1);
}
void turnallinjoff() {
digitalWrite(31, LOW);
digitalWrite(33, LOW);
digitalWrite(35, LOW);
digitalWrite(37, LOW);
}