Best way of implementing control loops in microcontroller software? - Page 1
Forum section: electronics / general

author: ZeroResistance
author_rank: Frequent Contributor
timestamp: November 03, 2016, 04:44:10 am
content: What are the traditional design patterns to implement control / feedback loops in software.From what I know there is1. A sensor signal input.2. A target inputThe firmware will compare these and generate an error output and based on this error the signal to the actuator would have to be modified to achieve minimum error or till target achieved.How do people already do this?1. Are there any recommended patterns.2. Are there different ways to approach this for slow changing sensors like temperature vs fast changing like motor current etc.?3. Any sample code available to understand the approach?4. Any references like books, websites etc ...Your inputs would be highly appreciated ..

author: obiwanjacobi
author_rank: Super Contributor
timestamp: November 03, 2016, 07:22:46 am
content: Sounds to me like you're looking for a PID controller: Proportional, Integral, Differential. ?

author: Jeroen3
author_rank: Super Contributor
timestamp: November 03, 2016, 08:10:28 am
content: Get a routine, call it at a fixed frequency. Put your control loop in there.Acquisition can run much faster, depending on the filtering the signals it require.For a thermostat, this isn't spectacular. 30 seconds probably, and the sensor sampling + filtering can be performed at 1 Hz.And as you'd understand, the control loop of a camera gimbal needs to be much faster. But basically the same theory applies.You can somewhat derive the speed of your loop depending on the method you have to influence the system. Eg: a stepper motor can react in ms, but room temperature needs to turn on the gas heater. Any result isn't happening in the coming 60 seconds.Books? I don't know of an control theory books in English. Try looking up some digital PID control theory.

author: H.O
author_rank: Frequent Contributor
timestamp: November 03, 2016, 08:30:35 am
content: You could have a look at theParallax Process Control"book". It's fairly comprehensive but still sort of "newbie oriented" without too many complicated math formulas that makes your head hurt :-) Theory, flowcharts, code, examples etc - check it out.Yes, they're using the BasicStamp (of course) but the theory is obviously applicable to any controller.

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2016, 08:33:50 am
content: There are two parts for the answer. How to achieve the hard realtime closed-loop control, and how to do that while also doing anything else required.For implementing the hard realtime closed-loop control and nothing else, see any textbook on control/feedback theory.For implementing a hard realtime control loop while also doing other processing, you will need to structure your code so that the hard realtime code executes at regular intervals, and the other processing occurs in between those intervals. Typically that will involve:an interrupt to mark timeinterrupts to indicate other processing needs to be donethe interrupt service routines do nothing more than gathering input from peripherals (if any), and posting a message that the input is ready to be processedthe mainloop does nothing but wait for messages, and then processes them in priority orderExtra marks are awarded for mentioning "priority inversion", maximum latency and jitter, and ensuring there is sufficient time available to process all the inputs.

author: nctnico
author_rank: Super Contributor
timestamp: November 03, 2016, 09:47:32 am
content: If the realtime requirements are strict then do all the processing in an interrupt routine. No need to shift that to the main loop because it makes things complex and adds overhead and latency (buffering, signalling).Also don't filter the input signals but filter the result (control value) otherwise you'll compromise the loop bandwidth you can achieve. I bought this book a while ago: Applied Control Theory for Embedded Systems by Tim Wescott

author: nfmax
author_rank: Super Contributor
timestamp: November 03, 2016, 10:02:51 am
content: I've used 8-bit PICs to implement deeply embedded control systems (including loops), and developed a technique which I like. I've also spread this around at work and others have used it successfully, though it isn't original with me. This is all in assembly language:No interrupts - all I/O is polled. If the processor doesn't have enough time to poll for I/O then it doesn't have enough time to handle the worst-case arrival rate of interruptsThe processing is partitioned into a set of communicating tasks. Each task is responsible for a single, well-defined and generally quite limited operation, such as reading an ADC.Each task is written as a non-blocking state machine. Its state is stored as a number in a single byte in the register file. State 0 is always 'do nothing', meaning the task is effectively idle. Most tasks will only have a few states - generally less than 10The application is written as a loop, waiting (polling) for TMR0 to overflow and then calling each task's state machine in turn. TMR0's reload value sets the system 'tick rate' (or for minimum jitter don't reload, and use a 256 cycle tick period).Alltasks get to run oneverytick. After all tasks have been called, the application increments a system timer (2 or 3 bytes in the register file), which is used for long-period delaysThe tick period is generally very short - a few hundred microseconds to a few tens of milliseconds, depending on the applicationThe task code uses the task state number as an index into a jump table. State zero just returns immediately, the other states jump to code to implement that state's actions and then return. The state action code is usuallyveryshort - often no more than a few instructions. The rules for writing tasks are:All loops in the state code must be bounded (i.e. no waiting for a external event). Polling is done by changing to a new state if the polled event has happened, otherwise stay in the 'polling' state.Only one task runs at a time. This means each task has a 'global lock' on all memory, including the state number of all other tasks, and the multiple bytes of the system timer. It can read & write these without worrying about their values changing.A task sends a message to another task by changing the receiving task's state number. Data is passed between tasks by using a shared memory location, with the receiving task's state number being used as a 'data ready' message. No acknowledgement is necessary, because the receiving taskwillhave run the receiving state's code before the transmitting tasks next runsA task can 'sleep' for a given period by reading the system timer, adding the required sleep period (in system ticks), saving the resulting value to memory, and entering a state which will test, each time the state code is run, if the system timer is equal to this value (and change to a new state if it is).You should get the idea now. Since unbounded loops are prohibited, is possible toprove, by counting instruction cycles in the longest state code of each task, that the application will always meet its scheduling deadline. Priority inversion is impossible because all tasks are equal (and no, some are not more equal than others). If you have difficulty meeting the schedule just use a faster clock.It is a fair criticism that this approach pretty much requires programming in assembly language. However, the structure it imposes consists of 'boilerplate' code which is always the same, and very simple, very structured fragments of assembly code that are easy to write and easy to comprehend. Some operations, e.g. floating-point arithmetic, are too lengthy to be implemented by a single state's code: these are split between multiple states, with each state just moving to the next in sequence.This isn't a universally applicable solution, but it works very well on 8-bit PIC micros, which have just the right set of capabilities and limitations.

author: Kalvin
author_rank: Super Contributor
timestamp: November 03, 2016, 10:16:15 am
content: Quote from: nfmax on November 03, 2016, 10:02:51 amNice and clean solution. Time-triggered, run-to-completion, co-operative tasker is a very robust, clean pattern. And it it also quite easy to debug is only one task is running at a time. Implementing the tasks as state machines go well with the design (actually it is quite impossible to do this otherwise). Implementing a simple  state machine pattern would complement the tasker pattern nicely. This can be implemented in C as well, so the implementation is independent of the processor architecture and the progamming language. The tasker could implement a simple safe-guard facility to monitor task execution so that each task shall be completed before the next system clock tick.Here is one book:http://www.safetty.net/publications/pttesAlthough it focuses on 8051 architecture, but the ideas and the patterns presented are easily portable to other architectures.A nice paper discussing the time-triggered co-operative software architectures:http://cdn.intechweb.org/pdfs/29201.pdf

author: dannyf
author_rank: Super Contributor
timestamp: November 03, 2016, 10:18:44 am
content: QuoteNo. it is application specific.QuoteYes. But you can design a control mechanism, with differing parameters, to deal with either case.What i typically do is to push as much of the input sampling to the interrupts. If it is a temperature sensor, the adc will be done automatically and repeatedly, with its output stored for access by your control algorithm. If it is a digital input, it is only read in an interrupt and again with its latest state stored.Once that is done, the control mechanism is called periodically, typically through a flag set by a timing isr, or in a loop, or in the isr directly, depending on the complexity, and the latest inputs are processed there.This approach makes the control algorithm independent of the data acquisition mechanisms, which is typically the most hardware dependent aspect of your design.

author: madires
author_rank: Super Contributor
timestamp: November 03, 2016, 10:57:26 am
content: My recipe:- understand what the problem is- define what the control process should do and what has to be considered- define how the control process fails safe- define what should be monitored and what to do in the case of unsual behaviour/reaction- write your control loop- test everything including every fault condition and improve the control loop

author: Jeroen3
author_rank: Super Contributor
timestamp: November 03, 2016, 11:06:20 am
content: Quote from: nfmax on November 03, 2016, 10:02:51 amIt might on an 8 bitter since the stack waste of state function calls would be high. But it is not required if you don't have to squeeze the dollars.Even on a cortex, this fsm* approach istheway to run multiple "threads" without operating system.The other approach is putting all "threads" in interrupts without preemption. Even then it will still need fsm.However, rule #1 isn't fully true. Interrupts are inevitable. You will need some to handle rx/tx complete from spi/uart and some buffers when things are fast. The next poll might be 10 bytes away.And last but not least, you'll need a timer to set the "go" flag for a fsm iteration. And check if the flag was cleared to indicate the previous FSM iteration took too much time. Which youneed to knowbefore the product ships.*https://en.wikipedia.org/wiki/Finite-state_machine

author: nfmax
author_rank: Super Contributor
timestamp: November 03, 2016, 11:32:42 am
content: Quote from: Jeroen3 on November 03, 2016, 11:06:20 amI've made interrupt-free applications which receive data using I2C, which has the benefit that the hardware will clock-stretch if necessary so as not to overrun the receive buffer. SPI is more of a problem since there is no way to 'throttle' it. But what happens if the sending system gets into a fault state where it just sends continuously at full speed? The sending device controls the clock, the interrupt routine can get called arbitrarily often! SPI offers too little protection against faults like this (though I2C can get stuck as well).I think it is better for the task polling the communicatons interface to detect buffer overrun, and handle it at the application level. There will be a maximum supportable receive rate and any attempt by a remote device to send data faster is an error.I always use TMR0 as the tick tmer, as it is the least generally useful timer, but it's always there on a PIC and has enough functionality for the job. No interrupt needed, just poll on the T0IF bit in INTCON. If you are paranoid (and you probably should be) you can test this bit immediately before entering the tight polling loop. Though if it's already set, probably the only thing worth doing is a reset. Like I said, you canprovethe application will always meet the scheduling deadline. You can't do that with interrupts enabled.In some cases, if you can identify a set of low priority tasks that can run on every other tick, you can unroll the task loop into two loops: the first instance runs all the high-priority tasks plus the first half of the low priority list; the second instance runs the high-priority tasks plus the second half of the list. Or if you don't care about some tasks being blocked indefinitely, use a single task loop but check the TMR0 value remaing before the calls the low-priority tasks, and omit them if the time remaining is too short (this idea worked well enough when trying to land on the moon).

author: Phoenix
author_rank: Frequent Contributor
timestamp: November 03, 2016, 11:51:10 am
content: I implement digital closed loop controllers for power electronics at up to 200kHz sample/update rate.Because of the requirements of synchronous current sampling for switching converters the way I have done it is to have:- main interrupt that perform the high speed filtering and closed loop controllers synchronised with the PWM (I've done up to 200kHz)- background tasks in a superloop divided into 10 slots, a different task executes every 1ms then back to the first task, can be further divided to create 100ms 1s etc. tasks (polling a basic timer)- non-blocking poll as much as possible, other very short interrupts as required (i.e. comms)The current project I'm working on has (on one of the micros) from memory 4 or 5 feedback controllers in the main interrupt and 3 slower controllers in the background routines. The main interrupt takes about 40% of the processor time, leaving 60% for background tasks and context switching. Every background task must complete before the next one starts (with a basic monitoring system).If you're asking how to design the feedback controllers - that's a whole different story that won't fit in a post. Plenty of control theory books, not sure what's good.

author: Phoenix
author_rank: Frequent Contributor
timestamp: November 03, 2016, 11:54:15 am
content: Quote from: nctnico on November 03, 2016, 09:47:32 amFiltering anywhere in the closed loop path will have the same effect on loop gain/bandwidth (assuming no non-linear effects). Does it say otherwise in that textbook?

author: nfmax
author_rank: Super Contributor
timestamp: November 03, 2016, 12:20:22 pm
content: As far as books go, I have a copy of (the first edition of)https://www.amazon.co.uk/PID-Controllers-Theory-Design-Tuning/dp/1556175167/ref=sr_1_13?ie=UTF8&qid=1478175454&sr=8-13&keywords=PID+controlwhich is pretty good (but expensive).It's not clear if you are after help with designing the controller itself, or on its implementation using a microcontroller (or other computer)

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2016, 12:33:17 pm
content: Quote from: nctnico on November 03, 2016, 09:47:32 amThat runs into difficulties where there is more than one input (and hence ISR) that has to be captured quickly, and where output jitter is more important than internal latency.It can also be an issue with some processors/compilers if floating point would have to be used inside an ISR: FP processor internal state might have to be saved to the stack as well.

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2016, 12:47:50 pm
content: Quote from: nfmax on November 03, 2016, 10:02:51 amI have no strong quibble with that, since it ensures several valuable system properties in small systems. Those properties are also valuable in large systems, but some parts of that design pattern will "run out of puff".In no particular order, I'll note thatsome peripheral libraries might presume the use of interruptscommunicating FSMs is a very powerful generic design abstraction. I don't understand why computer weenies aren't taught it ("Aren't FSMs used in parsers?")it presumes non-realtime processing can be conveniently completed within one timer tickinputs can wait for one timer tick before they are capturedalmost all of that design pattern can be efficiently implemented in Cthe addition of coroutines including explicit "yield()" points, is arguably more expandable

author: nfmax
author_rank: Super Contributor
timestamp: November 03, 2016, 02:12:49 pm
content: Quote from: tggzzz on November 03, 2016, 12:47:50 pmI think my only comment would be that the non-realtime stuff does not have to be done in a single timer tick - it can be split into tick-size chunks implemented by multiple states. Though in that case you have to worry about other tasks changing memory between your states.It's really that you can use the pattern to create a supportive environment for writing hard-real-time, multitasking applications even on the simplest of hardware - doing more, with less

author: John Coloccia
author_rank: Super Contributor
timestamp: November 03, 2016, 02:36:54 pm
content: A design pattern I've tended to use is something like:1) main loop handles the control law calculation and housekeeping (health and status, comms...whatever)2) timer interrupt comes in at a regular interval and spits the result out to whatever you're controllingOr if the control law is very simple and fast (and some are) then you can simply calculate it right in the interrupt.What I like doing for stuff like this is tossing together a very simple prototype...no interrupts or anything like that. Just toss everything together using clocks, spin waits and things like that, and get a feel for the timing and how the system actually behaves. Then use that to drive your actual design. Everything will be much clearer when you have a prototype.edit:If the data is "framed" and it doesn't matter exactly what time the actuator command goes out (as long as it's under some max time) then the situation is even simpler. You can do everything in a main control loop, with data-in being the beginning of the frame. Whenever you can arrange it that you just have to be "fast enough" as opposed to doing something at a precise time, that's the best situation, and lots of systems work like this.

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2016, 03:14:46 pm
content: Quote from: nfmax on November 03, 2016, 02:12:49 pmI'm sure it works as advertised, but it is a "contrary" programming style and a little brittle if anything changes, e.g. loop time, per-state processing.QuoteCan I suggest you look at the XMOS processors, since they were designed from the outset for hard realtime systems. They have several desirable attributes, including low cost, "no" interrupts, multicore, communicating processes, and the "C+bits" compilerguaranteesthe maximum loop time. They seem to have found favour with the audio brigade, who are traditionally very sensitive to jitter.You may recognise some of the architects/advisers, and their track record, e.g. David May (Transputer, OCCAM), Ivan Sutherland, Stephen Furber (ARM), Robin Saxby, Hermann Hauser.http://www.xmos.com/about/managementhttp://www.digikey.co.uk/product-search/en?keywords=xmos

author: Cerebus
author_rank: Super Contributor
timestamp: November 03, 2016, 03:18:03 pm
content: Quote from: tggzzz on November 03, 2016, 12:47:50 pmComputer Science graduates should indeed know all about Finite Automata, including how to turn Non-deterministic ones into Deterministic ones. The problem is that the vast majority of coders out there aren't Computer Scientists but EE graduates, Physics graduates, hell even Biochemists and Librarians with no formal Computer Science training.

author: tggzzz
author_rank: Super Contributor
timestamp: November 03, 2016, 03:30:03 pm
content: Quote from: Cerebus on November 03, 2016, 03:18:03 pmIn my experience, the electronic engineers and physicists naturally adopt FSMs for systems, either because they were shown it or, as in my case, they triumphantly reinvent them without realising it.(In my case my first assembler program was to convert one 5-channel paper tape code into another. It worked first time, unlike someone else's program with lots of nested if-then-elses. The only other language I could have used was Algol-60, but the assembler was short and sweet)

author: rstofer
author_rank: Super Contributor
timestamp: November 03, 2016, 04:10:10 pm
content: Quote from: tggzzz on November 03, 2016, 03:30:03 pmI'm pretty sure EEs were using FSMs before there even was a computer to program. The largest FSM I ever saw was a 1000 line PBX (telephone Private Branch Exchange) that used cross-bar relays. What a magnificent bit of electrical engineering!We sure spent a lot of time in the Logic Design class working on minimizing the number of states in an FSM. States cost flops and flops cost money!

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: November 03, 2016, 04:26:51 pm
content: For hard real-time control when I'm working with hardware that needs to be serviced at discrete intervalsno matter what, I use a scheme where I use several MCU timers to generate interrupts every 100 usec, 500 usec, 1 msec, 8 msec, etc. Each interrupt handler will run a queue of C functions sorted in priority order. This scheme works well as long as no list of functions exceeds its queue interval (i.e. the functions called in the 1 msec timer interrupt take no longer than 1 msec to execute).On the Cortex-M series, I set the interrupt priorities such that the faster interrupts are higher priority than the slower interrupts. With the code instrumented to toggle GPIO ports in the interrupt handlers, I can verify the timing to ensure that all of the required deadlines are met.This type of thing is harder to do with an RTOS due to the timing jitter associated with context switches and other latencies in the kernel.

author: madires
author_rank: Super Contributor
timestamp: November 03, 2016, 04:48:55 pm
content: It's called a scheduler

author: JPortici
author_rank: Super Contributor
timestamp: November 03, 2016, 06:27:47 pm
content: Quote from: Cerebus on November 03, 2016, 03:18:03 pmI was tought FSM in high school :/ You know, PLC and stuff.. most if not all that i've seen is implemented as a state machineThen while i attended university there was an introductory course on FPGA which was basically finite state machines

author: John Coloccia
author_rank: Super Contributor
timestamp: November 03, 2016, 07:11:22 pm
content: I tend to use an FSM to do the housekeeping tasks after the real time stuff is completed. You know...update some status light, process a serial/network message. I like to keep the core tasks separate if possible. Not sure where this idea that comp. sci majors aren't taught state machines started. They're pretty simple, though, so I think most people probably just figure it out on their own regardless.

author: KenGaler
author_rank: Contributor
timestamp: November 03, 2016, 08:15:01 pm
content: I attached an excellent paper about how to implement a PID. This works and won't drive you crazy.Ken

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: November 03, 2016, 08:36:30 pm
content: Quote from: KenGaler on November 03, 2016, 08:15:01 pmPIDs are easy to implement. Tuning them, however, is a different story.

author: dannyf
author_rank: Super Contributor
timestamp: November 03, 2016, 10:58:22 pm
content: QuotePID itself is fairly simple and intuitive. Coding for it is not difficult, even if done in fixed point math.tuning the parameters so that the loop performs well under a broad set of conditions can be very difficult and sometimes downright impossible.

author: nctnico
author_rank: Super Contributor
timestamp: November 04, 2016, 12:33:47 am
content: Quote from: Phoenix on November 03, 2016, 11:54:15 amThe simplest model of a control loop is an opamp with feedback:Putting filtering on the (feedback) input signal is like putting a capacitor parallel to Rg in the picture above which creates a frequency dependant gain (pole) in a place where you (probably) don't want it.

author: obiwanjacobi
author_rank: Super Contributor
timestamp: November 04, 2016, 07:49:42 am
content: Quote from: Sal Ammoniac on November 03, 2016, 08:36:30 pmDo not assume you need all three. Start with P and then work your way to I and D.

author: KenGaler
author_rank: Contributor
timestamp: November 04, 2016, 05:56:00 pm
content: Do not assume you need all three. Start with P and then work your way to I and D.That's right. I've done a lot of control loops and maybe just one needed a D term.Ken

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: November 04, 2016, 08:40:32 pm
content: Quote from: tggzzz on November 03, 2016, 12:47:50 pmAnother reason not to use peripheral libraries!QuoteNo it, doesn't. Non-realtime tasks just have to be broken up into 'states' that take less than 1 timer tick to execute. The only inconvenience is that you may have to write your own code instead of using libraries (on the plus side, you will know exactly what it does!).Where it gets really tricky is when you have to run multiple real-time tasks simultaneously with exact timing, and you are using a chip which has no hardware timers or interrupt capability! (or it does, but they would introduce too much jitter).Here's part of a program I wrote for an electronic speed controller that used a PIC12C509. Running at an effective 1MHz (1us instruction cycle time) the CPU generates 3kHz PWM to control motor speedandat the same time measures the width of the 1~2ms servo pulse with a resolution of 7us, as well as checking for low battery - all without any hardware assistance (the 12C509 doesn't have timer capture, PWM hardware or interrupts!). The numbers in brackets are the number of CPU cycles for each line of code.In this program 'task switching' is achieved by interleaving instruction sequences. The two critical real-time tasks are defined in macros to save typing and make the code easier to read. These macros are inserted into the code at regular intervals, while other tasks are broken into short segments which fill in the gaps. This technique can waste a lot of memory if you are not careful, but modern MCUs usually have plenty of ROM available (my code originally fitted in a 12C508, which only has room for 512 instructions!).Code:; Macro to set the initial state of the motor fet. W contains the count; on exit. The code in this Macro uses 5 clocks.;DoRunBit MACROmovf PwmWidth, Wskpzbsf GPIO, RunBitskpnzbcf GPIO, RunBitENDM; Macro to keep up with the servo pulse duration; The code in this Macro uses 2 clocks.;DoServoCount MACRObtfsc GPIO, ServoBitincf ServoCount, FENDM; The main PWM loop; Two timing loops have to be simultaneously maintained:-; 1/ Measure servo pulse width every 7 clocks. DoServoCount takes; 2 clocks, thus 5 clocks are available for other processing.;; 2/ DoRunBit + 17 clocks + DoPwmPulse + 2 clocks etc. This creates; the PWM cycle time of 329 clocks, which corresponds to a PWM; frequency of 3Khz.;; NOTE: DoServoCount occurs 43 times inside DoPwmPulse.;;ServoIsHigh: bsf Flags, PriorServoBit ;(1) servo pulse has started!DoServoCount ;(2) 3rd precyclebtfsc Flags, BattLow ;(2) If battery was ever low, quit nowgoto BattLoShutdown ;incf HiCount,F ;(1) HiCount = ServoCount/47 (+-47)skpnz ;(1) Limit HiCount to 255 maximumdecf HiCount,F ;(1)MainPwmLoop: DoServoCount ;(2) 4th PrecycleNO_OP 1 ;(1)call DoPwmPulse ;(4,2,5) generate PWM (DoServoCount)DoServoCount ;(2) 1st PrecycleMainPwmEntry: DoRunBit ;(5)DoServoCount ;(2) 2nd precyclemovwf PwmCount ;(1)btfsc GPIO, ServoBit ;(2) is servo pulse Hi ?goto ServoIsHigh ;(+1)btfsc Flags, PriorServoBit ;(2) Servo pulse now low, but was it high?goto EndOfPulse ;(+1) yes, then must be end of pulseclrf ServoCount ;(1) no, so reset servo pulse countDoServoCount ;(2) 3rd precyclebtfsc Flags, BattLow ;(2)goto BattLoShutdown ; If battery was ever low, quit nowgoto MainPwmLoop ;(2); ==========================================================================; The main PWM pulse routine. On entry, the motor may be on or off.; If the motor is off, it will never be turned on. However, it will be; turned off when (if) the PWM_Count register reaches zero.;; NOTE: This is the LAST subroutine allowed, as it extends past the; 256 byte boundary!;DoPwmPulse:PWM_LOOP_COUNT SET PWM_Period - PWM_Start ; 43 timesWHILE PWM_LOOP_COUNTbtfss GPIO, BattOkBit ;(2) check for low batterybsf Flags, BattLowDoServoCount ;(2) measure servo pulse lengthdecf PwmCount,F ;(1)skpnz ;(1) end of PWM hi pulse?bcf GPIO, RunBit ;(1) yes, then turn off motorPWM_LOOP_COUNT SET PWM_LOOP_COUNT - 1ENDWretlw 0 ;(2)

author: danadak
author_rank: Super Contributor
timestamp: November 04, 2016, 10:34:00 pm
content: A Cypress PSOC is quite capable for PID control, combination of extensive analog,A/D, D/A, amp, digital filter, and DMA can create a fully background PID controlloop. The DMA operations can be chained one peripheral to another, so the entirechain operates in background while you use the CPU to do the heavy lifting.http://www.cypress.com/file/137191/download1) Routability2) Fast 12 bit SAR A/D and slow 20 bit DelSig3) DFB (Digital Filter Block) that is dual channel, handle FIR or IIR filters, or DFBcan be used as a GP fast processor block, sililiar to RISC block4) MSI logic elements GUI based and/or the UDB Verilog capability. Eg. the FPGAlike capability5) Onboard Vref6) DAC, IDAC, OpAmps (up to 4), comparator, mixer, switch cap, analog mux....7) LCDCOM, UART, I2C, I2S, One Wire, SPI, Parallel, LIN, CAN, BLE9) Custom components capability10) DMA to offload processes like filters11) ARM M0 or M3 or 8051 core12) Extensive clock generation capabilitieshttps://www.element14.com/community/thread/23736/l/100-projects-in-100-days?displayFullThread=truehttp://www.cypress.com/documentation/code-examples/psoc-345-code-examplesGreat video libraryAttached component list. A component is an onchip HW resource.Free GUI design tool with schematic capture, "Creator". Components have rich API library attachedto each componentThis is low end of family, consider 5LP parts as well. PSOC also has arduino footprint boards (pioneer) as wellhttps://www.elektormagazine.com/labs/robot-build-with-cypress-psochttp://www.cypress.com/products/32-bit-arm-cortex-m-psocRegards, Dana.

author: ZeroResistance
author_rank: Frequent Contributor
timestamp: November 05, 2016, 04:47:55 am
content: Lets say if the output actuator has a range between 0 to 100, and is currently at 30If my input is 10 and setpoint is 50.So we first find the errorerror = setpoint - intput = 50 - 10 = 40;so how do we close in onto the setpoint? is it as simple as using just proportional, where we calculate the % error.so ((50 - 10)/50) * 100 = 80% error and so would it be as simple as give 80% power to the actuator so that the the input closes in onto the SP?and then how do you accurately maintain the set point?Yes people have mentioned PID but is that the only way or are there other methods?It's just that I don't know what they are called knowing the names would help in finding more info on the web.Thanks.

author: danadak
author_rank: Super Contributor
timestamp: November 06, 2016, 11:30:28 am
content: Google "PID alternatives", there are a number of them.Regards, Dana.

author: John Coloccia
author_rank: Super Contributor
timestamp: November 06, 2016, 12:45:37 pm
content: Quote from: ZeroResistance on November 05, 2016, 04:47:55 amThe I term allows you to get to a zero error steady state. With P alone, you can never get there. It's very common to see PI loops, without the derivative term, and sometimes just a proportional term alone.One common alternative is a lead-lag controller (or compensator, as it's called).

author: ZeroResistance
author_rank: Frequent Contributor
timestamp: November 08, 2016, 06:29:11 am
content: Quote from: John Coloccia on November 06, 2016, 12:45:37 pmthat's interesting never heard that before do you use that often in your control loops?Quote from: evb149 on November 06, 2016, 01:30:56 pmYes I made a mistake.so my desired value is 50 and current output is 30This 30 would become an input to the control loop.so error is 50 -30 = 20Then you have calculated 2 errors variables relative to setpoint and relative to output.. which one of these is widely used?

author: RoGeorge
author_rank: Super Contributor
timestamp: November 08, 2016, 07:52:06 am
content: Brian Douglas has a very good YouTube channel and free book about control theory, including PID:https://www.youtube.com/user/ControlLectures

author: John Coloccia
author_rank: Super Contributor
timestamp: November 08, 2016, 11:05:48 am
content: Quote from: ZeroResistance on November 08, 2016, 06:29:11 amOnly if necessary as it's more complex and more difficult to tune than a simple PID loop. PID is much easier to get working reasonably if you don't know a lot about the system. If the system behavior is very well understood, or if you can simply measure the transfer function directly, you can potentially get better performance with a lead-lag compensator.

author: Cerebus
author_rank: Super Contributor
timestamp: November 08, 2016, 04:44:19 pm
content: Quote from: John Coloccia on November 08, 2016, 11:05:48 amIt's probably worth saying that, as a rule of thumb, you'll get more bandwidth with a lead-lag compensator than you will from any other method. (The usual caveat, as with any rule of thumb, is that there are exceptions to this that are being glossed-over here.)