Projekt ist mit dem Arduino und dem RTC-Shield einen Datenlogger zu bauen. Aktuell lasse ich mir die Daten auf dem Serial Monitor ausgeben, da ich mit ein paar Problemen zu kämpfen hatte und das mit der SD-Karte dann zu nervig war.
Die Hardware die angeschlossen wird ist nur ein digitaler Ausgang eines Sensors der bis zu 500 Pulse pro Sekunde generieren kann. Ich will diese Pulse in den ersten 10s jeder Minute zählen und dann die Gesamtzahl ausgeben lassen. Wenn ich mit 5V an den Eingangspin gehe und das 5 mal sollte nach den 10s mir ausgegeben werden, das 5 pulse gezählt wurden, jedoch wird mir 175 ausgegeben oder mal 60... das einzige was zuverlässig bisher funktioniert ist das 0 Pulse gezählt werden, wenn es auch 0 waren. Ich habe schon diverse Code-Änderungen durchgeführt und ChatGPT zu rate gezogen, aber es geht einfach nicht. Wo ist der Fehler im Code oder evtl Hardware?
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
// Deklaration Dateien und Objekte
File dataFile; // Deklaration einer Datei-Variablen für die Datenaufzeichnung
RTC_DS3231 rtc; // Deklaration eines Objekts für die RTC (Echtzeituhr)
// Deklaration Variablen
const int diPin = 7; // Definition des digitalen Eingangs für die Impulserfassung
int pulseCount; // Zähler für die Impulse
bool currentState; // Variable für den aktuellen Status am Pin
bool lastState; // Variable für den letzten Status am Pin
void setup() {
Serial.begin(9600); // Start der seriellen Kommunikation mit 9600 Baud
Wire.begin(); // Starten der I2C-Kommunikation
pulseCount = 0; // Zähler für die Impulse
lastState = LOW; // Setzen der Variable auf LOW zum initialiseren der Funktion
if (!rtc.begin()) { // Überprüfen, ob die RTC initialisiert werden kann
Serial.println("RTC nicht gefunden!"); // Fehlermeldung, falls die RTC nicht gefunden wird
while (1)
; // Endlosschleife bei einem Fehler
}
pinMode(diPin, INPUT); // Festlegen des digitalen Eingangs als Eingangspin
}
void loop() {
DateTime now = rtc.now(); // Abfrage deraktuellen Zeit
while (now.second() >= 0 && now.second() <= 10) {
currentState = digitalRead(diPin); // Lesen des aktuellen Zustands des Pins
while (currentState == HIGH && lastState == LOW) {
pulseCount++; // +1, wenn HIGH-Signal an Pin anliegt
lastState = HIGH; // zum beenden der Schleife, damit nur bei steigender Flanke gezählt wird
}
while (lastState == HIGH) {
lastState = digitalRead(diPin); // Prüfen wann das Signal wieder auf LOW fällt umd den nächsten Puls zählen zu können
}
now = rtc.now();
}
// Gib die Anzahl der Impulse aus
Serial.print("Pulse erkannt: ");
Serial.println(pulseCount);
// Warte bis zum Ende der Minute
while (now.second() > 10) {
now = rtc.now(); // Aktualisierung der Zeitvariable
pulseCount = 0;
}
}
Und wie machst du das mit dem 5 Pulsen ?
Einfach Draht mit 5Volt an den Pin anlegen ?
Wenn ja, dann ist das klar. Dein Draht der prellt. Stellt also den Kontakt mehrfach kurz hintereinander her.
Du musst den Pin entprellen. Das geht über eine Library "Debounce" .
Zieht der Sensor für einen Puls nach +5V oder nach GND?
Im ersten Fall hilft ein externer Pulldown-Widerstand, im zweiten die Konfiguration als INPUT_PULLUP.
Wenn du sie nach Entprellen fragst, vielleicht doch. Davon gelesen hat sie schon viel.
Solltest dich aber entscheiden: Entweder chatty oder hier.
Hier werden die Leute leichter sauer, andererseits haben sie bessere Glaskugeln zum Raten. Und wenn ein Mensch mal falsch rät, reagieren die andern besser als bei chatty, wenn die daneben liegt.
Ich hab Deinen mal komplett umgeschrieben.
Grund ist, dass mit Deinen Schleifen Du Dir selbst ein Bein stellst.
In den 10 Sekunden Messzeit bist Du nicht in der Lage was anderes zu machen und die ganze schachtelei ist auch nciht grad von Vorteil.
Wenn Du deinen di von 7 auf 2 legst, kannst Du Dich ganz entspannt zurück lehnen und den ganzen Kram den Prozessor selbst machen lassen. Ganz ohne extra Code drum rum.
Nur zählen musst Du selber.
Here we go.
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
// Deklaration Dateien und Objekte
File dataFile; // Deklaration einer Datei-Variablen für die Datenaufzeichnung
RTC_DS3231 rtc; // Deklaration eines Objekts für die RTC (Echtzeituhr)
// Deklaration Variablen
constexpr byte diPin {2}; // Definition des digitalen Eingangs für die Impulserfassung
struct COUNTDATA
{
bool isActive;
volatile uint16_t count;
} countData;
void setup()
{
Serial.begin(9600); // Start der seriellen Kommunikation mit 9600 Baud
Wire.begin(); // Starten der I2C-Kommunikation
if (!rtc.begin()) // Überprüfen, ob die RTC initialisiert werden kann
{
Serial.println(F("RTC nicht gefunden!")); // Fehlermeldung, falls die RTC nicht gefunden wird
while (1)
; // Endlosschleife bei einem Fehler
}
pinMode(diPin, INPUT); // Festlegen des digitalen Eingangs als Eingangspin
}
DateTime now;
// ISR
void countUp()
{
countData.count++;
}
//
void loop()
{
now = rtc.now(); // Abfrage deraktuellen Zeit
byte mySecond = now.second();
if (mySecond > 0 && mySecond < 11)
{
if (!countData.isActive)
{
countData.isActive = true;
countData.count = 0;
attachInterrupt(digitalPinToInterrupt(diPin), countUp, FALLING);
}
}
else
{
if (countData.isActive)
{
countData.isActive = false;
detachInterrupt(digitalPinToInterrupt(diPin));
printData();
}
}
}
void printData()
{
// Gib die Anzahl der Impulse aus
Serial.print(F("Pulse erkannt: "));
Serial.println(countData.count);
//
}
Ich habe das "debounce" eingefügt und den Pin über 1MOhm auf masse gesetzt jetzt komme ich auf die Anzahl die es sein soll +-1 bisher, kann aber bei den Testversuchen am zittern liegen. Hätte aber nicht gedacht, dass das "prellen" so viele kontaktierungen verursacht. again what learned. DANKE!
Ich hatte es auch schon mit ISR versucht, jedoch war das auch nicht zielführend zumindest nicht das Programm was ich hatte. Ich werde das mit deinem auch nochmal probieren im passenden versuchsaufbau. Danke
Mit einem 1M Widerstand kannst du u.U. andere Probleme bekommen. Setze lieber einen 10k Widerstand ein. Damit verhinderst du auch Störungen die evtl. von extern kommen.