• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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)));

}
 

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
Most Helpful Member
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
Most Helpful Member
Note that the cast in Green = (unsigned char)(Im); will be 0 or 1 and only 1 at solar max.

Mike.
 

Ian Rogers

User Extraordinaire
Forum Supporter
Most Helpful Member
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
Most Helpful Member
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.

Latest threads

EE World Online Articles

Loading
Top