电导率在线采集-Arduino中文社区 - Powered by Discuz! Archiver

王大富 发表于 2021-11-5 10:07

电导率在线采集

#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++;}//去掉前后20个数据
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;

}function varargout = EC_GUI(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',gui_Singleton, ...
                   'gui_OpeningFcn', @EC_GUI_OpeningFcn, ...
                   'gui_OutputFcn',@EC_GUI_OutputFcn, ...
                   'gui_LayoutFcn',[] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
end

%% 主要函数
function EC_GUI_OpeningFcn(hObject, eventdata, handles, varargin)
edit3_Callback(hObject, eventdata, handles)
handles.output = hObject;
guidata(hObject, handles);
end
function varargout = EC_GUI_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
end

%% 用来从GUI的edit传递参数到m文件的变量,此处传递的是串口名称
function edit3_Callback(hObject, eventdata, handles)
global come12;
come12='COM10';%(COM4是默认值)
str1=get(handles.edit3,'string');
come12=str1;
end
function edit3_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end

%% 用于链接串口
function pushbutton4_Callback(hObject, eventdata, handles)
global Port;
global come12;
Port=serial(come12);%定义串口对象可能会出现错误,根据提示修改即可
fclose(instrfind);
set(Port,'BaudRate',9600);%设置波特率
set(Port,'DataBits',8);%8位数据位
set(Port,'StopBits',1);%1位停止位
fopen(Port); %打开串口
global nn
nn=0;
global samplename2
samplename2=[];
end

%% 用来从GUI传递参数到m文件中的变量,此处传递的是样本名称
function edit1_Callback(hObject, eventdata, handles)
global samplename1
global samplename2
global nn
global val1
%samplename1='new';%(a是初始值)
%val1=get(handles.edit1,'string');
samplename1=get(handles.edit1,'string');%样本名称
nn=nn+1;
samplename2{nn}=val1;
%legend(samplename2{:});
end
function edit1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end
%% 用来从GUI传递参数到m文件中的变量,此处传递的是_BaCl2浓度
function edit9_Callback(hObject, eventdata, handles)
global BaCl2;
BaCl2=get(handles.edit9,'string');%(a是初始值)
end
function edit9_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end
end

%% 开始启动并采集数据的按钮
function pushbutton1_Callback(hObject, eventdata, handles)
global Port;
global nn;
global samplename1;
global BaCl2;
global excel_name;
global write_sheet;
global x1;
global x2;
global x3;
global x4;
global xt;

fprintf(Port,'1');

%%%%%%%%%%%%%%%%%%%%%%%可能需修改%%%%%%%%%%%%%%%%%%%%%%
interval = 10000; %可能需要修改
passo = 1;t = 1;
file_address1='D:\';%数据存放文件路径
%% 文件的创建

if (t==1)
%% 获取当前时间
now=fix(clock);
time=strcat(num2str(now(1)),'_',num2str(now(2)),'_',num2str(now(3)));%年月日   
mkdir(strcat(file_address1,'Ion_Test'));%新建大文件名
file_address=strcat(file_address1,'Ion_Test\');
mkdir(strcat(file_address,time));%新建大文件名
File1=strcat(file_address,time);%大文件路径

mkdir(strcat(File1,'\','EC'));%新建EC文件
File_EC=strcat(File1,'\','EC\');%EC文件路径
mkdir(strcat(File_EC,samplename1));%新建样本文件
File_EC_sample=strcat(File_EC,samplename1,'\');%样本文件路径

% mkdir(strcat(File1,'\','pH'));%新建pH文件
% File_pH=strcat(File1,'\','pH\');
% mkdir(strcat(File_pH,samplename1));%新建样本文件
% File_pH_sample=strcat(File_pH,samplename1,'\');
%% 根据时间命名文件名
TIME=strcat('(',num2str(now(4)),'_',num2str(now(5)),')');%时分
samplename=strcat(TIME,samplename1);%样本名
end
%% 线条颜色调整
% nrgb=1000;
% for i=nrgb:10*nrgb
%   rgb=64/i;
%   mycolormap_r=interp1(,,1:rgb:64);
%   mycolormap_g=interp1(,,1:rgb:64);
%   mycolormap_b=interp1(,,1:rgb:64);
%   if length(mycolormap_r)>=nrgb
%         break
%   end
% end
% mycolor=;
% colormap(mycolor);
% hco = colorbar ;

set(0,'defaultfigurecolor','w');%设定背景颜色为白色
%x1=0;x2=0;x3=0;x4=0;
vv='The test has been started'
while(t<interval)

   
b = str2num(fgetl(Port));%读取串口数据,当出现终止符(换行符)停止。
if(t==1)
x4=0;
end
x4 = ;%取串口第4个数据并进行串联


if(t==1)
x1=b(1);
end
x1 = ;%取串口第1个数据并进行串联
% plot(handles.axes9,x4,x1,'-','linewidth',2);
% xlabel(handles.axes9,'V(ml)');
% ylabel(handles.axes9,'T(\circC)');

if(t==1)
x2=b(2);
end
x2 = ;%取串口第2个数据并进行串联
% plot(handles.axes8,x4,x2,'-','linewidth',2);%plot(handles.axes8,x4,x2,'-','linewidth',2,'color',mycolor(nn,:));hold on
% xlabel(handles.axes8,'V(ml)');
% ylabel(handles.axes8,'pH');

if(t==1)
x3=b(3);
end
x3 = ;%取串口第3个数据并进行串联
plot(handles.axes5,x4,x3,'-','linewidth',2);
xlabel(handles.axes5,'V(ml)');
ylabel(handles.axes5,'EC(ms\cdotcm^{-1})');

now=fix(clock);
if(t==1)
x40=now(4);
x50=now(5);
x60=now(6);
x00=x40*3600+x50*60+x60;
xt=0;
end
xt1=now(4)*3600+now(5)*60+now(6)-x00;
xt=;
tt=
%% 数据的保存
savefig(strcat(File_EC_sample,samplename,'.fig'));%保存fig数据格式
saveas(gcf, strcat(File_EC_sample,samplename,'.tif'));%保存tif数据格式

excel_name=strcat(File_EC_sample,samplename);
excel_name=strcat(excel_name,'.xls');
write_sheet='sheet1';
if(t==1)
xlswrite(excel_name,{'样本名'},write_sheet,'A1');%写入样本名
xlswrite(excel_name,{samplename1},write_sheet,'A2');%写入样本名
xlswrite(excel_name,{'BaCl2浓度(mol/l)'},write_sheet,'A3');%写入BaCl2浓度
xlswrite(excel_name,{BaCl2},write_sheet,'A4');%写入BaCl2浓度

xlswrite(excel_name,{'V(ml)'},write_sheet,'B1');%写入样本名
xlswrite(excel_name,{'EC(ms.cm^{-1})'},write_sheet,'C1');%写入样本名
xlswrite(excel_name,{'voltage(mV)'},write_sheet,'D1');%写入样本名
xlswrite(excel_name,{'T(。C)'},write_sheet,'E1');%写入样本名
xlswrite(excel_name,{'time(s)'},write_sheet,'F1');%写入样本名
end



t = t+passo;
drawnow;
end

end
%% 用于停止运行的按钮
function pushbutton2_Callback(hObject, eventdata, handles)
global Port;
global excel_name;
global write_sheet;
global x1;
global x2;
global x3;
global x4;
global xt;
for ij=1:20
fprintf(Port,'0');
end
vv='The test has been terminated'
xlswrite(excel_name,x4',write_sheet,'B2');%写入滴定体积
xlswrite(excel_name,x3',write_sheet,'C2');%写入EC
xlswrite(excel_name,x2',write_sheet,'D2');%写入pH
xlswrite(excel_name,x1',write_sheet,'E2');%写入T
xlswrite(excel_name,xt',write_sheet,'F2');%写入pH
fprintf(Port,'0');
hold off


end


页: [1]
查看完整版本: 电导率在线采集