I am not able to set up
the Quaduature Encoder Interface
for a MicroChip 18F4431.
Any help with the set up code
would be appreciated.
Thank you in advance.
Richard
I am not able to set up
the Quaduature Encoder Interface
for a MicroChip 18F4431.
Any help with the set up code
would be appreciated.
Thank you in advance.
Richard
Hi,
This works for me on 18F2431, should be the same. Don't forget to set the QEA, QEB & QEI pins to inputs.
/Henrik Olsson.Code:QEICON = %00010100 'Setup QEI, 4X mode, reset on indexpulse. PosHigh var BYTE PosLow var BYTE PosTemp var BYTE Position var WORD 'Motor position in encoder counts. Main: Gosub GetPosition HSEROUT [#Position,13,10] Pause 100 Goto Main GetPosition: 'Since the position counter isn't double buffered we can get to situations 'where the lowbyte overflows between readings of the high and low byte. This 'is prevented by reading the high byte two times and compare the two readings. 'If they are the same then we're fine, if not re-read the registers. PosHigh = POSCNTH 'Get high byte of counter PosLow = POSCNTL 'Get low byte of counter PosTemp = POSCNTH 'Get high byte again If PosHigh - PosTemp = 0 then Goto Done 'Compare, if equal we're done. PosHigh = POSCNTH 'If not, get values again. PosLow = POSCNTL Done: Position = PosHigh * 256 + PosLow 'Put high and lowbyte together. RETURN
Last edited by HenrikOlsson; - 19th February 2007 at 21:31. Reason: Code errror fixed.
Henrik,
The problem was that I did not set
the ANSEL0 register to digital i/o.
Great tip on counter overflow.
I will definately incorporate.
Thank You again.
Richard
Isn't that an awesome controller? The motion feedback module with pulse width & frequency measurement is really handy.
Note: On the 28-pin version, forget using RE3 as an input. I tried, and submitted a support ticket to Microchip. Here's what I received back;
RE3 pin in PIC18F2331/2431 has been removed as a digital input. Hence, pin no. 1 of PIC18F2331/2431 can be used for MCLR/ Vpp only.
This change will be notified in a datasheet's (DS39616B.pdf) future update.
Last edited by Bruce; - 19th February 2007 at 23:36.
Hi Bruce,
Thank you for info regarding RE3/MCLR as input.
It sure is a cool device. Using Darrel's interupt routines I managed to get motor controller for my robot working, with PID filter and all. Very fun project.
However.....I never managed to get QEI module going in velocity mode. I made a few attempts to begin with but could never quite figure it out so I went for my own velocity calcs (newPos-oldPos). Any pointers?
Thanks!
/Henrik Olsson.
hi all...
i am starter for PIC 18F4431......
i want to interface a encoder to that...
what are the things i need to take care?
how to do?
is it like a plug and play?(i hope no)
First is the same thing that should be first for every new pic, can you blink a led? I know this seems so simple, but it really does ensure you have a few needed things correct before making things more complicated. After 10+ years, I still blink LEDs the first time I use a new pic.
-Bert
The glass is not half full or half empty, Its twice as big as needed for the job!
http://foamcasualty.com/ - Warbird R/C scratch building with foam!
I use the "Hello World" out the serial port test. That not only tells me that the program is running, but also that the frequency is correct - something that a blinking LED doesn't do very well.
Charles Linquist
While Bert's statement might sound like just so much talk to some I vouch for his opinion especially if you are moving to 18F chips for the first few times, I had an amazingly difficult time just getting this chip to blink the LED, owing to programmer issues, config issues . . . . ( I Know, men do not HAVE ISSUES, but PICs some times do).
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
HI All,
This explanation has been the best one that I have found concerning the use of the PCPWM. That said, there still seems to be a bit of mystery surrounding it's use, at least to me. I mapped out the formulas in Excel, but I am still having trouble getting my head around the details. I'm trying to make a generic H-bridge for low frequencies and keep running into the wall. An 18F1330 with two pots, a switch, and the FETs with drivers. One Pot is for Frequency, the other is for Duty. The switch controls if the output is pulsed DC or cycles both ways. I'm not understanding the interaction of the frequency to the Duty. I can control the Freq just fine, but it makes a mess of the duty. Currently, the application needs it to run from 3 Hz to 100Hz with control from low power to high power (~5%-95% duty). I can see that there is a dependency with the PWM resolution, but I'm not sure how to manage it. I can get the PTPER values within 0-4096, but the resolution gets out of range. I'm thinking I need to find some way to scale the Duty to the PTPER values, and adjust accordingly, but I haven't managed to make it click. Any suggestions?So I guess the question is: Can anyone explain the relationship between PTPER and PDCx in this dynamic environment in a way that I'm not seeing?Code:'**************************************************************** '* Name : PCPWM_1330_H-bridge84.BAS * '* Author : Mark Rokus * '* Notice : Copyright (c) 2012 Controlled Surroundings Inc. * '* : All Rights Reserved * '* Date : 6/9/2012 * '* Version : 1.0 * '* Notes : 18F1330 to drive H bridge: * '* : (2)L6378 drivers to (4) FDP22N50N N-FETs * '* used PCPWM_1330_H-bridge5 to test Hardware on separate FETS '* New rewrite using ints '* moved switch to RB3, rewire drivers complementary '* NOTE: Int not working, Not going into AC '* Freq and Duty not correct '**************************************************************** ' 18F1330 ' ---------------------u---------------------- ' Freq -1|RA0/AN0/INT0 RB3/INT3/CMP1|18- Switch ' Duty -2|RA1/AN1/INT1 RB2/INT2/CMP2|17- Pad ' Pad -3|RA4/TOCKI/AN2 RA7/OSC1/CLKI|16- Pad ' Vpp -4|RA5/MCLR/vpp RA6/OSC2/CLKO/AN3|15- Pad ' Gnd -5|-- VSS VDD++|14- 5 vdc ' Tx -6|RA2/TX/CK RB7/PGD/PWM5|13- PGD ' Rx -7|RA3/RX/DT RB6/PGC/PWM4|12- PGC ' Pad -8|RB0/PWM0 RB5/PWM3|11- Q1/Q4 PWM ' Pad -9|RB1/PWM1 RB4/PWM2|10- Q2/Q3 PWM ' |___________________________________________| #CONFIG CONFIG OSC = INTIO2 ;Internal oscillator, port function on RA6 and RA7 #ENDCONFIG DEFINE OSC 4 ' Actually @ 2MHz OSCCON = %11011100 ' INTOSC primary, 2MHz '****** Hardware Serial Setup *************** DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1 DEFINE HSER_CLROERR 1 ' Clear overflow automatically DEFINE HSER_SPBRG 8 ' 57600 Baud @ 2MHz, -3.55% SPBRGH = 0 BAUDCON.3 = 1 ' Enable 16 bit baudrate generator '*************************************** TRISA = %00000011 ' PortA : outputs except RA.0/RA.1= AN TRISB = %00001000 ' all outputs ex: RB.3 switch i/p INTCON = 0 ' INTCON2 = 0 CMCON = 0 ' Comparators off clear '**** Analog setup **** ADCON1 = %00001100 ' AN0,AN1 Analog: VDD ref. RA4 & RA6 DIO ADCON2 = %10010001 ' Right justified, 8 Tad, Fosc/8 '***** PWM Setup ? ******************** PTCON0 = %00001110 ' 1:1 post, Fosc/256 (1:64) pre, UpDown(...00 free) PTCON1 = %11000000 ' PWM Time Base timer on, Count Down PWMCON0 = %00110111 ' 0-3 PWM, complementary PWMCON1 = 1 ' 1:1 postscale, updates enabled, overrides sync DTCON = 0 ' zero dead-time PTCON1 = %10000000 ' PWM time base is ON, counts up FLTCONFIG = 0 ' disable fault A OVDCONS = %00000000 ' ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ' Variable definition ':::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: PORTB = 0 ' clear port latch Fraw var word ' Raw reading for Frequency Freq var word ' Frequency of PWM Draw var word ' Raw reading for Duty Duty Var Word ' Duty of PWM Sw var PORTB.3 ' switch input for AC or Positive only '************************************************ Start: hserout ["1330_H-bridge83",13,10] pause 500 '************************************* PosOnly: If sw = 0 then ac ' mode check ADCON0 = %00000011 ' Start conversion on AN0 WHILE ADCON0.1=1 ' Wait for it to complete WEND Fraw.HighByte = ADRESH ' get result from AN0 Fraw.LowByte = ADRESL ' ADCON0 = %00000111 ' Start conversion on AN1 WHILE ADCON0.1=1 ' Wait for it to complete WEND Draw.HighByte = ADRESH ' get result from AN1 Draw.LowByte = ADRESL ' Freq = (Fraw) max 3 ' Duty = (Draw*3) max 1 ' PTPERH = Freq.highbyte 'load timer: Freq low byte PTPERL = Freq.lowbyte ' Freq low byte PDC1H = Duty.HighByte ' PWM duty on Out1 PDC1L = Duty.LowByte OVDCOND = %00001000 ' enable PWM3 OUT1 (Q1/Q4 on RB5) hserout ["Duty ",dec duty," PosFreq ",dec Freq] goto PosOnly ' Loop '*************************************************************************** AC: ' sequence for generating Alternating pulses PosAlt: 'drive Positive pulse on bridge If sw = 1 then posonly ' mode check PIR3.4 = 0 ' reset PWM Int flag while PIR3.4 = 0 OVDCOND = %00001000 ' enable PWM3 OUT1 (Q1/Q4 on RB5) ADCON0 = %00000011 ' Start conversion on AN1 WHILE ADCON0.1=1 ' Wait for it to complete WEND Fraw.HighByte = ADRESH ' get result from AN0 Fraw.LowByte = ADRESL ' Freq = Fraw max 3 ' PTPERH = Freq.highbyte 'load timer: Freq low byte PTPERL = Freq.lowbyte ' Freq low byte wend ' one cycle until Int NegAlt: ' drive Negative pulse on bridge PIR3.4 = 0 ' reset PWM Int flag while PIR3.4 = 0 OVDCOND = %00000100 ' enable PWM1 OUT2 (Q2/Q3 on RB4) ADCON0 = %00000111 ' Start conversion on AN0 WHILE ADCON0.1=1 ' Wait for it to complete WEND Draw.HighByte = ADRESH ' get result from AN1 Draw.LowByte = ADRESL ' Duty = (Draw) max 1 ' PDC1H = Duty.HighByte ' PWM duty on Out1 PDC1L = Duty.LowByte wend ' one cycle until Int hserout ["Duty ",dec duty," ACFreq ",dec Freq] goto AC ' Loop end
Thanks
Bo
Hi,
Basically, when you change the frequency (which you do when you change the PTPER) you also change the resolution. So, if you set the duty cycle to 50% at one frequency and then change the frequency the actual dutycyle will also change.
Basically the module is counter and two comparators. When the counter starts at 0 the output is set, when it "hits" the value of the first comparator the outputs is cleared and when the counter "hits" the value of the second compartor the PWM cycle starts over. In this case the value "in" the first comparator is your PDCx (duty)and the value in the second comparator is your PTPER (period) registers.
If the counter was an 8 bit counter and you had your second comparator (PTPER) set to 255 then there would be 256 "steps" to one PWM period. If you then set the value "in" the first compartor (PDC) to 127 you'll get a 50% dutycycle because the output will be set when the counter starts at 0 and cleared when it reaches 127, the counter will then continue to 255 and start over at which point the output is again set and so on.
Now, if you change the value of the second comparator (PTPER) to say 180 there's no longer 256 "steps" to one PWM period, the counter will start over when it "hits" 180 instead of 255 - the PWM period is shorter, PWM frequency is higher. So if you keep the value "in" the first comparator (PDC) unchanged (127) the dutycycle will no longer be 50% because the output will be "on" from 0 to 127 and then off from 127 to 180 at which point the cycle starts over.
The PWM module is more complec than this, as you've noticed, but the above is a basic explanation of the interaction between PWM period and PWM dutycycle.
/Henrik.
Hi all,
Does some one by any chance have a C code on this QEI module?
Thanks !!!!!!!!!!!!
This is NOT a " C " forum, it is M E Labs PBASIC.
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
Bookmarks