|
|
View previous topic :: View next topic |
Author |
Message |
borseyogesh1436
Joined: 30 Nov 2017 Posts: 29
|
float value increment with two switch |
Posted: Mon Dec 11, 2017 11:39 pm |
|
|
Hi friends, i want to store float value like 1234.5678 with two buttons, one is for shifting digit and the other is for incrementing digit with below code using pic18f46k22 with display jhd12864E.
Code: |
include <18F46K22.h>
#include <HDM64GS12.c>
#include <graphics.c>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#use delay(crystal=7372800)
void main()
{
int8 cnt=1,a1,b1,c1,d1,e1,f1,g1,h1;
float ENTERRNG;
char yazi[15];
glcd_init(on);
delay_ms(10);
while(TRUE)
{
if(input(PIN_C0)==0){
if(cnt==8){
cnt=0;
}
cnt=cnt+1;
}
if(input(PIN_C3)==0)
{
if(cnt==1)
a1=a1+1;
if(cnt==2)
b1=b1+1;
if(cnt==3)
c1=c1+1;
if(cnt==4)
d1=d1+1;
if(cnt==5)
e1=e1+1;
if(cnt==6)
f1=f1+1;
if(cnt==7)
g1=g1+1;
if(cnt==8)
h1=h1+1;
if(a1==10)
{a1=0;}
else if(b1==10)
{b1=0;}
else if(c1==10)
{c1=0;}
else if(d1==10)
{d1=0;}
if(e1==10)
{e1=0;}
else if(f1==10)
{f1=0;}
else if(g1==10)
{g1=0;}
else if(h1==10)
{h1=0;}
}
ENTERRNG=(a1*10000000)+(b1*1000000)+(c1*100000)+(d1*10000)+(e1*1000)+(f1*100)+(g1*10)+h1;
ENTERRNG=(float)ENTERRNG/10000.0;
sprintf(yazi,"%4.4f",(float)ENTERRNG);
glcd_text57(15,20,yazi,2,ON);
write_float_eeprom(0xA2,ENTERRNG);
Delay_ms(100);
}
}
|
This code is working before decimal point values but not increment value after decimal point. Is there anything wrong with code or suggest me any other way to do this. Pls help me thanks . |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19603
|
|
Posted: Tue Dec 12, 2017 2:31 am |
|
|
There are a couple of problems.
The first is that a float just doesn't hold this many digits. Typically 6 digits. So the last couple are going to sometimes get corrupted or lost, with the conversion. Consider holding as an int32 instead.
Second comment. There is a problem with the wrap arithmetic. Imagine. a1 is 9, and b1 increments. It is not going to be tested, since you have an 'else' in the tests. You increment b1 again. It is now 11 (gone past 10), but has not been stopped. When you get to the maths, you are going to get an overflow here.
Then there are potential problems in the conversion maths at certain points. f1*100 for example. This involves two int8 integers. This will overflow. Same potentially happens with the *10000 calculation (this time overflowing int16).
Consider using an array. This way the whole sequence can be done by a repeated code. You already have the index in cnt (though 1 to 8, not 0 to 7).
So:
Code: |
int8 cnt=0;
int8 digits[8]={0,0,0,0,0,0,0,0};
int32 sum;
int8 sum_ctr;
//Then
while(TRUE)
{
if(input(PIN_C0)==0)
{
if(cnt>=7)
cnt=0;
else
cnt=cnt+1;
} //cnt will now count from 0 to 7 not 1 to 8
if(input(PIN_C3)==0)
{
digits[cnt]++;
if (digits[cnt]>=10)
digits[cnt]=0;
} //Handles all the digits
sum=0;
for (sum_ctr=0;sum_ctr<8;sum_ctr++)
{
sum*=10;
sum+=digits[cnt];
}
//This adds up all the eight digits - all the maths here is int32
//'sum' now is the sum of all eight digits, the last unmultiplied,
//the one before *10, etc..
|
Now, stopping at this point, but there is a general comment. Can't you leave writing to the EEPROM, until you have the number fully ready?. As it stands you are writing it every time round the loop. This will use up the life of the EEPROM quite quickly. Not good..... |
|
|
borseyogesh1436
Joined: 30 Nov 2017 Posts: 29
|
|
Posted: Tue Dec 12, 2017 3:27 am |
|
|
Thanks for reply Ttelmah
I change code with your code and there are incrementing all 8th digit.
When i select one, all the digits increment.
Sorry for my english.
I want to store float value
Code: |
11111111
22222222
33333333 |
Code: |
int8 cnt=0;
int8 digits[8]={0,0,0,0,0,0,0,0};
int32 sum;
int8 sum_ctr;
float ENTERRNG;
if(input(PIN_C0)==0)
{
if(cnt>=7)
cnt=0;
else
cnt=cnt+1;
} //cnt will now count from 0 to 7 not 1 to 8
if(input(PIN_C3)==0)
{
digits[cnt]++;
if (digits[cnt]>=10)
digits[cnt]=0;
} //Handles all the digits
sum=0;
for (sum_ctr=0;sum_ctr<8;sum_ctr++)
{
sum*=10;
sum+=digits[cnt];
}
ENTERRNG=(float)sum/10000.0;
sprintf(yazi,"%4.4f",(float)ENTERRNG);
glcd_text57(15,20,yazi,2,ON);
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19603
|
|
Posted: Tue Dec 12, 2017 3:57 am |
|
|
It's not. Silly mistake:
Code: |
sum=0;
for (sum_ctr=0;sum_ctr<8;sum_ctr++)
{
sum*=10;
sum+=digits[sum_ctr]; //used the wrong counter here.....
}
|
|
|
|
borseyogesh1436
Joined: 30 Nov 2017 Posts: 29
|
|
Posted: Tue Dec 12, 2017 4:30 am |
|
|
thanks Ttelmah it's working |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19603
|
|
Posted: Tue Dec 12, 2017 6:05 am |
|
|
Good.
Do consider if there is some way to only write when the whole number is complete. Would potentially save a lot of lives on the EEPROM. |
|
|
borseyogesh1436
Joined: 30 Nov 2017 Posts: 29
|
|
Posted: Tue Dec 12, 2017 6:40 am |
|
|
I am saving that value on power down, thanks for help Ttelmah. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19603
|
|
Posted: Tue Dec 12, 2017 7:27 am |
|
|
Big grin. Ideal. |
|
|
|
|
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
|