programmazione di circuiti PID in C


11

Sono un ingegnere elettrico che è stato un po 'impegnato nel mondo digitale e ha imparato mentre procedevo. Sto programmando un processore TI per eseguire un loop PID (proporzionale-integrale-derivativo) , illustrato da questo diagramma:

Immagine del loop PID da Wikipedia

Lo descriverò anche:

Amplificatore operazionale con feedback negativo, con terminale non invertente collegato a terra. Ingresso tramite terminale negativo. Il circuito di retroazione è un circuito serie RE in parallelo con un resistore e tutto ciò in parallelo con un cappuccio.

Qualcuno ha idea di come convertire questo circuito in codice C? Sono un po 'fuori dal mio elemento su questo e potrei usare l'aiuto.


Puoi collegarti a una foto e qualcuno convertirà utile quel link in una vera immagine per te.
Joachim Sauer,

2
Il link che hai pubblicato fornisce uno pseudocodice di base per procedere. Se non ti dispiace C #, ecco un esempio di un ciclo pid in C # .
Neil,

1
Neil ha ragione. Ho implementato quasi esattamente quel loop in C su TI. Un suggerimento: utilizzare un ciclo temporale costante e fattorizzare il fisso dtnelle costanti, invece di fare ulteriori divisioni e moltiplicazioni nel ciclo.
AShelly,

1
@Neil era un link che ho aggiunto nella revisione 2 perché non sapevo cosa fosse un loop PID e sospettavo che molti altri non lo sapessero.

@MichaelT, ah le mie scuse allora.
Neil,

Risposte:


18

Il circuito

Ok, ho appena creato un account qui quando ho visto questa domanda. Non riesco a modificare la tua domanda in modo che io possa correggere l'errore di battitura che hai fatto. Credo che tu intendessi il circuito serie RC in parallelo invece di RE (se lo è, non ho un solo indizio sul significato)

Sembra che il circuito analogico che si desidera simulare usando C sia simile a questo

                         Ci
                  |------| |--------------|
                  |           Rp          |
                  |----/\/\/\/\-----------|
                  |          Rd    Cd     |
           Rf     |----/\/\/\---| |-------|
Vin o----/\/\/\---|                       |
                  |    |\                 |
                  |    | \                |
                  |----|- \               | 
                       |   \              |
                       |    \-------------|---------o  Vout
                       |    /
                       |   /
                       |+ /
                   ----| /
                  |    |/
                  |
                  |
               ___|___ GND
                _____
                 ___
                  _

LEGEND:
  Vin is the input signal.
  Vout is the Output.
  Rp controls the propotional term ( P in PID) 
  Ci controls the Integral term ( I id PID)
  Rd and Cd controls the differential term ( D in PID)
  Rf is the gain control, which is common to all of the above controllers.

(Non ho potuto resistere alla mia voglia di disegnarlo perché volevo dirti come gli ingegneri elettrici / elettronici erano soliti comunicare nei forum e nelle e-mail senza immagini ... e perché adoriamo il corriere, caratteri a larghezza fissa)

Devo confessare che il circuito che stai usando è semplice da configurare ma è matematicamente molto complesso, quando si tratta di sintonizzare le costanti Propotional, Integral e Derivative del sistema su un valore desiderato individualmente non è possibile.

Consiglio vivamente di usare il circuito di questa fonte per studiare.

Anche se un po 'noioso da configurare, matematicamente è molto più semplice da analizzare in quanto è possibile collegarlo direttamente alla forma matematica standard anziché a quella ideale.

Infine, il Vout va a controllare un motore o qualunque cosa debba essere controllata. E Vin è la tensione variabile di processo.

Prima di bagnare i piedi in C (mare?)

Presumo che tu stia leggendo i segnali da un qualche tipo di convertitore analogico a digitale. Altrimenti dovresti simulare il segnale come input.

Se si utilizza il modulo standard,

Supponendo che il tempo di esecuzione del loop sia abbastanza piccolo (un processo lento), possiamo usare la seguente funzione per calcolare l'output,

output = Kp * err + (Ki * int * dt) + (Kd * der /dt);

dove

Kp = Proptional Constant.
Ki = Integral Constant.
Kd = Derivative Constant.
err = Expected Output - Actual Output ie. error;
int  = int from previous loop + err; ( i.e. integral error )
der  = err - err from previous loop; ( i.e. differential error)
dt = execution time of loop.

dove inizialmente 'der' e 'int' sarebbero zero. Se usi una funzione di ritardo nel codice per sintonizzare la frequenza del loop per dire 1 KHz, il tuo dt sarebbe 0,001 secondi.

Disegnando in C

Ho trovato questo eccellente codice per PID in C, anche se non copre tutti gli aspetti, è comunque buono.

//get value of setpoint from user
while(1){
  // reset Timer
  // write code to escape loop on receiving a keyboard interrupt.
  // read the value of Vin from ADC ( Analogue to digital converter).
  // Calculate the output using the formula discussed previously.
  // Apply the calculated outpout to DAC ( digital to analogue converter).
  // wait till the Timer reach 'dt' seconds.
}

Se prendiamo un processo lento, allora possiamo usare una frequenza inferiore tale che il tempo di esecuzione del codice dt >>> per il singolo loop (molto più grande di). In tali casi possiamo eliminare il timer e utilizzare invece una funzione di ritardo.


6
Il diagramma di Ascii mi ha fatto impazzire. +1
Bangkok,

1
il link "questa fonte" non funziona
Ccr

Oh mi dispiace sentirlo, una buona risorsa si è persa :(. Beh, il concetto è stato spiegato nel codice di esempio while loop che avevo condiviso. Non ho esperienza su come gestire questa situazione, forse alcuni editor possono risolverlo con messaggio proprio (il punto morto)
D34dman,

2
La "fonte" mancante potrebbe essere disponibile qui: educypedia.karadimov.info/library/piddocs.pdf
David Suarez,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.