Other Parts Discussed in Thread: ADS1230
I am facing following issue.
Let’s say I am calibrating grocery weigh scale with 5kg weight .
At zero weight I am getting 1000 count from ADS1230 and @5kg I am getting 6000 count from ADC.
Hence,
Display weight = ((ADC Count – Zero count)* Calibration weight)/(Span Count – Zero count)
For example lest say I am getting 6002 count from ADC, so as per above formula,
Display weight = ((6002-1000) * 5000)/(6000-1000) = 5002 gm, and weight put is also same.
Now over the time,
I am getting, 1002 count for zero weight.
Display weight = ((1002-1000) * 5000)/(6000-1000) = 2 gm, and weight put is zero, and
lest say I am getting , 998 count for zero weight.
Display weight = ((998-1000) * 5000)/(6000-1000) = -2 gm, and weight put is zero.
This is issue of zero count shift. With it span count also shifts,but I have to know new zero so that it can be taken care automaticallu.
People use auto zero for this. I used that method but still this issue persist. I have attached code part of that function.
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Function to read ADC
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void read_ADS1230(void)
{
adc_data=serial_read(21);
adc_data>>=3; // Convert to 18 bit
adc_sample[mov_sample_counter++] = adc_data;
mov_average(); // block average + moving avaerage(with fast update) (use variable 'weight' as a stable data)
if(run_mode)
{
update_display=1;
main_disp=weight;
if(hold_flag)
main_disp=hold_weight;
}
else if(set_mode)
{
if(index==27)
{
tare_count=0;
zero_count=adc_final;
update_display=1;
}
else if(index==31)
{
span_count=adc_final;
update_display=1;
}
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Routine to read 21 bit data from ADS1230
// Read data when clock is low
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
long serial_read(unsigned char bits)
{
long data1=0;
for(i=0;i<bits;i++)
{
data1<<=1;
ADS_SCLK=1;
_nop_();
_nop_();
ADS_SCLK=0;
if(ADS_SDO)
data1 |= 0x00000001;
}
return(data1);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Moving Average Method
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void mov_average(void)
{
long templ1,templ2;
if(mov_sample_counter>=MOVE_SAMPLE)
{
mov_sample_counter=0;
templ1=0;
for(i=0;i<MOVE_SAMPLE;i++)
templ1+=adc_sample[i];
adc_final=templ1>>3; // Divide by 8
// if(adc_final > zero_count) // Auto zeroing
// templ2=(adc_final - zero_count);
// else
// templ2=(zero_count - adc_final);
if(start_mode)
{
if(++start_time>STRT_DLY)
{
start_mode=0;
run_mode=1;
run_zero = adc_final;
}
start_update=1;
}
// templ1=set_auto0;
// auto_zr=(templ1*CNT_GRM)+OFST_GRM;
// if((weight >= -templ1) && (weight <= templ1) && (templ2 < auto_zr))
// {
// if(adc_final > run_zero)
// templ2=(adc_final - run_zero);
// else
// templ2=(run_zero - adc_final);
// run_zero = adc_final;
// if(tare_count!=0)
// {
// if(tare_count>0)
// tare_count=tare_count-templ2;
// else if(tare_count<0)
// tare_count=tare_count+templ2;
// }
// }
}
else
{
templ1=0;
for(i=0;i<MOVE_SAMPLE;i++)
templ1 += adc_sample[i];
templ1=templ1>>3;
templ2=templ1-adc_final;
if(templ2>3)
{
buzzer_on();
}
adc_final = templ1;
}
if(run_mode)
calculation();
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Weight Calculation
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void calculation(void)
{
long templ1,templ2;
sign_flag=1;
templ2 = (span_count - zero_count);
if(set_auto0==0)
templ1 = adc_final - zero_count;
else
templ1 = adc_final - run_zero;
if(!gross_flag)
templ1 = templ1 - tare_count;
weight = ((float)templ1 * cal_weight ) / templ2;
if(weight < 0)
weight *= (-1);
else
sign_flag = 0;
decide_capacity();
if(liter_mode)
{
weight = (weight * 977 );
weight = (weight/1000);
}
}
Commented portion is one method I have adopted but still facing problem.