Forum: Mikrocontroller und Digitale Elektronik Countdown für Brutautomat über mehrere Tag mit Bascom


von Simon H. (simon24j)


Lesenswert?

Hallo zusammen,

habe mir einen Brutautomaten mit Steuerung über AVR gebaut, funtioniert 
soweit auch super, nur habe ich einen Countdownzähler drin der bei den 
21Tagen um ca 3 Tagen abweicht :-(
1
Schlupfzaehler:
2
if sekunden_schlupf > 0 or minuten_schlupf > 0 or stunden_schlupf > 0 or tage_bis_schlupf > 0 then
3
      decr sekunden_schlupf
4
5
6
      if sekunden_schlupf >= 60 then
7
         sekunden_schlupf = 59
8
         decr minuten_schlupf
9
      end if
10
11
12
      if minuten_schlupf >= 60 then
13
         minuten_schlupf = 59
14
         decr stunden_schlupf
15
         stunden_schlupf_ram = stunden_schlupf
16
17
         end if
18
      if stunden_schlupf >= 24 then
19
         stunden_schlupf = 23
20
         decr tage_bis_schlupf
21
         tage_bis_schlupf_ram = tage_bis_schlupf
22
      end if
23
24
end if
25
Return
die Routine wird über sectic jede sekunde aufgerufen
Uhrzeit stimmt nach den 21Tagen auch noch auf paar minuten genau, kann 
also auch daran ned liegen :-(

aber bin mir bei obrigen Code ned ganz sicher ob das so passt!?!?

Bitte um HILFE

BEsten Dank schon mal

: Bearbeitet durch User
von René B. (reneb)


Lesenswert?

Überarbeite mal dein Design ein wenig.
Dein Zählwerk da oben ist etwas strange, aber sicher kann man das auch 
irgendwie fixen. Ist aber eben etwas unglücklich zu warten und zu 
verstehen.

Für den internen Coutner verwendest du EINE Variable als Sekundenwerk 
und zählst das sauber runter.
Die Anzeige wie lange es noch dauert rechnest du aus diesem 
Sekundenzähler heraus um. Das geht über Division (/) mit module (%) 
deutlich einfacher.

von Jürgen S. (jurs)


Lesenswert?

Simon H. schrieb:
> habe mir einen Brutautomaten mit Steuerung über AVR gebaut, funtioniert
> soweit auch super, nur habe ich einen Countdownzähler drin der bei den
> 21Tagen um ca 3 Tagen abweicht :-(

Das ist ein extrem merkwürdiger Countdown-Zähler.

Wenn ich unter Arduino einen 21-Tage Countdown-Zähler machen würde, dann 
würde dieser Zäler bei "86400L*21" anfangen zu zählen und pro Sekunde 
würde davon 1 abgezogen werden, bis der Zähler 0 erreicht. 86400 ist die 
Anzahl der Sekunden pro Tag.

Falls der Zähler zwischendurch mit seiner verbleibenden Restzeit 
angezeigt werden soll, würde ich die Zahl der Sekunden in die 
anzuzeigenden Werte umrechnen, z.B. Tage, Stunden, Minuten und Sekunden, 
und entsprechend für die Ausgabe formatieren.

von Simon H. (simon24j)


Lesenswert?

Hallo,

wie gesagt die Routine wird über die sectic variable die ja die 
Soft-clock mit liefert sekündlich aufgerufen, und da die Uhrzeit über 
den Zeitraum ja auch passt muss ich davon ausgehen das auch die sectic 
wirklich sekündlich aufgerufen wird.

leider habe ich keine Ahnung was du mit "Das geht über Division (/) mit 
module (%) deutlich einfacher." meinst

von Falk B. (falk)


Lesenswert?

@ Simon H. (simon24j)

>habe mir einen Brutautomaten mit Steuerung über AVR gebaut, funtioniert
>soweit auch super, nur habe ich einen Countdownzähler drin der bei den
>21Tagen um ca 3 Tagen abweicht :-(

Sind schnelle Brüter nicht aus der Mode gekommen? ;-)

http://de.wikipedia.org/wiki/Schneller_Br%C3%BCter

3 Tage Fehler in 21 Tagen sind ~14%. Das ist ein kapitaler 
Programmierfehler oder ein arg tolerierter RC-Oszillator.

Dein Zähler ist auch arg merkwürdig.
Du DEKREMENTIERSt die Sekunden, prüfst dann aber auf >=60?
Das klappt nur, wenn deine Variabeln alle vorzeichenlos sind.
Dieses Fragment von Code ist nicht ausreichend zur Fehlersuche. Poste 
vollständigen Code als Anhang,.

>aber bin mir bei obrigen Code ned ganz sicher ob das so passt!?!?

Sieht erstmal OK aus.

von Falk B. (falk)


Lesenswert?

@ Simon H. (simon24j)

>leider habe ich keine Ahnung was du mit "Das geht über Division (/) mit
>module (%) deutlich einfacher." meinst

Man nimmt eine 32 Bit Variabel und zählt normal runter

time32--;

Wenn man dann was anzeigen will, rechnet man von der Sekundendarstellung 
in time32 in hh::mm::ss um

Tag = time32 / (24 * 86400);
Rest = time32 % (24 * 86400);
Stunde = Rest / 3600;
Rest = Rest % 3600;
Minute = Rest / 60;
Sekunde = Rest % 60;

von Simon H. (simon24j)


Lesenswert?

Hallo,

den ganzen Code zu posten wäre bissl viel 3000Zeilen!!
hier die Deklaration zu den Variablen
1
dim tage_bis_schlupf as byte
2
dim tage_bis_schlupf_ram as eram byte
3
tage_bis_schlupf = tage_bis_schlupf_ram
4
dim sekunden_schlupf as byte
5
dim minuten_schlupf as byte
6
dim stunden_schlupf_ram as eram byte
7
dim stunden_schlupf as byte

den Quarz schließe ich aus da ja die Uhrzeit auch nach 21 Tagen noch 
stimmt, und der sectic erfolgt aus dieser softclock

von Simon H. (simon24j)


Lesenswert?

@Falk

ok deine Version gefällt mir,danke, aber vermute das 24 * 86400 stimmt 
nicht oder?
86400 sind ja die sekunden eines tages!?!?

von Simon H. (simon24j)


Lesenswert?

würde bei mir in Bascom jetzt so aussehen:
1
dim sekunden_schlupf32 as  Long
2
dim sekunden_schlupf32_ram as  eram Long
3
dim sekunden_rest as long
1
tage_bis_schlupf = sekunden_schlupf32 / 86400
2
sekunden_rest = sekunden_schlupf32 mod 86400
3
stunden_schlupf = sekunden_rest / 3600
4
sekunden_rest = sekunden_rest mod 3600
5
minuten_schlupf = sekunden_rest / 60
6
sekunden_schlupf = sekunden_rest mod 60

einmalig wird die Brutzeit eingestellt
1
sekunden_schlupf32 = tage_bis_schlupf * 86400
2
sekunden_schlupf32_ram = sekunden_schlupf32

Wie könnt ich es jetzt am besten realisieren das die sekunden_schlupf32 
alle 30min ins Eram gespeichert werden??
if Minute = 30 then ist ja scheiße da ja das dann eine Minute lang 
ansteht, wenn ich die Sekunde noch mit rein nehme dann speichert er ja 
auch öfters in dieser einen Sekunde, wei löst man das am elegantesten?


kanns leider ned testen da ich weit weg bin :-(

von Falk B. (falk)


Lesenswert?

@ Simon H. (simon24j)

>ok deine Version gefällt mir,danke, aber vermute das 24 * 86400 stimmt
>nicht oder?
>86400 sind ja die sekunden eines tages!?!?

Ja, kleiner Fehler.

>Wie könnt ich es jetzt am besten realisieren das die sekunden_schlupf32
>alle 30min ins Eram gespeichert werden??
>if Minute = 30 then ist ja scheiße da ja das dann eine Minute lang
>ansteht, wenn ich die Sekunde noch mit rein nehme dann speichert er ja
>auch öfters in dieser einen Sekunde, wei löst man das am elegantesten?

if Minute = 30 and sekunde = 0 then

von npn (Gast)


Lesenswert?

Falk Brunner schrieb:
> if Minute = 30 and sekunde = 0 then

Da speichert er aber nur alle 60min (wenn eben die Minute==30 ist). :-)

von Simon H. (simon24j)


Lesenswert?

ja so hätt ichs eigentlich auch gemacht, aber die sekunde ist ja eine 
ganze sekunde lang null, keine da speichert er dann sicher öfter wie 
einmal.

von Cyblord -. (cyblord)


Lesenswert?

Schon erschreckend wie manche programmieren. Und das geht dann 3000 
Zeilen so?

von Simon H. (simon24j)


Lesenswert?

hab nie gesagt das ich ein experte bin, und die 3000Zeilen 
funktionieren,
hab 100% Bruterfolg und die Temperatur im Brutautomaten wird auf 0,1°C 
genau gehalten (Phasenabschnittdimmer) und PID regelung.
ob man den Code auf 1000Zeilen verkürzen kann, vermutlich ja :-)

von Eliza (Gast)


Lesenswert?

Ich glaube, simon24j ist ein neues IQ<10 Simulationsprogramm.

von Simon H. (simon24j)


Lesenswert?

schön das man statt Antworten auf die Frage, nur Blödsinn als Antwort 
bekommt.
Konstruktive Kritik gerne erwünscht, will ja dazulernen, aber solche 
arten von Antworten helfen dabei nicht weiter!

von Eliza (Gast)


Lesenswert?

Simon H. schrieb:
> Konstruktive Kritik gerne erwünscht, will ja dazulernen

Lern nicht dazu. Vergiss erst mal, was du zu können meinst. Fang dann 
von vorne an. Wäre Radieschen züchten nicht auch ein schönes Hobby?

von Simon H. (simon24j)


Lesenswert?

Eliza schrieb:
> Wäre Radieschen züchten nicht auch ein schönes Hobby?

Zum Radieschen anbauen is schon zu warm, das macht man im Frühjahr!!

von Falk B. (falk)


Lesenswert?

@ npn (Gast)

>> if Minute = 30 and sekunde = 0 then

>Da speichert er aber nur alle 60min (wenn eben die Minute==30 ist). :-)

Aufmerksamkeitstest bestanden. Wie man das alle 30min macht, ist eine 
Aufgabe för den Schöööler.

von Falk B. (falk)


Lesenswert?

@ Simon H. (simon24j)

>ja so hätt ichs eigentlich auch gemacht, aber die sekunde ist ja eine
>ganze sekunde lang null, keine da speichert er dann sicher öfter wie
>einmal.

Nö, wenn man die Speicherroutine an der richtigen Stelle aufruft, wird 
nur einmal gespeichert. Oder man setzt ein Flag, das dann beim Speichern 
gelöscht wird.

In der Uhr

if (minute=30 or minute =0 ) and sekunde =0 then flag=1


Beim Speichern

if flag = 1 then
  flag = 0
  Speichern
end if

von Simon H. (simon24j)


Lesenswert?

mhhh sehe ich das falsch oder kommt das aufs selbe hin?
das flag wird dann innerhalb der sekunde wieder 1 und die routine 
speichert ein weiteres mal!?!?

von Falk B. (falk)


Lesenswert?

@ Simon H. (simon24j)

>mhhh sehe ich das falsch

JA!

>oder kommt das aufs selbe hin?

NEIN!

>das flag wird dann innerhalb der sekunde wieder 1 und die routine
>speichert ein weiteres mal!?!?

Warum sollte das Flag mehrmal pro Sekunde 1 werden, wenn deine Uhr nur 
einmal pro Sekunde über sectic aufgerufen wird?

von Simon H. (simon24j)


Lesenswert?

Tja, hast natürlich vollkommen recht.

Besten Dank

von omg (Gast)


Lesenswert?

> Man nimmt eine 32 Bit Variabel und zählt normal runter
>
> time32--;

 Oder man macht es so wie du es gemacht hast, indem man Sekunden Minuten 
Stunden in jeweis einem Byte speichert. daran ist absolut nichts 
verkehrt, es hat sogar enorme Vorteile. z.B. spart man sich die teuren 
zeitaufwändigen Umrechnungen, pro Sekunde wenn man die Daten sowieso 
anzeigen will.
Damit brauchst du in 59 Sekunden nur eine Addition und ein Vergleich.
Nur jede Minuet wird es mal etwas mehr.
 Würde dann ungefähr so aussehen.
 if (Sekunden > 0) then Sekunden = Sekunden -1 ;
 else
   Sekunden = 59 ;
   if ( Minuten > 0) then Minuten = Minuten = -1 ;
   else     .. Schachteln)
      Minuten = 59
      .. hier stunden, ggf tage usw hinmachen..

      .. im letzten else ist auch die Bedingung erfüllt das der Zähler 
abgelaufen ist da alles Null ist.
      -- hier alle fi (oder end if bei dir)
   fi
 fi
 Du benötigst viel weniger Rechenleistung, als wenn du die Zeit jede 
Sekunde umrechen müßtest. Zählst du nur verdeckt runter, also ohne 
anzuzeigen, kannst du das auch mit der long machen. Kommt immer darauf 
an was man mit der Uhrzeit anstellst.
 Die Aussage "Man nimmt" ist einfach falsch. Dein Ansatz war durchaus 
brauchbar, auch wenn man ihn noch optimieren sollte spric die >60 
Abfrage ist nicht so sauber. Auch die Abfrage ob alles Null ist, muß man 
nicht am Anfang machen, sondern sie ergibt sich von selber, im letzten 
else.

 Du könntest die auch eine RTC anschliessen, das hätte den Vorteil, du 
könntest jede Sekunde deine Daten reinschreiben da sie RAM hat, der 
Batteriegepuffert ist. Könntest auch die Endzeit dort einfach eintragen, 
dann mußt du gar nichts aktualisieren, da sie ja konstant ist. Wenn die 
Zeit abgelaufen ist kannt du einen IRQ erzeugen lassen. Oder nutzt sie 
einfach parallel laufen lassen. Sollte der uC mal ausfallen oder 
resetten stehen alle Daten die du brauchst da drin, und die Uhrzeit 
läuft auch weiter.

von Simon H. (simon24j)


Lesenswert?

Hallo OMG,

besten Dank für deinen Beitrag, das mit der Rechenleistung hab ich mir 
fast gedacht, und ich zeige die Restzeit ständig auf nem Touch an.
Danke für deine Bestätigung und Verbesserungsvorschlag zu meinem Code.

von Uwe (Gast)


Lesenswert?

Hi,
>auch wenn man ihn noch optimieren sollte spric die >=60 Abfrage ist nicht >so 
sauber
oh doch, die Abfrage ist sauber wenn "sekunden_schlupf " unsigniert ist.
Aus asm-Sicht wäre >59 allerdings günstiger.
Die 3 Tage Abweichung sind allerdings komisch und sollten nicht in 
deinem Couter entstehen.

viel Erfolg, Uwe

von Franz Furz (Gast)


Lesenswert?

Vielleicht sind die 3000 Zeilen Code ja auch einfach nur so 
rechenintensiv, das der Programmteil, der die Zeiten runter zählt, nicht 
oft genug ausgeführt werden kann und ein paar sectics verloren gehen.
Oder anders ausgedrpckt: Die Temperaturregelung und der Countdown laufen 
länger als 1 Sekunde, dadurch gehen schlicht und ergreifend tics 
verloren.

Das lässt sich aber nur dann herausfinden, wenn man den komplettten Cod 
ekennt.

von Programmieranfänger (Gast)


Lesenswert?

Ich kann zwar nicht programmieren, aber ganz so miserabel wie Simon bin 
ich darin denn doch nicht.

Was ist das für ein Schwachsinn? Deine Schlüpfe werden nur 
dekrementiert, aber du testest immer wieder auf >=60 bzw. >=24.

Logisches Denkvermögen ist nicht so ganz dein Ding, was?

von Karl H. (kbuchegg)


Lesenswert?

Programmieranfänger schrieb:
> Ich kann zwar nicht programmieren, aber ganz so miserabel wie Simon bin
> ich darin denn doch nicht.
>
> Was ist das für ein Schwachsinn? Deine Schlüpfe werden nur
> dekrementiert, aber du testest immer wieder auf >=60 bzw. >=24.

Du hast offensichtlich nicht geschnallt, das er auf den Underflow aus 
ist.
Dekrementierst du eine unsigned Variable mit 8 Bit, dann passiert was?
1
  .., 5, 4, 3, 2, 1, 0, 255, 254, 253, ....

nach 0 kommt also die größtmögliche Zahl, die mit dieser Bitbreite 
möglich ist. Definitiv größer als 60

von Programmieranfänger (Gast)


Lesenswert?

Ja und? Unlogischer gehts doch nicht, oder was willst du mir nun sagen?

Abgesehen davon überspringt er jeden Tag eine Stunde, jede Stunde eine 
Minute usw.

von Peter D. (peda)


Lesenswert?

Karl Heinz schrieb:
> Du hast offensichtlich nicht geschnallt, das er auf den Underflow aus
> ist.

Deshalb sollte man es besser lesbar schreiben:

omg schrieb:
> if (Sekunden > 0) then Sekunden = Sekunden -1 ;
>  else
>    Sekunden = 59 ;
>    if ( Minuten > 0) then Minuten = Minuten = -1 ;
>    else     .. Schachteln)
>       Minuten = 59
>       .. hier stunden, ggf tage usw hinmachen..

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.