TDScc(外科医生的反渗透净水机的控制主板)系列连载——TDS检测技术实例
很幸运地我在网络上获得了瑞萨电子(Renesas Electronics)公开的全套RL78/G11 TDS水质测试笔资料。
(详见:
电路原理图
TDS测量以及温度测量流程图
TDS计算的源程序(关键是温度补偿的参数!)
void R_TDS_Calculate(uint16_t adcr_average_value)
{
uint16_t tds_resister, siemens_value;
float electornic_conductor,temperature;
g_tds_ProbeShortConnect = 0;
adcr_average_value = adcr_average_value - 15;
if(adcr_average_value >= 0x3e6)
{
g_tds_Value = 0;
}
else if(adcr_average_value <= 10)
{
g_tds_ProbeShortConnect = 1;
}
else
{
tds_resister = (uint32_t)adcr_average_value * 1500 / (1024 - adcr_average_value);
siemens_value = POLAR_CONSTANT / tds_resister;
temperature = g_Temperature[0] + (float)g_Temperature[1] / 10;
if (g_Temperature[0] <= 10)
{
electornic_conductor = siemens_value / (0.0169 * temperature + 0.5583);
}
else if (g_Temperature[0] <= 20)
{
electornic_conductor = siemens_value / (0.018 * temperature + 0.5473);
}
else if (g_Temperature[0] <= 30)
{
electornic_conductor = siemens_value / (0.0189 * temperature + 0.5281);
}
else
{
electornic_conductor = siemens_value / (0.022 * temperature + 0.45);
}
g_tds_Value = electornic_conductor * TDS_COEFFICIENT / 100;
}
}
难题:RL78/G11型号MCU无足够IO以扩展出对系统多个继电器、电磁阀的控制。唯有消化其原理后选择其它适用MCU来组建系统。
我的TDS检测方案
考虑51系列单片机比较普及(其实是我根本什么都不会,手头有本单片机入门书《爱上单片机》(杜洋),觉得行,就决定了),故选用带AD功能的STC12C2052AD搭建实验电路。
电路设计
电路特点。STC12C2052AD的P1.5(经R8分压后的TDS)与P1.6(TB)强推挽输出驱动方波电压至TDS探测电极,P1.7为ADC状态,将TDS端(电极间导电的水等效于电阻,与R8形成分压)的电压模数变换。C2为滤波电容。考虑目标水样TDS较低,电阻值达数十k(本例探头下),故R8分压电阻较参考电路为大(10到20k),以在8位ADC下能在低TDS区间有较高分辨率。
困难
1.无法照搬转换系数TDS_COEFFICIENT 。因为探头导电面积、探头距离等会直接影响到检测出来的电压,进而影响结果。这影响关系的计算非常复杂。另外,考虑到DIY的条件,统一探头材质、尺寸是非常不现实的。但情况并不悲观,因为我们检测TDS变化才是关键,精确度不重要!所以,直接用已知TDS值的水去标定(就是确定计算系数)会简单、可行。你手头应该就有一只TDS检测笔吧,几十块钱而已。没的就去买。
2.8位的51MCU运算能力太弱了,特别是浮点运算!庆幸的是,TDS结果肯定不会太大,产水能到255ppm(0xff)或99(两位LED数码管显示)就非常恐怖了。我轻易就把运算都变换成8位或16位整形的简单运算了,而且对精度和溢出都作了很好的考虑。
源代码(节选)
unsigned char tds_ads_v = 0 ; //TDS平均ADC值
unsigned char TDS = 0 ; //TDS值
unsigned char TEMP = 0 ; //温度值
sbit TA=P1^5 ; //P1^5与P1^6输出驱动电压
sbit TB=P1^6 ;
#define K_TDS 90 //TDS转换系数(需按探头参数调整)
void TDS_Calculate(u8 tds_v)
{
unsigned int tk = 0 ;
unsigned int tds_t = 0 ;
if( tds_v > 252 ) //下限
{
TDS = 0 ;
}
else if( tds_v < 10 ) //上限
{
TDS = 99 ;
}
else
{
if (TEMP <= 10)
{
tk = 17 * TEMP + 558 ;
}
else if (TEMP <= 20)
{
tk = 18 * TEMP + 547 ;
}
else if (TEMP <= 30)
{
tk = 19 * TEMP + 528 ;
}
else
{
tk = 22 * TEMP + 450 ;
}
tds_t = 255 - tds_v ;
tds_t <<= 8 ; //左移位8次,扩大被除数可多保留有效位。
tds_t = tds_t / tk ;
tds_t = tds_t * K_TDS ; //乘后再除,增加得数有效值
TDS = tds_t / tds_v ;
}
}
上面是第一代(试验版)方案。而在第3代控制板,采用了新的驱动电路,只需使用两个IO端口,而且能够在负脉冲周期也能采样一次,所以速度加倍。同时,这两个端口驱动一个由两个MOS管构成的与门电路,作为蜂鸣器的驱动。总的效果就是节省了端口之余还增加了功能,同时检测速度还加倍。当然,编程难度会增加。