Anfänger Fragen zu S0 Logging und Standby Killer

Hallo Zusammen,

ich versuche jetzt mal die einzelnen Fragen nochmal zu beantworten:
Die Schaltung die ich aktuell verwende sieht man am besten im Post vom "March 18, 2014, 07:50:11" Anfänger Fragen zu S0 Logging und Standby Killer - #58 by system - Deutsch - Arduino Forum dort habe ich Bilder hinterlegt.
Dort ist auch der Sketch den ich verwendet habe als Datei angefügt. Heute hab ich darin nur noch alles rund um LCD und im Loop auch die serielle Ausgabe mit // auskommentiert....
Warum ich bei 470Ohm vermutlich nichts zählen kann, darüber spekuliert peter_de in seinem Post Anfänger Fragen zu S0 Logging und Standby Killer - #62 by peter_de - Deutsch - Arduino Forum

S0+ und S0- hab ich korrekt verbunden... - inzwischen mit Verpolungsschutz :wink:

Grundsätzlich find ich die Idee mit dem Abfangen der "kurzen Impulsabstände ganz interessant, vielleicht entlastet das noch ein wenig... also dass er Impulse mit einem Abstand zueinander von weniger als z.B. 5 Sekunden nur gesammelt schreibt...
Sammeln tut er im Moment zwar auch schon aber "unprogrammiert" siehe hier: Anfänger Fragen zu S0 Logging und Standby Killer - #20 by system - Deutsch - Arduino Forum

Und damit Ihr mal wieder was zum Schmunzeln habt: Leider hab ich beim letzten Versuch mit den 4.7kOhm die SD-Karte nicht eingelegt und magels Anzeige am auskommentierten LCD auch nix davon bemerkt... mist...

Hallo,
also- Ich, finde, das Ding ist falsch angeschlossen.
Ich würde 5v mit auf Klemme 20
Dann würde ich Klemme 21 mit 470 Ohm gegen Masse und weiter an Pin25 Arduino.
Gruß und Spaß
Andreas

Parador:
S0+ und S0- hab ich korrekt verbunden... - inzwischen mit Verpolungsschutz :wink:

Wie sieht denn der Verpolungsschutz aus? Hoffentlich kein zusätzliches elekr. Bauteil wie Diode oder so.

Ich habe bei mir den Interrupteingang (Pin 2) über einen 4,7k Widerstand auf +5V gezogen.
Ein Optokoppler, bei mir ein CNX35, zieht Pin 2 dann auf GND.
Zwischen Optokoppler und Arduino habe ich 10m Kabel (cat5e).
Mein Arduino zählt so bis 24 Impulse pro Sekunde bei eine Impulsdauer von 2ms.

Hier mal mein auf die reine Imulserfassung reduzierter Sketch:

volatile int Pin2 = HIGH;                // S0 Impulseingang = Pin2
volatile unsigned long s0start    = 0;   // für Zeitmessung S0-Impuls
volatile unsigned long s0dauer    = 0;
volatile unsigned long s0dauerSum = 0;
volatile unsigned long s0ImpAnz   = 0;
volatile float kWh  = 0;                 // Arbeit aus S0-Impuls
         float watt = 0;                 // Leistung aus S0-Impuls

void setup()
{
  pinMode(Pin2, INPUT_PULLUP);        // S0 Impulseingang
  attachInterrupt(0, ISR0, FALLING);  // Interrupt für S0-Impuls aktivieren
}

/******************************************
 *                                        *
 * SUB - Leistung aus S0-Impuls berechnen *
 *                                        *
 ******************************************/ 
void s0Leistung ()
{
watt = 0;  
if (s0ImpAnz != 0) {  
  watt = 360000000/(float)(s0dauerSum/s0ImpAnz); 
  s0dauerSum = 0;
  s0ImpAnz   = 0;
  }
}

/****************************************************************
 *                                                              *
 * SUB - Interruptroutine ausgelöst durch Flanke 1-->0 an Pin 2 *
 *                                                              *
 ****************************************************************/ 
void ISR0()
{ 
  Pin2 = !Pin2;
  s0dauer = micros() - s0start;
  s0start = micros();
  s0dauerSum = s0dauerSum + s0dauer;
  ++kWh;
  ++s0ImpAnz;
}

void loop() // Hauptroutine
{
  s0Leistung (); // Leistung aus S0-Impuls berechnen

//  Serial.print(watt,2);         // Aktuelle Leistung
//  Serial.print((kWh/10000),4);  // aufsummierte Arbeit
}

Vielleicht gibt der Code für Dich noch was brauchbares her.

Hallo,
lass das mal mit dem Interrupt und dem ganzen anderen ProgrammMüll.

Lege den S0 mal auf einen Digital Pin.
Den fragst Du so in der Art ab:

static boolean RunAction = true; // für einmal zählen
const int S0B = 25; // für S0 Eingang
int zlWSZ = 0; // Zähler für Impuls


void setup()  
{
 pinMode(S0B, INPUT);
}


void loop() 
{
if (digitalRead(S0B) == HIGH)

{
if(RunAction) // 1 impuls einmal zählen
{
(zlWSZ++);
lcd.setCursor(0, 0);
  lcd.print(zlWSZ);
RunAction = false;
}
}
else 
{
  RunAction = true;
}
}

Dann hast Du eine sichere Methode die Impulse zu erkennen, ohne das
"unbekannter" Code Dir etwas verfummelt.
Gruß und Spaß
Andreas

Moin Parador,

nun - wie ist's?
Hast Du schon mit anderen Teilen und Werten testen können?

Hallo Zusammen,

leider sind noch nicht alle Teile da... schade sonst hätte ich das WE über was machen können...
nächste Woche bin ich ziemlich ausgebucht, da wirds vermutlich nichts, ich melde mich sobald ich wieder getestet habe.

Viele Grüße und schönen restlichen Sonntag!

Hallo Zusammen,

da bin ich wieder, nach vielen Versuchen und einigen großen Bergen Wäsche :wink:
Ich habe nun letztlich mit der Variante von SkobyMobil viel getestet und bin dann nach einige Versuchen auch soweit, dass die Impulse ordentlich gezählt und auf der SD-Karte mitgeloggt werden.
Ich kann nun ein ordentliches Strom-Verbrauchs-Profil eines Gerätes erstellen...

An dieser Stelle vielen Dank für Euere Geduld und die vielen Tipps und Tricks...
Sicher werde ich mich (vielleicht) bald wieder bei Euch allen melden und wieder Fragen haben.. im Moment bin ich happy und bastle weiter :wink:

Viele Grüße

Hallo Parador

Auch ich bin änfanger, wollte auch mal dein sketch gebrauchen. Ich sehe aber nicht die complete sketch.
Hast du die noch fur mich.

Grüsse

Hallo Zusammen

@Parador: Habe eine Frage zu deinen S0 Logger, super Arbeit von euch allen

Bis vor ein paar Tagen hat dein Sketch fast perfekt funktioniert,

(Code von #57 übernommen)

hatte eine kleine Abweichung beim Zähler,

(Proband 100 Watt Lampe S0 Zähler dieser

http://www.amazon.de/gp/product/B006J3LM5O?psc=1&redirect=true&ref_=oh_aui_detailpage_o05_s00

der Arduino UNO v3 zählte um 13 Impulse zu viel, danach habe ich den 10kOhm Wiederstandwert

verändert wie es in den #53 besprochen wurde, da hatte ich immer um 20 Impulse mehr.

Nach ein paartagen Pause wollte jetzt wieder weiter machen, (habe nichts geändert)

jetzt bekomme ich immer diese Fehlermeldung beim Kompilieren.

This report would have more information wit
"Show verbose output during compilation" enabled in File > Preferences.
Arduino: 1.0.6 (Windows 7), Board: "Arduino Uno"
RTClib\RTClib.cpp.o: In function date2days': C:\Users\Masster\Documents\Arduino\libraries\RTClib/RTClib.cpp:26: multiple definition of i'
_2014_03_17_S0_Dataloger_0102_kurzform.cpp.o:(.data.i+0x0): first defined here

Habe schon alles möglich versucht, da ich aber nicht gut im Programmieren und englisch bin möchte ich um

eine kleine Hilfe bitten, ob jemand einen Tipp für mich hat, was ich das ändern soll.

Beim Studieren der trockenen Theorie bin ich leider auch nicht viel schlauer geworden.

Danke schon mal im Voraus Martin

Hallo,

als Anfänger bezüglich Arduino bin ich am experimentieren bezüglich dem erfassen und auswerten der S0 Pulse von Drehstromzwischenzähler.

Das triggern mit dem S0 Pulse funktioniert von der Hardwareseite.

Meine ersten Versuche waren mit einem Pythonscript und Interrupt auf einem Raspberry die Daten in eine csv Datei zu schreiben. Das hat funktioniert, nur läuft auf diesem Raspi noch eine Smart Home Control software, hauptsächlich in php geschrieben und diese wird durch die vielen Interrupts (2000pulse / kWh)gestört.

Deshalb möchte ich das Zählen und berechnen auf einen Arduino oder besser noch auf einen ESP8266 auslagern. Die Auswertung der Ergebnisse soll im Volkszähler erfolgen.

Es gibt im Netz zahlreiche Ansätze hierzu. Mein Favorit ist:

https://wwwvs.cs.hs-rm.de/vs-wiki/index.php/Internet_der_Dinge_WS2015/EnergyEye

Hier wird ein Real Time OS auf dem ESP8266 verwendet. Für einen Laien wie mich sehe ich aber keine Möglichkeit die Anleitung umzusetzen.

Kennt jemand vielleicht ein Tutorial, wo dies bereits einmal einfacher umgesetzt wurde?

Funktioniert das überhaupt mit einem "einfachen sketch" auf einem Arduino oder besser ESP8266 ohne SD Karte die der S0 Pulse pro Minute zu zählen und an den Volkszähler zu übergeben, ohne in dieser Zeit eingehende Impulse zu verlieren?

Oder muss man doch auf ein Real Time OS zurückgreifen?

Im Augenblick experimentiere ich mit dem Code aus #82 und habe ihn etwas angepasst.

// Linefeet geht nicht
// Watt werden nicht angezeigt

volatile int Pin2 = HIGH; // S0 Impulseingang = Pin2
volatile unsigned long s0start = 0; // für Zeitmessung S0-Impuls
volatile unsigned long s0dauer = 0;
volatile unsigned long s0dauerSum = 0;
volatile unsigned long s0ImpAnz = 0;
volatile float kWh = 0; // Arbeit aus S0-Impuls
volatile float watt = 0; // Leistung aus S0-Impuls

void setup()
{
pinMode(Pin2, INPUT); // S0 Impulseingang
Serial.begin(9600);
attachInterrupt(0, ISR0, FALLING); // Interrupt für S0-Impuls aktivieren
}

/******************************************

  • SUB - Leistung aus S0-Impuls berechnen *

******************************************/
void s0Leistung ()
{
watt = 0;
if (s0ImpAnz != 0) {
watt = 360000000/(float)(s0dauerSum/s0ImpAnz);
s0dauerSum = 0;
s0ImpAnz = 0;
}
}

/****************************************************************

  • SUB - Interruptroutine ausgelöst durch Flanke 1-->0 an Pin 2 *

****************************************************************/
void ISR0()
{
Pin2 = !Pin2;
s0dauer = micros() - s0start;
s0start = micros();
s0dauerSum = s0dauerSum + s0dauer;
++kWh;
++s0ImpAnz;
}

void loop() // Hauptroutine
{
s0Leistung (); // Leistung aus S0-Impuls berechnen

Serial.print("Watt = " );
Serial.print(watt,2); // Aktuelle Leistung
Serial.print("\t kWh = " );
Serial.print((kWh/800),2); // aufsummierte Arbeit
}

Leider bekomme ich hier keine Watt Ausgabe. Immer 0. kWh werden hochgezählt. Ausserdem wird alles in eine Zeile geschrieben. Da habe ich auch keinen Plan, warum es keine Spalten sind.

Wenn ich hier plausible Ergebnisse hätte, könnte ich weiter daran arbeiten die Impulse pro Minute zu zählen. Wobei ich mich frage, ob ich hier ein RTC Modul benötige.

Bin für jede Hilfe dankbar.

Hallo,

ich bin auf der Suche nach einem Impulszähler für S0 auf dieses Forum gestoßen. Eigentlich will ich nur die Impulse zählen und nicht die aktuelle Leistung messen.
Das funktioniert mit dem etwas abgewandelten digitalem StateChangeDetection Sketch welches ich in den Vorlagen gefunden habe auch ganz gut.

// this constant won't change:
const int  buttonPin = 7;    // the pin that the pushbutton is attached to

// Variables will change:
int impuls = 0;   // counter for the number of button presses
int State = 0;         // current state of the button
int lastState = 0;     // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  State = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (State != lastState) {
    // if the state has changed, increment the counter
    if (State == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      impuls++;
      Serial.print("Impuls: ");
      Serial.print(impuls);
      Serial.print("\t kWh = ");
      Serial.println(impuls/2000);
    } 
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastState = State;
  
}

Allerdings würde ich gerne mehrere S0 Zähler an das arduino Mega anschließen.
Bei blog.elektrowolle.de gesehen das auch mehrere Pins in einer Gruppe zusammen gefasst werden können. Wenn ich das sketch auf meinem Arduino laufen lasse werden pro Impuls 3mal die Zeit zwischen den beiden Impulsen in ms angezeigt und an welchem PIN das gemessen wird kann ich nur schwer zuordnen.
Jetzt endlich zur Frage: Wie kann ich diese Zählung auf mehren PIN ausweiten und den PIN Serial ausgeben damit ich erkennen kann auf welchem INPUT Pin der Impuls eingegangen ist.

Hallo,
könnte helfen, ist recht einfach.
Gruß und Spaß
Andreas

Hey SkobyMobil,

das ist ja das verlinkte Projekt von elektrowolle, das eigentlich nur die Zeit zwischen den Impulsen misst. Das ganze als Counter umzustellen ist mir nicht gelungen und warum der Input dann in ASCII chart umgerechnet wird verstehe ich nicht so ganz.

Hallo,
ja, doppeltGemoppelt…
Aber in dem Sketch steht doch alles?
Er gibt die Pin´s vor und bezeichnet sie mit A, B, C…

Wenn Du nun einen S0-Zähler anschließt, dann weiß Du doch an welchem Pin
dieser hängt?

Auch wird es über seriell ausgegeben…

Die Zeit zwischen den Impulsen brauchst Du doch. Dann kannst Du die Impulse
doch berechnen. Sein Sketch ist für 1000Imp/kWh.
Verstehe ich da etwas nicht?

Wenn Du nur Impulse willst dann mache doch:
wenn pin high
impuls++
serial.print (impuls)

Gruß und Spaß
Andreas

P.S.
ich weiß nicht ob es läuft- habe ich seiner Zeit mal probiert.
1-S0-Zähler an Pin 30 des Mega

#include <LiquidCrystal.h>
//******************************     Für S0-Zähler     *************************
const byte counterPins[1] = {30};
unsigned long millisBetween[8];
unsigned long lastMillis[8];
byte lastState[8];
int kwz=-1;
float ZeitWatt;
float KWH;
//******************************************************************************

LiquidCrystal lcd(12, 11, 5, 4, 7, 2);
void setup()  
{
  lcd.begin(20, 4);
Serial.begin(9600);
//******************************     Für S0-Zähler     *************************
 for (byte i = 0; i < sizeof(counterPins); i++) {
     pinMode(counterPins[i], INPUT);
     digitalWrite(counterPins[i], LOW);

  }
  //******************************************************************************
}

void loop()
{

  unsigned char bitMaskToSend = 0;
  unsigned long time = millis();
  for (byte i = 0; i < 1; i++) {
     byte val = digitalRead(counterPins[i]);
     if (val == HIGH && lastState[i] == LOW) {
       millisBetween[i] = time-lastMillis[i];
       lastMillis[i] = time;
       bitSet(bitMaskToSend, i);
     }
     lastState[i] = val;
  }
  for (byte i = 0; i < 1; i++) {
     unsigned long dataToWrite = millisBetween[i];
     if (bitRead(bitMaskToSend,i))
     kwz++;
     {
       lcd.setCursor(0, 1);
       
       lcd.print((char)('A'+i));
       lcd.print(" ");
       lcd.print(dataToWrite);
       lcd.print("   ");
       lcd.print(kwz);
       lcd.print("   ");
      ZeitWatt=dataToWrite;
      KWH=(3600000/ZeitWatt)*0.5;
      lcd.setCursor(0, 2);
      lcd.print(KWH,2);
      lcd.print("    ");
      
     }
  }
}

P.P.S.
jetzt habe ich mir Deinen Sketch mal genauer angeschaut…
Was soll das denn?

Du willst ja "Tasten wie oft gedrückt" auswerten, und als schlaues Kind hast
Du Dir gedacht, ein S0-Zähler macht das gleiche.
Macht er aber nicht!

Das Forum ist voll von "wie oft Taste gedrückt" Da wirst Du sicher etwas
passendes finden.

Hier gibt es mal einen Einstieg…

Taste
entprellen
und zählen