Go Down

Topic: Arduino Mega als Schaltcomputer missbrauchen (Read 4230 times) previous topic - next topic

heinz g

Hallo zusammen,
Samstag ist ein Teil meiner bestellten Hardware gekommen. Den Arduino Mega habe ich natürlich gleich mit dem DCF77 Modul verbunden, hatte mir aus dem Netz einige Beispiel-Programme geladen ausprobiert. Das synchronisieren dauert etwas länger als beim C-Control aber klappte auf Anhieb und ich habe auch das Gefühl das sich der Arduino (die Uhrzeit) öfters synchronisiert wie das das C-Control tat. Leider habe ich aber nachdem ich wahrscheinlich auf die primitivste Art im Programm ein Relais angesprochen und Schaltzeiten programmiert hatte festgestellt. Immer wenn sich das Modul neu synchronisiert kommt es zu falschen Uhrzeiten, sprich die Uhr geht etwas nach bis zu 2 Minuten um dann wenn der Vorgang abgeschlossen ist wieder genau zu gehen. Kommt es in dieser Zeit allerdings zu Schaltvorgängen werden die zum Teil gar nicht oder später ausgeführt. Das geht überhaupt nicht. Beim C-Control läuft die Uhrzeit genau weiter und die Schaltvorgänge werden auch während eines Synch-Vorgangs ausgeführt.  Hat jemand irgendeine Idee wie man das abstellen kann ? Ich denke mir eventuell das man die Zeiten das DCF77 Moduls in eine Software Uhr einspeichert oder als Variable übergibt und die Zeiten aus dieser Softwareuhr benutzt um Schaltvorgänge zu starten. 
Toll ist auf jeden Fall wie einfach sich der Arduino bedienen lässt und der Input im Netz ist gewaltig.
Gruß Heinz

rudirabbit

Seltsam, ich verwende die Lib's  DCF77.h und Time.h und kann diesen Fehler nicht nachvollziehen.

Hast du das Problem auch wenn keine Relais angeschlossen sind ?
Je nach Design der Relaistreiberschaltung macht der Arduino seltsame Dinge.

Es gibt fertige Relaisplatinen mit Optokopplern die mit dem Arduino gut funktionieren,
einige hier verwenden auch SS Relais weil die offensichtlich Ärger mit den mechanischen Relais hatten.
Arduino UNO,MEGA  Fremdgänger mit dem  Nucleo L152RE   
Dunkel die andere Seite ist. - Klappe, Yoda, und iss deinen Toast :-)

dischneider

Interessant wäre die Frage, wie die Uhrzeit kontrolliert wird (Display?) und wie die Steuerung der Relais hinterlegt ist, "delay()" könnte da z.B. eigenwillige Effekte haben, da es ja den Arduino in der Abarbeitung seiner Routinen unterbricht.
Aber die DCF-Library nutzt Interrupt, da sollte nichts zwischenfunken.

using arduino leonardo, arduino uno ...
--
tomorrow today will only be yesterday, so live your life today!

Serenifly


Suche mal bei eBay Artikelnummer 251208194968

Ich finde da ein Modul für 5 Euro. Kostenloser Versand aus China :smiley-eek: Verkäufer hat super Bewertungen aber die verdienen doch daran nichts mehr.

-Micky



Suche mal bei eBay Artikelnummer 251208194968

Ich finde da ein Modul für 5 Euro. Kostenloser Versand aus China :smiley-eek: Verkäufer hat super Bewertungen aber die verdienen doch daran nichts mehr.
Das glaubst Du aber nur. Schon mal gesehen was ein durchschnittlicher Arbeiter da verdient?


Micky

heinz g

Der Fehler ist gefunden, die Relaisplatine stört nicht, es war scheinbar das zusammenspiel von serieller Ausgabe und gleichzeitiger auf einem Display. Nur mit Display läuft alles suber durch.
Paralell habe ich auch noch getestet die Uhrzeit per NTP-Server und RTC zu synchronisieren. Das gefällt mir gut und klappt auch, Nachteil ist natürlich das man den Arduino im Betrieb immer in der Nähe eines Routers betreiben muss.
Ich würde doch lieber bei meiner DCF77 Version bleiben, da gibt es ja bei ELV auch ein Modul wo die Uhrzeit vom RTC durch die des DCF77 gestellt wird. Leider ist dies im Moment nicht lieferbar. Hat das schon jemand hier im Forum und keine seine Erfahrung mitteilen?
Ein anderes Problem finde ich die eingabe der Schaltzeiten, da ich Anfänger bin viel mir im Moment nicht anderes ein als die Schaltzeiten so einzugeben
if (RTC.dow == 5 && RTC.hour == 6 && RTC.minute ==15)
    digitalWrite(relaisChef, HIGH);
  if (RTC.dow == 5 && RTC.hour == 6 && RTC.minute == 16)
    digitalWrite(relaisChef, LOW);
   
  if (RTC.dow == 5 && RTC.hour == 6 && RTC.minute ==55)
    digitalWrite(relaisWerkstatta, HIGH);
  if (RTC.dow == 5 && RTC.hour == 6 && RTC.minute ==56)
    digitalWrite(relaisWerkstatta, LOW);
   
    if (RTC.dow == 5 && RTC.hour == 7 && RTC.minute ==1)
    digitalWrite(relaisWerkstattb, HIGH);
  if (RTC.dow == 5 && RTC.hour == 7 && RTC.minute == 2)
    digitalWrite(relaisWerkstattb, LOW);
   
    if (RTC.dow == 5 && RTC.hour == 7 && RTC.minute ==25)
    digitalWrite(relaisSekra, HIGH);
  if (RTC.dow == 5 && RTC.hour == 7 && RTC.minute == 26)
    digitalWrite(relaisSekra, LOW);
usw usw...
Gibt es hierfür eine elegante Lösung ? Der kurze Abstand zwischen HIGH und LOW ist der Zeitraum den die jeweilige Rolllade braucht um hoch bzw runter zu fahren.

Serenifly

#21
Jun 21, 2013, 01:11 pm Last Edit: Jun 21, 2013, 01:17 pm by Serenifly Reason: 1
Du kannst deine if-Abfragen verschachteln, dann musst du nicht dauernd nochmal darauf testen

z.B:
Code: [Select]

if(RTC.dow == 5)
{
  if(RTC.hour == 6)
  {
      if(RTC.minute == 15)
      {
      }
  }
  else if(RTC.hour == 7)
  {
  }
}
else if...



Für die Minute wäre auch eine Switch-Abfrage übersichtlicher:

Code: [Select]

switch(RTC.minute)
{
    case 1:
      digitalWrite(...);
      break;
    case 2:
       ....
       break;
    case 15:
       ....
       break;
}



Das kannst du dann einmal in eine if-Abfrage für den Tag und die Stunden packen.

Und kannst du da nicht einfach ein Delay für eine Minute machen? Mit millis vielleicht wenn du solange nicht alles blockieren willst. Oder du könntest einen Timer starten, der nach einer Minute  den Pin wieder zurückschaltet.

heinz g

Mit dem verschachteln der if-Anweisung ist eine gute Idee gewesen, das klappt auch alles . Ist die Anzahl der if-Anweisungen in einem Programm begrenzt oder kann man unendlich viele verwenden? Hilfreich wäre auch wenn man die Einschaltzeit eines Relais für mein Vorhaben brauche ich ja nur immer maximal 60 Sekunden, mittels Befehl begrenzen könnte.
So in etwa ist RelaisChef HIGH  dann aber nach 60 Sekunden LOW, aber diese Funktion sollte für alle HIGH Zustände Gültigkeit haben und nicht nach jedem Einschaltbefehl neu gesetzt werden müssen, dies würde mir programmiertechnisch einiges an Tipparbeit ersparen.

Serenifly

#23
Jun 25, 2013, 12:45 pm Last Edit: Jul 05, 2013, 04:57 pm by Serenifly Reason: 1
Das solltest du so viele wie du willst verwenden können. Wieso soll da was begrenzt sein? Wird ja letztlich in Machinencode übersetzt.

Die Schaltzeit des Relais kannst du einfach mit Konstanten setzen.

Du definierst dir einmal global sowas (außerhalb von setup und loop):
const long relayTime = 60000;

Dann machst du das Schalten so:
Code: [Select]

digitalWrite(..., HIGH);
delay(relayTime);      //Verzögerung um relayTime in Millisekunden
digitalWrite(..., LOW);


Wenn du dann relayTime änderst, werden alle Schaltzeiten angepasst. Wenn du die Zeit zur Laufzeit ändern willst, lässt du das const weg.

Delay blockiert dir solange das gesamte Programm und du kannst sonst nichts mehr machen. Bei deiner Anwendung sollte das akzeptabel sein, aber wenn nicht schau dir das Beispiel "BlinkWithoutDelay" an.

Funktionen die ständig wieder verwendet werden packt am besten in eigene Methoden. Das habe ich bei mir gemacht:

Code: [Select]

void triggerRelay()
{
digitalWrite(Start, LOW);
delay(1000);
digitalWrite(Start, HIGH);
}


Das kann man kombinieren, aber beide Versionen bewirken für sich, dass du das Verhalten des Relais nur noch an einer Stelle definiert hast.

heinz g

Danke erst einmal für die Antwort, ich hätte vielleicht erwähnen sollen das ich ein Display angeschlossen habe. Wenn die das PRG jetzt starte bleibt die Uhrzeit im Display stehen. Mit dem delay klappt es dann wohl nicht, ich werde mich dann wohl mit dem Beispiel aus BlinkWithoutDelay auseinandersetzen müssen. Schön wäre es nur wenn man das für alle Ports in einer Struktur zusammen fassen könnte und nicht wie ich das im Moment verstehe das ich das für jeden Port einzeln angehen muss. Weiter möchte ich ganze erweitern, so wie ich es verstanden habe kann man mit digitalread den Zustand der Ports abfragen um dann als Beispiel eine Kontroll-Led anzuschließen die jeweils leuchtet wenn der Port HIGH ist.

heinz g

Hallo zusammen,
ich habe mittlerweile meine Rollladenschaltung incl. Lichtsteuerung und Temperatur hinbekommen. Das ganze läuft allerdings noch mit einer DS1307 zusammen die scheinbar nur eine Sekunde Abweichung pro Monat hat. Mit dem DCF 77 Modul bin ich noch nicht so weit. Es fehlt leider auch die Zeit dafür.
Ich habe jetzt 21 Ports in Betrieb 16 für die Rollladenschaltung und 5 für Beleuchtung. Angeschlossen habe ich ein Display das mir die Zeit, Datum, Temperatur und Luftfeuchte anzeigt. Ich habe auf dem Display noch etwas Platz und suche nach einer Möglichkeit mir anzeigen zu lassen welcher Port (welche Portnummer) gerade von LOW auf HIGH wechselt, macht ja auch Sinn bei so vielen Anschlüssen.
Leider finde ich hierfür keine Infos, hat jemand hierfür eine Idee wie man so etwas realisiert?
 

sth77

Um welches Display geht es denn? Irgendwas mit einem HD44780 oder einem kompatiblen Controller? Wie groß, also vieviel Zeichen hat das Display. Wie groß ist dein zur Verfügung stehender Platz?
Ich würde in regelmäßigem Abstand (Sekundentakt) den Status der Ausgänge durchlaufen lassen, also die Nummer des Ausgangs und dann ein oder zwei selbstdefinierte Symbole.
Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

heinz g

Ja es ist ein HD44780, es hat 20X4  Zeichen, ich habe wenn ich alles etwas zusammen rücke 2 Zeilen ab 20 Zeichen Platz.

Serenifly

Bezügliches des Wortes "Port": ich verstehe was du meinst, aber eigentlich meinst du einen Pin. Ein "Port" sind immer 8 Pins zusammen, die über ein Register angesprochen werden. Die Arduino IDE versteckt dir Aufbau des Prozessors lediglich, so dass man das oft nicht sieht. Die Ports werden mit Buchstaben bezeichnet, und die Pins mit Nummern 0-7. "PB7" ist dann Pin 7 auf Port B. Das Arduino Board setzt dann auf andere Pin-Nummern um, so dass aus "PB7" -> Pin 13 wird. Siehe hier:
http://www.pighixxx.com/pgdev/Temp/ArduinoMega_b.png

Das mag hier egal sein, aber irgendwann ließt du vielleicht mal was wo der Unterschied relevant ist :)

heinz g

Danke für den Hinweis Serenifly, natürlich meinte ich die Pins.
Sehr überschaubares Pinout Diagram. Trotz alledem habe ich bisher nichts gefunden das mir die Bezeichnung Pins und deren momentaner Zustand anzeigt, vor allen Dingen so das ich sie im Display sehen kann. Den Zustand der Pins ob LOW oder HIGH das habe ich schon hinbekommen, aber das nutzt mir nichts.

Go Up