Ich teile hier mal den Code mit euch, ansonsten funktioniert das Programm doch er stürzt halt immer wieder ab. Das ganze soll eine Aufzuchtstation für Jungpflanzen werden. Verwendet werden eine RTC DS1302
SHT30 über I²C
LCD 16x2 I²C
#include <SHT31.h>
#include <virtuabotixRTC.h>
#include <LiquidCrystal_I2C.h>
#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include "Wire.h"
LiquidCrystal_I2C lcd(0x27, 16, 2);
virtuabotixRTC myRTC(6, 7, 8);
SHT31 sht;
// Pin Belegung
#define BUTTON_UP PB1
#define BUTTON_DOWN PB2
#define BUTTON_SELECT PB3
#define LIGHT_RELAY_PIN PD2
#define WATER_RELAY_PIN PD3
#define HEAT_RELAY_PIN PD4
#define SHT31_ADDRESS 0x44
// Menüzustände
enum MenuState {
Wahl,
Aufzucht,
Entnahme
};
MenuState currentState = Wahl;
// Menüoptionen
const char* Pflanzenmenu[] = {
"Salat",
"Brokkoli",
"Tomaten",
"Paprika",
"Eisbergsalat",
"Zucchini",
"Zwiebeln",
"Gurken",
"Auberginen"
};
//Globale Variablen
int8_t currentMenu = 0;
int8_t counter_Aufzucht = 0;
uint8_t verstrichene_Tage=0;
//Datenstruktur
struct Datensatz {
int nummer;
char name[20];
uint8_t Belichtungsdauer; // Std.
float Temperatur; // °C
float Feuchtigkeit; // %
uint8_t Reife;};
Datensatz Pflanze[10]; // 10 Datensaetze sind möglich
void setup() {
Serial.begin(115200);
Wire.begin();
sht.begin(SHT31_ADDRESS);
myRTC.setDS1302Time(0, 0, 20, 2, 3, 10, 2023);
initializeData();
lcd.init();
lcd.backlight();
Serial.println("Start");
//Ausgaenge Definieren
DDRB |= (1 << LIGHT_RELAY_PIN) | (1 << WATER_RELAY_PIN) | (1 << HEAT_RELAY_PIN);
// Pull-Up-Widerstände aktivieren
PORTB |= (1 << BUTTON_UP) | (1 << BUTTON_DOWN) | (1 << BUTTON_SELECT);
}
void AuswahlLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Waehle Setzling:");
lcd.setCursor(0, 1);
lcd.print(Pflanzenmenu[currentMenu]);
_delay_ms(500);
}
void AufzuchtLCD(uint8_t i,uint8_t Tage) {
lcd.clear();
lcd.setCursor(0,0);
lcd.print(Pflanze[i].name);
lcd.setCursor(0,1);
lcd.print("Ernten in ");
lcd.print((Pflanze[i].Reife-Tage));
lcd.print(" T");
_delay_ms(500);
}
void Benutzereingabe_Wahl() {
if (currentState != Wahl) {
return; // Wenn nicht im Wahlzustand, beenden
}
bool buttonUpPressed = !(PINB & (1 << BUTTON_UP));
bool buttonDownPressed = !(PINB & (1 << BUTTON_DOWN));
bool buttonSelectPressed = !(PINB & (1 << BUTTON_SELECT));
if (buttonSelectPressed) {
currentState = Aufzucht; //Zustand auf Aufzucht ändern
Serial.println("Wechsel zum Aufzuchtzustand");
_delay_ms(250);
}
if (buttonUpPressed) {
currentMenu++;
Serial.println("Menü nach oben");
_delay_ms(250);
}
if (buttonDownPressed) {
currentMenu--;
Serial.println("Menü nach unten");
}
}
void Benutzereingabe_Aufzucht() {
if (currentState != Aufzucht) {
return; // Wenn nicht im Aufzuchtzustand, beenden
}
bool buttonUpPressed = !(PINB & (1 << BUTTON_UP));
bool buttonDownPressed = !(PINB & (1 << BUTTON_DOWN));
bool buttonSelectPressed = !(PINB & (1 << BUTTON_SELECT));
if (buttonSelectPressed && buttonUpPressed) {
currentState = Wahl; // Zustand auf Wahl ändern
Serial.println("Wechsel zum Wahlzustand");
}
}
void initializeData() {
// Daten für "Salat"
Pflanze[0].nummer = 0;
strncpy(Pflanze[0].name, "Salat", sizeof(Pflanze[0].name));
Pflanze[0].Belichtungsdauer = 14;
Pflanze[0].Temperatur = 25.0;
Pflanze[0].Feuchtigkeit = 70.0;
Pflanze[0].Reife = 30;
// Daten für "Brokkoli"
Pflanze[1].nummer = 1;
strncpy(Pflanze[1].name, "Brokkoli", sizeof(Pflanze[1].name));
Pflanze[1].Belichtungsdauer = 12;
Pflanze[1].Temperatur = 18.0;
Pflanze[1].Feuchtigkeit = 60.0;
Pflanze[1].Reife = 60;
// Weitere Daten für andere Pflanzen hier hinzufügen
}
void SteuereLicht(int8_t Belichtungsdauer, int currentHour) {
// Lichtsteuerung
if (currentHour >= 8 && currentHour < 22) {
// Prüfen, ob die Belichtungsdauer erreicht ist
if (currentHour - 8 < Belichtungsdauer) {
// Licht einschalten
PORTB |= (1 << LIGHT_RELAY_PIN);
Serial.println("Licht an");
}
else {
// Licht ausschalten, da die Belichtungsdauer erreicht ist
PORTB &= ~(1 << LIGHT_RELAY_PIN);
Serial.println("Licht aus");
}
}
else {
// Außerhalb der Zeitzone, Licht ausschalten
PORTB &= ~(1 << LIGHT_RELAY_PIN);
Serial.println("Keine Lichtfreigabe");
}
}
void FeuchtigkeitsRegelung(float Sollfeuchtigkeit) {
float IstFeuchtigkeit = feuchtigkeitEinlesen();
Serial.println(Sollfeuchtigkeit);
Serial.print(" ");
Serial.print(IstFeuchtigkeit);
if (IstFeuchtigkeit < (Sollfeuchtigkeit - 5.0)) {
// Bewässerung einschalten
PORTB |= (1 << WATER_RELAY_PIN);
Serial.println("Bewässerung ist an");
}
else if (IstFeuchtigkeit > (Sollfeuchtigkeit + 10.0)) {
// Bewässerung ausschalten
PORTB &= ~(1 << WATER_RELAY_PIN);
Serial.println("Bewässerung ist aus");
}
else {
// Bewässerung ausschalten
PORTB &= ~(1 << WATER_RELAY_PIN);
Serial.println("Bewässerung ist aus (Standard)");
}
}
float feuchtigkeitEinlesen() {
sht.read();
float Wet = sht.getHumidity();
return Wet;
}
void TemperaturRegelung(float Solltemperatur) {
float IstTemperatur = temperaturEinlesen();
Serial.println(Solltemperatur);
Serial.print(" ");
Serial.print(IstTemperatur);
if (IstTemperatur < (Solltemperatur - 2.0)) {
// Heizung einschalten
Serial.println("Heizung ein");
PORTB |= (1 << HEAT_RELAY_PIN);
}
else if (IstTemperatur > (Solltemperatur + 1.0)) {
// Heizung ausschalten
Serial.println("Heizung aus");
PORTB &= ~(1 << HEAT_RELAY_PIN);
}
else {
// Heizung ausschalten
PORTB &= ~(1 << WATER_RELAY_PIN);
Serial.println("Heizung aus (Standard)");
}
}
float temperaturEinlesen() {
sht.read();
float Temp = sht.getTemperature();
return Temp;
}
void loop() {
if (currentState == Wahl) {
AuswahlLCD();
Benutzereingabe_Wahl();
}
if (currentState == Aufzucht) {
int8_t currentday=myRTC.dayofmonth;
if(myRTC.dayofmonth!=currentday&&myRTC.hours==23){
verstrichene_Tage++;
}
myRTC.updateTime();
AufzuchtLCD(currentMenu,verstrichene_Tage);
Benutzereingabe_Aufzucht();
if(myRTC.minutes% 30 ==0)//&&myRTC.seconds% 1 == 0
{
//Sensorwerte aktualisieren, wenn das Intervall abgelaufen ist
SteuereLicht(Pflanze[currentMenu].Belichtungsdauer, myRTC.hours);
FeuchtigkeitsRegelung(Pflanze[currentMenu].Feuchtigkeit);
TemperaturRegelung(Pflanze[currentMenu].Temperatur);
}
}
}
verbesserungen im code sind auch gerne gehört bin noch blutiger anfänger wie man hier sicher sieht