ARDUINO uPCS
65 ARDUINO uPCS
ARDUINO DUE ( part 2 )
- a - signal generator ( pls see here )
- b - PID control
there are some arduino PID code projects out there, but i want do my own version:
- its an old hobby, i did my first 1984 for a Z80 slave controller ( CPM / Pascal / ASM )
- + and that was already with proportional auto tuning ( adaptive gain) !
- i design control structures and program DCS ( distributed or process control systems ) for 20 years
- i made a arduino PID version already for my uDuino DIY LINK SLAVE, but because i stopped
with that link software i never used / tested the PID code.
design ideas ( will be updated while i work ):
- hardware I/O
- - PV (A0) ( sensor )
- - SP (A1) ( poti )
- - OUTput (DAC0) ( to actuator )
- USB menu program
( pls note, as the DUE not has EEPROM that menu tuning adjustments are only temporary,
for a stand alone controller RSP setpoint, initial mode, PID tuning must be updated in the code )
- - input of RSP ( remote set point )
- - input of OUTPUT ( set output ( setpoint of MAN MODE ))
- - input of MODE ( MAN, AUTO, RSP, CAS )
- - input of TUNING
- - - PV input filter (t)
- - - output invert ( y / n )
- - - output lo, hi limit
- - - PID action ( reverse / direct )
- - - P ( gain )
- - - I ( reset )(t)
- - - D ( rate )(t)
- - - cycle time t
- - input of ALARM tuning
- - - PV lolo, lo, hi, hihi
- - - deviation ( PV - SP )
actually filter reset and rate are time depending values, so for the setup of a PID controller
the cycle time must be fixed, or, if that is tunable too, that 3 values must depend on it.
as the PID algorithm will be run by 1 conti job,
even more pid controller / or other jobs could be activated,
then a recheck of controller load is required / depending on that tuned cycle time.
( minimum a error msg ( via USB) on TOO LATE for cycle time )
so, that's the outer frame for the PID control function
lets start with the USB menu program we used above for that fast speed / benchmark test.
general operation via the USB menu:
menu 1:
the default is PID1 is enabled.
with 1 you stop the conti job PID1, and again with 1 you start it and can provide a cycle time
( initial default is 1000msec / by enter like bad / no number / [space]... or wait 30sec input timeout )
or better, default is last input.
so remember when you later in the tuning get 20 questions to provide settings, each question can be skipped by [ENTER] also [space] ( or any other BAD input )
DAC output:
now i read in forum that lots of users burned the DAC ( mostly with connecting a speaker ).
I think it should be able to drive 15mA to a load, what would be in my case a diode ( LED) and a resistor , what i think is a easy and perfect PROCESS to control.
The OUTPUT == DAC Volt,
the PROCESS VALUE == the volt on the resistor ( to A0 ) and that corresponds with the current in the diode.
the resistor would be ( 3.3V - 1V diode )/ 0.015A <= 153ohm, usually 220
but actually DAC output range is 1/6 x 3.3V = 0.55V to 5/6 x 3.3V = 2.75V,
and the voltage on a LED diode varies not only with current, also with color...
software: instead of just copy and paste my old control software and fix it until running,
i got the idea it must be special, i wanted to prepare all for multiple PID loops running.
- make a struct definition of a data set of a PID controller
- make a array with 2 ( N) of this sets for 2 PID controller
OR make 2 named sets
- find a way to call a function ( THE PID function ) what can not only use also operate that data, so they are also available in the main loop.
later when i needed a tuning function and a operating function, i used the same trick,
first ask what controller you want to tune / operate, then call a function pointing to it.
and i must admit that is a little above my head and arduino documentation is not too helpful here.
lucky i found that mentioned in the forum, in between many not working other C code.
it is one way to do it, try to take a close look on the pointer in the function call and the handling of the pointed values in there.
i reduced it to a 2 variable example just to show how it can work. while for a array there is a easier way, ( just pass the index to the function and use normal handling global data there ) in example 2 where i used 2 named sets, you understand that the pointer thing is the only way.
$('#zoom_24').elevateZoom();
$('#zoom_25').elevateZoom(); here the first look at the menu and the ( temporary) tuning
already 2 PID controller build in, default only PID1 started.
$('#zoom_26').elevateZoom();
$('#zoom_27').elevateZoom();
$('#zoom_28').elevateZoom(); 