Имитатор сигналов преобразователей термоэлектрических предназначен для проверки и настройки теплотехнических приборов (регистраторы и регуляторы температуры) у которых в качестве датчика температуры используется термопара. Напряжение выхода имитатора от -75 мВ до +75 мВ. Имитатор выдает напряжение соответствующее номинальной статической характеристики преобразования для термопар типа ТХА и ТХК (ГОСТ Р 8.585-2001).
Имитатор сигналов в своем составе содержит несколько недорогих элементов (модулей):
- Плата Arduino Nano (Atmega328)
- ЦАП на MCP4725 (модуль)
- АЦП на MCP3421 (модуль)
- Индикатор LCD1602
- Энкодер — ky-040 (модуль)
На LCD1602 выводится напряжение выхода имитатора, температура окружающей среды, показания температуры для соответствующего типа номинальной статической характеристики (с учетом окружающей среды) и тип номинальной статической характеристики преобразования.
Напряжение выхода имитатора изменяется при помощи поворота энкодера для точной регулировки, а нажатие и удержании кнопки c последующим поворотом ручки энкодера для грубого увеличения или уменьшения напряжения выхода.
Дополнительно для изменения параметров используются три кнопки:
- SET — изменение типа номинальной статической характеристики:
- Н_ТХК — для ТХК от -75 до 75 мВ
- L_ТХК — для ТХК от -35 до 35 мВ
- Н_ТХA — для ТХA от -75 до 75 мВ
- L_ТХA — для ТХA от -35 до 35 мВ
- 0 — кнопка установки нуля, при нажатии выходное напряжение имитатора равно 0 мВ, при повторном нажатии устанавливается ранее установленное напряжение.
- «-» — кнопка инверсии выхода, при нажатии кнопки появляется возможность получить на выходе отрицательное напряжение.
- Кнопка энкодера (нажать первой) + SET — включения и выключения режима регулировки датчика окружающей среды
- Кнопка энкодера (нажать первой) + 0 — отключение датчика окружающей среды, показания температуры для соответствующего типа номинальной статической характеристики будут выводится без поправки на окружающую среду.
- Кнопка энкодера (нажать первой) + «-» — вывод на экран выходного напряжения + напряжение переведенное из температуры датчика окружающей среды.
Типы характеристик L_ТХК и L_ТХA (режим L) имеют в 2 раза меньший диапазон выходного напряжения чем типы Н_ТХК и Н_ТХA, они предназначены для проверки приборов с диапазоном до 400 °С для ТХK и 800 °С для ТХА, их применение дает повышенную точность воспроизведения выходного напряжения, шаг регулировки для L режима — 0,008 мВ, что соответствует шагу от 0,09 °C до 0,18° С в диапазоне от 0 до 400 ° для ТХК и 0,2 °С для ТХА в диапазоне от 0 до 800 ° С.
Основной узел имитатора сигналов термопар состоит из ЦАП 12 бит и АЦП 18 бит. ЦАП воспроизводит напряжение, а АЦП с высокой точностью измеряет его. Резистор 10 Ом подключенный к выводу D8 Arduino образует делитель выходного напряжения для режима L. Так же в схеме используются два реле, первое используется для инвертирования выходного напряжения выхода имитатора, а второе для получения нулевого напряжения в режиме установки нуля, этот режим необходим для проверки температуры окружающей среды (имитация КЗ на входе проверяемого прибора). Цепь резисторов 10 Ом и 710 Ом представляет собой делитель напряжения ЦАП, уменьшает выходное напряжения с 5 В до 75 мВ.
Второй блок имитатора содержит плату Arduino, энкодер, дисплей и цифровой датчик температуры DS1624 (12 бит).
#define ADDR 0b1001000 // 0x48 MCP4725 #define ENC_SW 12 // encoder SW #define ENC_CLK 10 // encoder CLK #define ENC_DT 11 // encoder DT #define SET 9 // BUTTON set tepmopara #define INVERT A0 // BUTTON INVERT #define T_NULL A3 // BUTTON NULL #define OUT_NULL A2 // OUT NULL #define DEL 8 // OUT DEL1 #define OUT_RELE A1 // OUT RELE_INVERT #include <Wire.h> #include <MCP3421.h> // MCP3421-master.zip #include <LiquidCrystal.h> #include <Encoder.h> // Encoder.zip #include <EEPROM.h> #include <MsTimer2.h> // MsTimer2.zip MCP3421 mcp; LiquidCrystal lcd(7, 6, 2, 3, 4, 5);// RS,E,D4,D5,D6,D7 подключение LCD Encoder myEnc(ENC_CLK, ENC_DT); byte x1[8] = {0b11000,0b11000,0b00111,0b01000,0b01000,0b01000,0b00111,0b00000}; const float u_kall = 1.00223; // калибровка АЦП long dig,newPosition,oldPosition=-999; float u,t,u_sum,u0,t_iz,u_iz,tt; int i,out,w,set_t,del,w1,inv=0,out_old,t0,rej,reg_t,t_ok; // 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);conf_ds1624();mcp.setConfig(3,3);lcd.createChar(0,x1); pinMode(ENC_SW,INPUT); pinMode(SET,INPUT_PULLUP); pinMode(T_NULL,INPUT_PULLUP); pinMode(INVERT,INPUT_PULLUP); pinMode(OUT_RELE,OUTPUT); pinMode(OUT_NULL,OUTPUT); MsTimer2::set(1, to_Timer);MsTimer2::start(); lcd.setCursor(0,0);lcd.print("Calibrator");lcd.setCursor(0,1);lcd.print("temperature"); set_t=EEPROM.read(0);rej=EEPROM.read(1);t0=EEPROM.read(2);t_ok=EEPROM.read(3); if(rej>1){rej=0;}if(t0>1){t0=0;} digitalWrite(OUT_RELE,LOW);out=0;MCP4725(out);delay(1000);lcd.clear(); } void loop(){ /////////// SET TERMOPARA if(digitalRead(SET)==LOW&&digitalRead(ENC_SW)==HIGH){set_t++;if(set_t>3){set_t=0;}delay(200);w1=1;EEPROM.update(0,set_t);} if(set_t==0){txa();del=0;} if(set_t==1){txa();del=1;} if(set_t==2){txk();del=0;} if(set_t==3){txk();del=1;} if(w1==1){w1=0; if(del==1){pinMode(DEL,OUTPUT);digitalWrite(8,LOW);} if(del==0){pinMode(DEL,INPUT);}} ///////////// rej if(digitalRead(INVERT)==LOW&&digitalRead(ENC_SW)==LOW&&rej==0){rej=1;delay(200);EEPROM.update(1,rej);} if(digitalRead(INVERT)==LOW&&digitalRead(ENC_SW)==LOW&&rej==1){rej=0;delay(200);EEPROM.update(1,rej);} //////////// T_NULL if(digitalRead(T_NULL)==LOW&&tt==0&&digitalRead(ENC_SW)==HIGH){tt=1;out_old=out;out=0;MCP4725(out);delay(200);} if(digitalRead(T_NULL)==LOW&&tt==1&&digitalRead(ENC_SW)==HIGH){tt=0;out=out_old;MCP4725(out);delay(200);} if(out==0){digitalWrite(OUT_NULL,HIGH);}else{digitalWrite(OUT_NULL,LOW);} //////////// delete temp if(digitalRead(T_NULL)==LOW&&digitalRead(ENC_SW)==LOW&&t0==0){t0=1;delay(200);EEPROM.update(2,t0);} if(digitalRead(T_NULL)==LOW&&digitalRead(ENC_SW)==LOW&&t0==1){t0=0;delay(200);EEPROM.update(2,t0);} //////////// okr temp if(digitalRead(SET)==LOW&&digitalRead(ENC_SW)==LOW&®_t==0){reg_t=1;delay(200);} if(digitalRead(SET)==LOW&&digitalRead(ENC_SW)==LOW&®_t==1){reg_t=0;delay(200);} //////////// INVERT if(digitalRead(INVERT)==LOW&&inv==1&&digitalRead(ENC_SW)==HIGH){inv=0;digitalWrite(OUT_RELE,LOW);out=0;MCP4725(out);delay(200);} if(digitalRead(INVERT)==LOW&&inv==0&&digitalRead(ENC_SW)==HIGH){inv=1;digitalWrite(OUT_RELE,HIGH);out=0;MCP4725(out);delay(200);} /////////// READ T i++; dig = mcp.readWire();u_iz = dig * 0.256 /131071*u_kall;u_sum=u_sum+u_iz; if(i>=10){i=0;u=u_sum/10;u_sum=0;i=0;if(inv==1){u=u-2*u;}} Serial.println(t_ok); if(t0==0){t=ds1624_Read()+(t_ok-50)/10.00;}else{t=0;} /////////// LCD lcd.setCursor(0,0); if(t_iz==10000){lcd.print("HIGH ");} else if(t_iz==-1000){lcd.print("LOW ");} else{lcd.print(t_iz,1);lcd.write((uint8_t)0);lcd.print(" "); lcd.setCursor(7,0);if(tt==1){lcd.print("!");}else{lcd.print(" ");} lcd.setCursor(8,0);if(inv==1){lcd.print("*");}else{lcd.print(" ");}} lcd.setCursor(10,0);lcd.print(t,1);lcd.write((uint8_t)0);if(reg_t==1){lcd.print("* ");}else{lcd.print(" ");} lcd.setCursor(0,1); if(rej==0){lcd.print(u*1000,3);lcd.print("mV ");} if(rej==1&&(set_t==0||set_t==1)){lcd.print(u*1000+t*0.0400,3);lcd.print("mV+ ");} if(rej==1&&(set_t==2||set_t==3)){lcd.print(u*1000+t*0.0655,3);lcd.print("mV+ ");} lcd.setCursor(10,1);if(del==0){lcd.print("H");}else{lcd.print("L");} if(set_t==0||set_t==1){lcd.print("-TXA");} if(set_t==2||set_t==3){lcd.print("-TXK");} /////////// DAC if(tt==0&®_t==0){ if (newPosition != oldPosition && digitalRead(ENC_SW)==HIGH){oldPosition = newPosition; out=out+newPosition;myEnc.write(0);newPosition=0;w=1; if(out<0){out=0;}if(out>4095){out=4095;}MCP4725(out);} if (newPosition != oldPosition && digitalRead(ENC_SW)==LOW){oldPosition = newPosition; out=out+newPosition*30;myEnc.write(0);newPosition=0;w=1; if(out<0){out=0;}if(out>4095){out=4095;}MCP4725(out);} } // MCP4725(4000); if(reg_t==1){ if (newPosition != oldPosition && digitalRead(ENC_SW)==HIGH){oldPosition = newPosition; t_ok=t_ok+newPosition;myEnc.write(0);newPosition=0;w=1;EEPROM.update(3,t_ok); if(t_ok<0){t_ok=0;}if(t_ok>100){t_ok=100;}}} delay(100); }// loop void txa(){u0=u*1000+t*0.0400;// окружающая температура 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.0655;// окружающая температура 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;} } void to_Timer(){newPosition = myEnc.read()/4;} float ds1624_Read(){ Wire.beginTransmission(ADDR); Wire.write(0xAA); Wire.requestFrom(ADDR,2); while(Wire.available()<2); float value = Wire.read() + float(Wire.read()>>4)*0.0625; Wire.endTransmission(); return value; } void conf_ds1624(){ Wire.beginTransmission(ADDR); Wire.write(0xAC); Wire.write(0x00); Wire.endTransmission(); delay(100); Wire.beginTransmission(ADDR); Wire.write(0xEE); Wire.endTransmission(); delay(50); } void MCP4725(int data){ byte buffer[3]; buffer[0] = 0b01000000; // data=0; // buffer[0] = 0b01100000; // запись в память ЦАП 0 В buffer[1] = data >> 4; buffer[2] = data << 4; Wire.beginTransmission(0x60); Wire.write(buffer[0]); Wire.write(buffer[1]); Wire.write(buffer[2]); Wire.endTransmission(); }
Настройка прибора достаточна простая, необходимо провести ряд измерений выходного напряжения на уровне 75 мВ вольтметром класс точности которого не хуже 0,05 %, для калибровки АЦП. Меняя поправочный коэффициент необходимо добиться точности показаний выходного напряжения имитатора не хуже ± 10 мкВ.
const float u_kall = 1.00223; // калибровка АЦП
Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=3060#p3060
Примечание:
- На выходе имитатора сигналов установить конденсатор 2,2 мкФ (не полярный)
Здравствуйте. Резистор 150 Ом подключенный к выводу D8, а на схеме 10 Ом. Какой правильный? Тоже самое про цепь резисторов 10 кОм и 150 Ом (на схеме 10 и 710)
Я исправил текст.
Спасибо, схема интересная