Countdown für Brutautomat über mehrere Tag mit Bascom

#3717409
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
#3717412
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.
#3717419
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.
#3717420
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
#3717423
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.
#3717428
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;
#3717429
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
#3717481
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 :-(
#3717498
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
#3717650
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
#3717708
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?
Gast #3718175
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.
Gast #3718343
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
Gast #3718639
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.
Gast #3718928
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?
#3718930
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren