Car battery monitor,

jayanthd

Joined Jul 4, 2015
945
This is the new circuit you have to build. Only PORTA connections have changed.

Use 2.2k for R3.

See result.

Do you want a Battery low alarm using a 5V buzzer on CCP1 pin ?

 

Attachments

jayanthd

Joined Jul 4, 2015
945
Find the attached .hex file.

Attached is the final Schematic. RN2 is not needed in real hardware. It is used only for simulation.

Here is the code.

Code:
#include "float2ascii.h"

#define Ascii_Base 0x30
#define Dp         0x80;
#define Blank      0xFF

#define SSD_DATA_PORT PORTB
#define SSD_CTRL_PORT PORTA

//#define Max_Volt_To_Measure 15.698924
#define Max_Volt_To_Measure 14.6
#define Adc_Resolution      1023

char str_Volt[32];

unsigned int raw_adc_value = 0, previous_raw_adc_value = 1023;
double volt = 0.0;

unsigned char digits[4] = {0, 0, 0, 0};
unsigned char digit = 0;
unsigned char cc_mask[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

unsigned char my_flags = 0;

sbit run_once_flag at my_flags.B0;

//Timer1
//Prescaler 1:1; TMR1 Preload = 64536; Actual Interrupt Time : 1 ms
void InitTimer1() {
    T1CON = 0x01;
    TMR1IF_bit = 0;
    TMR1H = 0xFC;
    TMR1L = 0x18;
    TMR1IE_bit = 1;
}

void Interrupt() {
    if((TMR1IE_bit) && (TMR1IF_bit)) {
        //Enter your code here
        SSD_CTRL_PORT &= 0xD1;

        switch(digit) {
             case 0:
                  SSD_DATA_PORT = digits[0];
                  SSD_CTRL_PORT = (SSD_CTRL_PORT & 0xD1) | 0x02;
                  break;
             case 1:
                  SSD_DATA_PORT = digits[1];
                  SSD_CTRL_PORT = (SSD_CTRL_PORT & 0xD1) | 0x04;
                  break;
             case 2:
                  SSD_DATA_PORT = digits[2];
                  SSD_CTRL_PORT = (SSD_CTRL_PORT & 0xD1) | 0x08;
                  break;
             case 3:
                  SSD_DATA_PORT = digits[3];
                  SSD_CTRL_PORT = (SSD_CTRL_PORT & 0xD1) | 0x20;
                  break;
        };

        if(++digit >= 4) {
            digit = 0;
        }
  
        TMR1IF_bit = 0;
        TMR1H = 0xFC;
        TMR1L = 0x18;
    }
}

void main(void) {

    CMCON = 0x07;

    ADCON0 = 0x40;
    ADCON1 = 0xCE;

    TRISA = 0x01;
    TRISB = 0x00;
    TRISC = 0x00;
    TRISD = 0x00;
    TRISE = 0x00;

    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;

    Delay_ms(200);

    InitTimer1();

    while (1) {

        raw_adc_value = ADC_Read(4);
        Delay_us(20);
  
        if(previous_raw_adc_value != raw_adc_value) {
            volt = (((double)raw_adc_value * Max_Volt_To_Measure) / Adc_Resolution);
        
            Float2Ascii(volt, str_Volt, 3);
        
            if((volt >= 1.0) && (volt < 10.0)) {
               digits[0] = cc_mask[str_Volt[0] - Ascii_Base] | Dp;
               digits[1] = cc_mask[str_Volt[2] - Ascii_Base];
               digits[2] = cc_mask[str_Volt[3] - Ascii_Base];
               digits[3] = cc_mask[str_Volt[4] - Ascii_Base];
            }
            else if((volt >= 10.0) && (volt < 100.0)) {
               digits[0] = cc_mask[str_Volt[0] - Ascii_Base];
               digits[1] = cc_mask[str_Volt[1] - Ascii_Base] | Dp;
               digits[2] = cc_mask[str_Volt[3] - Ascii_Base];
               digits[3] = cc_mask[str_Volt[4] - Ascii_Base];
            }

            if(run_once_flag == 0) {
                INTCON = 0xC0;
                run_once_flag = 1;
            }
      
            previous_raw_adc_value = raw_adc_value;
        }
    }
}




A bug I found.

Replace

Code:
if((volt >= 1.0) && (volt < 10.0)) {
with

Code:
if((volt >= 0.0) && (volt < 10.0)) {
 

Attachments

Last edited:

jayanthd

Joined Jul 4, 2015
945
Condensed the code a little. I still have to see if the code can be condensed more.

Code:
#include "float2ascii.h"

#define Ascii_Base 0x30
#define Dp         0x80;

#define SSD_DATA_PORT PORTB
#define SSD_CTRL_PORT PORTA

#define Max_Volt_To_Measure 15.6989247
#define Adc_Resolution      1023

char str_Volt[32];

unsigned int raw_adc_value = 0, previous_raw_adc_value = 1023;
double volt = 0.0;

unsigned char digits[4] = {0, 0, 0, 0};
unsigned char digit = 0, shift_value = 0x02;
unsigned char cc_mask[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

unsigned char my_flags = 0;

sbit run_once_flag at my_flags.B0;

//Timer1
//Prescaler 1:1; TMR1 Preload = 64536; Actual Interrupt Time : 1 ms
void InitTimer1() {
    T1CON = 0x01;
    TMR1IF_bit = 0;
    TMR1H = 0xFC;
    TMR1L = 0x18;
    TMR1IE_bit = 1;
}

void Interrupt() {
    if((TMR1IE_bit) && (TMR1IF_bit)) {
        //Enter your code here
        SSD_CTRL_PORT &= 0xD1;

        SSD_DATA_PORT = digits[digit];
        SSD_CTRL_PORT = (SSD_CTRL_PORT & 0xD1) | shift_value;
      
        shift_value <<= 1;
      
        if(shift_value == 0x10)shift_value <<= 1;
        if(shift_value == 0x40)shift_value = 0x02;

        if(++digit >= 4) {
            digit = 0;
        }
      
        TMR1IF_bit = 0;
        TMR1H = 0xFC;
        TMR1L = 0x18;
    }
}

void main(void) {

    CMCON = 0x07;

    TRISA = 0x01;
    TRISB = 0x00;
    TRISC = 0x00;
    TRISD = 0x00;
    TRISE = 0x00;
  
    ADCON0 = 0x40;
    ADCON1 = 0xCE;
  
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;

    Delay_ms(200);

    InitTimer1();
  
    while (1) {

        raw_adc_value = ADC_Read(0);
        Delay_us(20);
      
        if(previous_raw_adc_value != raw_adc_value) {
            volt = (((double)raw_adc_value * Max_Volt_To_Measure) / Adc_Resolution);
            
            Float2Ascii(volt, str_Volt, 3);
            
            if((volt >= 0.0) && (volt < 10.0)) {
               digits[0] = cc_mask[str_Volt[0] - Ascii_Base] | Dp;
               digits[1] = cc_mask[str_Volt[2] - Ascii_Base];
            }
            else if((volt >= 10.0) && (volt <= 16.0)) {
               digits[0] = cc_mask[str_Volt[0] - Ascii_Base];
               digits[1] = cc_mask[str_Volt[1] - Ascii_Base] | Dp;
            }
          
            if((volt >= 0.0) && (volt <= 16.0)) {
              digits[2] = cc_mask[str_Volt[3] - Ascii_Base];
              digits[3] = cc_mask[str_Volt[4] - Ascii_Base];
            }
          
            if(run_once_flag == 0) {
                INTCON = 0xC0;
                run_once_flag = 1;
            }
          
            previous_raw_adc_value = raw_adc_value;
        }
    }
}
 

Attachments

Last edited:

jayanthd

Joined Jul 4, 2015
945
Thank you i will studied
Reduced the RAM usage.

Code:
#define Dp         0x80;

#define SSD_DATA_PORT PORTB
#define SSD_CTRL_PORT PORTA

#define Max_Volt_To_Measure 15.6989247
#define Adc_Resolution      1023.0

unsigned int raw_adc_value = 0, previous_raw_adc_value = 1023;
double volt = 0.0;
unsigned int tmp = 0;
char ten = 10;

unsigned char digits[4] = {0, 0, 0, 0};
unsigned char digit = 0, shift_value = 0x02;
unsigned char cc_mask[10] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};

unsigned char my_flags = 0;

sbit run_once_flag at my_flags.B0;

//Timer1
//Prescaler 1:1; TMR1 Preload = 64536; Actual Interrupt Time : 1 ms
void InitTimer1() {
    T1CON = 0x01;
    TMR1IF_bit = 0;
    TMR1H = 0xFC;
    TMR1L = 0x18;
    TMR1IE_bit = 1;
}

void Interrupt() {
    if((TMR1IE_bit) && (TMR1IF_bit)) {
        //Enter your code here
        SSD_CTRL_PORT &= 0xD1;

        SSD_DATA_PORT = digits[digit];
        SSD_CTRL_PORT = (SSD_CTRL_PORT & 0xD1) | shift_value;
       
        shift_value <<= 1;
       
        if(shift_value == 0x10)shift_value <<= 1;
        if(shift_value == 0x40)shift_value = 0x02;

        if(++digit >= 4) {
            digit = 0;
        }
       
        TMR1IF_bit = 0;
        TMR1H = 0xFC;
        TMR1L = 0x18;
    }
}

void main(void) {

    CMCON = 0x07;

    TRISA = 0x01;
    TRISB = 0x00;
    TRISC = 0x00;
    TRISD = 0x00;
    TRISE = 0x00;
   
    ADCON0 = 0x40;
    ADCON1 = 0xCE;
   
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    PORTE = 0x00;

    Delay_ms(200);

    InitTimer1();
   
    while (1) {

        raw_adc_value = ADC_Read(0);
        Delay_us(20);
       
        if(previous_raw_adc_value != raw_adc_value) {
            volt = (((double)raw_adc_value * Max_Volt_To_Measure) / Adc_Resolution);
           
            if((volt >= 0.0) && (volt < 10.0)) {
               tmp = (unsigned int)(volt * 1000.0);
               
               digits[3] = cc_mask[tmp % ten];          tmp /= ten;
               digits[2] = cc_mask[tmp % ten];          tmp /= ten;
               digits[1] = cc_mask[tmp % ten];          tmp /= ten;
               digits[0] = cc_mask[tmp % ten] | Dp;
            }
            else if((volt >= 10.0) && (volt <= 16.0)) {
               tmp = (unsigned int)(volt * 100.0);
               
               digits[3] = cc_mask[tmp % ten];          tmp /= ten;
               digits[2] = cc_mask[tmp % ten];          tmp /= ten;
               digits[1] = cc_mask[tmp % ten] | Dp;     tmp /= ten;
               digits[0] = cc_mask[tmp % ten];
            }
           
            if(run_once_flag == 0) {
                INTCON |= 0xC0;
                run_once_flag = 1;
            }
           
            previous_raw_adc_value = raw_adc_value;
        }
    }
}
 

Attachments

Thread Starter

Zun

Joined Aug 6, 2017
72
I just to program my pic, and, its say receive data error, and i try previous code, from first time pic16f1827 just OK, wonder
 

jayanthd

Joined Jul 4, 2015
945
DIY k150 v150807,i don't know genuine or clone, may about my pic kit
I have mikroProg for PIC Program,mer/Debugger and I never had problems with it.

99 USD. Is it much ? You get technical support and firmware updates when new devices are added. Works with mikroC/mikrobasic/mikroPascal Pro PIC/dsPIC/PIC32 Compilers.
 
Top