Avatar billede js_delphi Nybegynder
26. juli 2004 - 16:26 Der er 39 kommentarer og
2 løsninger

Tegning af kurve ved temperaturmåling.

Eksperthjælp søges!

Jeg er ved at lave et program til opsamling af måledata fra en temperaturføler.
Indtil videre bliver temperaturen vist ved hjælp af en label,
men det skulle gerne være muligt at se temperatur udviklingen, f.eks. over de sidste 2 minutter.
Dette skal ske ved, at der bliver tegnet en ”real time” kurve (i stil med en løgndetektor),
hvor ”papiret” bevæger sig. Skalleringen af X og Y aksen skal være programmerbar, således at der kan vælges f.eks. 10 sek. i stedet for de 2 min. osv. Til sidst skal det være muligt at gemme målingen (ikke kun grafisk, men også alle måledata), såledet, at den kan hentes frem igen på et senere tidspunkt.

Den aktuelle temperatur ligger i et word.

Hvordan laver man sådan en ”trendviewer”, og hvordan gemmes de målte data?

Det vil selvfølgelig være fedt med konkrete informationer til projektet, men ellers links til noget brugeligt.

Jeg bruger Delphi 7.

Pft.
Avatar billede borrisholt Novice
26. juli 2004 - 16:55 #1
Start med at ligge det i et Dataset, en memtabel.så klarer vi resten. Hvis ikke du har en memtable, så find en på torry.

Bare et simpelt er : med en tid (TDateTime) og en Værdi.

Kan du ikke lave en Text fil med måleresultaster, og tid i og dense til jens@borrisholt.com

Jens B
Avatar billede js_delphi Nybegynder
26. juli 2004 - 18:51 #2
Jeg har downloadet en memtabel, og sendt den per mail sammen med en .txt fil med måledata (tid + værdier).

Kan du give en kort beskrivelse af, hvad en memtabel er, da jeg ikke er så skarp til Delphi programmering :.)
Avatar billede stoney Nybegynder
26. juli 2004 - 19:00 #3
Kan du ikke prøve at paste lidt af din .txt fil med måledata her

Stoney
Avatar billede js_delphi Nybegynder
26. juli 2004 - 19:06 #4
Værsgo..
Nedenstående er ikke frembragt af Delphi, men af et andet måleprogram.
Er det sådan noget lignende, jeg skal have frem, før jeg kan generere en kurve?


Time    Chan A    Chan C    Chan E   
22.33    70.2    2    1183   
22.34    69.7    2    1192   
22.35    70.2    2    1197   
22.36    69.7    2    1181   
22.37    70.2    2    1185   
22.38    70.2    2    1185   
22.39    69.7    2    1188   
22.40    70.2    2    1196   
22.41    70.2    2    1179   
22.42    70.6    2    1174   
22.43    70.2    2    1190   
22.44    69.7    2    1190   
22.45    70.2    2    1196   
22.46    70.2    2    1179   
22.47    70.2    2    1176   
22.48    69.7    2    1191   
22.49    70.2    2    1188   
22.50    70.6    2    1194   
22.51    69.7    2    1190   
22.52    70.2    2    1174   
22.53    70.2    2    1190   
22.54    69.7    2    1192   
22.55    70.2    2    1194   
22.56    69.7    2    1188   
22.57    70.2    2    1177   
22.58    70.2    2    1196   
22.59    69.7    2    1190   
22.60    70.2    2    1194   
22.61    69.7    2    1191   
22.62    70.2    2    1176   
22.63    69.7    2    1194   
22.64    70.2    2    1187   
22.65    70.2    2    1196   
22.66    70.2    2    1183   
22.67    70.2    2    1183   
22.68    70.2    2    1194   
22.69    69.7    2    1188   
22.70    70.2    2    1190   
22.71    69.7    2    1181   
22.72    69.7    2    1182   
22.73    70.2    2    1190   
22.74    70.2    2    1196
Avatar billede stoney Nybegynder
26. juli 2004 - 19:25 #5
Jeg er ikke helt med, du vil have mulighed for at kunne se de sidste 10 sekunder, men dit måleprogram læser kun temp. 1 gang i minuttet.

Stoney
Avatar billede js_delphi Nybegynder
26. juli 2004 - 19:29 #6
Skulle jeg måske have forklaret lidt bedre...

"Time" er i sek, hvilket vil sige, at ovenstående måleserie er målt 100 gange i sekundet.
Avatar billede ruma1974 Nybegynder
26. juli 2004 - 23:19 #7
Du kan bruge Chart til dit formål f.eks. Teechart er nem at bruge

Du kan naturligvis også plotte direkte på en paintbox - det er der selvfølgelig lidt arbejde i.
Avatar billede borrisholt Novice
27. juli 2004 - 11:13 #8
http://borrisholt.com/Eksperten/Temp%20Graf.zip

Den benytter KbmMemTable v.3.01, som er gratis og god.
http://www.torry.net/quicksearchd.php?String=memtable&Title=Yes

Her fra er det blot at få din graf moslet på plads, men så er der også lidt til dig.

Jens B
Avatar billede js_delphi Nybegynder
27. juli 2004 - 11:58 #9
Tak for det!

Jeg tester det af i dag og i morgen, og så vender jeg tilbage.
Avatar billede js_delphi Nybegynder
27. juli 2004 - 13:36 #10
-> Borrisholt. Jeg har downloadet kbmMemTable v.3.01, og lagt alle filerne i samme mappe som indeholder filerne du har lavet.
Når jeg så forsøger at køre projektet fra Delphi, viser compileren "Undeclared identifier" + andre fejl gennem hele unit "kbmMemTable".
Når jeg følger installation.txt filens beskrivelse af, hvordan kbmMemTable skal indstalleres, får jeg her en
"read error on 'c:\programme\borland\delphi\Lib\vcl.dcp" fejl.

Hvis jeg åbner Projekt1.exe filen direkte, kører projektet uden problemer.

Håber du forstår, hvad jeg mener, og kan forklare, hvad der er galt!
Avatar billede stoney Nybegynder
27. juli 2004 - 19:16 #11
ellers prøv denne.
Den er dog ikke så hurtig som Borrisholt's, men til gengæld uden 3. parts
komponenter.

www.tradestone.dk/eks523370.zip

Stoney
Avatar billede js_delphi Nybegynder
28. juli 2004 - 00:34 #12
->Stoney.
Det ser overskueligt ud :-)

Det, jeg skal bruge i sidste ende, er dog en ”real time” opdatering af temperaturen, således, at grafens baggrund hele tiden bevæger sig mod venstre (evt. mod højre), og kurven derved altid viser f.eks. de sidste 10 sek.(skal være valgbart) opdatering (i stil med en løgndetektor eller jordskælvdetektor(!), hvor papiret bevæger sig).

Temperaturen ligger som et word, der bliver opdateret 100 gange i sek. i Delphi programmet. Det vil sige, at opdateringen allerede foregår med en timer, og skal således ”bare” skives til en eller anden form for liste, og vises som en graf.
Jeg kom et godt stykke længere med de sidste forslag, men mangler stadigvaek det med ”real time” opdateringen. Er det noget du/I har tid/lyst til at kigge på? :-)

Hvad mener du i øvrigt med, at din løsning ikke er så hurtig som Borrisholts?
Avatar billede stoney Nybegynder
28. juli 2004 - 01:54 #13
Hvad mener du med "Temperaturen ligger som et word" ?
Den Tstringlist jeg har lavet adder du bare nye målinger til og læser listen
bagfra med (tid * 100) alt sammen pakket ind i en timer.

Vedr. hastighed så er Borrisholt's hurtigere end min, man opdager det
bare ikke med dagens PC'ere. Men du kan prøve at måle med Gettickcount.

Stoney
Avatar billede js_delphi Nybegynder
28. juli 2004 - 03:20 #14
Jeg mener, at dataformatet er et word (temperaturen ligger i dette tilfælde som en 12 bits værdi, dvs. mellem 0 og 4096), som jeg så efterfølgende skallere om til at vise temperaturen i grader celcius (float).

Når du skriver, at jeg skal lægge nye målinger til, bliver de nye målinger vel bare vist sammen med de "gamle", således at det man ser på skærmen ikke altid kun er f.eks. de sidste 10 sek?
Ligesom hvis jeg trykker flere gange på knappen "Indlæs", bliver de indlæste målinger lagt til de eksisterende på skærmen, i stedet for at erstatte dem.

Som du selv er inde på, kan man vel bare læse listen bagfra, og så definere, hvor mange sekunder man vil tage med af listen.
Avatar billede stoney Nybegynder
28. juli 2004 - 03:26 #15
Du skal bare rydde/cleare grafen inden du indlæser igen.

Stoney
Avatar billede stoney Nybegynder
28. juli 2004 - 03:28 #16
altså via en timer, så får du en "real time" trend

Stoney
Avatar billede borrisholt Novice
28. juli 2004 - 08:39 #17
Stoney>> Dit eksempel er meget godt, men jeg vil lige angribe et enkelt punkt.

Jeg bryder mig ikke om du piller i DecimalSeparatoren det er en uskik, og en levn fra gamle dage, hvor man ikke havde TFormatSettings. js_Delphi nævner eksplisit Delphi 7, og derfor bruger jeg TFormatSettings. I øvrigt er det Thread safe, hvilket ikke er en uvæsenlig parameter.

js_delphi>> Hvis instalation af komponenter volder dig problemer, kan jeg godt lave en version hvor man sætter den på dynamisk, men jeg synes nu det er det bedste at du finder ud af hvordan man instalerer dem ;) En TMemTable kan bruges til mange ting !

Jens B
Avatar billede borrisholt Novice
28. juli 2004 - 08:55 #18
Du kan iøvrigt Scrolle med din Chart sådan her :
  chart1.BottomAxis.Scroll(10, false);

Jens B
Avatar billede hrc Mester
28. juli 2004 - 10:32 #19
Borrisholt:

1. Hvorfor skal han overhovedet bruge en memtable? Er temperaturer ikke noget man plejer at banke i en (filbaseret)tabel for derefter at køre en query på data? Men ja, en memtabel er en fin lille tingest.

2. Hvad er det der er galt med DecimalSeparatoren? Jeg plejer selv at bruge denne opbygning:

  OldDecSep := DecimalSeparator;
  DecimalSeparator := '.';
  try
    // ... En query der arbejder med decimaltal
  finally
    DecimalSeparator := OldDecSep;
  end;

Hvordan ser din løsning ud?
Avatar billede js_delphi Nybegynder
28. juli 2004 - 11:21 #20
Er først lige kommet til Pc'en.
Jeg kigger lige på sagerne, og vender så tilbage...
Avatar billede borrisholt Novice
28. juli 2004 - 11:43 #21
hrc>
1)
  Jeg vil bruge en Database, fordi så kunne man smide det direkte i et Chart ting, og lave databehandling på dem senere. Det der med først at impotere dem fra en fil var noget jeg lavede fordi jeg ingen Live målinger har.

2)
  Download mit eksempel og se. Den vil sikkert brokke sig over du ikke har TMemTable instaleret, men bare ignorer det, fordi det er jo det andet du er kommet efter. Det er lidt lettere at se hvad jeg mener me rigtig kode.

Jens B
Avatar billede js_delphi Nybegynder
28. juli 2004 - 12:33 #22
-> Stoney: Det med at rydde charten var jo meget logisk - bare ikke for mig...
Jeg mangler stadigvæk muligheden for at bestemme, hvor mange af de sidste målinger (eller sek.) jeg vil have med fra listen. Så vidt jeg kan forstå, indlæser den hele textfilen, som programmet kører nu.
En andet ting er, at jeg på et eller andet tidspunkt skal til at se på, hvordan jeg får de nye målinger skrevet til denne liste!

-> Borrisholt: Hvad mener du med en version, "hvor man sætter den på dynamisk"?
Mht. problemerne ved at bruge "decimalSeparatoren": er det mere usikkert at bruge denne metode (bliver programmet mere ustabilt - læs: går ned), eller hvori ligger problemerne?
Jeg synes umiddelbart Stoneys metode virker enklest, men når jeg på et senere tidspunkt skal til at gemme mine målinger, udskrive osv., kan det måske være, at din metode er den rigtige. Hvad siger du til det?
 
Ps. det med scroll funktionen er kanon!
Avatar billede stoney Nybegynder
28. juli 2004 - 12:46 #23
Jeg troede du fik målingerne fra et delphi program.
Nå, men hvis du vil læse de nyeste målinger læser du filen bagfra på denne
måde:

Ændre denne linie for i := 1 to sl.Count -1 do 
til
for i:= sl.Count-1 downto (sekunder * 100) do


Hvis du får målingerne fra et delphi program ligger du bare målingerne
i en Tstringlist og læser direkte fra memory i stedet for en txt fil.
Det går også meget hurtiger.

Stoney
Avatar billede js_delphi Nybegynder
28. juli 2004 - 13:51 #24
-> Stoney:

Ændringen i linien medfører, at hvis alle målingerne i .txt filen er 15 sek. i alt, og jeg skriver 10 sek. i linien "for i:= sl.Count-1 downto (sekunder * 100) do",
så får jeg de sidste 5 sek. at se på kurven.
Dvs., det tal jeg skriver, angiver hvor mange sek. af starten, jeg ikke vil have med.
 

Ang. hvor målingerne kommer fra:

som udgangspunkt eksisterer der slet ikke nogen .txt fil.
Hver gang "procedure TForm1.Timer1Timer(Sender: TObject);" bliver aktiveret, læses værdien af integer "Temperatur". Lige så snart værdien er blevet læst, skal den gemmes et eller andet sted (i RAM eller på harddisk, hvad ved jeg...).
Næste gang "procedure TForm1.Timer1Timer(Sender: TObject);" bliver aktiveret, læses værdien igen, og denne gang gemmes værdien det samme sted, men selvfølgelig som en ny linie.   
Delphi læser hele tiden værdierne fra dette sted, og opdaterer dermed kurven.

Når man så vælger at stoppe timeren (enable := false), stopper opdataringen af målingerne selvfølgelig. Når det er gjort, skal det være muligt at gemme de målte data, evt. som en .txt fil.

Hvis man på et senere tidspunkt så ønsker at se en gammel måling, skal denne, klart nok, læses fra den gemte .txt fil.

Sorry, hvis jeg ikke har beskrevet det godt nok tidligere..
Avatar billede stoney Nybegynder
28. juli 2004 - 14:38 #25
Så mu du læse den forfra.
Jeg gik ud fra at sidste måling er/var sidste i linie i txt filen.

Er det helt sikkert at dine målinger ser sådanne ud
Time    Chan A    Chan C    Chan E   
22.33    70.2    2    1183   
22.34    69.7    2    1192   
22.35    70.2    2    1197 

Altså 4 oplysninger pr måling.
Jeg spørger for at kunne lave et andet eks.
Skal det gemmes i en txt fil eller database ?

Stoney
Avatar billede js_delphi Nybegynder
28. juli 2004 - 15:55 #26
Sidste måling er sidste linie i .txt filen.

Hvordan målingerne ser ud, afhænger af, hvordan det laves i Delphi, da Delphi programmet jo aflæser temperaturen, og derefter genererer listen.
Jeg kunne forestille mig, at denne liste så sådan ud:

Time  ChanA    ChanB    ChanC    ChanD
00.00  70.8      20.1      -        -
00.01  70.9      20.6      -        -
00.02  70.2      20.4      -        -
00.03  70.5      20.6      -        -

Første linie bliver genereret første gang "procedure TForm1.Timer1Timer(Sender: TObject);" bliver aktiveret

Anden linie anden gang "procedure TForm1.Timer1Timer(Sender: TObject);" bliver aktiveret
osv.

Værdierne i kollone "ChanA", er temperaturen i en ovn, og bliver læst fra et word (integer) i Delphi programmet.

Værdierne i kollone "ChanB", er temperaturen uden for ovnen, og bliver læst fra et andet word (integer) i Delphi programmet.

I første omgang behøves der kun at tages hensyn til "ChanA", da jeg efterfølgende selv kan tilføje resten (håber jeg...).

Hvis brugeren vælger at gemme målingerne, efter han har stoppet opdateringen, er det fint med mig, hvis de bliver gemt som en .txt fil, eller noget andet standart, som f.eks. .csv (kommasepareret).
 
Den .txt fil jeg har sendt til dig, er genereret af et andet måleprogram, som jeg slet ikke skal bruge i denne sammenhæng.
Avatar billede js_delphi Nybegynder
28. juli 2004 - 16:25 #27
Forlader Pc'en et par timer - tilbage omkring kl. 19.
Avatar billede stoney Nybegynder
28. juli 2004 - 18:44 #28
www.tradestone.dk/eks523370V2.zip

Nu burde du kunne klare resten selv :-)

Stoney
Avatar billede js_delphi Nybegynder
28. juli 2004 - 22:05 #29
Det ser sgu godt ud!
Men...
De nye data bliver stadigvæk "lagt til"  de data, som i forvejen ligger i sl.
Det betyder, at sl bliver længere og længere, jo længere tid opdateringen kører.
Er det ikke muligt at bestemme mængden af data, sl må indeholde, således, at hvis man har valgt f.eks. 10 sek. i en editbox, bliver lænden af BottomAxis (på charten) ikke længere end de 10 sek? Dvs., når de 10 sek. er fyldt ud, bliver de nye målinger stadigvæk lagt til sl, mens de ældste målinger i sl "ryger ud".

Håber du gider bruge lidt tid på ovennævnte, da jeg derefter selv kan komme videre!!

Jeg må hellere forhøje til 200 point - er det ikke det, man max må give?
Avatar billede stoney Nybegynder
28. juli 2004 - 22:28 #30
knald en edit på formen og ændre koden på timeren til

procedure TForm1.Timer1Timer(Sender: TObject);

var

i : integer;
min,max : real;
begin
chart1.SeriesList.Series[0].Clear;
min := 5000;
max := -5000;
sl.Add(floattostr(RandExt(71)));
if (sl.Count > (strtoint(edit1.Text)*100)) then
begin
for i := 0 to (sl.Count -(strtoint(edit1.Text)*100)-1)  do
sl.Delete(i);
end;

for i := 0 to sl.Count -1 do
  begin


  if max < strtofloat(sl[i]) then
  max := strtofloat(sl[i]);
    if min > strtofloat(sl[i]) then
  min := strtofloat(sl[i]);

  chart1.SeriesList.Series[0].AddY(strtofloat(sl[i]),'',clgreen);




  end;
  chart1.Title.Text.Text := inttostr(sl.Count) + ' målinger ' + 'Max: ' + floattostr(max) + '  Min: ' + floattostr(min);

  chart1.LeftAxis.Maximum := max + 0.1;
  chart1.LeftAxis.Minimum := min - 0.1;

end;

Stoney
Avatar billede stoney Nybegynder
28. juli 2004 - 22:35 #31
Hvis du giver point vil jeg da også sætte pris på lidt karma :-)

Stoney
Avatar billede js_delphi Nybegynder
28. juli 2004 - 22:58 #32
-> Stoney:
Det virker jo perfekt, tusind tak for ulejligheden!
Jeg læser lige lidt på, hvordan man fordeler point, da Borrisholt også lige får et par stykker for sine forslag.
Er 185/15 i orden med dig?

Karma er givet!
Avatar billede js_delphi Nybegynder
28. juli 2004 - 23:31 #33
Hva' dælen...
Jo længere tid opdateringen kører, desto langsomere kører timeren!
Kan det laves om, da opdateringstiden (10mSek) meget gerne skulle være konstant?
Avatar billede stoney Nybegynder
28. juli 2004 - 23:45 #34
Det forstår jeg ikke.
Min kører upåklageligt og med konstant memory forbrug.
Jeg kører XP, hvad kører du ?

Stoney
Avatar billede js_delphi Nybegynder
29. juli 2004 - 00:03 #35
Ligeledes XP.
CPU belastningen stiger fra 1 til 100 % i løbet af ca. 10 sek., når jeg kører med en opdateringstid på 10 mSek.
Sætter jeg opdateringstiden til 100 mSek., er belastningen steget til 40 % efter 500 sek., og den stiger stadigvæk. Men indtil videre er opdateringstiden (100 mSek) stabil.
Avatar billede stoney Nybegynder
29. juli 2004 - 00:16 #36
Nåh, jeg troede du mente grafen hakkede i det.
Min bruger også ca 100% CPU.
Den thread der er i Timeren er vist ikke helt stueren.
Ellers skal du til at kigge på Setpriorityclass

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/setpriorityclass.asp

Om du kan "overrule" thread processen i timeren ved jeg ikke, men man kan
sætte prioteten på en alm. exe fil om end der ikke er så meget at vælge i mellem.

Stoney
Avatar billede js_delphi Nybegynder
29. juli 2004 - 00:20 #37
Opdateringstiden begynder først at blive længere, når CPU belastningen har nået 100 %.
Når jeg kører programmet på en anden, og langsomere, PC (med Windows 98), er opdateringstiden fra starten længere (ca. 20 mSek), og bliver så først endnu længere, når CPU belastningen har nået 100 %.
Avatar billede js_delphi Nybegynder
29. juli 2004 - 00:25 #38
Allright, så det er ikke fordi, der er lavet noget fusker-programmering i selve programmet?
Avatar billede stoney Nybegynder
29. juli 2004 - 00:42 #39
Jeg tror du lader dig snyde af et optisk bedrag.
Lad os sige graffen skal plotte 100 målinger.
Det gør den på samme areal som ved 2000 målinger.
Der for ser det ud som om den arbejder hurtiger i starten.
Så når den når max antal målinger skal den "flytte" stregerne et kortere stykke.

Stoney
Avatar billede js_delphi Nybegynder
29. juli 2004 - 01:04 #40
Oven over grafen står der, hvor mange målinger, der ligger i sl.
De første ca. 10 sek. kan man se, at den rigtig nok tæller 100 målinger pr. sek.
Når CPU'en så arbejder 100 %, er det tydeligt at se, at opdateringen bliver langsomere.
Er det ikke lidt mærkeligt, at opdateringtiden (10 mSek) ikke overholdes på en langsomere PC, selvom CPU'en ikke arbejder 100 %?
Avatar billede js_delphi Nybegynder
29. juli 2004 - 09:05 #41
Man kan åbenbart kun give det antal point, som man angivede, da man stillede spørgsmålet.
-> Stoney: jeg har oprettet et nyt spørgsmål til dig, så du kan få de sidste 65 point (og jeg kan få et svar...).
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester