PDA

View Full Version : EPWM control



Asmith
- 26th September 2007, 18:39
Hello again everyone. I have not been on in a long time. I have new project I'm working on and can't seem to get the solution I'm looking for. Bascially it is suppose to set one of 3 DC for the PWM, and continuously re-locate the motor based on the position of some other pieces. I try to set up the PW registers at the start and only monitor the DC (Duty Cycle) and direction throughout the rest of the code. I'm using a PIC16F684 and would like to stick with registers and not hpwm. Mister E thank you for your simple yet great multi-calc program. I also double checked all of the register values before using them so I know they are correct. Here are the things I'm noticing with this software.

1. The frequency the PWM is running at is suppose to be 8kHz and is only at 4kHz.

2. The DC only works in the middle range, below shown as 717. Surrounding values do not work.

3. Sometimes it seems as if there are sections of 0% DC popping up.

Below I tried to give as much of the code as I could without getting to long. I've read through the data sheet and app notes many time now and can't seem to find where I'm messing this up. Is it possible I'm trying to update the DC to quickly? Any help from anyone is greatly appreciated, please ask me if you need any more information. I can post the entire code if anyone needs it.

My test is just on the chip with a scope, telling the motor to go to a point it can never reach. This should give me a constant set of pulses at the same DC forever. I have a pot conected to ADCIN 5 to change the DC but like I said before when I move out of the mid range the signal out drops to 0% DC.



'-------------------------------------------------------------------------'
' Hardware Defines Specific to PIC Basic Pro '
'-------------------------------------------------------------------------'
define ADC_BITS 10 'Set A/D coverter to use 10 bits
define ADC_SAMPLEUS 50 'Set A/D sample time as 50us
DEFINE OSC 8 'Change clock speed to 8Mhz

'-------------------------------------------------------------------------'
' Initialise PIC Hardware '
'-------------------------------------------------------------------------'
CMCON0 = 7 'Turn comparators off
ANSEL = %00110111 'Turn on select analog registers
TRISA = %00001111 'Turn on select register inputs
TRISC = %00111111 'Turn on select register inputs
ADCON0.7 = 1 'Set A/D Values to be right justified
ADCON0.0 = 1 'Turn on A/D Converter

PR2 = 249
CCP1CON = %11001100
CCPR1L = 0
PIR1.1 = 0
T2CON.0 = 0
T2CON.1 = 0
T2CON.2 = 1
WHILE (PIR1.1 = 0)
WEND;
TRISC.5 = 0
TRISC.4 = 0
TRISC.3 = 0
TRISC.2 = 0

Main:
ADCIN 5, Speed
Speed.lowbyte = ADRESL
Speed.highbyte = ADRESH

IF (Speed > AnalogLow) & (Speed < AnalogHigh) THEN
DUTY = 717
ENDIF
IF (Speed < AnalogLow) THEN
DUTY = 512
ENDIF
IF (Speed > AnalogHigh) THEN
DUTY = 922
ENDIF

.
..
.... (To much to insert here)
.......
..........


TimeToMove:
ADCIN 2, Position
Position.LowByte = ADRESL
Position.HighByte = ADRESH

If (Position < Seeking + 10) OR (Position > Seeking - 10) THEN
DUTY = 0
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
Goto Main
ELSE
IF (Position > Seeking + 10) THEN
CCP1CON.7 = 1
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
GOTO MAIN
ENDIF
IF (Position < Seeking - 10) THEN
CCP1CON.7 = 0
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
Goto Main
ENDIF
ENDIF
GOTO Main

mackrackit
- 26th September 2007, 21:22
Hi,

Trying to understand..
Speed is the POT, what is AnalogLow? Is the POT linear?

Asmith
- 26th September 2007, 22:04
Thank you for the reply mackrackit. What I'm actually doing is taking a 3 position knob say (slow, medium, and fast speed settings) I bring 2 of the settings into a dual opto on a pcb and basically turn it into an analog signal using a set of four resistors on the output. For example slow speed would give me a close to 0V on the pin of the PIC. Medium means niether opto is on and gives 2.5V to the PIC. Fast speed turns the bottom opto on giving close to 5V signal on the PIC. Analog Low I have defined as 256 decimal or 1.25V on the pin. Analog high I have defined as 768 or 3.75V. It's just a way I tried to use 3 digital input as one analog to save I/O ports. I hope this is a good explaination. If you would like to see the circuit I can share that as well.

I have done this PWM before but with much less code so I went back to the basics. Here is the code that I have running right now and does work correctly.



'-------------------------------------------------------------------------'
' PIC Defines Specific to PIC Basic Pro '
'-------------------------------------------------------------------------'
' 1. Use internal system clock
@ DEVICE PIC16F684, INTRC_OSC_NOCLKOUT
' 2. Turn watchdog timer on
@ DEVICE PIC16F684, WDT_OFF
' 3. Power on time on
@ DEVICE PIC16F684, PWRT_ON
' 4. Turning off the master clear input
@ DEVICE PIC16F684, MCLR_OFF
' 5. Brown out detect on
@ DEVICE PIC16F684, BOD_ON
' 6. Data EE Read protect is off
@ DEVICE PIC16F684, CPD_OFF
' 7. Code protect is off
@ DEVICE PIC16F684, PROTECT_OFF

'-------------------------------------------------------------------------'
' Hardware Defines Specific to PIC Basic Pro '
'-------------------------------------------------------------------------'
define ADC_BITS 10 'Set A/D coverter to use 10 bits
define ADC_SAMPLEUS 50 'Set A/D sample time as 50us
DEFINE OSC 8 'Change clock speed to 8Mhz

'-------------------------------------------------------------------------'
' Define Program Variables '
'-------------------------------------------------------------------------'
R VAR BYTE
ScaledX VAR BYTE
ScaledY VAR BYTE
ShortX VAR BYTE
ShortY VAR BYTE
Slope VAR WORD

AnalogLow VAR WORD 'Digital value for an analog low signal
AnalogHigh VAR WORD 'Digital value for an analog high signal
CurrentSpeed VAR WORD
DUTY VAR WORD
ExtLimit VAR WORD 'Stored value of the extend limit setting
JoyX VAR WORD
JoyY VAR WORD
RetLimit VAR WORD 'Stored value of the retract limit setting
Position VAR WORD 'Analog value of the internal potentiometer
Seeking VAR WORD
Speed VAR WORD

'-------------------------------------------------------------------------'
' Define I/O and EEPROM Definitions '
'-------------------------------------------------------------------------'


' The following 3 Data Commands write the Program Name and Revision
' number on the chips EEPROM in Location D0 - FF. This can be read
' by placing the chip in the programmer, reading it with MPLAB,
' and viewing the EEPROM.
DATA @208, "BadBoy Mowers "
DATA @224, "U3 Double "
DATA @240, "Rev. 1 A.S. "

data @0,word 768 'Set default extend limit
data @2,word 256 'Set default retract limit

AnalogHigh = 768 'Set analog high signal level
AnalogLow = 256 'Set analog low signal level

' READ 1, RetLimit.Highbyte
' READ 0, RetLimit.Lowbyte
' READ 3, ExtLimit.Highbyte
' READ 2, ExtLimit.Lowbyte

'-------------------------------------------------------------------------'
' Initialise PIC Hardware '
'-------------------------------------------------------------------------'
CMCON0 = 7 'Turn comparators off
ADCON0.7 = 1 'Set A/D Values to be right justified
ADCON0.0 = 1 'Turn on A/D Converter
ANSEL = %00110111 'Turn on select analog registers
TRISA = %00001111 'Turn on select register inputs
TRISC = %00111111 'Turn on select register inputs

PR2 = 249
CCP1CON = %11001100
CCPR1L = 0
PIR1.1 = 0
T2CON.0 = 0
T2CON.1 = 0
T2CON.2 = 1
WHILE (PIR1.1 = 0)
WEND;
TRISC = %00000011
'-------------------------------------------------------------------------'
' Start of Main Program '
'-------------------------------------------------------------------------'
Main:
ADCIN 5, Speed
Speed.lowbyte = ADRESL
Speed.highbyte = ADRESH

CCP1CON.4 = Speed.0
CCP1CON.5 = Speed.1
CCPR1L = Speed >> 2

GOTO Main



There are some useless variables in there because I commented most of the code out. I'm going to slowly try to incorperate the rest in now since I know this basic works. One thing I just noticed is that when I pull the pot wiper wire out of AN5 the DC goes back to 50%, not sure why but I will figure it out. Thanks again and I hope to here from you soon because this is driving me nuts. I know it's something simple.

mackrackit
- 27th September 2007, 02:19
Off hand I do not see anything wrong with the logic, so check hardware.

Can you add to your code a quick debug out put---serot to hyperterm the values of Speed and AnalogLow/High or the ADC value of that pin?

The ADC with out the pot could float to mid range.

Along with the debug, check the voltages at the ADC pins(sure you have done this,basic trouble shooting).

Hard code Duty a a give value to check the output(if you have a spare pin --- add some where in the main loop--- if pin? then Duty = ?.

I know this is not much help but a the moment it is all I can suggest:(

Asmith
- 27th September 2007, 14:47
It's ok mackrackit any help is better than none. Here's where I'm at as of now. I have encorperated the rest of the code back into the main now. I've left out the section where I figure out the seeking value and hard coded it. I've also given position a hard coded value as with nothing attached to the pin I will get garbage on the pin. I still have a pot tied to AN5 which does change the DC as I move it up and down. If you look below there are 6 lines in the "timeTomove" sub, if I uncomment the first four only I get no output. If I uncomment out the bottom two I get a couple of pulses on the output (Maybe 2 of 3) but after that the signal drops out. Any ideas? I will continue to work on this, and thank you for the help so far.




'-------------------------------------------------------------------------'
' PIC Defines Specific to PIC Basic Pro '
'-------------------------------------------------------------------------'
' 1. Use internal system clock
@ DEVICE PIC16F684, INTRC_OSC_NOCLKOUT
' 2. Turn watchdog timer on
@ DEVICE PIC16F684, WDT_OFF
' 3. Power on time on
@ DEVICE PIC16F684, PWRT_ON
' 4. Turning off the master clear input
@ DEVICE PIC16F684, MCLR_OFF
' 5. Brown out detect on
@ DEVICE PIC16F684, BOD_ON
' 6. Data EE Read protect is off
@ DEVICE PIC16F684, CPD_OFF
' 7. Code protect is off
@ DEVICE PIC16F684, PROTECT_OFF

'-------------------------------------------------------------------------'
' Hardware Defines Specific to PIC Basic Pro '
'-------------------------------------------------------------------------'
define ADC_BITS 10 'Set A/D coverter to use 10 bits
define ADC_SAMPLEUS 50 'Set A/D sample time as 50us
DEFINE OSC 8 'Change clock speed to 8Mhz

'-------------------------------------------------------------------------'
' Define Program Variables '
'-------------------------------------------------------------------------'
R VAR BYTE
ScaledX VAR BYTE
ScaledY VAR BYTE
ShortX VAR BYTE
ShortY VAR BYTE
Slope VAR WORD

AnalogLow VAR WORD 'Digital value for an analog low signal
AnalogHigh VAR WORD 'Digital value for an analog high signal
CurrentSpeed VAR WORD
DUTY VAR WORD
ExtLimit VAR WORD 'Stored value of the extend limit setting
JoyX VAR WORD
JoyY VAR WORD
RetLimit VAR WORD 'Stored value of the retract limit setting
Position VAR WORD 'Analog value of the internal potentiometer
Seeking VAR WORD
Speed VAR WORD

'-------------------------------------------------------------------------'
' Define I/O and EEPROM Definitions '
'-------------------------------------------------------------------------'

data @0,word 768 'Set default extend limit
data @2,word 256 'Set default retract limit

AnalogHigh = 768 'Set analog high signal level
AnalogLow = 256 'Set analog low signal level

' READ 1, RetLimit.Highbyte
' READ 0, RetLimit.Lowbyte
' READ 3, ExtLimit.Highbyte
' READ 2, ExtLimit.Lowbyte

'-------------------------------------------------------------------------'
' Initialise PIC Hardware '
'-------------------------------------------------------------------------'
CMCON0 = 7 'Turn comparators off
ADCON0.7 = 1 'Set A/D Values to be right justified
ADCON0.0 = 1 'Turn on A/D Converter
ANSEL = %00110111 'Turn on select analog registers
TRISA = %00001111 'Turn on select register inputs
TRISC = %00111111 'Turn on select register inputs

PR2 = 249
CCP1CON = %11001100
CCPR1L = 0
PIR1.1 = 0
T2CON.0 = 0
T2CON.1 = 0
T2CON.2 = 1
WHILE (PIR1.1 = 0)
WEND;
TRISC = %00000011
'-------------------------------------------------------------------------'
' Start of Main Program '
'-------------------------------------------------------------------------'
Main:
ADCIN 1, JoyX
JoyX.LowByte = ADRESL
JoyX.HighByte = ADRESH

ADCIN 0, JoyY
JoyY.LowByte = ADRESL
JoyY.HighByte = ADRESH

ShortX = JoyX / 4
ShortY = JoyY / 4
Seeking = 400
GOTO TimeToMove

TimeToMove:
ADCIN 2, Position
Position.LowByte = ADRESL
Position.HighByte = ADRESH

Position = 300

If (Position < Seeking + 10) OR (Position > Seeking - 10) THEN
' DUTY = 0
' CCP1CON.4 = DUTY.0
' CCP1CON.5 = DUTY.1
' CCPR1L = DUTY >> 2
ELSE
IF (Position > Seeking + 10) THEN
' CCP1CON.7 = 1
GOSUB GETSpeed
ENDIF
IF (Position < Seeking - 10) THEN
' CCP1CON.7 = 0
GOSUB GetSpeed
ENDIF
ENDIF
GOTO Main

GetSpeed:
ADCIN 5, Speed
Speed.lowbyte = ADRESL
Speed.highbyte = ADRESH
IF (Speed > AnalogLow) & (Speed < AnalogHigh) THEN
DUTY = 617
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
ENDIF
IF (Speed < AnalogLow) THEN
DUTY = 400
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
ENDIF
IF (Speed > AnalogHigh) THEN
DUTY = 850
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
ENDIF
RETURN

END

mackrackit
- 28th September 2007, 01:37
After DUTY gets a value in the main part of the program you have DUTY=0 in timeTOmove.

The code you have working writes to the high and low byte for Speed the goes straight to CCP1CON.4 and CCP1CON.5 with the low and high byte of speed.

In the one that is not working DUTY has 0 written to it before CCP1CON.4 and CCP1CON.5.

Asmith
- 28th September 2007, 15:45
The part of the code I last posted that has 0 being put into DUTY is there to stop the motor from running. The position is between the two required points so I want to stop motion. The other two if statments is is the motor is not in the correct position then it needs to move. To do that you change the CCP1CON.7 pin to either a 1 or 0 for full H-bridge mode, and use the standard duty cycle. It's just a way so I do not have to shut down the PWM and leave it running forever.

I will be working on this all day today, and try to give an update as I progress. If you have anything at all please let me know, I'm starting to run out of ideas. Thanks again.

mister_e
- 28th September 2007, 23:55
mmm, something spring to mind now form your first post, you said it was suppose to produce 8KHz but, in real-world, it produce 4KHz.

DEFINE OSC 8 don't change the internal OSC speed, it's more a compiler directive to match PAUSE, PAUSEus and all other timed stuff with the real OSC speed.

POR value for the internal osc is 4 MHZ, to change it to 8 MHZ you want to use


OSCCON = %01110000 ' this set the internal osc to 8MHz

for now i can't check the whole thing here, but let us know if the above fix something. At very least, you should have the right PWM frequency.

HTH

Asmith
- 1st October 2007, 14:53
Thank you Mister_e, that did help out. The running frequency is now 8KHz. I ran a small bit of code below.



'-------------------------------------------------------------------------'
' PIC Defines Specific to PIC Basic Pro '
'-------------------------------------------------------------------------'
' 1. Use internal system clock
@ DEVICE PIC16F684, INTRC_OSC_NOCLKOUT
' 2. Turn watchdog timer on
@ DEVICE PIC16F684, WDT_OFF
' 3. Power on time on
@ DEVICE PIC16F684, PWRT_ON
' 4. Turning off the master clear input
@ DEVICE PIC16F684, MCLR_OFF
' 5. Brown out detect on
@ DEVICE PIC16F684, BOD_ON
' 6. Data EE Read protect is off
@ DEVICE PIC16F684, CPD_OFF
' 7. Code protect is off
@ DEVICE PIC16F684, PROTECT_OFF

'-------------------------------------------------------------------------'
' Hardware Defines Specific to PIC Basic Pro '
'-------------------------------------------------------------------------'
define ADC_BITS 10 'Set A/D coverter to use 10 bits
define ADC_SAMPLEUS 50 'Set A/D sample time as 50us
DEFINE OSC 8 'Change clock speed to 8Mhz
OSCCON = %01110000 'Change internal osc to 8MHz
'-------------------------------------------------------------------------'
' Define Program Variables '
'-------------------------------------------------------------------------'
R VAR BYTE
ScaledX VAR BYTE
ScaledY VAR BYTE
ShortX VAR BYTE
ShortY VAR BYTE
Slope VAR WORD

AnalogLow VAR WORD 'Digital value for an analog low signal
AnalogHigh VAR WORD 'Digital value for an analog high signal
CurrentSpeed VAR WORD
DUTY VAR WORD
ExtLimit VAR WORD 'Stored value of the extend limit setting
JoyX VAR WORD
JoyY VAR WORD
RetLimit VAR WORD 'Stored value of the retract limit setting
Position VAR WORD 'Analog value of the internal potentiometer
Seeking VAR WORD
Speed VAR WORD

'-------------------------------------------------------------------------'
' Define I/O and EEPROM Definitions '
'-------------------------------------------------------------------------'
data @0,word 768 'Set default extend limit
data @2,word 256 'Set default retract limit

AnalogHigh = 768 'Set analog high signal level
AnalogLow = 256 'Set analog low signal level
ExtLimit = 750
Retlimit = 50
'-------------------------------------------------------------------------'
' Initialise PIC Hardware '
'-------------------------------------------------------------------------'
CMCON0 = 7 'Turn comparators off
ADCON0.7 = 1 'Set A/D Values to be right justified
ADCON0.0 = 1 'Turn on A/D Converter
ANSEL = %00110111 'Turn on select analog registers
TRISA = %00001111 'Turn on select register inputs
TRISC = %00111111 'Turn on select register inputs

PR2 = 249
CCP1CON = %11001100
CCPR1L = 0
PIR1.1 = 0
T2CON.0 = 0
T2CON.1 = 0
T2CON.2 = 1
WHILE (PIR1.1 = 0)
WEND;
TRISC = %00000011
'-------------------------------------------------------------------------'
' Start of Main Program '
'-------------------------------------------------------------------------'
Main:

WHILE(1)
CCP1CON.7 = 1
DUTY = 300
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
PAUSE 1000
DUTY = 0
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
PAUSE 200

CCP1CON.7 = 0
DUTY = 300
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
PAUSE 1000
DUTY = 0
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
PAUSE 200
WEND

END


This ran a few times on the motor back and forth, and then ruined one of the driver chips on the board shorting my pcb out. This is an update of where I am at the moment. I starting trouble shooting on it now, so hopefully if anyone finds a solution so will I. One of the things that might be hurting me is a electro cap on the 5V rail (I know duh) or a very high uF cap on the +12V rail for the 2 H-bridges running DC brush motors. (Again, I can't believe I forgot these) I'm also attaching the schematic as this might help some see something in the hardware. I really appreciate all of the help so far guys. Thank you

Anthony

mister_e
- 1st October 2007, 16:31
Seems you forgot the back EMF diode in your H-Bridge driver.

470 Ohm seems a bit bit high for a gate resistor... if even really needed...

How many amp you need to drive?

Did you also tried with a resistive load?

I'll look the whole thing later, sure i missed something else.

Fortunately, someone else may beat me to the punch :D

Asmith
- 2nd October 2007, 21:09
Thank you mister_e again for your input. I think I might have made some headway on this project. Things I have chaged from last sch:

1. Removed and placed jumpers instead of the 470ohm gate resistors.

2. Place a 25V 470uF elect Capacitor for the 12V on the motor.

3. Placed 1uF 50V Ceramic caps on the 12V power for the driver chips, and across the H-Bridge 12V.

These seem to have cleaned the signals up a lot. I know can run the test code and a have the motor run back and forth forever. The load of each of the 2 motors is 5A each, I use 100uF for each 1A as a rule of thumb that I had forgotten.

The Back emf diodes are included in the mosfets, and I also have TVS to help with these problems. If you have anything else please free to let me know. I will try to keep everyone updated.

Thank you,
Anthony

mister_e
- 2nd October 2007, 22:30
:eek: yeah but usually those internal diode are just simply too slow...

I think we don't use the same rules of thumbs ;) 1000uF/Amp here... maybe i'm wrong?

When you said.. Place a 25V 470uF elect Capacitor for the 12V on the motor.
you mean in parallel with the motor??? not sure if you really need it. And.. mmm, if it's not a not-polarized type, you may have some problem one day or another... If it's only on the Vdd rails then.. that's ok.

Across the driver i would suggest 10-47uF tantalum + 0.1 uF ceramic.

Enjoy! and great to know it solve most of the problem :D