Zu viele gezählte Impulse am DI-Pin, Datenlogger

Hallo. Ich versuche es mal richtig zu machen in meinem ersten Beitrag.
Ich habe folgende Ausrüstung:

AZDelivery AZ-ATmega328DIP-Board Mikrocontroller Board ATmega16U2 8-bit Entwicklerboard mit Hauptplatine und USB-Kabel inklusive E-Book!

https://www.amazon.de/dp/B08G1X67Y9?ref=ppx_yo2ov_dt_b_product_details&th=1

AZDelivery DatenLogger Modul Data Recorder Shield kompatibel mit Arduino inklusive eBook

https://www.amazon.de/dp/B01NATCT7N?ref=ppx_yo2ov_dt_b_product_details&th=1
Arduino IDE 2.2.1

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;
  }
}

Mein Rat:

Frage den Roboter so lange, bis er dir das richtige Ergebnis liefert, das du erwartest.

Eine Antwort könnte wahrscheinlich 42 sein.

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" .

Da hilft dir ChatGPT sicher nicht weiter.

1 Like

Masse von Sensor und Arduino verbunden?

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.

  • Du hast den PIN extern mit einem Widerstand nach GND beschaltet
  • Du hast einen prellfreien Kontakt

Wenn Du eines davon mit Nein beantwortest, kommst Du auf kein Ergebnis, was Deiner Vorstellung entspricht.

1 Like

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.

Und genau da ist das Forum klar im Vorteil. Noch :wink:
Hier muss der TO keine Frage bzgl. Kontaktprellen stellen.
Diese Info bekommt er auch so.

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.

1 Like

Danke für die Hilfe!

Gerne.
Bitte beachte, dass Du zwingend einen Widerstand brauchst - jenachdem wie Dein Sensor seinen Pegel ausgibt.

Sollte der Sensor nach GND schalten, kannst Du auch auf einen R verzichten und den internen PullUp via

  pinMode(diPin, INPUT_PULLUP);  // Festlegen des digitalen Eingangs als Eingangspin

festlegen.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.