Hallo zusammen,
ich brauche mal wieder den Rat der Experten, da ich alleine nicht weiterkomme.
Für mein bestehendes größeres Projekt der Steuerung einer Solaranlage möchte ich eine Temperatur/Feuchte-Überwachung mit dem DHT11 hinzufügen und auf dem Monitor bzw. einem OLED-Display anzeigen. Wenn ich den Sketch alleine auf dem Nano teste, funktioniert es auch wie erwartet. Ich habe lediglich den Pin 2 gegen Pin 13 getauscht, da Pin 2 bereits belegt ist. In meinem Fall sind keine anderen Pins mehr frei.
Hier zunächst der Original-Sketch für den DHT11:
/* OK mit Arduino Nano
* Pin 13 anstatt Pin 2 verwendet
* 08.01.2022
* Example of a non-blocking read of DHTxx sensor values.
*
* The sensor is connected to the Arduino with a 10 kOhm pull-up
* resistor connected to the data pin.
*
* (C) 2015 Ole Wolf <wolf@blazingangles.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dht_nonblocking.h>
/* Uncomment according to your sensortype. */
#define DHT_SENSOR_TYPE DHT_TYPE_11
//#define DHT_SENSOR_TYPE DHT_TYPE_21
//#define DHT_SENSOR_TYPE DHT_TYPE_22
static const int DHT_SENSOR_PIN = 13;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );
/*
* Initialize the serial port.
*/
void setup( )
{
Serial.begin( 9600);
Serial.print("Start");
}
/*
* Poll for a measurement, keeping the state machine alive. Returns
* true if a measurement is available.
*/
static bool measure_environment( float *temperature, float *humidity )
{
static unsigned long measurement_timestamp = millis( );
/* Measure once every four seconds. */
if( millis( ) - measurement_timestamp > 3000ul )
{
if( dht_sensor.measure( temperature, humidity ) == true )
{
measurement_timestamp = millis( );
return( true );
}
}
return( false );
}
/*
* Main program loop.
*/
void loop( )
{
float temperature;
float humidity;
/* Measure temperature and humidity. If the functions returns
true, then a measurement is available. */
if( measure_environment( &temperature, &humidity ) == true )
{
temperature = temperature - 1; // Temperatur-Kalibrierung
Serial.print( "T = " );
Serial.print( temperature, 1 );
Serial.print( " deg. C, H = " );
Serial.print( humidity, 1 );
Serial.println( "%" );
}
}
Meine voids sind im loop wie folgt untergliedert:
void loop()
{
solarRegler(); // Accu 1 + Solarzellen mit dem Solar-Regler verbinden (Beim Start getrennt)
monoflops(); // Laufzeiten für Wechselrichter, Notbetrieb, Displayanzeige
alarmUnterspannung(); // Piezo-Summer ertönt bei Taster 1 (FB1) und Unterspannung Accu 1
spannungsMessung(); // Ausgabe Monitor
oledDisplay(); // Ausgabe OLED-Display
temperaturFeuchte(); // DHT11
}
Wenn ich den ersten void (solarRegler) auskommentiere, läuft das Script durch, zeigt aber die Ergebnisse des DHT11 nicht an. Ist dieser void aktiv, bleibt der Sketch hängen.
Hier nun der gesamte Sketch mit dem erwähnten Konflikt zur Ansicht:
/* Solaranlage Garage
Ardunino Nano Port COM7, ATmega328P Old Bootloader)
Version 1.0
Datum: 08.01.2022
3x Monoflops OK
3x Spannungsmesser OK (Widerstände noch ausmessen) Spannung ungenau!
OLED-Display für Spannung/Strom mit Taste einschalten OK
Solar-Regler mit Accu 1 und Solarzellen verbinden OK
Alarm Unterspannung (Bei Abschaltung durch SpÜ mit Schalttransistor) OK
//Interne Referenzspannung 1,1 Volt aktivieren OK
Externe Referenzspannung 3,3 Volt aktivieren OK
To Do: Temperatursensor Fehler, wenn void solarRegler aktiv ist
To Do: Stromsensoren
*/
// Bibliotheken
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <dht_nonblocking.h>
// Solar-Regler verbinden
// Pins
// D4 to resister and yellow LED
// D3 to resister and red LED
// D2 to push button switch
// state holds the current status.
// 0 = all off // Accu 1 + Solarzellen getrennt
// 1 = red LED // Accu 1 mit Solar-Regler verbunden
// 2 = red LED + yellow LED // Accu 1 und Solarzellen mit Solar-Regler verbunden
// Define the pins being used
int pin_LEDred = 3; // Accu 1 mit Solar-Regler verbinden
int pin_LEDyellow = 4; // Solarzellen mit Solar-Regler verbinden
int pin_switch = 2; // Taste 4 zum Verbinden von Solarzellen und Accu 1 (Beim Start getrennt)
// variables to hold the new and old switch states
boolean oldSwitchState = HIGH; // Setzt State auf 0 (Alle LEDs zum Start sind ausgeschaltet)
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
byte state = 0;
// OLED-Display
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// DHT11
#define DHT_SENSOR_TYPE DHT_TYPE_11
// Pausen
unsigned long startTime; // Startzeit
unsigned long startTime3; // Startzeit3
unsigned long startTime4; // Startzeit4
unsigned long currentTime; // Aktuelle Zeit Spannungsmesser Monitor
unsigned long currentTime3; // Aktuelle Zeit3 Solar
unsigned long currentTime4; // Aktuelle Zeit3 Accu 1
const unsigned long period2 = 2000; // Pausenlänge Stromsensoren
// Pin Spannungsmesser
const byte solarPin = A0;
const byte accu1Pin = A1;
const byte accu2Pin = A2;
//const unsigned int REF_VOLTAGE = 11.13; // entspricht 1,1 V
const unsigned int REF_VOLTAGE = 33.0; // entspricht 3,3 V
const unsigned int PIN_STEPS = 1023; // sollte das nicht 1023 sein?
const unsigned long multiplikator = 1000; // für Ganzzahlberechnung
unsigned int vout = 0, vin = 0;
unsigned int solarV = 0; // Solarzelle
unsigned int accu1V = 0; // Accu 1
unsigned int accu2V = 0; // Accu 2
// Spannungsteiler
unsigned int R1 = 100; // resistance R1 (= 100 KOhm)
unsigned int R2 = 10; // resistance R2 (= 10 KOhm)
unsigned int R3 = 100; // resistance R1 (= 100 KOhm)
unsigned int R4 = 10; // resistance R2 (= 10 KOhm)
unsigned int R5 = 100; // resistance R1 (= 100 KOhm)
unsigned int R6 = 10; // resistance R2 (= 10 KOhm)
// Monoflop 1 Wechselrichter
const byte FB1Pin = 9; // FB1-Taster für Trigger (gegen Masse) Pin 9
const byte outputPinWR = 10; // Ausgang für LED, MOSFET, Relais Pin 10
const unsigned long Laufzeit1 = 1 * 3 * 1000UL; // Laufzeit Monoflop/WR (5 min.) -> 5*60*1000UL = 5 min. (Test: 3 sec.)
static uint32_t previousMillis1 = 0;
// Monoflop 2 Notbetrieb (Accu 1 Unterspannung)
const byte FB2Pin = 11; // FB2-Taster für Trigger (gegen Masse) Pin 11
const byte outputPinNB = 12; // Ausgang für LED, MOSFET, Relais Pin 12
const unsigned long Laufzeit2 = 1 * 2 * 1000UL; // Laufzeit Notbetrieb (5 min.) -> 5*60*1000UL = 5 min. (Test: 2 sec.)
static uint32_t previousMillis2 = 0;
// Monoflop 3 OLED-Display einschalten
const byte displayOn = 5; // Taster für Trigger (gegen Masse) Pin 5
const byte outputPinDP = 6; // Ausgang für Display (if-Bedingung) Pin 6
const unsigned long Laufzeit3 = 2 * 10 * 1000UL; // Anzeige OLED-Display (5 min.) -> 5*60*1000UL = 5 min. (Test: 20 sec.)
static uint32_t previousMillis3 = 0;
// Alarm bei Unterspannung Accu 1 (Spannungsüberwachung hat Accu 1 getrennt)
const byte inputUS = 7; // Unterspannung Pin 7
const byte outputPinUS = 8; // Ausgang für Piezo Pin 8
void setup()
{
pinMode(FB1Pin, INPUT_PULLUP);
pinMode(FB2Pin, INPUT_PULLUP);
pinMode(outputPinWR, OUTPUT);
pinMode(displayOn, INPUT_PULLUP);
pinMode(outputPinDP, OUTPUT);
pinMode(outputPinNB, OUTPUT);
pinMode(inputUS, INPUT_PULLUP);
pinMode(outputPinUS, OUTPUT);
pinMode(solarPin, INPUT);
pinMode(accu1Pin, INPUT);
pinMode(accu2Pin, INPUT);
startTime = millis(); //initial start time
Serial.begin(9600);
Serial.print("Sketch: "); Serial.println(__FILE__);
Serial.print("Uploaded: "); Serial.println(__DATE__);
Serial.println("Start");
Serial.println("");
pinMode(pin_LEDyellow, OUTPUT);
digitalWrite(pin_LEDyellow, LOW);
pinMode(pin_LEDred, OUTPUT);
digitalWrite(pin_LEDred, LOW);
pinMode(pin_switch, INPUT_PULLUP); // Taste 5 (Accu 1 + Solarzellen mit Solar-Regler verbinden
// analogReference(INTERNAL); //Referenz intern
analogReference(EXTERNAL); //Referenz extern
// OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) // Address 0x3D for 128x64
{
// Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
// suppress noise
if (vin < 0.09)
{
vin = 0.0;
}
}
/* DHT11
* Poll for a measurement, keeping the state machine alive. Returns
* true if a measurement is available.
*/
static const int DHT_SENSOR_PIN = 13;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );
static bool measure_environment( float *temperature, float *humidity )
{
static unsigned long measurement_timestamp = millis( );
/* Measure once every four seconds. */
if( millis( ) - measurement_timestamp > 3000ul )
{
if( dht_sensor.measure( temperature, humidity ) == true )
{
measurement_timestamp = millis( );
return( true );
}
}
return( false );
}
void loop()
{
solarRegler(); // Accu 1 + Solarzellen mit dem Solar-Regler verbinden (Beim Start getrennt)
monoflops(); // Laufzeiten für Wechselrichter, Notbetrieb, Displayanzeige
alarmUnterspannung(); // Piezo-Summer ertönt bei Taster 1 (FB1) und Unterspannung Accu 1
spannungsMessung(); // Ausgabe Monitor
oledDisplay(); // Ausgabe OLED-Display
temperaturFeuchte(); // DHT11
}
void solarRegler() // Accu 1 + Solarzellen mit dem Solar-Regler verbinden (Beim Start getrennt)
{
newSwitchState1 = digitalRead(pin_switch);
delay(1);
newSwitchState2 = digitalRead(pin_switch);
delay(1);
// if all 2 values are the same we can continue
if ( (newSwitchState1 == newSwitchState2))
{
if ( newSwitchState1 != oldSwitchState )
{
// has the button switch been closed?
if ( newSwitchState1 == HIGH )
{
// increase the value of state
state++;
if (state > 3) {
state = 0;
Serial.println("Accu 1 und Solarzellen getrennt");
Serial.println("");
}
// Pin 3+4 mit Trigger MOSFETs verbinden
// turn all LEDs off. Doing it this way means we do not need to care about the individual LEDs
// simply turn them all off and then turn on the correct one.
digitalWrite(pin_LEDred, LOW); // Accu 1 und Solarzellen getrennt
digitalWrite(pin_LEDyellow, LOW);
// Turn on the next LED
// Because the value of state does not change while we are testing it we don't need to use else if
if (state == 1) { // Accu 1 mit Solar-Regler verbunden
digitalWrite(pin_LEDred, HIGH);
Serial.println("Accu 1 mit Solar-Regler verbunden");
}
if (state == 2) { // Accu 1 und Solarzellen mit Solar-Regler verbunden
digitalWrite(pin_LEDred, HIGH);
digitalWrite(pin_LEDyellow, HIGH);
Serial.println("Accu 1 und Solarzellen mit Solar-Regler verbunden");
}
if (state == 3) { // Accu 1 mit Solar-Regler verbunden; Solarzellen getrennt
digitalWrite(pin_LEDred, HIGH);
Serial.println("Accu 1 mit Solar-Regler verbunden; Solarzellen getrennt");
}
}
oldSwitchState = newSwitchState1;
}
}
}
void monoflops()
{
// Monoflop 1, Wechselrichter
if (digitalRead(FB1Pin) == LOW)
{
digitalWrite(outputPinWR, HIGH);
previousMillis1 = millis();
}
if (millis() - previousMillis1 > Laufzeit1 && digitalRead(outputPinWR) == HIGH)
{
digitalWrite(outputPinWR, LOW);
}
// Monoflop 2, Notbetrieb (Accu 100Ah Unterspannung)
if (digitalRead(FB2Pin) == LOW)
{
digitalWrite(outputPinNB, HIGH);
previousMillis2 = millis();
}
if (millis() - previousMillis2 > Laufzeit2 && digitalRead(outputPinNB) == HIGH)
{
digitalWrite(outputPinNB, LOW);
}
// Monoflop 3, OLED-Display einschalten
if (digitalRead(displayOn) == LOW)
{
digitalWrite(outputPinDP, HIGH);
previousMillis3 = millis();
}
if (millis() - previousMillis3 > Laufzeit3 && digitalRead(outputPinDP) == HIGH)
{
digitalWrite(outputPinDP, LOW);
}
}
//void spannungsMessung() //Ausgabe Monitor
float voltMess(const byte messstelle)
{
uint32_t vout = 0;
switch (messstelle)
{
case 0:
vout = analogRead(solarPin) * REF_VOLTAGE * multiplikator / PIN_STEPS;
//vout = 1023 * REF_VOLTAGE * multiplikator / PIN_STEPS;
vout = vout / (R2 * multiplikator / (R1 + R2));
break;
case 1:
vout = analogRead(accu1Pin) * REF_VOLTAGE * multiplikator / PIN_STEPS;
vout = vout / (R4 * multiplikator / (R3 + R4));
break;
case 2:
vout = analogRead(accu2Pin) * REF_VOLTAGE * multiplikator / PIN_STEPS;
vout = vout / (R6 * multiplikator / (R5 + R6));
break;
}
return vout / 10.0; // Original
//return vout / 9.7; // Korrekturfaktor
}
void spannungsMessung() //Ausgabe Monitor
{
const unsigned long period1 = 2000; // Pausenlänge Spannungsmesser
// Spannungsmesser: Ausgabe Monitor
if (millis() - startTime >= period1) //Pause1 abgelaufen?
{
startTime += period1;
// A0
Serial.print(F("U Solar = "));
Serial.print(voltMess(0), 2);
Serial.println(F("V"));
// A1
Serial.print(F("U Accu 1 = "));
Serial.print(voltMess(1), 2);
Serial.println(F("V"));
// A2
Serial.print(F("U Accu 2 = "));
Serial.print(voltMess(2), 2);
Serial.println(F("V"));
Serial.println(F(""));
}
}
void oledDisplay() // Ausgabe OLED-Display
{
const uint32_t intervall = 2000;
static uint32_t lastmillis = 0;
static byte page = 0;
// Ausgabe OLED-Display
// OLED-Display einschalten
if (digitalRead(outputPinDP) == HIGH) { // Taste zum Einschalten für das OLED-Display gedrückt
if (millis() - lastmillis >= intervall)
{
lastmillis = millis();
page++;
if (page > 3) page = 0;
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
switch (page)
{
case 0:
// Solar
display.println(F("Solarzelle"));
schreibeDisplayVolt();
display.print(voltMess(page), 1);
schreibeDisplayRest();
break;
case 1:
// Accu 1
display.println(F("Accu 1"));
schreibeDisplayVolt();
display.print(voltMess(page), 1);
schreibeDisplayRest();
break;
case 2:
// Accu 2
display.println(F("Accu 2"));
schreibeDisplayVolt();
display.print(voltMess(page), 1);//
schreibeDisplayRest();
break;
case 3:
// Temperatur
display.println(F("Temperatur"));
//schreibeDisplayVolt();
//display.print(voltMess(page), 1);//
//schreibeDisplayRest();
break;
}
display.display();
}
}
else {
display.clearDisplay(); // Display ausschalten
display.display();
}
}
void schreibeDisplayVolt()
{
display.println(F("----------"));
display.print(F("U = "));
}
void schreibeDisplayRest()
{
display.println(F(" V"));
display.println(F("I = 0.1 A"));
}
void alarmUnterspannung() // Piezo-Summer ertönt bei Taster 1 (FB1) und Unterspannung Accu 1
{
// Alarm Unterspannung (Piezo bei Taster FB1 und Unterspannung) -> noch Fehler
if (digitalRead(FB1Pin) == LOW && digitalRead(inputUS) == LOW) { // Trigger SpÜ Unterspannung Alarm
digitalWrite(outputPinUS, HIGH); // Piezo über MOSFET einschalten
}
else {
digitalWrite(outputPinUS, LOW); // Piezo über MOSFET ausschalten
}
}
void temperaturFeuchte ()
{
float temperature;
float humidity;
/* Measure temperature and humidity. If the functions returns
true, then a measurement is available. */
if( measure_environment( &temperature, &humidity ) == true )
{
temperature = temperature - 1; // Temperatur-Kalibrierung
Serial.print( "T = " );
Serial.print( temperature, 1 );
Serial.print( " deg. C, H = " );
Serial.print( humidity, 1 );
Serial.println( "%" );
}
}
Könnt ihr bitte mal einen Blick drauf werfen und mir einen Tipp geben?
Vielen Dank.