# decimals in xc8

Status
Not open for further replies.

#### Dr_Doggy

##### Well-Known Member
First please note that the value for eeprom#2 =oxFF is wrong due to importing during writing, the actual value is 0, because Green is multiplied by 0 in the subroutine.

... which leads me to my problem... variable Im should be calculation that returns percent value of solar intensity, however as we can see in eeprom Im returns as 0, which i dont think is always the case cause the led is on sometimes, but I have not yet sampled data where the green value is other than 0 & 255...

.... so basically my problem is: How do i get the percent value of "Im" to multiply properly by the "Green" value?! ... which if i calculated correctly should be a decimal value between 0 & 1, I have tried calling it as both a float and double,...

EEPROM Output = AA 00 FF 6F 8C 7F 00

Code:
unsigned int solar = 0;
unsigned int  solarMin = 255;
unsigned int  solarMax = 0;

unsigned char Red = 0;
unsigned char Green = 0;
unsigned char Blue = 0;

while (1){
solar = getSolar();   // Dark=63 Light=129
if (solar > solarMax){solarMax = solar;}
if (solar < solarMin){solarMin = solar;}

setColorB(2);  // sets values for Green = 255;

float Im;

Im =  (solar - solarMin)/(solarMax-solarMin);   // convert solar to percent
//               if (Im > 1){Im = 1;}
//               if (Im < 0){Im = 0;}
I = Green *  Im;             // ajust green based on solar percent
Green = (unsigned char)(Im);

Im = Im*100;

EEPROM_WRITE(0, 0xAA);
EEPROM_WRITE(1, ((unsigned char)(Im)));
EEPROM_WRITE(2, Green);
EEPROM_WRITE(3, ((unsigned char)(solarMin)));
EEPROM_WRITE(4, ((unsigned char)(solarMax)));
EEPROM_WRITE(5, ((unsigned char)(solar)));
EEPROM_WRITE(6, ((unsigned char)(I)));

}

#### Jon Wilder

##### Active Member
Can you post the code for function getSolar();?

#### Dr_Doggy

##### Well-Known Member
getsolar is just reading analog pin 3 and returns a 10 bit value ... will post it tonite if required

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
My only concern here is that EEprom only has 100,000 (ish) cycles.... If this routine runs 10 times a second for two days, the eeprom will be exhausted!!

Also this line
Im = (solar - solarMin)/(solarMax-solarMin); // convert solar to percent
will always yield a 0, as solar is an int... Use a cast

Im = ((float)solar - solarMin)/((float)solarMax-solarMin); // convert solar to percent

Then Im will get a float!!#

#### Dr_Doggy

##### Well-Known Member
Thanks Ian!
eeprom is only for debugging here!

I thought about it last night .. knew i was casting wrong ..surprised that it didnt recognize it all as float when i set the Im as the float ... thanks for affirmation, would have taken a bit to figure out!

#### Pommie

##### Well-Known Member
Note that the cast in Green = (unsigned char)(Im); will be 0 or 1 and only 1 at solar max.

Mike.

#### Dr_Doggy

##### Well-Known Member
cast again like this?

I = (float)Green * Im; // ajust green based on solar percent

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Note that the cast in Green = (unsigned char)(Im); will be 0 or 1 and only 1 at solar max.

Mike.
I think the line
Im = Im*100;
should come before the line
Green = (unsigned char)(Im);

#### Dr_Doggy

##### Well-Known Member
my thinking is:
Im = current/total = percent, or 0. value
so when solar is at 50% should be (float)0.5
0.5(Im) * 255(green) = 127(new val for green)

Im * 100; // convert 0.5(50%) to whole number for eeprom
0.5 * 100 = 50 // better value for eeprom

still a glitch somewhere i think, but could be related to post 9, didn't get a chance to test yet

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
This is my take..

C:
unsigned int solar = 0;
unsigned int  solarMin = 255;
unsigned int  solarMax = 0;

unsigned char Red = 0;
unsigned char Green = 0;
unsigned char Blue = 0;

while (1){
solar = getSolar();   // Dark=63 Light=129
if (solar > solarMax){solarMax = solar;}
if (solar < solarMin){solarMin = solar;}

setColorB(2);  // sets values for Green = 255;

float Im, I;

Im =  ((float)solar - solarMin)/((float)solarMax-solarMin);   // convert solar to percent
//               if (Im > 1){Im = 1;}
//               if (Im < 0){Im = 0;}

I = (unsigned char)((float)Green *  Im);

Im = Im*100;

EEPROM_WRITE(0, 0xAA);
EEPROM_WRITE(1, ((unsigned char)(Im)));
EEPROM_WRITE(2, Green);
EEPROM_WRITE(3, ((unsigned char)(solarMin)));
EEPROM_WRITE(4, ((unsigned char)(solarMax)));
EEPROM_WRITE(5, ((unsigned char)(solar)));
EEPROM_WRITE(6, ((unsigned char)(I)));

}

#### Dr_Doggy

##### Well-Known Member
you guys are right on all corrections above,
extra variables always show up when I'm narrowing down issues, didn't mean for them to make it to post...
plus there was other mistake with globals.
MAINLY the values are passing through now! Thanks!

still need to inverse "Im" and other tweaks for good range output for a nightlight... any ideas of equation or better relation calculation!?

Code:
void ModeDimmer( unsigned char C, unsigned int s, unsigned char IRme)
{
// C = 3-bit default color(R,G,B,Y,C,M,W)
// s = solar (dark = 40-60, light = 128 -136)avg

IRmode = IRme;       // IRme = IRmode  sets up variables irrelevant here
unsigned char  R = 0,G = 0,B = 0;   // passed to global too soon, fixed here
if (C==1 || C==4 || C==6 || C==7){R = 255;}
if (C==2 || C==4 || C==5 || C==7){G = 255;}
if (C==3 || C==5 || C==6 || C==7){B = 255;}
float Im =  ((float)(s - solarMin)/(float)(solarMax-solarMin));
Im = Im * Im;                                                                //   need next to find a good gravity equation
if (Im > 1){Im = 1;}
if (Im < 0){Im = 0;}
// now ready to be global,     255 = on, 1 = 1/255 pulse, 0 = off
setColor(((unsigned char)((float)R * Im)),
((unsigned char)((float)G * Im)),
((unsigned char)((float)B * Im)));
//// debug complete! data returns proper values, save the eeprom!
//    Im *=100;
//    eeprom_write(0, Blue);
//    eeprom_write(1, Im);
//    eeprom_write(3, Red);
//    eeprom_write(4, Green);
//    eeprom_write(5, s);
//    eeprom_write(6, solarMin);
//    eeprom_write(7, solarMax);
//    delayMS(1000);
}

Status
Not open for further replies.