Ich schmier mal schnell einen Pseudo-Pseudo-Code hin, damit du dich nicht so quälen musst. Du bist nämlich noch ein gutes Stück von mir entfernt.
Es stellt sich aber dennoch die Frage, ob es Sinn macht, meine Gedankengebäude nachzuprogrammieren wenn ich das Konzept noch nicht einmal vollständig durchdacht habe.
Noch ein Hinweis zu deiner Maschine_Bereit Sache: Sinn und Zweck der Fifos ist es doch gerade, DAS unnötig zu machen. Die Maschine soll nahtlos ihren Job abarbeiten, ohne beim PC immer nerven zu müssen. Die CNC baut sich einen FiFo auf und arbeitet DEN schrittweise ab.
Der PC selbst soll möglichst wenig mit allem zu tun haben, was Verzögerungen bewirkt, optimal ist es, wenn die Motion-Control schon nach dem letzten Schritt "weiß" wo sie als nächstes hinfährt, dieses Element aus dem Motion-Fifo holt und beim nächsten Timer-Interrupt einfach weiterarbeiten kann.
Delphi-Quellcode:
var rx_fifo, tx_fifo, gcode_fifo, motion_fifo : TFifo;
var rx_errors, decode_state : byte;
procedure main; //alles hat einen anfang
begin
while (true) do
begin
command_decode; //kommandodekodierung
gcode_preprocessor; //g-code-interpretierung;
end;
end;
procedure rs232_receive;
begin
if not rx_fifo.add(rx_register) then
rx_errors := rx_errors or FEHLERCODE_FÜR_VOLLEN_FIFO;
else
begin
if rx_fifo.size-5 < rx_fifo.count then
rx_errors := rx_errors or WARNCODE_FÜR_FAST_VOLLEN_FIFO;
end;
end;
procedure rs232_transmit;
var out_buf : byte;
begin
if tx_fifo.get(@out_buf) then
tx_register = out_buf
else disable_rs232_transmit_interrupt;
end;
procedure command_decode;
begin
case decode_state of
wait_for_startflag : //eingangsfifo nach startflag durchsuchen und bei gefundenem startflag die nächste stufe scharfschalten
read_message_size : //sobald ein byte gekommen ist, als message_size interpretieren + nächsten schritt aktivieren
receiving_telegram : //warten (nachsehen, danach funktion verlassen wenn nicht alles da) bis alle angekündigten bytes da sind, danach nächster schritt
check_stopflag : //prüfen ob das telegramm tatsächlich da ein ende hat wo es eines haben sollte, wenn ja: weiter
check_cmd_code : //doppelten commandocode prüfen, weiter wenn ok,
check_sum : //checksumme prüfen, weiter wenn ok
launch_parser : //payload an den parser übergeben, z.bsp für gcode
rst_wait_stopflag : //wenn ein fehler aufgetreten ist, überspringen wir hier solange eingehende bytes, bis ein stopflag dabei ist, danach schritt eins scharfschalten
if rx_errors <> 0 then //irgendwann beim dekodieren oder empfangen ist ein fehler aufgetreten, das teilen wir dem master mit
begin
if transmit_command(receive_error,@rx_errors,sizeof(rx_errors)) then
rx_errors := 0; //transfer erfolgreich, wir können den fehler löschen.
end;
end;
procedure gcode_preprocessor;
begin
//mach was sinnvolles mit dem gcode, abhängig vom aktuellen zustand berechnungen anstelle, neue codes aus dem gcode_fifo entnehmen und interpretieren und dann in den motion_fifo einfügen oder oder
end;
procedure timer1_interrupt;
begin
//zu toggelnde pins ermitteln
//toggeln
//distanzen updaten etc.
//zurücktoggeln
//wenn job done, neuen nachladen oder in idle-mode gehen
end;
mfG
Markus