Plötzlich komisches verhalten Uno/Mega fehlerhafte Impulse

pinMode(sobus, INPUT);             
digitalWrite(sobus, LOW);

Was willst du denn damit erreichen? Ein digitaler Eingang mnuss immer ein definiertes Pegel haben, sonst fängt man sich massiv Störungen ein, der Pin wirkt wie eine Antenne. So wie es aussieht, brauchst du nur einen externen Pull-Down-Widerstand, wenn du auf impstate auf HIGH-Pegel prüfst.

Hi,

ursprünglich war es anders.

pinMode(sobus, INPUT);
digitalWrite(sobus, HIGH); ← Pullup

Leider hat es so nicht bei mir funktioniert.

Bin aktuell noch sehr neu in dem Thema.

<brauchst du nur einen externen Pull-Down-Widerstand, wenn du auf impstate auf HIGH-Pegel prüfst.

Wärst du so nett und würdest es etwas ausführen? Und ist es erklärbar, warum es eine kurze Zeit funktioniert hat?

Dank und Grüße,
nox

losNOXos:
ursprünglich war es anders.

pinMode(sobus, INPUT);
digitalWrite(sobus, HIGH); ← Pullup

Leider hat es so nicht bei mir funktioniert.

Input Signale offen lassen geht nicht. Mindestens wenn ein Stück Draht dranhängt, das auf der anderen Seite nicht verbunden ist, fängst du dir irgendein Signal, beliebig schnell wechselnd, ein.
Schau dir das Button-Beispiel an. Das benutzt einen PullDown Widerstand.

digitalWrite(sobus, HIGH);   //  Pullup …sorgt dafür, dass ein offenes Eingangssignal sicher HIGH ist. Um ein LOW Signal zu erhalten, verbindest du es direkt mit GND ( z.B. über einen Taster ), ohne einen externen Widerstand zu brauchen.

Kleine Anmerkung:

pinMode(sobus, INPUT);             
digitalWrite(sobus, HIGH);

Dieser Code aktiviert den internen Pull-Up-Widerstand. Da diese beiden Zeilen aber (gerade für Anfänger) sehr verwirrend sind, kann man in den neueren Versionen der Arduino-IDE auch einfach: pinMode(sobus, INPUT_PULLUP); schreiben. Einen internen Pull-Down-Widerstand gibt es übrigens nicht, wenn benötigt muss eben ein externer Widerstand vorgesehen werden.

Hi,

danke für die Tipps!

Aber eins verstehe ich einfach nicht. Warum ging es 2-3 Tage? Zufall?

Und noch eine viel wichtigere Frage, wie lernt man sowas? Einfach durch Erfahrung? Elektro Studium?

Für Anfänger: Wie unter dem Link "Button" angegeben, sollte ich eine Wiederstand auf GND legen?

Bin wie gesagt noch am lernen. Deswegen die für manche bestimmt "blöden" Fragen.

Dank und Grüße, nox

losNOXos: Aber eins verstehe ich einfach nicht. Warum ging es 2-3 Tage? Zufall?

Ja, Zufall und/oder günstige Bedingungen.

Und noch eine viel wichtigere Frage, wie lernt man sowas? Einfach durch Erfahrung? Elektro Studium?

Ich glaube, die wenigsten haben hier ein Elektronik-Studium hinter sich. Es fällt aber auch nicht unter den Bereich Allgemeinwissen. Wenn man sich erst einmal damit auseinandergesetzt hat, denkt man von ganz allein an solche Sachen.

Für Anfänger: Wie unter dem Link "Button" angegeben, sollte ich eine Wi~~e~~derstand auf GND legen?

Richtig erkannt, steht auch als Kommentar im Quellcode: * 10K resistor attached to pin 2 from ground

Bin wie gesagt noch am lernen. Deswegen die für manche bestimmt "blöden" Fragen.

Dafür gibt es ja das Forum, dass man Fragen stellen kann. Und irgendwann kann man was vom Gelernten wieder zurückgeben.

losNOXos: Und noch eine viel wichtigere Frage, wie lernt man sowas? Einfach durch Erfahrung? Elektro Studium? Bin wie gesagt noch am lernen. Deswegen die für manche bestimmt "blöden" Fragen.

Es gibt keine blöden Fragen, nur blöde Antworten. Einige dieser "blöden" Fragen sind die fiesesten zu beantworten. ;) ;) ;) Das lernst Du aus Erfahrung, weil Du diese Fehler machst. Dann beim nächsten mal erinnerst Du Dich sicher und machst andere Fehler ;) ;) ;) Grüße Uwe

Hallo,

vielen Dank für eure Hilfe. Stand jetzt scheint es zu funktionieren.

Leider bin ich dann direkt zu mutig geworden und wollte es mit einem Interrupt + DS18B20 versuchen.

Das funktioniert aber nicht so wirklich. Vermutlich benutze ich den Interrupt falsch. Werde noch berichten ob ich Erfolg hatte.

Eine Frage habe ich noch. Ich scheine mit der Stromversorgung leichte Probleme zu haben. Ich wollte den Uno+LCD für den So-Bus Zähler über ein Iphone Lagegerät laufen lassen. Aber wenn ich das angeschlossen habe, wird auf dem LCD totaler quatsch angezeigt. Über das Notebook sieht es ok aus. Mag es an der fehlenden Leistung des Netzteils liegen?

Grüße, nox

Wenn Du die Hintergrundbeleuchtung des Displays an hast: wahrscheinlich. Klemm diese mal ab. Grüße Uwe

Hallo,

danke ich benutze ich ein andere Netzteil.

Auf den ersten Blick funktioniert jetzt alles. Leider aber nur auf den ersten.
Wenn der Arduino länger läuft, gehen die Zählerstände auseinander.
Zum Test habe ich schon einen einfachen Counter eingebaut, um mir die Takte ansehen zu können.

Das verhalten habe ich , wenn ich es mit Interrupt versuche und mit den alten Coding.

Hat noch jemand eine Idee? Bin mir langsam nicht mehr sicher, ob der Zähler auch wirklich 1000 imp/kWh ausgibt.

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);    // Pinbelegung für SainSmart LCD Keypad Shield


const int IMPULSE = 1000;     // hier die Impulse pro kWh vom Stromzähler eintragen

const int long RECHENIMP = 3600000 / IMPULSE * 1000;

int long ElapsedTime = 0;
int long StartTime = 0;
int long WATT = 0;
int long COUNT = 0;
int counter;
float KWH;

int impState = 0;
int lastimpState = 0;


void setup() {
  lcd.begin(16, 4);
  lcd.print("Boot...");
  delay(200);
  lcd.clear();
  lcd.setCursor(0, 0);   
  lcd.print("BASTELGARAGE.de");
  delay(100);
  lcd.setCursor(0, 1);   
  lcd.print("EnergieMonitor");
  delay(400);

  pinMode(2, INPUT);             // Pin 2 als Eingang
  digitalWrite(2, HIGH);         // Interner Pullup Widerstand AN

}



void loop() {

  impState = digitalRead(2);      // Pin 2 auslesen

  if (impState != lastimpState) {
    if (impState == LOW) {

      counter++;

      ElapsedTime = millis() - StartTime;
      StartTime = millis();
      WATT = RECHENIMP / ElapsedTime;

      COUNT++;

      KWH = (float)COUNT / IMPULSE;

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Aktuell:");
      lcd.setCursor(9, 0);
      lcd.print(WATT);

      lcd.setCursor(0, 1);
      lcd.print("kW/h:");
      lcd.setCursor(9, 1);
      lcd.print(KWH);
      lcd.setCursor(1, 2);
      lcd.print(counter);
      delay(20);
    }
  }
  lastimpState = impState;  
}

Grüße,
nox

Du schreibst auf dein LCD "Bastelgarage.de", die Seite habe ich mir mal angesehen. Da ist auch eine Abbildung deines Stromzählers mit einem kleinen Hinweis "1600 imp/kwh". Sollte das schon die Lösung sein? Oder hast du einen anderen Zähler zu überwachen?

Hi,

ja das kommt von da. Dachte es ist fair es erst mal drin zu lassen.

Die Impulse habe ich angepasst.

const int IMPULSE = 1000; // hier die Impulse pro kWh vom Stromzähler eintragen

Zum Test habe ich auch einen Counter eingebaut. Der Zählt einfach pro Impuls +1.

counter++;

Aber selbst der counter passt irgendwann nicht mehr.

Grüße, nox

Mit welchem Sensor wertest du denn die Impulse aus?

Hi,

B+G DRT428B - 3x 230/400V 20(80)A

Weiß langsam nicht mehr, wie ich den Fehler eingrenzen soll.

Das war ein versehen meinerseits. Im Startposing hast du ja geschrieben, dass du die S0-Schnittstelle anzapfst. Ich hatte noch ein vergleichbares projekt im Hinterkopf, wo jemand das Blinken der LED mit einem Fotowiderstand oder -transistor ausgewertet hat.

Hab mal nach deinem Stromzähler gegoogelt: http://www.debnar-messtechnik.de/DRT428B.pdf Passt es denn mit den angegebenen 800 Impulsen pro kWh besser? ;)

Hi,

ich prüfe ich später noch mal.

Allerdings steht auf meinem Zähler 1000imp/kWh.

Und das sind auch keine 200 imp Unterschied.

Zählst du eigentlich zu viele Impulse gegenüber der Display-Anzeige oder zu wenige? Für den ersten Fall sollte man mal das Signal untersuchen, ob da irgendwelche Störungen drin sind. Nach den Spezifikationen der S0-Schnittstelle sollte ja eine bestimmte Mindestimpulslänge vorliegen. Eventuell könnte man das in den Code einbauen, dass bspw. nur Impulse gezählt werden, die mindestens 50 ms lang sind. pulseIn() kann das zwar, blockiert aber auch den Programmablauf ähnlich einer delay()-Anweisung, zum Testen reicht das aber im Allgemeinen aus.

Hi,

es werden zu viele Impulse gezählt. Allerdings nicht sofort, sondern erst mit der Zeit. Habe schon mit Delay rumgespielt, leider ohne erfolg.

Auch Interrupt nutzen hat leider keine Veränderung gebracht.

Ich werte es später genau aus und melde mich noch mal.

Danke! nox

Du sollst ja auch kein delay benutzen, sondern testweise die pulseIn-Funktion, um ausschließlich entsprechend lange Impulse zu messen. Laut dem von mir verlinkten Datenblatt soll so ein Impuls etwa 90 ms dauert. Somit würde ich alles verwerfen, was kürzer als 50 ms ist - vielleicht gibt es kurze Störungen/Unterbrechungen im Signal, die das Ergebnis verfälschen.

Ich zähle mit einem Reflexoptokoppler MRL601 die Impulse meines Gaszählers . Die Impulse werden nach jedem Zählerdurchlauf an der Ziffer 6 erkannt, hier reflektiert ein kleiner Reflexpunkt Das funktioniert mit der MRL601 sehr gut!

Von der Schaltung geht es auf PIN 7 zum Arduino, dort habe ich die Interrupt Schaltung von der Familie Kriwanek benutzt siehe Code im Link.

http://www.kriwanek.de/arduino/grundlagen/182-pin-change-interrupts-grundlagen.html

NUN ZUM PROBLEM:

Auch ich habe den Eindruck, dass mit zunehmender Laufzeit der Zähler vom Arduino zu viel zählt. Ich habe wirklich lange vor dem Impulsgeber gesessen und die Impulse kontrolliert, nach jedem Impuls habe ich den Zählerstand im Arduino kontrolliert, es war immer alles ok, aber nach 2 - 5 Stunden (ich war nun nicht mehr im Keller :-) ) sind plötzlich Abweichungen dar, und es ist immer so, dass der Arduino zu viel gezählt hat, nicht sehr viel aber ein paar Ticks schon.

Ich kann es mir nicht erklären, habe auch schon andere "ZählCodes" verwendet, es ist immer das gleiche Ergebnis, die gezählten Ticks sind zu hoch...

Hat jemand eine Idee oder Vorschlag was ich tun kann

(Bin noch Anfänger und habe mir die Scripts auch nur zusammengebastelt, bitte um Verständnis)

Danke Jürgen