Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Beginer's program. ADC to PWM

Status
Not open for further replies.

thecritic

Member
I have done a simple light dimmer project on 16f676. The program, reads a ADC channel

(Potentiometer), calculates dutycyle and adjusts the lights brightness by PWM. Since this

is probably my first project in PIC, I want to know if I have done something silly or I

have done something very awkwardly? Is there something I can do here to make it more
reliable or better?
(I have used LM7805 with decoupling caps at both input and output, for 5 V. the Power)

(Schematic is attached)
Code:
#include<htc.h>
//__CONFIG(DEBUGDIS & INTROSC & WDTEN & PWRTEN & LVPDIS);  // here ; must be used
#define _XTAL_FREQ 4000000
#define Out			0x00
#define In			0xFF
volatile int x=0;     // counter for PWM
volatile char duty = 90; // duty cycle set for PWM by ADC. 100 means 100 % . initial 90
volatile bit on = 0;     // flag bit used in PWM to set current state

void interrupt isr(void){   // timer0 interrupt for PWM
	if(T0IF){
    	x++;				// increment counter on every interrupt
		if(on==0 && x>=100-duty){   // switch on (if off) output as soon as x reaches (100-duty)
          on=1;						// set on flag
          x=1;						// reset x to 1
  		}     
   		if(on==1 && x>=duty){		// switch off (if on) as soon as x reaches duty. 
	      on=0;						// reset off flag
          x=1;						// reset x to 1
        }
		if(on) { RC3=1; RA5=1; }	// switch on/off actual output ports according to flag bit.
		else {RA5=0; RC3=0; }
       T0IF=0;						// clear interrupt flag
	}
}

void main(){

	TRISC = Out;
    TRISA = Out;
	TRISC2 = 1;  // analoge input channel an6
    CMCON = 0xff;  //disable all the comparators
    ANSEL = 0b01000000;  // disable all the analog modulse except an6
    OPTION = 0b11011000 ;// disable internal weak pullup,,internal clock source for T0
                             // ,, assign prescaler to wdt,prescaler 000
    T0IE = 1; //enable timer 0 interrupt
    GIE = 1; // enable global interrupt
    ADCON0 = 0b10011001 ; //enable adc. 
// right-justified/Vref=Vdd/(Ignore)/(c1/c2/c3)channel 6/godone/adon
    ADCON1 = 0b01010000 ; //recomended value for ADC clock for 4Mhz, always use this
    __delay_ms(30);
                          
while(1){  // main loop

int lowtot; // sum of lower 8 bits of ADC
char high;  // variable for storing upper 2-bits. bit 9 and bit 10. 
lowtot=0; // initialize to 0
char samples = 50; // no of samples for avaraging
for(char i=0;i<samples;i++){
while(GODONE); // wait till finish
GODONE=1; // start ad conversion
while(GODONE); // wait till finish
lowtot+=ADRESL; // keep adding
}
lowtot /= samples;  // find avarage

duty = ADRESH*25 + (lowtot*25/255) ; // calculate duty cycle. if ADC reading is all 1111111111, then duty = 100.
// 75% weitage to ADRESH and 25% weitage to lowtot.

}

}


I want to use this circuit also to make a battery charger.
For this, I will be
1. Replacing the POT with a resistive voltage divider to read the battery's voltage
2. Replace the battery with the charger
3. Replace the Lamp with the battery to be charged.

What further improvements I need?
 

Attachments

  • dimmer.png
    dimmer.png
    58.1 KB · Views: 333
Last edited:
O.K. I got my answer. --There is nothing anyone finds worth mentioning. Thanks. :). I will move on to battery charger now. Will comeback with specific questions if I encounter any.
 
I am now going to make the battery charger.
For this I need to write code. I will use this circuit.
**broken link removed**

I will read the voltage accross the Rsense to read the charging current. But since I am controlling the charge current by PWM, I don't think, the ADC will read the correct average current? What should I be doing?
1. Read the voltage when PWM is high, and estimate the average current by considering current duty cycle?
2. do something else. :)
 
There are numerous things wrong with that design.

1) The bottom of the current-sense resistor is connected directly to ground, bypassing the FET altogether. The actual ground coming from the bridge rectifier isn't labeled as ground which may have lead to that error.

----------

2) R2 is supplying the turn-on current for the FET by default. This means that while your micro-controller is initializing it's ports and various peripherals, the FET is on and supplying full current to the battery.

If the supply is say for example 16V, then R2 is limiting the peak gate current to V/R = 16/1500 ≈ 0.011A = 11mA.

With Gate Charge of 63nC and a Peak Gate Current of 11mA, it would take roughly 6 µSeconds to fully turn on.
Can you fully initialize your PIC ports, various peripherals, and turn on Q1 in less than 6 µSeconds? :)

If you want to use only a transistor and resistor to switch the FET, use a pull down resistor to to turn it off and ensure it's off at powerup and a PNP to pull it to supply to turn it on.

All you need is a programming bug to stop the PIC and the FET would just be on frying the battery.
 
Last edited:
Hi, Thanks for the reply.
Your suggestion about using Pull Down for the FET instead of Pull Up is very nice. How about this now.
Also, I placed a capacitor from PIC pin to the Transistor, so that, if the programs hangs and stop giving PWM then, a constant DC level wouldn't pass. I am not sure How nicely the capacitor can do this.

**broken link removed**

Now for the actual question, when do I read the Rsense? Or, I should place a capacitor accross it (Rsense) so that it will be charged to its average (or what?) voltage?
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top