Auch die serielle Schnittstelle sollte man wieder schliessen wenn man fertig ist. Die ``with``-Anweisung ist eine sehr praktische Sache für so etwas.
Bezüglich der Dateien sind die ``if``/``elif``-Kaskaden unsinnig weil auf Grund des Wertes von immer das gleiche gemacht wird, es unterscheidet sich nur durch ein Zeichen im Dateinamen: Und das ist immer der Wert von `i`. Also kann man den auch ganz einfach einsetzen, ohne die ganzen ``if``/``elif``\s.
Python hat einen eigenen Typ für Wahrheitswerte (`bool`) und die Werte `True` und `False`. Die sollte man verwenden statt Zahlen dafür zu missbrauchen.
`x` und `y` brauchen nicht in `float`\s umgewandelt werden — das sind bereits welche.
Beim Anhängen des `x`/`y`-Paares muss ich sagen Hut ab: Noch verwirrender und umständlicher könnte man das wahrscheinlich nicht mal machen wenn man es gezielt darauf anlegt. Die Werte werden erst in eine Liste gesteckt, die als einziges Element eine Liste mit den beiden Werten als Zeichenketten formatiert, enthät.
Über diese Liste, die garantiert immer nur ein Element hat, wird dann mit einer Schleife iteriert. In dieser Schleife werden dann die beiden Elemente aus der inneren Liste genommen, in Zeichenketten umgewandelt — wir erinnern uns: Das *sind schon* Zeichenketten — unübersichtlich mit ``+`` zu *einer* Zeichenkette zusammengebastelt und an `writelines()` übergeben. Was dazu führt das die Zeichenkette in einzelne Zeichen zerlegt wird und jeder Zeichen einzeln in die Datei geschrieben wird. Argh. Aber ich weiss — es ”funktioniert” ja.
Um's mal konkret zu machen: Das hier alles…
Code: Alles auswählen
x = x * 1000
y = y
dli = [['%.2f' % float(x),
'%.2f' % float(y)]]
for element in dli:
data_file.writelines(str(element[0]) +
";"+str(element[1])+'\n')
Code: Alles auswählen
data_file.write('{0:.2f};{1:.2f}\n'.format(x * 1000, y))
Code: Alles auswählen
import struct
import Gnuplot
import Gnuplot.funcutils
import Gnuplot.PlotItems
from serial import Serial
GNUPLOT_BINARY_FILENAME = r'C:\Programme\gnuplot\bin\gnuplot.exe'
DATA_FILE_COUNT = 5
DATA_FILENAME_TEMPLATE = 'XY{0}.txt'
PLOT_TEMPLATE = '"{0}" using 1:2 with linespoints smooth csplines'
def main():
#
# TODO This should be unnecessary except for the first file.
# And *that* can be solved by changing the order in which the
# files are emptied in the loop below.
#
for i in xrange(1, DATA_FILE_COUNT + 1):
with open(DATA_FILENAME_TEMPLATE.format(i)):
pass
gnuplot = Gnuplot.Gnuplot(debug=True)
Gnuplot.GnuplotOpts.prefer_inline_data = True
Gnuplot.GnuplotOpts.gnuplot_command = GNUPLOT_BINARY_FILENAME
gnuplot.title('ASM Kennlinie')
gnuplot.xlabel('Drehzahl [1/min]')
gnuplot.ylabel('Drehmoment [Nm]')
gnuplot('set xtics 0,200,3000')
gnuplot('set ytics 0,0.2,4')
gnuplot('set xrange[0:3000]')
gnuplot('set yrange[0:4]')
gnuplot('set grid')
with Serial(port='COM6') as serial:
i = 1
while True:
x, y = (
value / 100.0 for value in struct.unpack('<2h', serial.read(4))
)
if x > 0.450:
print 'X-Achse: {0:.3f} Y-Achse: {1:.3f}'.format(x, y)
with open(DATA_FILENAME_TEMPLATE.format(i), 'a') as data_file:
data_file.write('{0:.2f};{1:.2f}\n'.format(x * 1000, y))
gnuplot('set terminal windows')
gnuplot('set datafile separator ";"')
gnuplot.plot(
PLOT_TEMPLATE.format(DATA_FILENAME_TEMPLATE.format(i))
)
if i == DATA_FILE_COUNT and x < 450:
source = ', '.join(
PLOT_TEMPLATE.format(DATA_FILENAME_TEMPLATE.format(j))
for j in xrange(1, DATA_FILE_COUNT + 1)
)
gnuplot('set multiplot')
gnuplot('set datafile separator ";"')
gnuplot.plot(source)
gnuplot('unset multiplot')
gnuplot('set terminal png size 1400,600')
gnuplot('set output "Kennlinen.png"')
gnuplot('set multiplot')
gnuplot('set datafile separator ";"')
gnuplot.plot(source)
gnuplot('unset multiplot')
gnuplot('pause 0.1')
gnuplot('replot')
gnuplot('exit')
break
else:
i += 1
with open(DATA_FILENAME_TEMPLATE.format(i), 'w'):
pass
if __name__ == '__main__':
main()