Guten morgen,
ich bin gerade dabei einen ersten Bargraph auf den TFT zu bringen.
So soll es werden.
Aller 15 Sekunden wird die Temperatur gemessen und in "int TempLesen"
übergeben und gleichzeitig in das Array "byte Temp[10];" auf das erste
Element "Temp[0]; übergeben. ABER, vorher sollen die Werte alle um eine
Stelle nach Rechts verschoben werden.
Also z.b so:
vor dem schieben Temp[] = 12,14,15,17,20
nach dem schieben Temp[] = 11,12,14,15,17 neu ist die 11 und die 20 soll
wegfallen!
Das ganze hatte ich mir so überlegt:
Das Problem ist aber, dass das ganze Array mit der gleichen Zahl
beschrieben wird!
Jetzt habe ich gegooglt und finde paar Sachen mit einer for-schleife
aber so richtig schlau werde ich dabei nicht! Vlt hat ja jemand
Denkanstöße
Eine Schleife ist Kosmetik.
Kann man später drüber reden.
Schau dir mal an was dein Code macht.
Du schreibst die Zahl x von Arrayposition 4 nach 3. Von 3 nach 2... usw.
Das erklärt dein Ergebnis.
Allerdings sollte an Position 0 dann wirklich deine ausgelesene
Temperatur stehen.
Martin T. schrieb:> if(Sekunde==15 || Sekunde==30|| Sekunde==45 || Sekunde==0)
Du bist sicher, dass die Schleife pro Sekunde nur einmal durchlaufen
wird?
Martin T. schrieb:> Temp[4]= Temp[3];> Temp[3]= Temp[2];> Temp[2]= Temp[1];> Temp[1]= Temp[0];> Temp[0]= TempRead;
Der Fehler liegt in dem Teil des Codes den du nicht gepostet hast.
Die klassische Lösung für dein Problem wäre ein Ringpuffer.
Dann zeig doch mal den fehlerhaften Code.
Zu Testzwecken kannst du ja mal Temp[0]= Sekunde; schreiben, denn die
scheint sich ja zu ändern.
Schau dir mal einen Ringbuffer an.
Phil J. schrieb:> Eine Schleife ist Kosmetik.> Kann man später drüber reden.>> Schau dir mal an was dein Code macht.>> Du schreibst die Zahl x von Arrayposition 4 nach 3. Von 3 nach 2... usw.> Das erklärt dein Ergebnis.> Allerdings sollte an Position 0 dann wirklich deine ausgelesene> Temperatur stehen.
Hmmm...hab ich nen Denkfehler?
Wert[5] übernimmt Wert[4] -> Wert[4] den Wert[3]...usw!
Und das es ja eine if Funktion ist wird das ganze nur einmal gemacht
also müsste das doch klappen.... verstehe ich gerade nicht! :(
Der Andere schrieb:> Die klassische Lösung für dein Problem wäre ein Ringpuffer.
Ob sich der lohnt, bei 10 Bytes, die alle 15 Sekunden mal verschoben
werden sollen?
Wie mein Vorredner schon angedeutet hat, überschreibst du deine Werte.
Wenn du das so machen willst, musst die die Daten temporät
zwischenspeichern, bevor du diese neu zuordnest.
Einfach geht es, wenn du das von hinten aufrollst, da ein letzter Wert
ja wegfallen soll:
Martin T. schrieb:> loop...>> if(Sekunde==15 || Sekunde==30|| Sekunde==45 || Sekunde==0)> {
Wahrscheinlich wird die "loop" Schleife mehrere 100 (1000) mal
durchlaufen während Sekunde== 15 oder ... ist. Wenn TempRead aber nur
einmal gesetzt wurde steht im ganzen Array dann TempRead drin.
Siehe meine Frage oben:
Der Andere schrieb:> Du bist sicher, dass die Schleife pro Sekunde nur einmal durchlaufen> wird?Martin T. schrieb:> Temp[10]
Und dein Array ist auch 11 Elemente groß? Offset 0 bis Offset 10?
Martin T. schrieb:> Und das es ja eine if Funktion ist wird das ganze nur einmal gemachtDer Andere schrieb:> Du bist sicher, dass die Schleife pro Sekunde nur einmal durchlaufen> wird?
Wirklich ganz sicher? Nur einmal in der Sekunde.
Oder ist die loop Schneller und mehrere Tausend mal in einer Sekunde
durchlaufen?
Phil J. schrieb:> Du schreibst die Zahl x von Arrayposition 4 nach 3. Von 3 nach 2... usw.> Das erklärt dein Ergebnis.
Das ist großer Quatsch. Das Ziel steht links und die Quelle rechts.
Also wird von Position 3 nach Position 4 kopiert.
Dominik B. schrieb:> Einfach geht es, wenn du das von hinten aufrollst, da ein letzter Wert> ja wegfallen soll:> for(int i=4; i>0; i--){> Temp[i] = Temp[i-1];> }> Temp[0] = TempRead;
Ist eleganter macht aber exakt das GLeiche wie der gepostete Code.
if (Sekunde==0...) kann ganz schon oft wahr sein, kommt eben auf den
Restprogramm an.
Ansonsten ist es eigentlich Quatsch, alle Variablen ständig
rumzuschubsen. Benutz doch einfach einen Zeiger.
Temp[index++]=TempRead;
if (index >=sizeof...) index=0;
Martin T. schrieb:> Und das es ja eine if Funktion ist wird das ganze nur einmal gemacht
aber auch nur, wenn die if-Abfrage auch wirklich nur einmal für jeden
Sekundenwert aufgerufen wird, zB wenn sie nur nach einer Änderung des
Sekundenwertes durchlaufen wird. Ansonsten wird sie ja bei 15.000s,
15.001s, 15.002s,... aufgerufen, weil "Sekunde" ja wohl für eine ganze
Sekunde den Wert 15 haben wird. In dieser Sekunde wird dann die ganze
Zeit die Temperatur ausgelesen, und wenn die sich in der einen Sekunde
nicht ändert, hast du natürlich immer denselben Wert eingelesen und in
dem Array verschoben
Martin T. schrieb:> if(Sekunde==15 || Sekunde==30|| Sekunde==45 || Sekunde==0)
Wie lange braucht der Prozessor für den Verschiebe und Schreib Vorgang?
Wenn er langsam ist, ist er nach 1/100s fertig. Und dann beginnt der
nächste Schiebevorgang - immer wieder, bis endlich die Sekunde vorbei
ist.
Wenn sonst nichts zu tun ist, musst du nach dem Verschieben warten, bis
die Sekunde vergangen ist. Das ist für einen Anfänger die einfachste
Lösung. Danach kannst du dann über Flags nachdenken.
Erstmal danke für die ganzen Antworten :D Muss ich jetzt erstmal
sortieren. Stimmt, daran haeb ich nicht gedacht. eine Sekunde ist zwar 1
Sekunde aber der uC macht da weiterhin noch 10.000 Schritte.
Also wenn ich meinen Code nehme und die Schleife wirklich nur einmal
mache dann würde das gehen oder?
Das mit dem FIFO hört sich interessant an...da muss ich mich mal mit
auseinander setzen.
Martin T. schrieb:> Also wenn ich meinen Code nehme und die Schleife wirklich nur einmal> mache dann würde das gehen oder?
Ja.
Martin T. schrieb:> Das mit dem FIFO hört sich interessant an...da muss ich mich mal mit> auseinander setzen.
Deinen Code kann man leicht nachvollziehen und der ist bei 5 Werten auch
in Ordnung.
Wenn du schneller sein musst oder mehr Werte hast, kannst du die anderen
Sachen nehmen.
Allerdings ist das jetzt gerade sehr übersichtlich um die andern
Vorschläge zu verstehen.(ansehen und verstehen, brauchen tust du es hier
nicht)
Phil J. schrieb:> Du schreibst die Zahl x von Arrayposition 4 nach 3. Von 3 nach 2... usw.
Na hier sind ja Profis unterwegs.
So geht es
[/c]
byte SekundeGeschoben=0;
setup..
loop...
if(Sekunde!=SekundeGeschoben && (Sekunde==15 || Sekunde==30||
Sekunde==45 || Sekunde==0))
{
.
.
.
Temp[4]= Temp[3];
Temp[3]= Temp[2];
Temp[2]= Temp[1];
Temp[1]= Temp[0];
Temp[0]= TempRead;
SekundeGeschoben = Sekunde;
}
[/c]
wird das Problem lösen aber besser ist:
Habe es jetzt mal ausprobiert aber nicht mit einen Sensor sondern
Seriell.
Ich denke das ist für mich die einfachste Lösung. :) Das klappt
wunderbar und da mein Array max. 10 groß wird reichts aus.
1
bytetemp[6];//Array für die Temperaturdaten
2
bytetempRead;//Variable zum vorspeichern
3
4
bytestat=2;//Status-Variable damit die if Schleife nur einmal abläuft
5
6
voidsetup()
7
{
8
Serial.begin(19200);
9
}
10
11
voidloop()
12
{
13
if(Serial.available())
14
{
15
tempRead=Serial.parseInt();//Serielle Daten empf. und an tempRead übergeben
16
Serial.println("Seriell Empfangen! - ");
17
stat=1;//Status auf 1 setzen
18
}
19
20
if(stat==1)//Wenn Status 1 dann....
21
{
22
stat=0;//Status auf 0 setzen, somit wird die If-Anweisung nur einmal ausgeführt
Ändert an der Funktion des Programms nichts sollte man aber wissen:
>byte stat = 2; //Status-Variable damit die if Schleife nur einmal abläuft
www.if-schleife.de
Begriffe schrieb:> Ändert an der Funktion des Programms nichts sollte man aber wissen:>>>byte stat = 2; //Status-Variable damit die if Schleife nur einmal abläuft>> www.if-schleife.de
Haaahaaa....dann halt Abfrage! Jedenfalls wird diese dadurch dann nur
einmal ABGEFRAGT!
@ Rolf Magnus (rmagnus)
>> Die klassische Lösung für dein Problem wäre ein Ringpuffer.
Genau.
>Ob sich der lohnt, bei 10 Bytes, die alle 15 Sekunden mal verschoben>werden sollen?
Ja. Erstens weil der OP dabei was lernt und 2. ist die Logik für diesen
Ringpuffer fast schon trivial. Er braucht keine Füllstandserkennung wie
ein FIFO, nur 2 Indizes für Schreib- und Lesezugriff und einfachste
Modulo-Zählung. Wenn man dann die Anzeige schneller, größer, whatever
machen will, kostet das nur wenig CPU-Last. Es gibt schon genug
schlechte Software auf dieser Welt.
Falk B. schrieb:> @ Rolf Magnus (rmagnus)>>>> Die klassische Lösung für dein Problem wäre ein Ringpuffer.>> Genau.>>>Ob sich der lohnt, bei 10 Bytes, die alle 15 Sekunden mal verschoben>>werden sollen?>> Ja. Erstens weil der OP dabei was lernt und 2. ist die Logik für diesen> Ringpuffer fast schon trivial. Er braucht keine Füllstandserkennung wie> ein FIFO, nur 2 Indizes für Schreib- und Lesezugriff und einfachste> Modulo-Zählung. Wenn man dann die Anzeige schneller, größer, whatever> machen will, kostet das nur wenig CPU-Last. Es gibt schon genug> schlechte Software auf dieser Welt.
Hast ja auch recht damit, ich werde mich mal mit beidem beschäftigen.
Aber für meine Zwecke ist das was ich jetzt habe völlig ausreichend. :D
Danke für die tolle Hilfe die man hier immer bekommt.