电导率滴定仪-Arduino中文社区 - Powered by Discuz! Archiver

王大富 发表于 2021-11-3 19:35

电导率滴定仪

#include <OneWire.h>
#define pH_PIN A5
#define EC_PIN A4
int DS18B20_Pin = D3; //DS18B20信号引脚在D3上
OneWire ds(DS18B20_Pin);//配置数字引脚D3

int x,i=0, n = 0,j=0,k,nn,N;
float voltage, ecValue,ecValue_sum,ecValue_aver,ecValue_t, temperature = 25.0;
float _kvalueLow = 0.820756, _kvalueHigh = 1.003577, _kvalue = 0.987, rawEC, valueTemp, value;
float celsius, fahrenheit;
float Temp_Buffer = 0, vv = 0;
float val = 0, EV = 0, strain = 0, pH = 0;

void setup()
{ Serial.begin(9600);
pinMode(pH_PIN, INPUT);
pinMode(EC_PIN, INPUT);
pinMode(D6, OUTPUT); // Enable: EN可以使用单片机端口控制,也可以直接连接GND使能
pinMode(D5, OUTPUT); // steps:脉冲个数
pinMode(D4, OUTPUT); // dir:为方向控制
digitalWrite(D6, LOW); // Enable处于低电平或悬空时能够正常运行
//pinMode(D8, OUTPUT);digitalWrite(D8, HIGH);
//pinMode(D9, OUTPUT);digitalWrite(D9, HIGH);
//pinMode(D10, OUTPUT);digitalWrite(D10, HIGH);


while(j < 1){celsius=getTemp();j++;}
}

void loop()
{ if(Serial.read()=='1'){//串口接收到1时运行以下函数
n = 0;
for (i = 0; i < 10000000000000; i++)
{n++;
if(Serial.read()=='0'){break;}//串口接收到0时跳出循环

celsius=getTemp();
Serial.print(celsius); Serial.print(' '); //串口输出温度
   
//pHval();//测量pH

ecValue_sum=0;
nn=100;
for (k = 0; k < nn; k++){ECdata();ecValue_t=ecValue;delay(10);}
sort();
N=0;
for (k = 20; k < 80; k++){ecValue_sum=ecValue_sum+ecValue_t;N++;}
ecValue_aver=ecValue_sum/N;

Serial.print(voltage,4); Serial.print(' '); //串口输出pH
Serial.print(ecValue_aver,4); Serial.print(' '); //口输出电导率

motor();//添加溶液
Serial.println(n*0.01389*1.1429); //串口输出体积
}}
}

void sort()
{int ii,jj;
float temp1;
    for(ii=0;ii<nn-1;ii++)
    {for(jj=0;jj<nn-1-ii;jj++)
      {if(ecValue_t>ecValue_t)
            {   temp1=ecValue_t;
                ecValue_t=ecValue_t;
                ecValue_t=temp1;
            }
      }
    }
}


void motor() {//控制42步进电机
digitalWrite(D4, HIGH); // Set Dir high
for (x = 0; x < 200; x++) // 300个脉冲数
{ digitalWrite(D5, HIGH); // Output high
    delayMicroseconds(600); // Wait 1/2 a ms
    digitalWrite(D5, LOW); // Output low
    delayMicroseconds(600); // Wait 1/2 a ms
}
}

void pHval() {
val = analogRead(pH_PIN); //传感器接到模拟口A0
EV = val * 3.3/ 4096;
pH = 16.7935 -5.7124 * EV;
}

void ECdata()
{ voltage = analogRead(EC_PIN)*3300 / 4096;//电压毫伏
rawEC = 1000 * voltage / 820.0 / 196.0;//原始电导率,电压与电导率的线性比列关系,有先前实验得到
//value = rawEC * _kvalue;//初始不计算仪器引起的误差
//if (value > 2.5) {
//    _kvalue =0.97268554323* _kvalueHigh;//高校正值
//}
//else if (value < 2.0) {
//    _kvalue = 0.58245127484*_kvalueLow;//低校正值
//}
value = rawEC * _kvalue;//校正机械误差后的电导率,_kvalueLow和_kvalueHigh由实际的电导率比上测试得到的电导率
temperature = celsius; //dht.getTemperature();//校正后的电导率
ecValue = value / (1.0 + 0.0185 * (temperature - 25.0));//修正后的电导率,修正完以后都是25摄氏度下的数据,因此用除
}



float getTemp(){//获取DS18B20温度数据
byte data;//定义一个12位的字节的字符变量,每个字节有8位构成
byte addr;//定义一个8位的字节的字符变量
if ( !ds.search(addr)) {//若无传感器继续搜索   
      ds.reset_search();
      Serial.println("CRC is not valid!");
      return -1000;
}
if ( OneWire::crc8( addr, 7) != addr) {
      Serial.println("CRC is not valid!");
      return -1000;
}
if ( addr != 0x10 && addr != 0x28) {//开始的 8 位是产品类型编码(DS18B20 是 0x10)
      Serial.print("Device is not recognized");
      return -1000;
}
ds.reset();
ds.select(addr);//
ds.write(0x44,1); //开始转换

byte present = ds.reset();
ds.select(addr);   
ds.write(0xBE); //读暂存寄存器

for (int i = 0; i < 9; i++) { //读取9个字节
    data = ds.read();//读取数据
}

ds.reset_search();

byte MSB = data;//高8位,第2个字节
byte LSB = data;//低8位,第1个字节
float tempRead = ((MSB << 8) | LSB);
float TemperatureSum = tempRead / 16;
return TemperatureSum;

}

页: [1]
查看完整版本: 电导率滴定仪