![]() |
![]() |
![]() |
|
|
|||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
|
|
Thread Tools | Display Modes |
|
|
(permalink) |
|
Hi,
I am halfway through a project which involves using a dc to dc converter to boost the voltage from a solar panel to a constant 100V. I have designed and successfully built the boost converter and have written a simple PWM code to boost 17V (rated output voltage from panel) to 100V: #include <p16f877.h> void main(void) { trisc = 0x00; portc = 0x00; pr2 = 0x18; //sets PWM period ccpr1l = 0x14; //sets PWM duty cycle to 82% t2con = 0x05; //enables timer 2 modules and sets the TMR2 prescale value to 4. ccp1con = 0x2C; //Enables PWM mode } This is working fine. Now I want to write additional code so i can send the correct PWM to the switch so i can maintain 100V output whatever the input voltage/light level i.e (input voltage 0-20V) - which will involve adjusting the duty cycle according to the input voltage. As i'm a beginner to programming it has been suggested to me that i use a control circuit consisting of op amps to reduce the input voltage range to 0-5V and feed this into the A/D input of the pic that I am using (PIC16F877A). This is where I am stuck: After reading the datasheet, I still don't understand how the A/D would convert the input voltage and where the 8bit digital number is stored? hence where i can call it from. Is the A/D simple to set-up? Do you think the above method would work? I'm really struggling with this feedback code, so any help or advice on the best way to implement a solution to what i'm trying to achieve would be greatly apreciated. Thanks elec123 |
|
|
|
|
|
|
(permalink) |
|
Here is a tutorial on the ADC:
http://www.winpicprog.co.uk/pic_tutorial11.htm To use the PIC as a boost converter, you'll need to implement a PID algorithm to avoid an unstable control loop. Microchip has an application note on that: http://www.microchip.com/stellent/id...pnote=en021807 You could use a simpler loop that uses the following logic: Increase PWM if ADC reading drops below set value. Decrease PWM if ADC reading rises below set value. Maintain PWM if ADC reading equals set value. However, this type of algorithm tends to be somewhat unstable and the 100V output would wander around a bit. Here's another ap note from Microchip that you may be able to adapt: http://ww1.microchip.com/downloads/e...tes/01047a.pdf
__________________
--- The days of the digital watch are numbered. --- Last edited by kchriste; 27th January 2008 at 02:23 AM. |
|
|
|
|
|
|
(permalink) |
|
I have worked through the tutorial but am still having troubles setting up my adc for my boost converter.
It would be really helpful if you could look through my code and see where i'm going wrong as i'm really stuck! At the start of the program i have two look up tables look1 and look2 each containing 256 values for ccpr1l and ccp1con (which i have calculated using an excel spreadsheet). then: void main(void); void Initialize_ADC(void); void main() { unsigned char dig_input; Initialize_ADC(); //Read_ADC ADGO = 1; //captures analogue voltage on pin. while (ADGO) { //dig_input = 0x00; } dig_input = ADRESH; //defines the digital input. if (dig_input<128) //if solar panel (Vin) to boost converter is less than 10V don't boost. { CCPR1L = 0x00; //sets pwm to have duty cycle of zero. CCP1CON = 0x00; } else { dig_input -= 128; //dig_input = dig_input-128 dig_input += dig_input; //multiplies dig_input by 2 CCPR1L = look1[dig_input]; CCP1CON = look2[dig_input]; } } void Initialize_ADC() { TRISA = 0x01; TRISC = 0x00; PORTC = 0x00; PR2 = 0x18; T2CON = 0x05; ADCON0 = 0x80; //clear ADCON0 A2D starts sampling again. //Set ADCON1 ADCON1 = 0x00; // clear ADCON1 register.// ADCON1 = 0x02; // set PCFG1 bit i.e AN0 is analogue input. ADON = 1; }; Basically i want to read analogue input, convert it to digital, with this digital voltage assign ccpr1l and ccp1con the appropriate hex value so that the correct duty cycle is sent to the pwm output (want to have set period just change the duty cycle). Can't see where i'm going wrong in the above code, was wondering if it was something to do with the required acquisition time of the adc? do i need to set this? I have probable missed something obvious as i'm a beginner to all of this! Any help would be greatly appreciated. Thanks |
|
|
|
|
|
|
(permalink) |
|
Your code looks fine. You only need to worry about the acquisition time if you are changing channels, as you are only reading AN0 then you should be fine. Can you simply put a pot on the ADC input and see if it boosts below a certain level and doesn't above?
Mike. |
|
|
|
|
|
|
(permalink) |
|
I have programmed the code onto the PIC and tested it by varying the input voltage on AN0 from 0-5V and just get a "not square" square wave, and the duty cycle doesn't change at all, just the voltage level of the output signal.
In MPLAB, my code builds successfully but when i go to MPLAB SIM in the output box i get the message: "ADC-W0010: A Minimum of 2 TADs are required before another conversion should be started. Does this mean i need to add a delay somewhere in my program? I have been reading this thread: http://www.electro-tech-online.com/m...8f452-adc.html In which forum members describe the need for delays in the program, where should these delays be placed? From my understanding of the datasheet, TAD is controlled by the ADCON0 register? I have to use the 32Tosc operation as my external oscillator crystal is at 8MHz, this corresponds to ADCS1:ADCS0 being 10, is this correct? Help on this would be great, Thanks |
|
|
|
|
|
|
(permalink) |
|
It seems to me that your main routine is executed once and the program might be not properly terminated (this might be compiler dependent and could yield unexpected results). It's good practice to use a while instruction in order to create an endless loop.
Code:
void main(){
// initialization
while(1){ // always true
// ADC operation and control
}
}
Last edited by eng1; 4th February 2008 at 02:52 PM. |
|
|
|
|
|
|
(permalink) |
|
I don't know why you would get that error as you are only converting once (as pointed out by eng1 - I missed that). You should do as eng1 says and put a while(1) after the initialisation and put a short delay at the end of the while loop.
Mike. |
|
|
|
|
|
|
(permalink) |
|
I have added a delay (frank) which i thought would solve the problem:
void main(void); void Initialize_ADC(void); void main() { unsigned char dig_input; unsigned char frank; Initialize_ADC(); while(1) { //Read_ADC ADGO = 1; //captures analogue voltage on pin. frank = 0x10; while(frank != 0x00) {frank -= 1;} while (ADGO) {} frank = 0xFF; while(frank != 0x00) {frank -= 1;} dig_input = ADRESH; //defines the digital input. if (dig_input<128) { CCPR1L = 0x00; //sets pwm to have duty cycle of zero. CCP1CON = 0x00; } else { dig_input -= 128; //dig_input = dig_input-128 dig_input += dig_input; //multiplies dig_input by 2 CCPR1L = look1[dig_input]; CCP1CON = look2[dig_input]; } } }; void Initialize_ADC() { TRISA = 0x01; TRISC = 0x00; PORTC = 0x00; PR2 = 0x18; T2CON = 0x05; ADCON0 = 0x80; //clear ADCON0 A2D starts sampling again. //Set ADCON1 ADCON1 = 0x00; // clear ADCON1 register.// ADCON1 = 0x02; // set PCFG1 bit i.e AN0 is analogue input. ADON = 1; }; Still getting the message: "ADC-W0010: A Minimum of 2 TADs are required before another conversion should be started" are the delays in the right position? not really sure on how long the delays need tobe....any ideas on how to solve this, and get the adc working properly? thanks |
|
|
|
|
|
|
(permalink) |
|
You really need to put code tags around your code. Put [code] and [/co de] (without the space) before and after your code and it will keep the formatting.
Mike. |
|
|
|
|
|
|
(permalink) |
|
Try something like,
Code:
void main(){
unsigned char dig_input;
unsigned int i;
Initialize_ADC();
While(1){
//Read_ADC
ADGO = 1; //captures analogue voltage on pin.
while (ADGO);
dig_input = ADRESH; //defines the digital input.
if (dig_input<128){ //if solar panel (Vin) to boost converter is less than 10V don't boost.
CCPR1L = 0x00; //sets pwm to have duty cycle of zero.
CCP1CON = 0xc0;
}
else{
dig_input -= 128; //dig_input = dig_input-128
dig_input += dig_input; //multiplies dig_input by 2
CCPR1L = look1[dig_input];
CCP1CON = look2[dig_input];
}
for(i=0;i<1000;i++);
}
}
Edit, I should have pointed out that I think setting CCP1CON to zero is not a good idea. I changed it above. Last edited by Pommie; 4th February 2008 at 03:55 PM. |
|
|
|
|
|
|
(permalink) |
|
thanks for your help on this, will give it a try and let you know how i get on.....
|
|
|
|
|
|
|
(permalink) |
|
I am stilling having troubles with my code and would appreciate if someone could have a look at it for me....
The input from the solar panel is scaled down from 0-20V to 0-5V using a simple op-amp circuit. I'm defining the result of the analogue to digital converter as dig_input. I have my two look up tables for ccpr1l and ccp1con each containing 256 values, where the 128th corresponds to 10V out of the solar panel (2.5V after the op-amps) My code is as follows: Code:
dig_input = 130; ///////////////REMOVE//////////////////
if (dig_input<128) //if solar panel (Vin) to boost converter is less than 10V don't boost.
{
CCPR1L = 0x64; //sets pwm to 100% this gets inverteted to 0% by driver i.e don't boost.
CCP1CON = 0x0C;
}
else
{
dig_input -= 128; // scaling dig_input to number between 0-255
dig_input += dig_input;
CCPR1L = look1[dig_input];
CCP1CON = look2[dig_input];
I get an error: Error[477] : fixup overflow in expression (location 0x72 (0x72+0), size 2, value 0x804) Anyone know what i'm doing wrong? and know how to solve this? i've looked the error message and get the impression that this means the vaue is to big for the location, but still don't understand it..... Any help on this would be greatly appreciated! (i'm probably doing something stupid!) Thanks elec123 |
|
|
|
|
| Bookmarks |
| Thread Tools | |
| Display Modes | |
|
|
|
|
||||
| Thread | Thread Starter | Forum | Replies | Latest |
| Using Oscilloscopes | mechie | Electronic Theory | 9 | 29th November 2007 09:48 PM |
| Control Feedback Systems | Electrostatic | General Electronics Chat | 2 | 6th February 2006 11:29 PM |
| Problem with Code: Help | Electrix | Micro Controllers | 7 | 29th September 2005 07:42 PM |
| C code for ADC sampling | patricktran | Micro Controllers | 4 | 15th June 2004 01:41 AM |
| feedback control circuit | gogkiran | Electronic Projects Design/Ideas/Reviews | 0 | 25th August 2003 04:18 AM |