CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Variable initialization error
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ozturkhuseyin



Joined: 26 Jan 2024
Posts: 9

View user's profile Send private message

Variable initialization error
PostPosted: Fri Jan 26, 2024 6:44 am     Reply with quote

Code:

    float en1 = 0.0;
    float en2 = 0.0;
    float en3 = 0.0;
   
    en1 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY1_0);
    en2 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY2_0);
    en3 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY3_0);
   
    energyL1 = en1;
    energyL2 = en2;
    energyL3 = en3;
   
    DEBUG("READING ENERGY L1: %.8f \n", en1);
    DEBUG("READING ENERGY L2: %.8f \n", en2);
    DEBUG("READING ENERGY L3: %.8f \n", en3);


In this code block, i read last values from internal eeprom and update energyL1,2,3 variables, after systems reads energy consumption and writes it to energyL1,2,3 as shown below

Code:

      energyL1 = energyL1 + (((float)energyL1tmp) / 1702000.0);
      energyL2 = energyL2 + ((float)energyL2tmp) / 1702000.0;
      energyL3 = energyL3 + ((float)energyL3tmp) / 1702000.0;


But this isn't work, energyL1,2,3 are always 0, i tested eeprom read/write operations they worked. But when initializing energyL1 = en1; if data readen from eeprom on start is commented systems works and i can see exact consumption values on variable via uart debug.

energyL1,2,3 variables are defined in a header file of lib.
gaugeguy



Joined: 05 Apr 2011
Posts: 288

View user's profile Send private message

PostPosted: Fri Jan 26, 2024 9:19 am     Reply with quote

Please post the full code of what you are doing.
temtronic



Joined: 01 Jul 2010
Posts: 9111
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jan 26, 2024 10:51 am     Reply with quote

curious am i....
as I don't use floating points....

this format...
%.8f

to me says display a floating point number BUT only the 'fractional part, to eight places .

say n=12.34567890
you would only see .34567890 ???
I'd think. %11.8f to get 12.34567890 ??
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Fri Jan 26, 2024 11:59 am     Reply with quote

I'm worried about his referring to 'lib'. Does this imply multiple compilaon
untis are being used?. If so, a misdeclaration of the import/export could
easily result in the values not correctly being transferred between parts,
Also, why not debug yourself? You are displayng the 'en' values, why not
display the 'energyL' values at this point?
temtronic



Joined: 01 Jul 2010
Posts: 9111
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jan 26, 2024 4:02 pm     Reply with quote

energyL1 = energyL1 + (((float)energyL1tmp) / 1702000.0);

hmm, wonder where energyl1tmp comes from ?

it'd be easier if we saw a complete program.

agree that displaying the intermediate values and calculations would point to the problem.
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Sat Jan 27, 2024 12:11 pm     Reply with quote

and also what compiler version, and chip.
The compiler version is vital, since there have been two maths errors, one at
about 5.085, and another in the low 5.10x's, which could cause this behaviour.
Both were fixed quickly, and versions released with the fixes, but if he
has one of the faulty versions, this would explain everything.

In fact the casts are not needed, and on some chips will waste code space.

Code:

       energyL1 = energyL1 + (energyL1tmp / 1702000.0);

is all that is needed. The division by a float, implicitly converts the tmp
value into a float.

However how energyL1tm is actually declared, and how the value is
put into it, is vital.
ozturkhuseyin



Joined: 26 Jan 2024
Posts: 9

View user's profile Send private message

PostPosted: Mon Jan 29, 2024 1:56 am     Reply with quote

chip is PIC18F46K22, complier version is 5.104

energyL1tmp is unsigned int32, readen from adc chip via I2C. EnergyL1 is float.

I am reading ADC chip with 100ms period. And after each read i update EnergyL1 with adding new temp value. Systems backups EnergyL1 value to eeprom 5mins period. My problem is here is that when system start i read eeprom to update latest EnergyL1 value but when i do this like below code block it doesnt work.

Code:

    float en1 = 0.0;
    float en2 = 0.0;
    float en3 = 0.0;
   
    en1 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY1_0);
    en2 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY2_0);
    en3 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY3_0);
   
    energyL1 = en1;
    energyL2 = en2;
    energyL3 = en3;
   
    DEBUG("READING ENERGY L1: %.8f \n", en1);
    DEBUG("READING ENERGY L2: %.8f \n", en2);
    DEBUG("READING ENERGY L3: %.8f \n", en3);


If i comment energyL1 = en1; initialization system works but i cant update latest energy value. EnergyL1 remains at 0. I checked ADC chip it reads values but doesnt update EnergyL1 value.

Btw energyL1 is defined in ADC chip's header file.
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Mon Jan 29, 2024 4:41 am     Reply with quote

Er.

"unsigned int32".

Your value is perpetually going to grow. This can never give a value lower
than zero, so every addition will make your sum larger. There is a huge issue
here. I'm guessing this is actually a signed value read from the ADC, so
needs to actually be put into a signed int value before the cast.
Long term you will have the issue as outlined here:

[url]
http://www.ccsinfo.com/forum/viewtopic.php?t=59059&highlight=cast
[/url]

You are mixing case on EnergyL1 and energyL1. Is it possible you have
case sensitivity enabled?. If so, these are not the same variable.....
ozturkhuseyin



Joined: 26 Jan 2024
Posts: 9

View user's profile Send private message

PostPosted: Mon Jan 29, 2024 5:51 am     Reply with quote

They are same variable just i writed wrong here. Just energyL1.

Unsigned int32 value is a register inside ADC ic and it resets when i read.

Code:

energyL1tmp = readI2CDoubleWord(SLAVE_DEV_ADDR,0xE400);


Then dividing it to ratio and adding it to energyL1 variable as float. So value doesnt get large.
ozturkhuseyin



Joined: 26 Jan 2024
Posts: 9

View user's profile Send private message

PostPosted: Mon Jan 29, 2024 5:59 am     Reply with quote

Systems works well if i commented energyL1 initialization from eeprom reading but cant start with latest energyL1 value with this.

Code:

    float en1 = 0.0;
    float en2 = 0.0;
    float en3 = 0.0;
   
    en1 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY1_0);
    en2 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY2_0);
    en3 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY3_0);
   
    //energyL1 = en1;
    //energyL2 = en2;
    //energyL3 = en3;
   
    DEBUG("READING ENERGY L1: %.8f \n", en1);
    DEBUG("READING ENERGY L2: %.8f \n", en2);
    DEBUG("READING ENERGY L3: %.8f \n", en3);


If energyL1 initialization at system start is commented system works with correct values. But when i undo my comments system doesnt update energyL1 variable. I am debugging via uart.

Code:

read_adc();
DEBUG("|V1: %.3lf |C1: %.3lf |APP1: %.3lf |VAR1: %.3lf |PHI1: %.3lf |EN1: %.8f |ACTIVE1: %.3lf\n", vL1 / 11558.0 , cL1 / 112388.0, appL1 / 151.50181, varL1 / 151.50181, pfL1 / 1.0, energyL1 / 1.0, activeL1 / 151.50181);


If i initialize energyL1 with a random value as energyL1 = 1234.5; system works also, but when i try to update it from eeprom backup its value doesnt change on runtime even i got values from adc ic.
ozturkhuseyin



Joined: 26 Jan 2024
Posts: 9

View user's profile Send private message

PostPosted: Mon Jan 29, 2024 6:55 am     Reply with quote

my adc read function is as below

Code:

      energyL1tmp = readI2CDoubleWord(SLAVE_DEV_ADDR,0xE400);
      energyL2tmp = readI2CDoubleWord(SLAVE_DEV_ADDR,0xE401);
      energyL3tmp = readI2CDoubleWord(SLAVE_DEV_ADDR,0xE402);

/* other adc readings */

      energyL1 = energyL1 + ((float)energyL1tmp) / 1702000.0;
      energyL2 = energyL2 + ((float)energyL2tmp) / 1702000.0;
      energyL3 = energyL3 + ((float)energyL3tmp) / 1702000.0;

      DEBUG("kWh (tmp)...E1:%.6f, E2:%.6f, E3:%.6f ...\n",((float)energyL1tmp) / 1702000.0 ,((float)energyL2tmp) / 1702000.0, ((float)energyL3tmp) / 1702000.0);     
      DEBUG("kWh E1:%.6f, E2:%.6f, E3:%.6f ...\n",energyL1 ,energyL2, energyL3);


DEBUG output is :
kWh (tmp)E1:0.000058, E2:0.000000, E3:0.000000 -> printed from inside lib
kWh E1:0.000000, E2:0.000000, E3:0.000000 -> printed from inside lib
|V1: 225.608 |C1: 2.925 |APP1: 674.071 |VAR1: -54.428 |PHI1: 67.000 |EN1: 0.00000000 |ACTIVE1: 423.328 -> printed in main.c
kWh (tmp)E1:0.000058, E2:0.000000, E3:0.000000
kWh E1:0.000000, E2:0.000000, E3:0.000000
|V1: 225.563 |C1: 2.925 |APP1: 674.460 |VAR1: -54.791 |PHI1: 72.000 |EN1: 0.00000000 |ACTIVE1: 423.123
kWh (tmp)E1:0.000059, E2:0.000000, E3:0.000000
kWh E1:0.000000, E2:0.000000, E3:0.000000
|V1: 225.621 |C1: 2.923 |APP1: 674.671 |VAR1: -55.642 |PHI1: 64.000 |EN1: 0.00000000 |ACTIVE1: 422.443
kWh (tmp)E1:0.000058, E2:0.000000, E3:0.000000
kWh E1:0.000000, E2:0.000000, E3:0.000000
|V1: 225.631 |C1: 2.926 |APP1: 675.774 |VAR1: -56.540 |PHI1: 67.000 |EN1: 0.00000000 |ACTIVE1: 422.305
kWh (tmp)E1:0.000058, E2:0.000000, E3:0.000000
kWh E1:0.000000, E2:0.000000, E3:0.000000
|V1: 225.729 |C1: 2.923 |APP1: 675.199 |VAR1: -56.157 |PHI1: 69.000 |EN1: 0.00000000 |ACTIVE1: 422.833
kWh (tmp)E1:0.000058, E2:0.000000, E3:0.000000
kWh E1:0.000000, E2:0.000000, E3:0.000000
|V1: 225.632 |C1: 2.927 |APP1: 675.120 |VAR1: -56.052 |PHI1: 69.000 |EN1: 0.00000000 |ACTIVE1: 423.084
kWh (tmp)E1:0.000058, E2:0.000000, E3:0.000000
kWh E1:0.000000, E2:0.000000, E3:0.000000


MCU reads ADC from i2c with correct values(energyL1tmp) but cant update energyL1 value with them.

Code:

energyL1 = energyL1 + ((float)energyL1tmp) / 1702000.0;


if i comment lines in system start as shown

Code:

    float en1 = 0.0;
    float en2 = 0.0;
    float en3 = 0.0;
   
    en1 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY1_0);
    en2 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY2_0);
    en3 = ReadFloatEepromBackup(EE_ADDR_INDEX_ENERGY3_0);
   
     /* this lines */
    //energyL1 = en1;
    //energyL2 = en2;
    //energyL3 = en3;


system updates energyL1 value correctly but i have to read last values and initialize system on start with them.
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Mon Jan 29, 2024 8:40 am     Reply with quote

First, this:
Code:

read_adc();
DEBUG("|V1: %.3lf |C1: %.3lf |APP1: %.3lf |VAR1: %.3lf |PHI1: %.3lf |EN1: %.8f |ACTIVE1: %.3lf\n", vL1 / 11558.0 , cL1 / 112388.0, appL1 / 151.50181, varL1 / 151.50181, pfL1 / 1.0, energyL1 / 1.0, activeL1 / 151.50181);


Makes no sense at all. You are calling the read_adc function, and not storing
the result from this.

Then do what has already been suggested. Change your debug after the
EEPROM read, and display both the en1 value, and the energyL1 value.

Then post your ReadFloatEepromBackup function.

You also have not answered the question about whether you are using
multiple compilation units?.

Do you have access to a slightly older compiler?. 5.104, was one where
there was a maths problem.
temtronic



Joined: 01 Jul 2010
Posts: 9111
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Jan 29, 2024 1:25 pm     Reply with quote

It'd be real nice to know what ADC is being used.
I'm kinda confused as, if it's a 'double word' ( 32 bit ?) from the ADC , why convert to floating point and do FP math ?
Surely scaled integers would be a LOT faster and easier as PICs HATE floating point numbers.

Also eventually adding the new reading into a 32bit variable, it'll overflow.

It might be easier to reduce the code to test on ONE ADC channel ? It looks like it's a '3 phase power ' program and having similar named variables,easy to mistype,make a mistake that way ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19224

View user's profile Send private message

PostPosted: Tue Jan 30, 2024 12:03 pm     Reply with quote

I have to also suggest you re-code all your printf formats to actually be
legal C.

Understand that in C, the number in fromnt of the decimal on the printf,
is the total output field width, The number after the decimal is the
digits to display after the decimal, The number in front is _not_ the
width in front of the decimal.
So yoru format is sayong to print with a zero output length, and then
to print 8 decimals. Illegal.
Now noramlly the printf will overflow, and realise it has to output the
number of digits youy are asking for, but there was an issue about the
compiler version you have, where overflowing the field width resulted
in numbers being displayed incorrectly.
It'd be really silly if it was your printf format that was causing thiings to
go wrong.

%9.8f
ozturkhuseyin



Joined: 26 Jan 2024
Posts: 9

View user's profile Send private message

PostPosted: Thu Feb 01, 2024 1:56 am     Reply with quote

temtronic wrote:
It'd be real nice to know what ADC is being used.
I'm kinda confused as, if it's a 'double word' ( 32 bit ?) from the ADC , why convert to floating point and do FP math ?
Surely scaled integers would be a LOT faster and easier as PICs HATE floating point numbers.

Also eventually adding the new reading into a 32bit variable, it'll overflow.

It might be easier to reduce the code to test on ONE ADC channel ? It looks like it's a '3 phase power ' program and having similar named variables,easy to mistype,make a mistake that way ?


It is ADE7878 adc chip. You are right about not doing floating point math but library i used is designed with floating points and i must not change library. Readings from chip are not that big to overflow variables. I am just testing on channel 1 already.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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