Тема: Иммитатор сигнала термопар (ТХА, ТХК, ТППs, -10...+100 mV)
Основная статья - http://rcl-radio.ru/?p=131011
#define NULLL 3247
#define MV30 5052
#include <Wire.h>
#include <EEPROM.h>
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <Encoder.h> // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <U8glib.h>
#include <OneWire.h> // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip
#include <iarduino_KB.h> // https://github.com/tremaru/iarduino_KB.git
iarduino_KB KB(8,7,6,5, 4,3,2);
Encoder myEnc(11, 12);// DT, CLK
OneWire ds1(13); // Вход датчика 18b20
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST); // Dev 0, Fast I2C / TWI
long oldPosition = 999,newPosition, times, times1,times_ds=10000,times14,save,times_off;
bool w,ttt=0;
byte ok,reg;
int menu;
float out = 0,e,temp,t_ok,t_ok_mv,temp_old,k_ok;
long code[5],ccc;
int i,i1,kb;
/// xa
float a[] = {0,3.9450128025*pow(10,-2),2.3622373598*pow(10,-5),-3.2858906784*pow(10,-7),-4.9904828777*pow(10,-9),
6.7509059173*pow(10,-11),-5.7410327428*pow(10,-13),-3.1088872894*pow(10,-15),-1.0451609365*pow(10,-17),
-1.9889266878*pow(10,-20), -1.6322697486*pow(10,-23)};
float b[] = {-1.7600413686*pow(10, -2),3.8921204975 *pow(10, -2),1.8558770032 *pow(10, -5),-9.9457592874 *pow(10, -8),
3.1840945719 *pow(10, -10),-5.6072844889 *pow(10, -13),5.6075059059 *pow(10, -16),-3.2020720003 *pow(10, -19),
9.7151147152 *pow(10, -23),-1.2104721275 *pow(10, -26)};
float c[] = {1.185976 *pow(10, -1),-1.183432 *pow(10, -4)};
float logg=2.718281828;int u=30;
/// xk
float a1[] = {-4.1626930*pow(10,-6),6.3310880*pow(10,-2),6.0118088*pow(10,-5),-7.9469796*pow(10,-8),9.3101891*pow(10,-11),
-2.4299630*pow(10,-14),-2.6547176*pow(10,-16),4.4332477*pow(10,-19),-2.1172626*pow(10,-22)};
// pps
//Для термопары типа S
float a2[] = {0, 5.40313308631*pow(10,-3),1.25934289740*pow(10,-5),-2.32477968689*pow(10,-8),3.22028823036*pow(10,-11),
-3.31465196389*pow(10,-14),2.55744251786*pow(10,-17),-1.25068871393*pow(10,-20),2.71443176145*pow(10,-24)};
float b2[] = {1.32900444085,3.34509311344*pow(10,-3),6.54805192818*pow(10,-6),-1.64856259209*pow(10,-9),1.29989605174*pow(10,-14)};
float c2[] = {1.46628232636*pow(10,2),-2.58430516752*pow(10,-1),1.63693574641*pow(10,-4),-3.30439046987*pow(10,-8),-9.43223690612*pow(10,-15)};
void setup(){
Serial.begin(9600);
delay(500);
pinMode(10,INPUT);// encoder button
// TIMER_1 D9 OUTPUT
DDRB = 1 << PB1; // D9 output pwm
noInterrupts();
TCCR1A=0;TCCR1B=0;
TCCR1A = 1 << COM1A1 | 1 << WGM11;
TCCR1B = 1 << WGM13 | 1 << WGM12 | 1 << CS10;
ICR1 = 20000;
MsTimer2::set(2, to_Timer);MsTimer2::start();
k_ok = (EEPROM.read(10)<<8)+EEPROM.read(11);
ok=EEPROM.read(0);menu=EEPROM.read(1);
times=float(MV30)/30.0*out+NULLL;
OCR1A = times;
interrupts();
KB.begin(KB3);
// if(ok==1||ok==2){temp = dsRead(0)*k_ok/100;}else{temp=0;}
}
void loop(){
if(digitalRead(10)==LOW){times_off=millis();}
if(KB.check(KEY_DOWN )){ kb=1;
if(digitalRead(10)==HIGH && KB.getNum==14){i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}kb=0;temp=0;delay(200);}
if(digitalRead(10)==HIGH && KB.getNum==15){delay(200);kb=0;temp=ccc;i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}}
if(digitalRead(10)==LOW && KB.getNum==1){menu=0;w=1;times1=millis();kb=0;temp=ccc;i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}delay(200);}
if(digitalRead(10)==LOW && KB.getNum==2){menu=1;w=1;times1=millis();kb=0;temp=ccc;i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}delay(200);}
if(digitalRead(10)==LOW && KB.getNum==3){menu=2;w=1;times1=millis();kb=0;temp=ccc;i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}delay(200);}
if(digitalRead(10)==LOW && KB.getNum==4){menu=3;w=1;times1=millis();kb=0;temp=ccc;i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}delay(200);}
if(digitalRead(10)==LOW && KB.getNum==7){ok=0;w=1;times1=millis();kb=0;temp=ccc;i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}delay(200);}
if(digitalRead(10)==LOW && KB.getNum==8){ok=1;w=1;times1=millis();kb=0;temp=ccc;i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}delay(200);}
if(digitalRead(10)==LOW && KB.getNum==9){ok=2;w=1;times1=millis();kb=0;temp=ccc;i=0;ccc=0;for(i1=0;i1<5;i1++){code[i]=0;}delay(200);}
if(digitalRead(10)==LOW && KB.getNum==0&&ttt==0){kb=0;KB.getNum=500;ttt=1;Serial.println(ttt);delay(500);}
if(digitalRead(10)==LOW && KB.getNum==0&&ttt==1){kb=0;KB.getNum=500;ttt=0;Serial.println(ttt);delay(500);}
if(digitalRead(10)==LOW && KB.getNum==14){menu=14;delay(200);}
if(menu==14&&KB.getNum==15){EEPROM.update(10,highByte(int(k_ok)));EEPROM.update(11,lowByte(int(k_ok)));save=millis();delay(200);}
////////////////////////////////////////////////////////////
if(KB.getNum<10&&i<5&&digitalRead(10)==HIGH){
code[i] = KB.getNum;delay(200);
switch(i){
case 0: ccc = code[0];break;
case 1: ccc = code[0]*10 + code[1];break;
case 2: ccc = code[0]*100 + code[1]*10 + code[2];break;
case 3: ccc = code[0]*1000 + code[1]*100 + code[2]*10 + code[3];break;
case 4: ccc = code[0]*10000 + code[1]*1000 + code[2]*100 + code[3]*10 + code[4];break;
}
i++;if(i>3){i=4;}
if(menu==0){if(ccc>13720){ccc=13720;}}
if(menu==1){if(ccc>8000){ccc=8000;}}
if(menu==2){if(ccc>17680){ccc=17680;}}
if(menu==3){if(ccc>10000){ccc=10000;}}
}
}
if(millis()-times_ds>10000){t_ok=dsRead(0)*k_ok/1000;times_ds=millis();}
if(menu==0){
if(newPosition != oldPosition){oldPosition = newPosition;pos();
if(digitalRead(10)==LOW){temp=temp+newPosition*50;}else{temp=temp+newPosition;}times_off=millis();
myEnc.write(0);newPosition=0;if(temp<-2700){temp=-2700;}if(temp>13720){temp=13720;}}
t_ok_mv = (t_ok-20)*0.0405+0.798;
if(ok==0){out=fun_xa(temp/10.0);}
if(ok>0){out=fun_xa(temp/10.0)-t_ok_mv;}
if(ttt==1){out=0;}
OCR1A=float(MV30)/30.0*out+NULLL;
if(millis()-times_off>300000){u8g.firstPage();do { } while( u8g.nextPage() );}
else{
u8g.firstPage();do {
u8g.setFont(u8g_font_profont29r);
u8g.setPrintPos(0, 20);
if(ttt==1){u8g.setFont(u8g_font_profont17r);u8g.drawStr(10,40,"Out=0 mV");}
else{
if(kb==0){u8g.print(temp/10.0,1);}
if(kb==1){u8g.print(ccc/10.0,1);}
u8g.setPrintPos(0, 45);
if(ok==2){u8g.print(out+t_ok_mv,3);}
else{u8g.print(out,3);}
u8g.setFont(u8g_font_profont17r);u8g.drawStr(5,64,"TXA");u8g.drawStr(100,20,"*C");
u8g.drawStr(100,45,"mV");
u8g.setPrintPos(75, 64);if(ok>0){u8g.print(t_ok,1);}
if(ok==2){;u8g.drawStr(60,64,"+");}
}
}
while( u8g.nextPage() );
}}
if(menu==1){
if(newPosition != oldPosition){oldPosition = newPosition;pos();
if(digitalRead(10)==LOW){temp=temp+newPosition*50;}else{temp=temp+newPosition;}times_off=millis();
myEnc.write(0);newPosition=0;if(temp<-2000){temp=-2000;}if(temp>8000){temp=8000;}}
t_ok_mv = (t_ok-20)*0.0661+1.290;
if(ok==0){out=fun_xk(temp/10.0);}
if(ok>0){out=fun_xk(temp/10.0)-t_ok_mv;}
if(ttt==1){out=0;}
OCR1A=float(MV30)/30.0*out+NULLL;
if(millis()-times_off>300000){u8g.firstPage();do { } while( u8g.nextPage() );}
else{
u8g.firstPage();do {
u8g.setFont(u8g_font_profont29r);
u8g.setPrintPos(0, 20);
if(ttt==1){u8g.setFont(u8g_font_profont17r);u8g.drawStr(10,40,"Out=0 mV");}
else{
if(kb==0){u8g.print(temp/10.0,1);}
if(kb==1){u8g.print(ccc/10.0,1);}
u8g.setPrintPos(0, 45);
if(ok==2){u8g.print(out+t_ok_mv,3);}
else{u8g.print(out,3);}
u8g.setFont(u8g_font_profont17r);u8g.drawStr(5,64,"TXK");u8g.drawStr(100,20,"*C");
u8g.drawStr(100,45,"mV");
u8g.setPrintPos(75, 64);if(ok>0){u8g.print(t_ok,1);}
if(ok==2){;u8g.drawStr(60,64,"+");}
}
}
while( u8g.nextPage() );
}}
if(menu==2){
if(newPosition != oldPosition){oldPosition = newPosition;pos();
if(digitalRead(10)==LOW){temp=temp+newPosition*50;}else{temp=temp+newPosition;}times_off=millis();
myEnc.write(0);newPosition=0;if(temp<-500){temp=-500;}if(temp>17680){temp=17680;}}
t_ok_mv = (t_ok-20)*0.006+0.113;
if(ttt==1){out=0;}
if(ok==0){out=fun_pps(temp/10.0);}
if(ok>0){out=fun_pps(temp/10.0)-t_ok_mv;}
OCR1A=float(MV30)/30.0*out+NULLL;
if(millis()-times_off>300000){u8g.firstPage();do { } while( u8g.nextPage() );}
else{
u8g.firstPage();do {
u8g.setFont(u8g_font_profont29r);
u8g.setPrintPos(0, 20);
if(ttt==1){u8g.setFont(u8g_font_profont17r);u8g.drawStr(10,40,"Out=0 mV");}
else{
if(kb==0){u8g.print(temp/10.0,1);}
if(kb==1){u8g.print(ccc/10.0,1);}
u8g.setPrintPos(0, 45);
if(ok==2){u8g.print(out+t_ok_mv,3);}
else{u8g.print(out,3);}
u8g.setFont(u8g_font_profont17r);u8g.drawStr(5,64,"TPPs");u8g.drawStr(100,20,"*C");
u8g.drawStr(100,45,"mV");
u8g.setPrintPos(75, 64);if(ok>0){u8g.print(t_ok,1);}
if(ok==2){;u8g.drawStr(60,64,"+");}
}
}
while( u8g.nextPage() );
}}
if(menu==3){
if(newPosition != oldPosition){oldPosition = newPosition;pos();
if(digitalRead(10)==LOW){temp=temp+newPosition*30;}else{temp=temp+newPosition;}times_off=millis();
myEnc.write(0);newPosition=0;if(temp<-1000){temp=-1000;}if(temp>10000){temp=10000;}reg=1;}
out=temp;
if(ttt==1){out=0;}
OCR1A=float(MV30)/30.0*out/100+NULLL;
if(reg==1){reg=0;Serial.println(OCR1A);}
if(millis()-times_off>300000){u8g.firstPage();do { } while( u8g.nextPage() );}
else{
u8g.firstPage();do {
u8g.setFont(u8g_font_profont29r);
u8g.setPrintPos(5, 20);
if(ttt==1){u8g.setFont(u8g_font_profont17r);u8g.drawStr(10,40,"Out=0 mV");}
else{
if(kb==0){u8g.print(temp/100.0,2);}
if(kb==1){u8g.print(ccc/100.0,2);}
u8g.setFont(u8g_font_profont17r);if(kb==0){u8g.drawStr(100,20,"mV");}
}
}
while( u8g.nextPage() );
}}
if(menu==14){
if(newPosition != oldPosition){oldPosition = newPosition;pos();
k_ok=k_ok+newPosition;myEnc.write(0);t_ok=dsRead(0)*k_ok/1000;newPosition=0;if(k_ok<800){k_ok=800;}if(k_ok>1200){k_ok=1200;}}
u8g.firstPage();do {
if(millis()-times14>1000){t_ok=dsRead(0)*k_ok/1000;times14=millis();}
u8g.setFont(u8g_font_profont29r);
u8g.setPrintPos(5, 20);u8g.print(t_ok,1);
u8g.setPrintPos(5, 45);u8g.print(k_ok/1000,3);
u8g.setFont(u8g_font_profont17r);
if(millis()-save<1000){u8g.drawStr(5,60,"SAVE");}
else{u8g.drawStr(5,60,"kall t_ok");}
}
while( u8g.nextPage() );
}
if(millis()-times1>5000 && w==1){EEPROM.update(0,ok);EEPROM.update(1,menu);w=0;}
}
float fun_xa(float t){
//термопары типа К -270...1372 (ХA)
if(t<=0){
e=(a[0]*pow(t,0))+(a[1]*pow(t,1))+(a[2]*pow(t,2))+(a[3]*pow(t,3))+(a[4]*pow(t,4))+(a[5]*pow(t,5))+(a[6]*pow(t,6))+(a[7]*pow(t,7))+(a[8]*pow(t,8))+(a[9]*pow(t,9))+(a[10]*pow(t,10));}
if(t>0){
e=(b[0]*pow(t,0))+(b[1]*pow(t,1))+(b[2]*pow(t,2))+(b[3]*pow(t,3))+(b[4]*pow(t,4))+(b[5]*pow(t,5))+(b[6]*pow(t,6))+(b[7]*pow(t,7))+(b[8]*pow(t,8))+(b[9]*pow(t,9)+(c[0]*pow(logg,c[1]*pow(t-126.9686,2))));}
return e;
}
float fun_xk(float t){
//термопары типа L -200...800 (ХК)
e=(a1[0]*pow(t,0))+(a1[1]*pow(t,1))+(a1[2]*pow(t,2))+(a1[3]*pow(t,3))+(a1[4]*pow(t,4))+(a1[5]*pow(t,5))+(a1[6]*pow(t,6))+(a1[7]*pow(t,7))+(a1[8]*pow(t,8));
return e;
}
// pps -50...+1768 (PPs)
float fun_pps(float t){
if(t<=1064){
e=(a2[0]*pow(t,0))+(a2[1]*pow(t,1))+(a2[2]*pow(t,2))+(a2[3]*pow(t,3))+(a2[4]*pow(t,4))+(a2[5]*pow(t,5))+(a2[6]*pow(t,6))+(a2[7]*pow(t,7))+(a2[8]*pow(t,8))+(a2[9]*pow(t,9));}
if(t>=1065 and t<=1664){
e=(b2[0]*pow(t,0))+(b2[1]*pow(t,1))+(b2[2]*pow(t,2))+(b2[3]*pow(t,3))+(b2[4]*pow(t,4))+(b2[5]*pow(t,5));}
if(t>=1665){
e=(c2[0]*pow(t,0))+(c2[1]*pow(t,1))+(c2[2]*pow(t,2))+(c2[3]*pow(t,3))+(c2[4]*pow(t,4));}
return e;
}
void pos(){if(newPosition>1){newPosition=1;}if(newPosition<-1){newPosition=-1;}}
void to_Timer(){newPosition = myEnc.read()/4;}
float dsRead(byte x) {
byte data[2], addr[8][8], kol = 0;
while (ds1.search(addr[kol])) { // поиск датчиков, определение адреса и кол-ва датчиков
kol++;
}
ds1.reset_search(); // Сброс поиска датчика
ds1.reset(); // Инициализация, выполняется сброс шины
ds1.select(addr[x]); // Обращение к датчику по адресу
ds1.write(0x44, 0); // Измерение температуры с переносом данных в память
ds1.reset(); // Инициализация, выполняется сброс шины
ds1.select(addr[x]); // Обращение к датчику по адресу
ds1.write(0xBE); // Обращение памяти
data[0] = ds1.read();// Чтение памяти byte low
data[1] = ds1.read();// Чтение памяти byte high
float value = ((data[1] << 8) | data[0]) / 16.0; return (float)value; // Расчет температуры и вывод
}