18.11.2018, 05:48 PM
(17.11.2018, 10:03 PM)alfsch schrieb: übliche Lösung: zwei Zenerdioden, in Serie+verpolt , mit Nennspannung ; also bei 12V eben 2 x 12V-Typen;
oder passender Überspannungsableiter (wird in Industrie-Relais / Schaltschrankbau oft verwendet)
Kondensatoren sind eher problematisch: damit produziert man auch Stoss-ströme beim Einschalten, was zb Relais gar nicht mögen (Lebensdauer...oder sogar Kontakt-verklebt....alles schon gehabt )
Ich hab Z-Dioden für 180V, 130V, 68V... aber keine 12V . Ich behelfe mich erstmal mit kleinen Kondensatoren nach Masse, die in den 2..3ms des Schaltvorgangs den Spulenstrom abnehmen. Und setze die Z-Dioden auf die Einkaufsliste.
Nun prellt und zuckt vorerst nix mehr, aber es gab Verluste... Ein Pin des µC ist tot, es hat auch mal geraucht (ist aber noch etwas Rauch dringeblieben - ich war schnell ).
Neue Software gibt es auch, meiner Meinung nach eleganter und richtiger
Code:
// 2018-11-18: TN-Tochteruhr mit hochgenauer RTC
// Version 2.00
// von kahlo (kahlo@stromrichter.org)
// Hardware: Adafruit Feather ( https://www.adafruit.com/product/2771 )
// Hardware: Adafruit DS3231 Precision RTC ( https://www.adafruit.com/product/3013 )
// Hardware: TN Tochteruhr, Bahnhofsuhr
// Hardware: 2 Relais 5V, 1xUM, 2 NMOS, Widerstände, LM7805
// Programmierumgebung: Arduino ( http://arduino.cc/ )
#include <Wire.h>
byte led = 13; // interne LED an Pin 13
byte TN1 = 6; // Ausgang 1 an Pin 6
byte TN2 = 15; // Ausgang 2 an Pin 15
byte power = 11; // Pin 11 ist der Sensor für die externe Spannungsversorgung
byte SQW = 1; // 1Hz Rechteck-Signal von RTC an Pin 1
byte SQWstatus = 0; // 1Hz Rechteck-Signal von RTC an Pin 0
byte SetPin = 14; // an Pin 14 kann die Uhr gestellt werden
volatile int minutes = 0; // Zähler m
volatile byte seconds = 0; // Zähler s
volatile bool TotzeitFlag = true;// Nomen est omen
bool coilstatus = LOW; // Polaritätsstatus der Uhrwerkes bzw. der Spule
void setup() {
Wire.begin(); // Initialisierung der RTC
Wire.beginTransmission(104); // DS3231 Adresse
Wire.write(0x0E); // Registerauswahl
Wire.write(0b01000000); // Registerbitmap, schaltet das 1Hz-Rechteck ein (siehe DB vom DS3231)
Wire.endTransmission();
pinMode(led, OUTPUT); // Definition der Pins
pinMode(TN1, OUTPUT);
pinMode(TN2, OUTPUT);
pinMode(power, INPUT);
pinMode(SQW, INPUT_PULLUP);
pinMode(SQWstatus, INPUT);
pinMode(SetPin, INPUT_PULLUP);
digitalWrite(TN1, LOW); // Beide Spulenenden auf Masse
digitalWrite(TN2, LOW);
attachInterrupt(3, Hz_interrupt,CHANGE); // Interrupt 3 an Pin 1 aktivieren
}
void loop() {
if (digitalRead(power) == HIGH && TotzeitFlag == false) {
if (minutes > 0) { // Minutenstack wird abgearbeitet
if (coilstatus == LOW) { // die Spule muss wechselseitig bestromt werden
digitalWrite(TN1, HIGH); // Anschluss 1 bekommt 12V
coilstatus = HIGH; // das nächstemal vom anderen Spulenende...
}
else { // das andere Ende
digitalWrite(TN2, HIGH);
coilstatus = LOW;
}
minutes--; // Minutenstack verkleinern
TotzeitFlag = true; // Atempause für die Uhrmechanik
}
}
if (digitalRead(SQWstatus) == LOW) { // 0,5s Atempause für die Uhrmechanik
digitalWrite(TN1, LOW);
digitalWrite(TN2, LOW);
}
}
void Hz_interrupt()
{
if (digitalRead(SQWstatus) == HIGH) {
seconds++; // schon wieder eine Sekunde im Stack
if (seconds == 60) {
seconds = 0;
minutes++; // der Minutenstack...
if (minutes >= 720) minutes = 0; // nach 12h ohne externe Spannungsversorgung
}
if (digitalRead(SetPin) == LOW) {
minutes++; // der Minutenstack wird per Hand erhöht (Uhr stellen)
seconds = 0;
}
digitalWrite(led, HIGH); // Funktionsindikator LED im 1s-Takt
TotzeitFlag = false; // bereit für neuen Schaltvorgang
}
else {
digitalWrite(led, LOW); // Funktionsindikator LED im 1s-Takt
TotzeitFlag = true; // 0,5s Pause
}
}