Coulometer Time Remaining Not changing Instantly(SOLVED)

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
dariods
Posts: 21
Joined: 26 Apr 2023 07:12

Coulometer Time Remaining Not changing Instantly(SOLVED)

#1 Post by dariods » 28 Jun 2023 10:25

I have modified code available in the internet to create a battery coulometer using PIC16F886 and 20x4 LCD display. All function works well, except Time remaining. All other readouts change instantly only time remaining literally works like a counter.
eg. If I draw 18 amps from a 18aH battery the battery should discharge completely in 1 hour and if I draw 6 amps it should discharge in 3 hours. I have done the simulation in Proteus and actual hardware also. The time remaining doesn't change instantly. Explanation in Proteus, If the switch is on 6 Amp, the Time remaining is 3 hours which is right but if I switch it to 18 Amps ,time remaining doesn't drop down instantly to 1 hour and vice versa. How to achieve instant change in display of time remaining. Please help
I have attached the complete project files and Proteus Simulation files.

Code: Select all

                              // LCD module connections
sbit LCD_RS at RC2_bit;
sbit LCD_EN at RC3_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;

sbit LCD_RS_Direction at TRISC2_bit;
sbit LCD_EN_Direction at TRISC3_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End LCD module connections

 // Define Ports
#define MENU PORTB.RB4
#define PLUS PORTB.RB1
#define MINUS PORTB.RB2
//#define VSENSE PORTA.RA1    // Battery Voltage Sense
#define ALARM PORTA.RA5     // Charging Limit Alarm
//#define RPM PORTB.RB0     // Speedometer/Odometer Input

//functions prototypes
void CustomChar(char pos_row, char pos_char);
//void Lcd_COut(char row, char col, const char *cptr);
void menu();
void battery_capacity();
void charge_alarm();
void tire_size();
void power_calc();
void save_data();
void batt_percNbar();
void delay_100ms(unsigned char n);

char look(int a)
{
   switch(a)
   {
       case 0:
              return '0';
       case 1:
              return '1';
       case 2:
              return '2';
       case 3:
              return '3';
       case 4:
              return '4';
       case 5:
              return '5';
       case 6:
              return '6';
       case 7:
              return '7';
       case 8:
              return '8';
       case 9:
              return '9';
       default:
              return '.';
   }
}

const char character[] = {31,31,31,31,31,31,31,31};
const char character1[] = {31,31,31,31,31,31,31,31};

// global variables
unsigned char count_1ms = 0;        // count number of 1ms interrupts
unsigned char flag_200ms = 0;       // set HIGH once 0.2 second (200ms)

unsigned int a,vadc,save_maH;
unsigned long int aH;
unsigned int batt_cap;
unsigned short int batt_max = 0;
unsigned short int disarm_alarm = 0; // Battery Full Alarm
unsigned short int DspUpdInt = 0; // Display Update interval
float mAsec;
unsigned short idx = 0;  // Loop index to read msg1 array
unsigned short Col = 1;  // Loop index for Column position
unsigned char *ampHour = "00.000aH";


//Timer1
//Prescaler 1:1; TMR1 Preload = 61536; Actual Interrupt Time : 1 ms
// MCU frequency 16 MHz
//Place/Copy this part in declaration section
void InitTimer1(){
  T1CON         = 0x01;
  TMR1IF_bit    = 0;
  TMR1H         = 0xF0;
  TMR1L         = 0x60;
  TMR1IE_bit    = 1;
  INTCON        = 0xC0;
}


// Interrupt from timer 1 ever 1 millisecond
void Interrupt(){

    if (TMR1IF_bit){               // timer 1 interrupt
        TMR1IF_bit = 0;            // clear Interrupt bit
        TMR1H      = 0xF0;         // load new timer value
        TMR1L      = 0x60;
        count_1ms++;               // count up every 1ms

        if(count_1ms > 200){      // 200 times 1ms is 0.2 second(200mSec)
           count_1ms = 0;       // reset counter
          flag_200ms = 1;      // indicate that 0.2 second has passed
        }
    }
}

void CustomChar(char pos_row, char pos_char)
     {
     char jp;
     Lcd_Cmd(64);
     for (jp = 0; jp<=7; jp++) Lcd_Chr_CP(character[jp]);
     Lcd_Cmd(_LCD_RETURN_HOME);
     Lcd_Chr(pos_row, pos_char, 0);
     }
 


void delay_ms100(unsigned char n)
{
   while (n-- != 0) {
   delay_ms(100);
   }
}

 void battery_capacity() {
    
    unsigned short int setup = 1;
    unsigned short int batt_cap_new = 0;
    char *capacity = "00.000aH";
    const unsigned char msg1[] = "Battery Capacity";
    //batt_cap=18000; // 18A x 1000mA = 18aH
    batt_cap = (EEPROM_Read(4) << 8) | (EEPROM_Read(3));
    Lcd_Cmd(_LCD_CLEAR);

  Delay_ms(50);
  Col =1;
  for (idx =0; idx != sizeof(msg1)-1; idx++) Lcd_Chr(1,Col++,msg1[idx]);

  while(setup == 1)
   {
     if(PLUS == 0 & batt_cap<65500) //PORTB.F3(RB3)
     {
      Delay_ms(2);  // Switch Debouncing Protection
      if(PLUS == 0) batt_cap += 100;
     }
     else if (MINUS == 0 & batt_cap !=0) //PORTB.F2(RB2)
     {
      Delay_ms(2); // Switch Debouncing Protection
      if (MINUS == 0) batt_cap -= 100;
     }
     Delay_ms(100);

     if (batt_cap_new != batt_cap)
     {
      capacity[0] = look(batt_cap/10000);
      capacity[1] = look((batt_cap/1000)%10);
      capacity[3] = look((batt_cap/100)%10);
      capacity[4] = look((batt_cap/10)%10);
      capacity[5] = look((batt_cap/1)%10);
      Lcd_Out(2,1,capacity);
     }
     batt_cap_new = batt_cap;
      if(MENU == 0)    // PORTB.F4 (RB4)
     {
       Delay_ms(2);  // Switch Debouncing Protection
       if(MENU == 0)
      {
        EEPROM_Write(3, (batt_cap & 0xFF));
        EEPROM_Write(4, ((batt_cap >> 8) & 0xff));
        Lcd_chr(4,1,'*');
        Lcd_chr(4,2,'*');
        Lcd_chr(4,3,'*');
        Lcd_out(4,4,"SAVED");
        Lcd_chr(4,9,'*');
        Lcd_chr(4,10,'*');
        Lcd_chr(4,11,'*');
        setup = 0;
        Delay_ms(1000);
        Delay_ms(1000);
        Lcd_Cmd(_LCD_CLEAR);
       }
     }
   }
 }

void charge_alarm() {
 unsigned short int chargelimit;
 unsigned short int setup = 1;
 unsigned short int level_new = 0;
 unsigned char *level = "000%";
 const unsigned char msg1[] = "Charge Alarm";
 const unsigned char msg2[] = "***SAVED***";
 Lcd_Cmd(_LCD_CLEAR);
 
 Delay_ms(50);
  Col =1;
  for (idx =0; idx != sizeof(msg1)-1; idx++) Lcd_Chr(1,Col++,msg1[idx]);
  chargelimit = EEPROM_Read(5);

  while(setup == 1)
   {
     if(PLUS == 0 & chargelimit<250)
     {
       Delay_ms(2);  // Switch Debouncing Protection
       if(PLUS == 0) chargelimit += 1;
     }
     else if (MINUS == 0 & chargelimit !=0)
     {
       Delay_ms(2);   // Switch Debouncing Protection
       if (MINUS == 0) chargelimit -= 1;
     }
     Delay_ms(200);  // 0.2 Second delay

     if (level_new != chargelimit)
     {
      level[0] = look(chargelimit/100);
      level[1] = look((chargelimit/10)%10);
      level[2] = look((chargelimit/1)%10);
      Lcd_Out(2,2,level);
     }
     level_new = chargelimit;
     
     if(MENU == 0)
     {
        Delay_ms(2);  // Switch Debouncing Protection
        if(MENU == 0)
       {
        EEPROM_Write(5, (chargelimit));

        Col = 1;
        for (idx =0; idx != sizeof(msg2)-1; idx++) Lcd_Chr(4,Col++,msg2[idx]);
        setup = 0;
        delay_ms100(20); // 2 Second Delay
        Lcd_Cmd(_LCD_CLEAR);

       }
     }
  }
}

void tire_size() {
 const unsigned char msg1[] = "Coming Soon";
 Lcd_Cmd(_LCD_CLEAR);
 Col = 1;
 for (idx =0; idx != sizeof(msg1)-1; idx++) Lcd_Chr(2,Col++,msg1[idx]);
 delay_ms100(30);   // 3 Second Delay
 Lcd_Cmd(_LCD_CLEAR);
}

  void menu() {

    unsigned int ex = 1;
    unsigned int sw = 1;
    
    const unsigned char msg1[] = "Entering Main Menu";
    const unsigned char msg2[] = "Please Wait...";
    const unsigned char BattCap[] = "Battery Capacity";
    const unsigned char ChrgAlr[] = "Charge Alarm";
    const unsigned char TSize[] = "Tire Size";
    const unsigned char Exit[] = "Exit";

    /// ***How to call this as Function
    ////////////////////////////////////////////////////////////////////
    Col =1;
    for (idx =0; idx != sizeof(msg1)-1; idx++) Lcd_Chr(1,Col++,msg1[idx]);
    ////////////////////////////////////////////////////////////////////

    Col =1;
    for (idx =0; idx != sizeof(msg2)-1; idx++) Lcd_Chr(2,Col++,msg2[idx]);

    delay_ms100(30);  // Delay 3 Second

    
    Lcd_Cmd(_LCD_CLEAR);
    startmenu:
    CustomChar(sw,1);

    Col =3;
    for (idx =0; idx != sizeof(BattCap)-1; idx++) Lcd_Chr(1,Col++,BattCap[idx]);
    Col =3;
    for (idx =0; idx != sizeof(ChrgAlr)-1; idx++) Lcd_Chr(2,Col++,ChrgAlr[idx]);
    Col =3;
    for (idx =0; idx != sizeof(TSize)-1; idx++) Lcd_Chr(3,Col++,TSize[idx]);
    Col =3;
    for (idx =0; idx != sizeof(Exit)-1; idx++) Lcd_Chr(4,Col++,Exit[idx]);

     do
    {
     if(PLUS == 0 & sw<4) //PORTB.F3
      {
        Delay_ms(2); // Switch Debouncing Protection
        if(PLUS == 0)
          {
           Lcd_out(sw,1," ");
           sw++;
           CustomChar(sw,1);
          }
      }
     else if (MINUS == 0 & sw !=1) //PORTB.F2
      {
        Delay_ms(2); // Switch Debouncing Protection
        if (MINUS == 0)
         {
           Lcd_out(sw,1," ");
           sw--;
           CustomChar(sw,1);
         }
      }
      delay_ms100(10);
       if(MENU == 0 & ex == 1) //PORTB.F4
         {
         Delay_ms(2); // Switch Debouncing Protection
         if(MENU == 0 & ex == 1); //PORTB.F4
         {
            if(sw==1) 
            {
            battery_capacity();
            goto startmenu;
            }

             else if(sw==2) 
             {
             charge_alarm();
             goto startmenu;
             }
             
             else if(sw==3) 
             {
             tire_size();
             goto startmenu;
             }

             else if(sw==4) ex=0;
          }
        }

    }while(ex==1);
    ex=0;
   }

 void power_calc(){
  //unsigned int dloop;
  unsigned int v,amps;
  unsigned long int wt;
  float i;
  
  char *volt = "00.00V";
  char *current = "00.00A";
  char *watt = "000W";
  char *sign;
  
               ADCON1 = 0x00;
               vadc = ADC_Read(0); // Read AN0/RA0 for voltage
               v = ((vadc*4.89));
               //Delay_ms(10);
               //for (dloop=0; dloop<20;dloop++) //Read value for 10 Times
               //{
               {
                 a = ADC_Read(3);  // Read AN2/RA2 for current
                 if (a>=511)
                 {
                  i = (float)(((a-511)*4.89)/6.6);
                  sign = "-";     //Battery Discharging
                 }
                 else if (a<510)
                 {
                  i = (float)(((511-a)*4.89)/6.6);
                  sign = "+";     // Battery Charging
                  }
               }
               //}
             //i/=20;
             amps = (int)(i*10);
             mAsec =(float)(i/180);  // mA/0.2Sec
             
             if(DspUpdInt > 4) //Display Voltage,Current,Watts every 1 Second
           {
             wt = ((long)v*i)/1000;

             //////////////////////
             //***LCD Line 2 ***//
             /// Voltage Display ///
             volt[0] = look(v/1000);
             volt[1] = look((v/100)%10);
             volt[3] = look((v/10)%10);
             volt[4] = look((v/11)%10);
             Lcd_Out(1,1,volt);

             /// Display  Current ///
             current[0] = look(amps/1000);
             current[1] = look((amps/100)%10);
             current[3] = look((amps/10)%10);
             current[4] = look((amps/1)%10);
             Lcd_Out(1,8,sign);
             Lcd_Out(1,9,current);

             /// Display Wattage  ///
             watt[0] = look(wt/100);
             watt[1] = look((wt/10)%10);
             watt[2] = look((wt/1)%10);
             Lcd_Out(1,16,sign);
             Lcd_Out(1,17,watt);
          }
 }
 
 void batt_percNbar() {
  unsigned long int batt_perc;
  unsigned long int BarSegmentNum;
  unsigned int bm;

  char z;
  char battcap[] = "  0%";

  batt_perc = (100*aH)/batt_cap;

  BarSegmentNum = (batt_perc/5) + 1;
     if (a<510 & batt_perc >= (EEPROM_Read(5)))
      {
       if(disarm_alarm != 1)
        {  ALARM = !ALARM; // Toggle RB5
           if(MENU == 0 || PLUS == 0 || MINUS == 0) 
           {
            disarm_alarm = 1;
            ALARM = 0;
           }
        }
      }
     else ALARM = 0;
 
        //////////////////////////////////
        //***LCD Line 3 ***//
        // Display Battery Percentage
        if (DspUpdInt > 4)
        {
            if (batt_perc >= 100)
            battcap[0] = look(batt_perc/100);
            battcap[1] = look((batt_perc/10)%10);
            battcap[2] = look((batt_perc/1)%10);
            Lcd_out(3,8,battcap);
        }
        ////////////////////////////
        //***LCD Line 4 ***//
        //  Display Battery Percentage in Bar Graph
       if (BarSegmentNum>21) BarSegmentNum=21;
       if (batt_max<BarSegmentNum)
        {
         for (z=batt_max;z<BarSegmentNum;z++) // Loop to print each bar segment in 4th row
          {
            if (!z<1) CustomChar(4,z); // Print custom character for bargraph segment
          }
        }
        else if (batt_max>BarSegmentNum)
        {
         {
          for (bm=BarSegmentNum;bm<21;bm++)
            {
             Lcd_out(4,bm," "); // Delete unused bar segment
            }
          }
        }
        batt_max = BarSegmentNum;

 }
 
 
 void save_data() {
  /////////////////////////////////////////////////
  // ** EEPROM Save Last aH Value on Power OFF **//
  ////////////////////////////////////////////////
  const unsigned char msg1[] = "Last Data Saved";

  Lcd_Cmd(_LCD_CLEAR);
    if (aH > batt_cap) aH = batt_cap;

    Lcd_Cmd(_LCD_CLEAR);
    Lcd_Cmd(_LCD_CURSOR_OFF);

    EEPROM_Write(1, (aH & 0xFF));
    EEPROM_Write(2, ((aH >> 8) & 0xff));
    Col = 1;
    for (idx =0; idx != sizeof(msg1)-1; idx++) Lcd_Chr(1,Col++,msg1[idx]);
    amphour[0] = look(aH/10000);
    amphour[1] = look((aH/1000)%10);
    amphour[3] = look((aH/100)%10);
    amphour[4] = look((aH/10)%10);
    amphour[5] = look((aH/1)%10);
    Lcd_Out(2,1,amphour);
    /////////////////////////////////////
 }


void main()
{

  unsigned int sample,hrs,min,sec;
  float maH,maH_tmp,mAavg,total_aH,timeSec;
  //unsigned int atimeSec;//,timeSec;
  unsigned char *TimeRemain = "00:00:00";


  //char timet;
  PORTA = 0x00;   // Clear PORTA before use
  ANSEL = 0b00001001; // Enable Analog function only on RA0,RA2
  // Set Input / Output Pins on PORTA
  TRISA = 0b11001001;//RA0=I,RA1=O,RA2=O,RA3=I,RA4=0,RA5=0,RA6=I,RA7=I

  PORTB = 0x00; // Clear PORTB before use
  ANSELH = 0x00;  // Disable Analog/ADC function on PortB
  // Set Input / Output Pins on PORTA
  TRISB = 0b00011110;//RB0=O,RB1=I,RB2=I,RB3=I,RB4=I,RB5=O,RB6=O,RB7=O

  OPTION_REG.NOT_RBPU=0;
  //WPUB = 0xFD; // no pull up resistor on RB1
  WPUB = 0b00011110; // Pull up resistor on RB1,RB2,RB3,RB4
  
  Lcd_Init();
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  sample = 0;
  maH_tmp = 0;

   if(MENU == 0) menu();// Button at RB4 pressed
   
   batt_cap = (EEPROM_Read(4) << 8) | (EEPROM_Read(3));
   total_aH = (EEPROM_Read(2) << 8) | (EEPROM_Read(1));
   // If stored capacity>set capacty,reset to set capacity
   if (total_aH>batt_cap) total_aH = batt_cap;
   
   if(MINUS == 0) total_aH = batt_cap;// Reset ampHour to Battery MAX Capacity

   Lcd_Cmd(_LCD_CLEAR);

   InitTimer1();      // set up timer 1 for Interrupt every 1 milliseconds
          ///////////////////////////////
         // Initiate main calculations //
         ///////////////////////////////
   Lcd_out(3,1,"0");
   Lcd_chr(3,2,'%');
   Lcd_out(3,17,"100");
   Lcd_chr(3,20,'%');
  do
     {
        {
         while(!flag_200ms);
         flag_200ms = 0;            // reset the 0.2 Second flag
         {
            DspUpdInt++;
            power_calc();  // Run Voltage, Current and Wattage Calculations

            {
             if (a>=511)  // Discharging
              {
                maH += mAsec;
                      if (maH>batt_cap) maH = batt_cap;
                      if (total_aH<mAsec) total_aH = 0;
                      else total_aH -= mAsec;
                      if (maH_tmp != maH)
                      sample++;
                      mAavg = maH / sample;
                      maH_tmp = maH;
                      if (aH !=0) timeSec = (float)((total_aH/mAavg)/5); // time remaining in seconds;
                      //if (aH !=0) timeSec = (total_aH/mAavg); // time remaining in seconds;
                      //timeSec = timeSec/5;
               }
                 else if (a<510) // Charging
               {
                 maH += mAsec ;
                      total_aH += mAsec;
                      //if (total_aH>batt_cap) total_aH = batt_cap;
                      if (maH_tmp != maH)
                      sample++;
                      mAavg = (float)maH/sample;
                      maH_tmp = maH;
                      if (batt_cap>total_aH)
                      timeSec = (float)(((batt_cap-total_aH)/mAavg)/5); // time remaining in seconds
                      //timeSec = (((batt_cap-total_aH)/mAavg)/5); // time remaining in seconds
                      else if (batt_cap<total_aH)
                      timeSec = (float)(((total_aH-batt_cap)/mAavg)/5); // time remaining in seconds
                      //timeSec = (((total_aH-batt_cap)/mAavg)/5); // time remaining in seconds
               }
             }
                 aH = (int)total_aH;

                 {
                  if (timeSec >= 3600) hrs = (timeSec/3600);
                  else hrs = 0;
                  if (timeSec >= 60) min = (timeSec-(hrs*3600))/60;
                  else min = 0;
                  if (timeSec != 0) sec = timeSec-((hrs*3600)+(min*60));
                  else sec = 0;
                 }
               //////////////////////
               //***LCD Line 2 ***//
               /// Ams-Hour Display ///

               amphour[0] = look((aH/10000)%10);
               amphour[1] = look((aH/1000)%10);
               amphour[3] = look((aH/100)%10);
               amphour[4] = look((aH/10)%10);
               amphour[5] = look((aH/1)%10);
               Lcd_Out(2,1,amphour);

               /// Charge-Discharge Time Remaining ///
////////////////////////////////////////////////////
               //****Problem - Time remaining doest change instantly
               //if(DspUpdInt > 4)
              {
               TimeRemain[0] = look(hrs/10);
               TimeRemain[1] = look((hrs/1)%10);
               TimeRemain[3] = look(min/10);
               TimeRemain[4] = look((min/1)%10);
               TimeRemain[6] = look(sec/10);
               TimeRemain[7] = look((sec/1)%10);
               Lcd_Out(2,11,TimeRemain);
              }
//////////////////////////////////////////////////
//////////////////////////////////////////////////
              batt_percNbar(); //Calculate & Display Battery Percentage/Bar
              if(DspUpdInt >= 5) DspUpdInt = 0; // 1 Second passed, Reset
          }
       }
    } while(vadc>500); //loop until Voltage more than 25 Volts on RA0 Pin

      save_data(); // save last capacity on Power Off
 }
Attachments
Coulometer.rar
The complete project files
(693.5 KiB) Downloaded 26 times
Last edited by dariods on 01 Jul 2023 14:35, edited 2 times in total.

dariods
Posts: 21
Joined: 26 Apr 2023 07:12

Re: Coulometer Time Remaining Not changing Instantly

#2 Post by dariods » 28 Jun 2023 10:28

Double post

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: Coulometer Time Remaining Not changing Instantly

#3 Post by hexreader » 29 Jun 2023 02:27

Attached is my attempt at a quick fix

// status 29 June 2023
//
// Only changes from original are :
// 1 default to 18 AH if EEPROM is blank (as when programmed)
// 2 formatting improvements
// 3 timing display over-ridden with a new simpler function
//
// - will latewr provide a function for text print to LCD
// - don't understand what the original time display was about - seems useless at the moment
// - would be good to force settings menu if EEPROM is blank
// - remove redundant time remaining code once replacement calculation shown to be good

What is the time display actually meant to indicate?
Attachments
Coulometer.zip
(776.11 KiB) Downloaded 29 times
Start every day with a smile...... (get it over with) :)

dariods
Posts: 21
Joined: 26 Apr 2023 07:12

Re: Coulometer Time Remaining Not changing Instantly

#4 Post by dariods » 29 Jun 2023 15:49

hexreader wrote:
29 Jun 2023 02:27
Attached is my attempt at a quick fix

// status 29 June 2023
//
// Only changes from original are :
// 1 default to 18 AH if EEPROM is blank (as when programmed)
// 2 formatting improvements
// 3 timing display over-ridden with a new simpler function
//
// - will latewr provide a function for text print to LCD
// - don't understand what the original time display was about - seems useless at the moment
// - would be good to force settings menu if EEPROM is blank
// - remove redundant time remaining code once replacement calculation shown to be good

What is the time display actually meant to indicate?
The time display is meant to indicate time remaining to battery discharge when using the motor and time remaining for the battery to be fully charged..
Eg. For a 18ah battery if I am driving at say constant speed and my motor is consuming 9 amps, the time remaining should show 2 hours.
When I am charging the battery the time remaining should show the time left to full charge the battery. I have not tried the modification given by you but will try and revert back soon. Thanks for being of so much help to me always.

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: Coulometer Time Remaining Not changing Instantly

#5 Post by hexreader » 30 Jun 2023 01:06

Updated code version attached

See comments at top of code to see what has changed
Attachments
Coulometer.zip
(773.13 KiB) Downloaded 26 times
Start every day with a smile...... (get it over with) :)

dariods
Posts: 21
Joined: 26 Apr 2023 07:12

Re: Coulometer Time Remaining Not changing Instantly

#6 Post by dariods » 30 Jun 2023 07:43

hexreader wrote:
30 Jun 2023 01:06
Updated code version attached

See comments at top of code to see what has changed
Your previous code works perfectly. I have done some changes in it to suite me.

Your code

Code: Select all

if(batt_cap = 0xffff){                                               // is EEPROM blank?
        batt_cap = 18000;                                                   // if so, then default to 18 AH
    }
I want it to be universal upto 65 amps so I changed to

Code: Select all

// force settings menu if EEPROM is blank as suggested by you
if(MENU == 0) || ((EEPROM_Read(4) << 8) | (EEPROM_Read(3)) = 0xffff){    // Button at RB4 pressed OR is EEPROM blank?
        menu();
    }
your code

Code: Select all

// the following lines of code are a simple alternative to the original calculation of timeSec variable
        if(charging_flag){                                                      // time-to-full display if charging
            if (aH < batt_cap){                                                 // if less than 100%
                timeSec = batt_cap - aH;                                        // full charge minus charge now
                timeSec = timeSec * 360;                                        // don't know why 360 rather than 3600, but it works
                timeSec = timeSec / amps;                                       // time in hours = AmpHours / amps
            }
            else{                                                               // over 100% charged
                timesec = 0;                                                    // - so show zero time remaining
            }
        }
        else{
            timeSec = aH * 360;                                                 // don't know why 360 rather than 3600, but it works
            timeSec = timeSec / amps;                                           // time in hours = AmpHours / amps
        }
The calculations may have errors in displaying the discharge and charge so if the battery max capacity is set to 18 aH the charging may show more than 18aH so allow it to show percentage more than 100 and count time up so it shows activity on LCD Display. Anyways even if the charge goes above the set battery capacity I save it to set battery capacity
These are my changes

Code: Select all

// the following lines of code are a simple alternative to the original calculation of timeSec variable
        if(charging_flag){                                                      // time-to-full display if charging
            if (aH < batt_cap){                                                 // if less than 100%
                timeSec = batt_cap - aH;                                        // full charge minus charge now

            }
            else if (aH > batt_cap){                                            // over 100% charged(There could be an error in calculations)
                timeSec = aH - batt_cap;
            }
                timeSec = timeSec * 360;                                        // don't know why 360 rather than 3600, but it works
        }
        else{
            timeSec = aH * 360;                                                 // don't know why 360 rather than 3600, but it works
        }
I am facing a problem. If I set the battery capacity to more than 50% of 65535 i.e. 32800 aH and above the calculation display or when I select exit the aH starts from 1800+ (32800 + 1800 = 34600). I dont know why. Please guide,

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: Coulometer Time Remaining Not changing Instantly

#7 Post by hexreader » 30 Jun 2023 11:57

Here is the next iteration of the code with AH greater than 32.767 AH fixed and forced settings menu for blank EEPROM

I could not make sense of your second code change, so I left it alone for you to implement
Attachments
Coulometer.zip
(765.38 KiB) Downloaded 24 times
Start every day with a smile...... (get it over with) :)

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: Coulometer Time Remaining Not changing Instantly

#8 Post by hexreader » 30 Jun 2023 16:42

Ah... I think I can maybe guess what you wanted....

You want to show time past 100%?

Makes no sense to me - this is just a confusing indication in my mind, but here it is anyway...
Attachments
Coulometer.zip
(765.86 KiB) Downloaded 28 times
Start every day with a smile...... (get it over with) :)

dariods
Posts: 21
Joined: 26 Apr 2023 07:12

Re: Coulometer Time Remaining Not changing Instantly

#9 Post by dariods » 01 Jul 2023 06:42

hexreader wrote:
30 Jun 2023 16:42
Ah... I think I can maybe guess what you wanted....

You want to show time past 100%?

Makes no sense to me - this is just a confusing indication in my mind, but here it is anyway...
I have checked the code in Proteus simulation, will program the pic and check it in actual hardware.

dariods
Posts: 21
Joined: 26 Apr 2023 07:12

Re: Coulometer Time Remaining Not changing Instantly

#10 Post by dariods » 05 Mar 2024 15:47

hexreader wrote:
30 Jun 2023 16:42
can you please help me to read write custom character array to EEPROM?
viewtopic.php?f=88&t=80542&p=318319#p318319

Post Reply

Return to “mikroC PRO for PIC General”