- LiFePO4 Speicher Test         
RSS-Feed anzeigen

witkatz

PIC an SciLab, einfach UART-Scope für Regler in ms Bereich

Bewerten
Bei der Optimierung von Regelungen ist eine grafische Aufzeichnung der Ist- und Reglerwerte sehr nützlich. Die einfachste Möglichkeit, Daten aus dem µC zum PC zu schicken ist wohl das UART, über das die meisten µC verfügen.

Man kann die Reglerwerte per UART aus dem Controller an den PC zwecks Visualisierung schicken, jedoch bei Abtastraten im Bereich von Milisekunden ist das nicht ganz so einfach. Mit blockierenden UART Funktionen und Versenden der Werte in Textform, würde der µC für mehrere ms nur mit dem Senden beschäftigt sein. Ich habe mir folgendermaßen geholfen:

1. Die UART Funktionen habe ich als asynchrone Funktionen ohne blockierende Warteschleifen wie while( ! PIR1bits.TXIF) implementiert. Die Schreibroutinen schreiben die zu sendenden Daten in Datenpuffer und brauchen dafür max. ein paar µs. Man kann so Daten aus zeitkritischens Programmteilen wie Regelungstask oder Interruptroutinen versenden, ohne den Programmfluss zu verzögern. Im Vergleich dazu würde eine synchrone Routine bei 9600Baud ca. 1ms pro Byte brauchen. Mit while( ! PIR1bits.TXIF); würde der µC für jedes char 1ms in der Warteschleife verplempern.

2. Die UART Senderoutine (execUartSending) wird aus der main_loop aufgerufen und legt die Daten auf UART wenn der frei ist. Sie muss nur im Schnitt oft genug aufgerufen werden damit der Sendepuffer nicht überläuft. Der Datendurchsatz ist durch die Baudrate begrenzt und das Senden von den zeitkritischen Programmteilen entkoppelt. Alle anderen Task-Routinen, die aus der main_loop quasi parallel aufgerufen werden, sollten ebenfalls Delay-Frei implementiert werden.
Code:
#define UARTBUFLEN 32
char UartSendBuf[UARTBUFLEN];
char BytesToSend = 0;
char IdxWriteToSendBuf = 0;
char IdxReadFromSendBuf = 0;

void incBufIdx(char *pIdx){
    *pIdx = *pIdx + 1;
    *pIdx %= UARTBUFLEN;
}
void AsyncSendStringUart(char* sendString){
    while(*sendString != 0){
        if (BytesToSend < UARTBUFLEN){
            UartSendBuf[IdxWriteToSendBuf] = *sendString;
            BytesToSend++;
            incBufIdx(&IdxWriteToSendBuf);
        }
        sendString++;
    }
}
void AsyncSendData(void *pVal, uint8_t bCnt){
    char *p = (char *)pVal;
    if (BytesToSend + bCnt <= UARTBUFLEN){
        BytesToSend += bCnt;
        while(bCnt){
            UartSendBuf[IdxWriteToSendBuf] = *p;
            incBufIdx(&IdxWriteToSendBuf);
            p++;
            bCnt--;
        }
    }
}
void AsyncSendByteUart(char val){
     if (BytesToSend < UARTBUFLEN){
        UartSendBuf[IdxWriteToSendBuf] = val;
        incBufIdx(&IdxWriteToSendBuf);
        BytesToSend++;
    }
}
void execUartSending(void){
    if (BytesToSend){
        if((PIR1bits.TXIF == 1) && (TXSTAbits.TRMT == 1)){
            TXREG = UartSendBuf[IdxReadFromSendBuf];
            incBufIdx(&IdxReadFromSendBuf);
            BytesToSend--;
        }
    }
}
3. Um nochmal Zeit zu sparen werden die Daten binär, also z.B. als int8, int16 oder float Werte gesendet. Am anderen Ende der seriellen Übertragungsstrecke (momentan noch USB Kabel und irgendwann WiFi wenn ich dazu komme, mich mit ESP8266 anzufreunden) wartet die OpenSource Software SciLab auf die Binärdaten.
Die asynchronen Senderoutinen in der Reglertask schreiben die Daten in den Sendepuffer
Code:
        AsyncSendByteUart(LinesensorVal);
        AsyncSendByteUart(RegValue);
        AsyncSendData(&RegValueID.value, 2);
4. In Scilab habe ich die "Serial Communication Toolbox" installiert, mit der ich die Daten des Roboters am virtuellen COM Port empfangen und auswerten kann. Das Scilab Script zum Empfangen und Darstellen der Daten im Scilab Grafik-Fenster habe ich angefügt. Damit hat man ein einfaches Scope für schnellere µC Regelungen, hier z.B. eine Aufzeichnung meines 4ms Linienreglers - Sensor und Reglerwerte - über 7s mit bewusst provozierter Schwingung durch zu starken I-Anteil.
Klicke auf die Grafik für eine größere Ansicht

Name:	Scilab Diagramm.PNG
Hits:	288
Größe:	21,7 KB
ID:	31290

Die Übertragung ginge natürlich auch deutlich schneller und länger - der Datendurchsatz ist theoretisch nur durch die Baudrate und die Aufzeichnungsdauer durch den PC-Speicher begrenzt.
Miniaturansichten angehängter Grafiken Angehängte Dateien

"PIC an SciLab, einfach UART-Scope für Regler in ms Bereich" bei Twitter speichern "PIC an SciLab, einfach UART-Scope für Regler in ms Bereich" bei Facebook speichern "PIC an SciLab, einfach UART-Scope für Regler in ms Bereich" bei Mister Wong speichern "PIC an SciLab, einfach UART-Scope für Regler in ms Bereich" bei YiGG.de speichern "PIC an SciLab, einfach UART-Scope für Regler in ms Bereich" bei Google speichern "PIC an SciLab, einfach UART-Scope für Regler in ms Bereich" bei del.icio.us speichern "PIC an SciLab, einfach UART-Scope für Regler in ms Bereich" bei Webnews speichern "PIC an SciLab, einfach UART-Scope für Regler in ms Bereich" bei My Yahoo speichern

Aktualisiert: 14.02.2016 um 00:31 von witkatz

Stichworte: pic uart scilab Stichworte bearbeiten
Kategorien
PIC Basteln

Kommentare

  1. Avatar von Searcher
    Interessant. Möchte demnächst auf einem reaktivierten Oldtimer von mir (dem Quadenc mit Mausencodern) auch irgendeine Art von Regelung realisieren.

    Gruß
    Searcher

LiTime Speicher und Akkus