|
|
View previous topic :: View next topic |
Author |
Message |
swapnil
Joined: 15 Dec 2016 Posts: 13 Location: delhi
|
no voltage display |
Posted: Tue Jan 10, 2017 8:55 am |
|
|
Code: | #include <16F872.h> //equivalent with 10bit ADC
#device ADC=10
#fuses HS //Never use the 'Protect' fuse until you have completed
//your development. Doing so forces every cell in the chip to be erased
//every time you re-program - wastes chip lives. Otherwise the
//programmer will erase only the cells needed.
#use delay (clock=20MHz) // 20MHz
#define use_portb_lcd TRUE
#include <lcd.c>
#define CCP1_PWM PIN_C2
#define MAINS_SWITCH PIN_C3
#define CHARGING_LED PIN_C4
#define PCU_LOAD PIN_C5
#define LOAD PIN_C6
#define LOW_BATT_LED PIN_C7
#define MV_PER_COUNT (int16)(22.87/1024)
//We will do all the 'float' maths at compile time using this
//Not in the PIC itself
#define COUNTS_TO_MV(x) (x*MV_PER_COUNT)
#define TO_MV(x) ((int16)(x*1000))
int16 mean_adc(byte channel)
{
const int16 AVERAGING_CYCLE_COUNT=32;
int8 i;//mean_total = 32;
int32 total =0;
set_adc_channel(channel);
delay_us(100);
for (i=0; i<AVERAGING_CYCLE_COUNT; i++)
{
delay_us(10); //specified Tacq for your chip
total += read_adc();
}
return(total/AVERAGING_CYCLE_COUNT);
}
//Tacq (no more is needed), is required before sampling, and between
//each reading. More != better.
//********** Main Program*******
void main ( )
{
const byte SOLAR_CHANNEL=0;
const byte BATTERY_CHANNEL=1;
int16 battery_mv, solar_mv; //,bin,sin;
set_tris_c(0b00000111);
// setup_adc_ports(ALL_ANALOG);
setup_adc_ports(AN0_AN1_VSS_VREF); // Only ever configure pins you
//use as analog. Enabling others increases noise pickup on the ADC
//Also setting this to use A3 as the Vref input (2.5v).
setup_adc(adc_clock_div_32);
setup_ccp1(ccp_pwm); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_1, 249, 1); // Set PWM frequency to 5kHz
//enable_interrupts(GLOBAL);
//Since you are not using interrupts don't enable this.
//Never enable 'GLOBAL', without at least one interrupt handler present
delay_ms(255); //Many LCD's need 250mSec+ to wake
lcd_init();
printf(lcd_putc,"\f WELCOME TO ");
printf(lcd_putc,"\n LUXNTEK SOLAR ");
delay_ms(50);
while(TRUE)
{
solar_mv=COUNTS_TO_MV(mean_adc(SOLAR_CHANNEL));
battery_mv=COUNTS_TO_MV(mean_adc(BATTERY_CHANNEL));
//Now just have the two readings in integer mV
printf(lcd_putc,"\fSOLAR =%4.1LwV",solar_mv/100);
//In 'C' the number in front of the DP is the 'total field width',
//not the digits here . To display 2 digits, DP, one digit, needs a
//field width of 4.
printf(lcd_putc,"\nBATTERY =%4.1LwV",battery_mv/100);
delay_ms(500);
if(solar_mv > battery_mv)
{ //solar > battery
if (battery_mv > TO_MV(2.0) && battery_mv <= TO_MV(14.5))
//This scares me. Do you really envisage any situation where
//battery_mv can be below 10v?. If so you have a dead battery....
{
setup_ccp1(CCP_pwm);
set_pwm1_duty(500);
output_high(CHARGING_LED);
delay_ms(200);
output_low(CHARGING_LED);
delay_ms(200);
printf(lcd_putc,"\fBATTERY CHARGING");
printf(lcd_putc,"\n BOOST MODE ");
delay_ms(400);
}
if(battery_mv > TO_MV(14.5))
{
setup_ccp1(CCP_pwm);
set_pwm1_duty(100);
delay_ms(100);
set_pwm1_duty(200);
output_high(CHARGING_LED);
delay_ms (600);
output_low(CHARGING_LED);
delay_ms(100);
printf(lcd_putc,"\fBATTERY CHARGING");
printf(lcd_putc,"\n TRICKLE MODE ");
delay_ms(500);
}
}
else
{ //solar<battery turn off
setup_ccp1(CCP_pwm);
output_high(CHARGING_LED);
delay_ms(300);
}
}
/////////////////////////////LOAD ////LED INDICATION ///////////////////////////////////////////////////////
//if dawn to dusk and load on batt
//actually sounds as if you mean dusk to dawn here (solar <5v)
if((solar_mv < TO_MV(5.0)) || (battery_mv > TO_MV(12.0)))
{
output_high(LOAD);
}
if(battery_mv <= TO_MV(11.0))
{
output_high(LOW_BATT_LED);
output_low(LOAD);
}
else
{
output_low(LOW_BATT_LED);
}
// Mains SNS PCU Load On
if((input(PIN_C3)==1) && (solar_mv > battery_mv) && (battery_mv > TO_MV(14.6)))
{
output_high(PCU_LOAD);
setup_ccp1(CCP_pwm);
set_pwm1_duty(500);
}
else if(battery_mv <= TO_MV(13.9))
{
output_low(PCU_LOAD);
}
} |
no display of voltage value on lcd _________________ heroswap1981 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19554
|
|
Posted: Tue Jan 10, 2017 1:18 pm |
|
|
Have you connected the Vref?.
Remember I said the code was to use an external 2.5v Vref. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jan 10, 2017 4:59 pm |
|
|
This looks incredibly suspicious. You're making a small number, less
than 1, and then you're converting it to an integer. That will give you 0.
Quote: | define MV_PER_COUNT (int16)(22.87/1024)
//We will do all the 'float' maths at compile time using this
//Not in the PIC itself
|
This means MV_PER_COUNT is 0. So the results of all the math below
are also 0.
Quote: |
#define COUNTS_TO_MV(x) (x*MV_PER_COUNT)
#define TO_MV(x) ((int16)(x*1000)) |
In your earlier thread, Ttelmah told you:
Quote: | So, learn to debug.
Print the number coming from the ADC with no processing at all. Is this right?.
Then work through things one stage at a time, checking the values, till you find where it goes wrong. |
But you didn't do that.
How did I verify there was a problem. First I was suspicious.
Then I added a little code to the start of your program and compiled it:
Code: | void main ( )
{
const byte SOLAR_CHANNEL=0;
const byte BATTERY_CHANNEL=1;
int16 battery_mv, solar_mv; //,bin,sin;
//=====================
// *** TESTING ***
int16 temp;
// Load this constant so we can see it in the .LST file.
temp = MV_PER_COUNT;
while(TRUE);
//====================== |
Then I looked at the .LST file and saw that temp is being set to 0x0000:
Quote: | .................... int16 temp;
....................
.................... // Load this constant so we can see it in the .LST file.
.................... temp = MV_PER_COUNT;
0311: BCF STATUS.RP0
0312: CLRF temp+1
0313: CLRF temp....................
.................... while(TRUE);
0314: GOTO 314 |
That means MV_PER_COUNT is 0x0000. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19554
|
|
Posted: Wed Jan 11, 2017 8:14 am |
|
|
And you will see why if you think that the figure should be in mV.....
#define MV_PER_COUNT (int16)(22870/1024)
The pity is I was hoping to teach him how to debug. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|