diff --git a/README.md b/README.md index 54f4c0b920c179112d3cca3bdd0afc5fda6477c9..d4479060d7ffc0d62479df8b08d8fa2ae74481ec 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,23 @@ PIDMotorControl Example includes code for DAC, ADC, PWM, Timer Interrupts, PID, Current Control, Encoders w/ interrupts, pins, clock frequency setup, and low pass filters -DAC +DAC()<< example in this code is meant only to use DACB due to poor construction +Used to convert digital signals to analog signals - really useful for debugging on scopes + + DAC + CTRLA - enable a channel on the DAC, and enable DAC + CTRLB - set DAC to single channel use or dual channel use + CTRLC - Set the reference voltage + + DAC Channel + DACB.STATUS - used to check if its ready to convert again. + DACx.CHyDATA - 12 bit value to output ADC(ADC, ADC_CH, ADC_CH_MUXPOS); Pass in the ADC you want to use. channel, and the Pin you want to sue for POS side(NEG is gnd here) +Used to convert Analog signals to digital signals for processing. (i.e. - current sensing) ADC can be setup in multiple ways- first divide being between single or differential mode In the example, it is setup in differential mode W gain. @@ -21,7 +32,9 @@ Pass in the ADC you want to use. channel, and the Pin you want to sue for POS si ADC Channel - CTRL- channel input mode(DIFFWGAIN in this case) and the gain value + CTRL- channel input mode(DIFFWGAIN in this case) and the gain value, and to start a scan(1<<7) + remember to check if scan is done being computed before doing again. Value 1<<7 is turned off + when scan is done MUXCTRL - setting the positive and negative pins. @@ -74,20 +87,89 @@ Setup mininum and maximum outputs, with integral portion not allowed to go over the MAX& MIN Outs. Since the derivative portion can be quite noisy run at a very fast frequency, a low pass filter is automatically applied to the D value, with K being a constant used to change the low pass filter's response time. See -low pass filter for details on that. +low pass filter for details on that. dt is the period of each loop.(1second /frequency) + + crunch(input) logic + current error = setpoint - current value<<<<<< this is changed if it is CONT. If CONT, find + the shortest distance to setpoint is the current error. + total error+= current error; + derivate error = filter(current error - previous error) + output = P* current error + I* total Error + D* derivative error + + onTarget() logic + if on target according to acceptable range for more than a + certain amount of time, return true + setAcceptableRange() logic + set the acceptable range +- where range is sepoint+-acceptable range + + setSetpoint() +Current Control(P, I, dt, MAX&MIN IN&OUT) +Basic PI loop. I is used much more than normal, P being used for the initial ramp up. +Same setup as PID loop, but without the derivative term + crunch(input) logic + current error = setpoint - current value + the shortest distance to setpoint is the current error. + total error+= current error; + output = P* current error + I* total Error + + onTarget() logic + if on target according to acceptable range for more than a + certain amount of time, return true + setAcceptableRange() logic + set the acceptable range +- where range is sepoint+-acceptable range + + setSetpoint() -Current Control -Encoder w/ interrupts -Pins -clock frequency setup -low pass filters +Encoder w/ interrupts/ATKEncoder +Encoders that automatically update based on interrupts running on a certain port. + PORTX_DIRSET &= ~(PINx_bm | PINy_bm) - set the direction of the two input pins + PORTX.INTCTRL - set the level of the interrupt(high/med/low) + PORTX.INTzMASK= set the interrupt of the port towards a certain pin + PORTX.PINxCTRL = set Pin to trigger on rising or falling edge + (make sure one interrupt is set on falling and other on rising edge) + + ISR(PORTX_INTz_vect) logic ( 1 for each pin used) + if pins are different values, add to counter value, if pins are the same, subtract + This is due to the nature of encoders and how they count. If running clockwise, + the values line up, and if counter clockwise they dont line up(the values are 90 degrees away + from each other) + +Basic Pin I/O + PORTX_DIRSET - set the direction of each port- 0 for input 1 for output + PORTX_DIRTGL - toggle direction + PORTX_DIRSET/CLR - set or clear direction of each port + + PORTX_OUTSET/TGL/CLR- set/toggle/clear output to high or low + +clock frequency setup +Don't really understand this, just copy paste. Used to set clock to 48 Mhz + + OSC.XOSCCTRL = OSC_XOSCSEL_XTAL_256CLK_gc | OSC_FRQRANGE_12TO16_gc; // select external source + OSC.CTRL = OSC_XOSCEN_bm; // enable external source + while(!(OSC.STATUS & OSC_XOSCRDY_bm)); // wait for external + OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | OSC_PLLFAC0_bm | OSC_PLLFAC1_bm; // select external osc for pll, do pll = source * 3 + //OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | OSC_PLLFAC1_bm; // pll = source * 2 for 32MHz std clock + OSC.CTRL |= OSC_PLLEN_bm; // enable PLL + while (!(OSC.STATUS & OSC_PLLRDY_bm)); // wait for PLL to be ready + CCP = CCP_IOREG_gc; // enable protected register change + CLK.CTRL = CLK_SCLKSEL_PLL_gc; // switch to PLL for main clock + + + +low pass filters(K) +Used to clean a noisy signal. meant to be run at a fast frequency, since (1-2^-k)takes many +clock counts to settle. +Algorithm- output = y(n) = (1-2^-k)(y(n-1)) + (2^-k)(x(n)) << y(n) output, x(n)new input, n current clock count + + filter(input) + give in new input, and returns in output