Continue to Site

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.

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

}
 
getsolar is just reading analog pin 3 and returns a 10 bit value ... will post it tonite if required
 
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!!#
 
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!
 
Note that the cast in Green = (unsigned char)(Im); will be 0 or 1 and only 1 at solar max.

Mike.
 
cast again like this?

I = (float)Green * Im; // ajust green based on solar percent
 
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);
 
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
 
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)));

}
 
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

New Articles From Microcontroller Tips

Back
Top