На странице http://rcl-radio.ru/?p=62308 описано применение АЦП 18 бит MCP3421 совместно с Arduino, приведены характеристики и пример использования АЦП в качестве вольтметра с выводом измененного значения напряжения в монитор порта. Минимальный диапазон измерения постоянного напряжения для MCP3421 находится в пределах ± 256 мВ, что дает возможность измерять ТЭДС термопар с достаточно большой точностью.
На этой странице приведен пример использования АЦП MCP3421 в составе терморегулятора, в который так же входит датчик температуры 18B20, энкодер, дисплей 1602 на базе контроллера HD44780 и плата Arduino Nano. В терморегуляторе имеется возможность измерять ТЭДС термопар типа ТХА и ТХК, но при желании можно добавить и другие термопары. Энкодер позволяет переключать тип термопары и настраивать температуру регулирования, в качестве коммутатора нагрузки (нагревательный элемент) служит модуль реле подключаемое к цифровому выходу D13. Для компенсации температуры холодного спая термопары используется цифровой датчик 18B20 показания которого преобразуются в мВ и суммируются в измеренным значением ТЭДС термопары.
На дисплей 1602 выводится показания температуры, температура регулирования, показания милливольтметра (без компенсации холодного спая) и характеристика термопары.
Терморегулятор используется в следующих диапазонах температур:
- тип L, обозначение ТХК, материал хромель\копель, диапазон температур от -200 до +800°С
- тип К, обозначение ТХА, материал хромель\алюмель, диапазон температур от -270 до 1372°С
Для более точного измерения температуры АЦП необходимо откалибровать, для этого на вход терморегулятора нужно подать напряжение 100 мВ измеренное с большой точностью и изменить переменную: const float u_kall = 1.00255; на свое значение. Следует отметить, что АЦП достаточно точен, и без калибровки погрешность его не превышает 0.3 %.
Термопара должна подключаться напрямую ко входу АЦП, если такой возможности нет, то используйте термокомпенсационные провода. Их изготавливают из материалов, которые развивают ту же ТЭДС, что и сама термопара.
#include <Wire.h> #include <MCP3421.h> #include <OneWire.h> #include <DallasTemperature.h> #include <LiquidCrystal.h> #include <Encoder.h> #include <EEPROM.h> #include <MsTimer2.h> OneWire oneWire(A0);// вход датчика 18b20 DallasTemperature temp(&oneWire); MCP3421 mcp; LiquidCrystal lcd(7, 6, 2, 3, 4, 5);// RS,E,D4,D5,D6,D7 подключение LCD Encoder myEnc(10, 11);//CLK, DT подключение энкодера const float u_kall = 1.00255; // калибровка АЦП float gis=1; // гистерезис long dig,t_ust; unsigned long newPosition,oldPosition=-999,time,time1; float u,t,u_sum,u0,t_iz; int i,x,w=0,menu; // XA K const float a[]{0,2.5173462*10,-1.1662878,-1.08336338,-8.9773540/10,-3.7342377/10,-8.6632643/100,-1.0450598/100,-5.1920577/10000}; const float a1[]{0,2.508355*10,7.860106/100,-2.503131/10,8.315270/100,-1.228034/100,9.804036/10000,-4.413030/100000,1.057734/1000000,-1.052755*pow(10,-8)}; const float a2[]{-1.318058*100,4.830222*10,-1.646031,5.464731/100,-9.6550715/10000,8.802193/1000000,-3.110810/100000000}; // XK L const float b[]{1.1573067/10000,1.5884573*10,4.0458554/100,0.3170064,0.1666128,5.146958/100,9.5288883/1000,1.0301283/1000,6.0654431/100000,1.5131878/1000000}; const float b1[]{7.2069422/1000,1.5775525*10,-0.2261183,9.4286756/1000,-3.5394655/10000,1.0050886/100000,-1.9323678/10000000,2.3816891/1000000000,-1.7130654*pow(10,-11),5.4857331*pow(10,-14)}; void setup(){ //Serial.begin(9600); Wire.begin();lcd.begin(16, 2); mcp.setConfig(3,3); // 12 14 16 18 bit - 0-3 // 1x 2x 4x 8x gain - 0-3 pinMode(12,INPUT);// КНОПКА ЭНКОДЕРA pinMode(13,OUTPUT); // вывод управления реле MsTimer2::set(1, to_Timer);MsTimer2::start(); temp.begin(); temp.setResolution(12);//12 бит temp.requestTemperatures();t = temp.getTempCByIndex(0); t_ust = EEPROM.read(0)*256 + EEPROM.read(1);menu=EEPROM.read(2); } void to_Timer(){newPosition = myEnc.read()/4; if((digitalRead(12)==LOW)){menu++;myEnc.write(0);time1=millis();if(menu>1){menu=0;}delay(200);}} void loop(){ // if((digitalRead(12)==LOW)){menu++;myEnc.write(0);time1=millis();if(menu>1){menu=0;}delay(200);}// меню if(millis()-time>10000&&w==0){temp.requestTemperatures();t = temp.getTempCByIndex(0);time=millis();} /////////////////// энкодер /////////////////////////////////////////////////////////////////////////////// if(menu==0){ ////// ТХА if (newPosition != oldPosition) { oldPosition = newPosition; t_ust=t_ust+newPosition;myEnc.write(0);newPosition=0;time1=millis();w=1;if(t_ust>1372){t_ust=1372;}if(t_ust<-270){t_ust=-270;}}} if(menu==1){ ////// ТХK if (newPosition != oldPosition) { oldPosition = newPosition; t_ust=t_ust+newPosition;myEnc.write(0);newPosition=0;time1=millis();w=1;if(t_ust>800){t_ust=800;}if(t_ust<-200){t_ust=-200;}}} ///////////////////////////////// измерение //////////////////////////////////////////////////////////////////////////////// if(w==0){ for(i=0;i<10;i++){ dig = mcp.readWire();u = dig * 0.256 /131071*u_kall;delay(100);u_sum=u_sum+u;} u=u_sum/10;u_sum=0;i=0;} //////////////////////////// tip ////////////////////////////////// if(menu==0){txa(); lcd.setCursor(10,1);lcd.print("TXA");} if(menu==1){txk(); lcd.setCursor(10,1);lcd.print("TXK");} /////////////////////////////// lcd /////////////////////////////////////////////////////////////////////////////////////// lcd.setCursor(0,0);if(t_iz==-1000){lcd.print(" LOW ");}else if(t_iz==10000){lcd.print(" HIGH ");} else{lcd.print(t_iz,1);lcd.print((char)223);lcd.print("C ");}lcd.setCursor(10,0);lcd.print(t_ust);lcd.print((char)223);lcd.print("C "); lcd.setCursor(0,1);lcd.print(u*1000,3);lcd.print("mV "); /////////////////////////////// реле + гистерезис ///////////////////////////////// if(t_ust >= t_iz + gis){digitalWrite(13,HIGH);lcd.setCursor(15,1);lcd.print("H");} if(t_ust <= t_iz - gis){digitalWrite(13,LOW);lcd.setCursor(15,1);lcd.print("L");} ////////////////////// eeprom + блокировка //////////////////////////////////////// if(w==1&&millis()-time1>3000){ EEPROM.update(0,highByte(t_ust)); EEPROM.update(1,lowByte(t_ust)); EEPROM.update(2,menu); w=0;} } void txa(){u0=u*1000+t*0.0403;// окружающая температура 0.0400 мВ на 1 гр.Цельсия от 0 до 40 гр.Цельсия для TXA(K) if(u0<0){t_iz=(a[0]*pow(u0,0))+(a[1]*pow(u0,1))+(a[2]*pow(u0,2))+(a[3]*pow(u0,3))+(a[4]*pow(u0,4))+(a[5]*pow(u0,5))+(a[6]*pow(u0,6))+(a[7]*pow(u0,7))+(a[8]*pow(u0,8));} if(u0>=0&&u0<=20.64){t_iz=(a1[0]*pow(u0,0))+(a1[1]*pow(u0,1))+(a1[2]*pow(u0,2))+(a1[3]*pow(u0,3))+(a1[4]*pow(u0,4))+(a1[5]*pow(u0,5))+(a1[6]*pow(u0,6))+(a1[7]*pow(u0,7))+(a1[8]*pow(u0,8))+(a1[9]*pow(u0,9));} if(u0>20.64){t_iz=(a2[0]*pow(u0,0))+(a2[1]*pow(u0,1))+(a2[2]*pow(u0,2))+(a2[3]*pow(u0,3))+(a2[4]*pow(u0,4))+(a2[5]*pow(u0,5))+(a2[6]*pow(u0,6));} if(u*1000<-6.35){t_iz=-1000;} if(u*1000>54.9){t_iz=10000;}} void txk(){u0=u*1000+t*0.06555;// окружающая температура 0.06476 мВ на 1 гр.Цельсия от 0 до 40 гр.Цельсия для TXK(L) if(u0<0){t_iz=(b[0]*pow(u0,0))+(b[1]*pow(u0,1))+(b[2]*pow(u0,2))+(b[3]*pow(u0,3))+(b[4]*pow(u0,4))+(b[5]*pow(u0,5))+(b[6]*pow(u0,6))+(b[7]*pow(u0,7))+(b[8]*pow(u0,8))+(b[9]*pow(u0,9));} if(u0>=0){t_iz=(b1[0]*pow(u0,0))+(b1[1]*pow(u0,1))+(b1[2]*pow(u0,2))+(b1[3]*pow(u0,3))+(b1[4]*pow(u0,4))+(b1[5]*pow(u0,5))+(b1[6]*pow(u0,6))+(b1[7]*pow(u0,7))+(b1[8]*pow(u0,8))+(b1[9]*pow(u0,9));} if(u*1000<-9.49){t_iz=-1000;} if(u*1000>66.47){t_iz=10000;} }