Schleife durchlaufen und angezeigte Werte aktualisieren

#3758512
Lesenswert?

Hallo,

vorab: Ich bin kein Informatiker und kann nicht so gut programmieren.

Ich durchlaufe eine Schleife so oft, bis Enter gedrückt wird.
Jedes Mal, wenn die Schleife durchlaufen wird, erscheint in diesem 
Konsolenfenster eine neue Zeile mit den aktuellen Werten (siehe Anhang).

Wie ist es nun möglich, dass ich zum Beispiel nur die letzten 3 Zeilen 
darstellen kann (die Werte sollen kontinuierlich erneuert werden) und 
darunter statisch schreiben kann: "Zum Beenden bitte Enter drücken"

Zum Beispiel sowas:

---

Zeit lesen <> schreiben: 0.123 Sekunden - Strom: 0.234 - Umdreh: 0.345
Zeit lesen <> schreiben: 0.345 Sekunden - Strom: 0.987- Umdreh: 0.586
Zeit lesen <> schreiben: 0.678 Sekunden - Strom: 0.475 - Umdreh: 2.485

Zum Beenden bitte Enter drücken

---

Das Ganze wurde bisher in C programmiert.
Kann mir hier jemand weiterhelfen?
Angehängte Dateien:
#3758525
Lesenswert?

Das "Programm" liest von einer NI USB 6009 Karte verschiedene Messwerte 
kontinuierlich ein.

Hier ist nachfolgend die Schleife, die kontinuierlich durchlaufen wird:
(Ich habe es momentan noch mit goto realisiert, das werde ich aber 
demnächst ändern, keine Angst ;) )


1
Schleife:
2

3

4
  prgstart=clock(); //CPU-Zeit zu Beginn des Programmes
5

6
  
7
  /*********************************************/  
8
  // DAQmx Read Code                
9
  /*********************************************/  
10
  DAQmxErrChk (DAQmxReadAnalogF64(Lesen,              //Task to read samples from
11
                        300,            //The number of samples, per channel, to read.(Pro Sekunde)
12
                        -1,              //The amount of time, in seconds, to wait for the function to read the sample(s)
13
                        DAQmx_Val_GroupByChannel,  //Specifies whether or not the samples are interleaved.
14
                        dataread,          //The array to read samples into
15
                        1000,            //The size of the array, in samples, into which samples are read.
16
                        &read,            //The actual number of samples read from each channel.
17
                        NULL));            //Reserved for future use. Pass NULL to this parameter.
18
  
19
  
20
  for ( x = 0; x < 300; x++ ) {  
21
    sum += dataread[x];
22
    datawrite[x]=0;
23
    }
24

25
  datawrite[0]=sum/300; 
26
  sum=0;
27

28
  /////////////////////////////
29

30

31
  for ( y = 300; y < 600; y++ ) {  
32
    summe += dataread[y];
33
    datastrom[y]=0;
34
    }
35

36
  datastrom[300]=summe/300; 
37
  summe=0;
38

39
  
40

41
  /*********************************************/
42
  // DAQmx Write Code
43
  /*********************************************/
44
  DAQmxErrChk (DAQmxWriteAnalogF64(Schreiben,              //Task to write samples to
45
                        1,              //The number of samples, per channel, to write.
46
                        1,              //Specifies whether or not this function automatically starts the task if you do not start it.
47
                        -1,              //The amount of time, in seconds, to wait for this function to write all the samples.
48
                        DAQmx_Val_GroupByChannel,  //Specifies how the samples are arranged
49
                        datawrite,          //The array of 64-bit samples to write to the task.
50
                        NULL,            //The actual number of samples per channel successfully written to the buffer.
51
                        NULL));            //Reserved for future use.
52
  
53
  prgende=clock();//CPU-Zeit am Ende des Programmes
54
  
55
  U=(datawrite[0]*2000)/(330*2)*1.6;
56

57

58
  printf("Zeit lesen <> schreiben: %.4f Sekunden - Strom: %.4f - Umdreh: %.4f \n",(float)(prgende-prgstart)/CLOCKS_PER_SEC, U, datastrom[300]*1.058*1000/4);
59
  
60
  goto Schleife;
61

62

63
  printf("Task wurde geschrieben\n");
Moderator #3758786
Lesenswert?

Früher gingen Dinge wie Cursorpositionierung, bunte Texte und Scrollen
in der Konsole noch ganz einfach mit ANSI-Steuersequenzen, die man in
die Printf-Aufrufe einflechten konnte. Aber das scheint in neueren
Windows-Versionen nicht mehr zu gehen.

Heute muss man dazu wohl die WinAPI-Funktionen bemühen, siehe

  http://msdn.microsoft.com/en-us/library/windows/desktop/ms682073%28v=vs.85%29.aspx

einen Windows-Port der Curses-Bibliothek installieren und verwenden,
siehe

  http://gnuwin32.sourceforge.net/packages/pdcurses.htm

ein Tool installieren, das der Konsole die verlorenen Features wieder
zurückgibt, siehe

  https://github.com/adoxa/ansicon

oder gar eine neue Programmiersprache lernen, siehe

  jz schrieb:
  > Wenn du Visual Studio schon hast, nimm doch C++/CLI.

oder eine GUI-Version des Programms hochziehen, was de facto ebenfalls
das Lernen einer neuen Programmiersprache (und noch einiges darüber
hinaus) impliziert, siehe

  St M schrieb:
  > Und warum nimmst du dann keine grafische Lösung? Ein Label, dass
  > sich immer aktualisiert?


Ich schätze, dass in diesem konkreten Fall die Verwendung der
WinAPI-Funktionen noch das kleinste Übel darstellt.

Die Lösung mit der Curses-Bibliothek hat immerhin noch den Vorteil,
dass diese plattformübergreifend verfügbar ist.
Gast #3758793
Lesenswert?

Yalu X. schrieb:
> Früher gingen Dinge wie Cursorpositionierung, bunte Texte und Scrollen
> in der Konsole noch ganz einfach mit ANSI-Steuersequenzen, die man in
> die Printf-Aufrufe einflechten konnte.

Auf jeden Fall geht noch der "\r" (Zeilenrücklauf). Damit kann man 
zumindest die Ausgabe einer Zeile immer wieder überschreiben.

Aber die Cursorpositionierung, Cursor Up und Home und ähnliches scheint 
nicht mehr zu funktionieren. Hab ich früher mit TurboPascal oft 
gemacht...
Gast #3758807
Lesenswert?

npn schrieb:
> Aber die Cursorpositionierung, Cursor Up und Home und ähnliches scheint
> nicht mehr zu funktionieren. Hab ich früher mit TurboPascal oft
> gemacht...

Heutzutage braucht das (fast) keiner mehr. Da macht man graphisch einen 
rollenden xt-Plot, so dass man immer den Verlauf der letzen Zeit im 
Fenster sieht und hat einen Button in der GUI, der über Hotkey auch per 
Tastatur bedienbar ist.
Gast #3758820
Lesenswert?

pnp schrieb:
> npn schrieb:
>> Aber die Cursorpositionierung, Cursor Up und Home und ähnliches scheint
>> nicht mehr zu funktionieren. Hab ich früher mit TurboPascal oft
>> gemacht...
>
> Heutzutage braucht das (fast) keiner mehr. Da macht man graphisch einen
> rollenden xt-Plot, so dass man immer den Verlauf der letzen Zeit im
> Fenster sieht und hat einen Button in der GUI, der über Hotkey auch per
> Tastatur bedienbar ist.

Hier gehts um eine ganz normale Consolenausgabe. Und da gibts nun mal 
nur Zeilen und Spalten, die mit Zeichen gefüllt werden...

Daß es Grafik gibt und GUIs, hat sich mittlerweile rumgesprochen ;-)

Johannes schrieb:
> ...und kann nicht so gut programmieren.

Es ist doch in Ordnung und überhaupt nichts falsches dran, wenn man 
erstmal Programme mit Konsolenausgabe schreibt und die Grundlagen lernt. 
Später, wenn man besser programmieren kann, ist man auch in der Lage, 
Dinge zu verstehen, die für einen Anfänger reichlich komplex sind. Zum 
Beispiel eine GUI-Programmierung.
Moderator #3758969
Lesenswert?

pnp schrieb:
> Heutzutage braucht das (fast) keiner mehr.

Es ist die gesamte Konsole, die  "fast" keiner mehr braucht. Trotzdem
gibt es sie immer noch. Die wenigen, die sie noch nutzen, wären ganz
froh, wenn die ohnehin schon spärlichen Features nicht immer noch mehr
zusammengestaucht würden. Die Funktionalität des früheren ANSI.SYS
würden, fest integriert in CMD.EXE, dieses vielleicht gerade einmal um
ein paar Hundert Bytes vergrößern. Da wird an anderen Stellen in Windows
für nutzlosere Features deutlich mehr Speicher verschwendet.

Stefan schrieb:
> letzte 3 Werte(paare) merken
> system ("cls");
> ausgeben

Das flackert evtl. ein Bisschen, ist aber dafür eine sehr einfach
umzusetzende Lösung des Problems.
Gast #3759490
Lesenswert?

npn schrieb:
> Yalu X. schrieb:
>> Früher gingen Dinge wie Cursorpositionierung, bunte Texte und Scrollen
>> in der Konsole noch ganz einfach mit ANSI-Steuersequenzen, die man in
>> die Printf-Aufrufe einflechten konnte.
>
> Auf jeden Fall geht noch der "\r" (Zeilenrücklauf). Damit kann man
> zumindest die Ausgabe einer Zeile immer wieder überschreiben.
>
> Aber die Cursorpositionierung, Cursor Up und Home und ähnliches scheint
> nicht mehr zu funktionieren. Hab ich früher mit TurboPascal oft
> gemacht...


Das habe ich jetzt gemacht. Dann belasse ich es vorerst dabei. Habe dann 
eben keine Historie.

Jetzt aber noch zwei weitere Fragen:
Die Zeile wird nun bei jedem Durchlaufen aktualisiert.
1. Wie kann ich nun statisch darunter "Zum Beenden bitte Enter druecken" 
schreiben?
Wenn ich nun mit \n arbeite, schreibt er wieder jede Zeile einzeln 
untereinander.
2. Wie kann ich in der Schleife auf eine Tastatureingabe abfragen, OHNE 
dass er mich bei jedem Durchlauf danach fragt? Er soll einfach so oft 
die Schleife durchlaufen bis ich Enter drücke und dann soll er 
rausspringen.
Mit "if (getchar() )goto Beenden;" geht es nicht, weil er dann jedes Mal 
danach fragt und erst weiter macht, wenn ich Enter drücke.
Gast #3759524
Lesenswert?

1. Mit Standard-C geht das nicht.
C kennt keinen Bildschirm.
Schreib es darüber.

2. Mit Standard-C geht das nicht.
C kennt keine Tastatur.

Es gibt bei MS die Funktionen kbhit() (deklariert in der conio.h) die 
feststellt ob eine Taste gedrückt wurde.
Wenn eine gedrückt wurde, kannst du die dann mit getchar einlesen.


Sonst google doch mal nach "Snake für DOS Konsole". Die haben da meist 
die gleichen Probleme wie du.
Gast #3759547
Lesenswert?

Muster schrieb:
> 2. Wie kann ich in der Schleife auf eine Tastatureingabe abfragen, OHNE
> dass er mich bei jedem Durchlauf danach fragt? Er soll einfach so oft
> die Schleife durchlaufen bis ich Enter drücke und dann soll er
> rausspringen.

Klar geht das. Binde die "windows.h" ein mit
1
#include <windows.h>
und dann kannst du mit
1
if(GetAsyncKeyState(VK_RETURN))
abfragen, ob Return gedrückt worden ist.

Wenn du andere Tasten abfragen willst, kannst du nach "Virtual-Key 
Codes" suchen, da findest du Listen.
Gast #3759611
Lesenswert?

npn schrieb:
> Muster schrieb:
>> 2. Wie kann ich in der Schleife auf eine Tastatureingabe abfragen, OHNE
>> dass er mich bei jedem Durchlauf danach fragt? Er soll einfach so oft
>> die Schleife durchlaufen bis ich Enter drücke und dann soll er
>> rausspringen.
>
> Klar geht das. Binde die "windows.h" ein mit#include <windows.h>
> und dann kannst du mitif(GetAsyncKeyState(VK_RETURN))
> abfragen, ob Return gedrückt worden ist.
>
> Wenn du andere Tasten abfragen willst, kannst du nach "Virtual-Key
> Codes" suchen, da findest du Listen.

Aaaah, wunderbar.


Sowas habe ich gesucht.

Vielen Dank
Gast #3760369
Lesenswert?

Hallo,

ich möchte nun, dass ich in meinem Konsolenfenster eine Drehzahl vorgebe 
und der Motor diese dann versucht zu erreichten.

Das ganze wird wieder in Visual Studio 2010 mit C programmiert.
Die Parameter gebe ich dann auf meine NI USB 6009 aus. Diese gibt dann 
eine Spannung von 0-5V aus.

Beispiel:

Der Motor steht.
Die zu erreichende Drehzahl ist nun 1000/min.

Ich möchte also, dass die Berechnung "Beschleunigen" aufgerufen wird.
Sobald die Drehzahl erreicht wurde, soll das Programm warten, bis etwas 
neues passiert. Zum Beispiel könnte ich den Motor belasten, sodass die 
Drehzahl fällt und er nachregeln muss. Allerdings könnte es auch sein, 
dass ich die Belastung wegnehme, folglich steigt die Drehzahl und dann 
Programm soll "Bremsen" aufrufen.
Das Spiel soll so lange weitergehen, bis es beende.

Ist dafür eine Switch Anweisung sinnvoll bzw. überhaupt machbar?
Bei Switch kann ich doch nur auf Konstante abfragen?!

Ich müsste doch dann zb. so abfragen:

Wenn Solldrehzahl>Istdrehzahl, dann beschleunigen.
Wenn Solldrehzahl<Istdrehzahl, dann bremsen.
Wenn Solldrehzahl=Istdrehzahl, dann warten.

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