MCP3421 + термопара (Arduino)

На странице 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;}
}

Добавить комментарий

Войти с помощью: