├── Gerber_(板厚0.8mm)328P迷你PD烙铁(合并).zip
├── Gerber_0.91OLED屏幕.zip
├── Gerber_V1.1主控屏幕合并.zip
├── Gerber_V1.1合并无开槽.zip
├── Gerber_V1.1拨码开关.zip
├── Gerber_单主控板_328P迷你PD烙铁.zip
├── Gerber_支架_2021-02-27.zip
├── Gerber_触摸支架_2021-03-26.zip
├── Picture
├── 1.png
├── 10.jpg
├── 11.jpg
├── 2.jpg
├── 4.jpg
├── 5.jpg
├── 6.png
├── 7.png
├── 8.jpg
└── 9.jpg
├── README.md
├── Schematic_328P迷你PD电烙铁.pdf
├── Schematic_328P迷你PD电烙铁V1.1.pdf
├── v1.03
├── A_ReadMe.ino
├── Buzzer.ino
├── CurveFitting.ino
├── Display.ino
├── DisplayMain.ino
├── DisplaySet.ino
├── EEPROM.ino
├── InterruptKey.ino
├── MsTimer2.ino
├── PID.ino
├── Sleep.ino
├── WDT.ino
├── analogRead.ino
└── v1.03.ino
├── v1.20.1
├── A_ReadMe.ino
├── Buzzer.ino
├── CurveFitting.ino
├── Display.ino
├── DisplayMain.ino
├── DisplaySet.ino
├── EEPROM.ino
├── InterruptKey.ino
├── MsTimer2.ino
├── PID.ino
├── Sleep.ino
├── WDT.ino
├── analogRead.ino
├── font.c
├── v1.20.1.ino
├── v1.20.1.ino.eep
├── v1.20.1.ino.hex
└── v1.20.1.ino.with_bootloader.hex
├── 主控板+屏幕V1.0版本iBOM.html
├── 主控板+屏幕V1.1版本iBOM.html
└── 用到的库
├── MsTimer2.zip
└── U8g2-2020-11-15.7z
/Gerber_(板厚0.8mm)328P迷你PD烙铁(合并).zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Gerber_(板厚0.8mm)328P迷你PD烙铁(合并).zip
--------------------------------------------------------------------------------
/Gerber_0.91OLED屏幕.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Gerber_0.91OLED屏幕.zip
--------------------------------------------------------------------------------
/Gerber_V1.1主控屏幕合并.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Gerber_V1.1主控屏幕合并.zip
--------------------------------------------------------------------------------
/Gerber_V1.1合并无开槽.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Gerber_V1.1合并无开槽.zip
--------------------------------------------------------------------------------
/Gerber_V1.1拨码开关.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Gerber_V1.1拨码开关.zip
--------------------------------------------------------------------------------
/Gerber_单主控板_328P迷你PD烙铁.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Gerber_单主控板_328P迷你PD烙铁.zip
--------------------------------------------------------------------------------
/Gerber_支架_2021-02-27.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Gerber_支架_2021-02-27.zip
--------------------------------------------------------------------------------
/Gerber_触摸支架_2021-03-26.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Gerber_触摸支架_2021-03-26.zip
--------------------------------------------------------------------------------
/Picture/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/1.png
--------------------------------------------------------------------------------
/Picture/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/10.jpg
--------------------------------------------------------------------------------
/Picture/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/11.jpg
--------------------------------------------------------------------------------
/Picture/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/2.jpg
--------------------------------------------------------------------------------
/Picture/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/4.jpg
--------------------------------------------------------------------------------
/Picture/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/5.jpg
--------------------------------------------------------------------------------
/Picture/6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/6.png
--------------------------------------------------------------------------------
/Picture/7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/7.png
--------------------------------------------------------------------------------
/Picture/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/8.jpg
--------------------------------------------------------------------------------
/Picture/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Picture/9.jpg
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 328P-MiNi-T12(所有文件打板不过审我不管!)
2 | - 所有文件不定期更新
3 |
4 | ## 更新历史
5 | - 2021.5.18 上传拨码开关版本PCB Gerber文件
6 | - 2021.4.5 上传已修改适配的甘草最新1.20版本程序
7 | - 2021.2.28 上传V1.1版本的iBOM以及原理图
8 | - 2021.3.26 更新触摸版本控制的支架(接线方法及所需元器件后期更新)打板不过审我不管
9 | - 2021.3.23 更新V1.1版本Gerber文件
10 | - 2021.2.27 上传支架Gerber文件
11 | - 2021.2.17 重新上传分开打板的文件并更新README.md
12 | - 2021.2.16 将主控板以及屏幕合并为同一打板文件并更新iBOM文件并更新README.md
13 |
14 | ## 注意事项
15 | - 屏幕主控在一起的板子没有打板过,不知道能不能过JLC审核(故保留分开打板的Gerber文件)
16 | - 合并的Gerber与分开的Gerber背面的焊点位置及丝印位置有些许差距,完全不影响
17 | - 屏幕和主控板暂时采用飞线连接
18 |
19 | ***支架板厚 1.0mm***
20 |
21 | ***主控板及屏幕板厚 0.8mm***
22 |
23 | ## 套件及成品开车QQ群:903440195(***不提供解决疑难杂症服务***)
24 |
25 | [B站视频地址①](https://www.bilibili.com/video/BV1q54y1p7Bn) [B站视频地址②](https://www.bilibili.com/video/BV1bz4y1m7pS)
26 |
27 | 项目源码及原理图基于 https://github.com/jie326513988/mini-T12 修改
28 |
29 | 以下带亚克力管的支架为触摸控制的支架,文件后续更新上来
30 |
31 | 
32 |
33 | 
34 |
35 | 

36 | ***
37 | ### 主控板成品照片
38 |
39 | V1.0版本
40 |
41 | 
42 |
43 | V1.1版本
44 |
45 | 

46 | ***
47 | ### 带有精美iBOM方便对照焊接
48 |
49 | 
50 |
--------------------------------------------------------------------------------
/Schematic_328P迷你PD电烙铁.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Schematic_328P迷你PD电烙铁.pdf
--------------------------------------------------------------------------------
/Schematic_328P迷你PD电烙铁V1.1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/Schematic_328P迷你PD电烙铁V1.1.pdf
--------------------------------------------------------------------------------
/v1.03/A_ReadMe.ino:
--------------------------------------------------------------------------------
1 | /*
2 | 校准温度曲线的方法
3 | 1.准备好能测量0 - 500摄氏度的设备,探头建议使用裸装,以免外壳热传导导致热量损失测量不准
4 | 2.将探头紧压住烙铁头发热前段(上锡部分再下来一点),一定要紧紧压住,不然也会测量不准
5 | 3.放置好烙铁头以免校准时烫伤手或物品!
6 | 4.接上电源,从控制板进入‘校准’界面,将空心选框移动至第1段温度处(即对应的ADC 10下面)
7 | 5.按下确认键,此时空心选框变成实心选框,烙铁头开始加热,等待最下方的‘Now ADC’值稳定在一定的范围,与第一行相应的ADC值差不多即可(此时是ADC 10)
8 | 6.使用测量设备测量烙铁头的温度,将第1段温度调至测量得到的温度(实心选框状态可旋转旋钮调节数值)
9 | 7.依次测量剩下的第2段、第3段、第4段温度并输入至控制器
10 | 8.测量完4段温度后将光标移至Save,按下确认键,等待程序计时温度曲线
11 | 9.计算完会显示P系数界面,,再按下确认键即可退出校准界面
12 | 10.在主界面准备进行二次校准
13 | 11.在主界面开启加热至第二段校准的温度,如265,则加热至260度,若显示温度比实际高的话就到校准界面调高第二段温度,低则调低
14 | 12.依次加热至第三第四段温度并校准,直至自己满意为止
15 | 13.进入到“烙铁”选项,将冷端补偿温度改为此时主界面所显示的环境温度值(屏幕右上角),完毕。
16 | */
17 |
18 | /*
19 | 长按操作(5下短音最后1下长音)
20 | 主界面,进入设置界面
21 | 其他界面,退出至主界面
22 | 双击操作(2下短音)
23 | 主界面,加热或停止状态切换
24 | 其他界面,无
25 | 单击(1下短音)
26 | 主界面,无
27 | 设置界面,进入二级菜单
28 | 二级菜单,切换数值更改选中状态,或确认更改数值,无选框状态则退出至一级菜单
29 | */
30 |
--------------------------------------------------------------------------------
/v1.03/Buzzer.ino:
--------------------------------------------------------------------------------
1 | //********** 控制蜂鸣器发声的频率和时间,系统延时法,占用系统速度大 **********
2 | uint32_t error_buzzer_db_time = 0;
3 | void buzzer_run()
4 | {
5 | if (buzzer_state == 1)
6 | {
7 | for (uint16_t i = 0; i < buzzer_count; i++)
8 | {
9 | digitalWrite(buzzer_pin, 1);
10 | delayMicroseconds(buzzer_time);
11 | digitalWrite(buzzer_pin, 0);
12 | if (i < buzzer_count - 1) delayMicroseconds(buzzer_time); //最后一次不需要延时
13 | }
14 | buzzer_state = 0;
15 | }
16 | //错误提示报警音
17 | if (vin_error == 1 || t12_adc_error == 1)
18 | {
19 | if (millis() - error_buzzer_db_time > 1000)
20 | {
21 | buzzer(120, 300);
22 | error_buzzer_db_time = millis();
23 | }
24 | }
25 |
26 | if (buzzer_szjm_state == 1) //进入设置界面时发出声音提示一下
27 | {
28 | buzzer(150, 720);
29 | buzzer_szjm_state = 0;
30 | }
31 | else if (buzzer_zjm_state == 1) //退出至主界面时发出声音提示一下
32 | {
33 | buzzer(150, 720);
34 | buzzer_zjm_state = 0;
35 | }
36 | }
37 |
38 | void buzzer(uint16_t time, uint16_t count)
39 | {
40 | buzzer_state = 1; //准备好蜂鸣器
41 | buzzer_time = time; //设置时间
42 | buzzer_count = count; //设置次数
43 | }
44 | //*********************************************************
45 |
46 | //****** 控制蜂鸣器发声的频率和时间,内部中断法,占用系统速度小 ******
47 |
48 | /*void buzzer(uint16_t time, uint16_t count) //时间单位ms
49 | {
50 | if (buzzer_state == 0 && digitalRead(buzzer_pin) == 0) //蜂鸣器停止状态才能设置定时器
51 | {
52 | buzzer_count = count; //设置次数
53 | Timer1.initialize(time); //设置时间
54 | Timer1.attachInterrupt(buzzer_isr); //设置定时器中断函数
55 | Timer1.start(); //启动定时器
56 | }
57 | }
58 | void buzzer_isr()
59 | {
60 | buzzer_isr_count++;
61 | bitWrite(PINB, 0, 1); //设置pin8为输出 PINX写1翻转状态
62 | buzzer_state = 1; //标识蜂鸣器正在工作
63 | if (buzzer_isr_count >= buzzer_count)
64 | {
65 | buzzer_isr_count = 0; // 清除计数
66 | buzzer_state = 0; //标识蜂鸣器已停止
67 | digitalWrite(buzzer_pin, 0); //关闭蜂鸣器
68 | Timer1.stop(); //停止中断
69 | }
70 | }*/
71 | //*********************************************************
72 | uint8_t get_num_digit(uint32_t num)//获取数字的位数
73 | {
74 | uint8_t count = 0;
75 | if (num == 0) count = 1;
76 | while (num != 0)
77 | {
78 | // n = n/10
79 | num /= 10;
80 | ++count;
81 | }
82 | return count;
83 | }
84 |
--------------------------------------------------------------------------------
/v1.03/CurveFitting.ino:
--------------------------------------------------------------------------------
1 | //********** 曲线拟合程序 **********
2 | //曲线拟合算法来至https://blog.csdn.net/m0_37362454/article/details/82456616 by欧阳小俊
3 | void qxnh_run() //曲线拟合运行
4 | {
5 | int16_t i, sizenum;
6 | float P[4];
7 | int8_t dimension = 3; //3次多项式拟合
8 | // 要拟合的数据
9 | int xx[] = {sz_adc0, sz_adc1, sz_adc2, sz_adc3}; //t12 adc
10 | //int yy[] = {45, 219, 366, 435}; //测量设备的温度
11 |
12 | sizenum = sizeof(xx) / sizeof(xx[0]); //拟合数据的维数
13 | polyfit(sizenum, xx, sz_temp, dimension, P);
14 |
15 | sz_p[0] = P[0];
16 | sz_p[1] = P[1];
17 | sz_p[2] = P[2];
18 | sz_p[3] = P[3];
19 | /*
20 | 得出系数:P[0],P[1],P[2]
21 | 曲线公式:y = P[3]*X*X*X+P[2]*X*X + P[1]*X + P[0]
22 | 曲线公式:t12_temp =P[3]* t12_ad * t12_ad* t12_ad + P[2] * t12_ad * t12_ad + P[1] * t12_ad + P[0];
23 | */
24 | }
25 |
26 | /*==================polyfit(n,x,y,poly_n,a)===================*/
27 | /*=======拟合y=a0+a1*x+a2*x^2+……+apoly_n*x^poly_n========*/
28 | /*=====n是数据个数 xy是数据值 poly_n是多项式的项数======*/
29 | /*===返回a0,a1,a2,……a[poly_n],系数比项数多一(常数项)=====*/
30 | void polyfit(int n, int x[], int y[], int poly_n, float p[])
31 | {
32 | int i, j;
33 | float *tempx, *tempy, *sumxx, *sumxy, *ata;
34 |
35 | tempx = (float *)calloc(n , sizeof(float));
36 | sumxx = (float *)calloc((poly_n * 2 + 1) , sizeof(float));
37 | tempy = (float *)calloc(n , sizeof(float));
38 | sumxy = (float *)calloc((poly_n + 1) , sizeof(float));
39 | ata = (float *)calloc( (poly_n + 1) * (poly_n + 1) , sizeof(float) );
40 | for (i = 0; i < n; i++)
41 | {
42 | tempx[i] = 1;
43 | tempy[i] = y[i];
44 | }
45 | for (i = 0; i < 2 * poly_n + 1; i++)
46 | {
47 | for (sumxx[i] = 0, j = 0; j < n; j++)
48 | {
49 | sumxx[i] += tempx[j];
50 | tempx[j] *= x[j];
51 | }
52 | }
53 | for (i = 0; i < poly_n + 1; i++)
54 | {
55 | for (sumxy[i] = 0, j = 0; j < n; j++)
56 | {
57 | sumxy[i] += tempy[j];
58 | tempy[j] *= x[j];
59 | }
60 | }
61 | for (i = 0; i < poly_n + 1; i++)
62 | {
63 | for (j = 0; j < poly_n + 1; j++)
64 | {
65 | ata[i * (poly_n + 1) + j] = sumxx[i + j];
66 | }
67 | }
68 | gauss_solve(poly_n + 1, ata, p, sumxy);
69 |
70 | free(tempx);
71 | free(sumxx);
72 | free(tempy);
73 | free(sumxy);
74 | free(ata);
75 | }
76 | /*============================================================
77 | 高斯消元法计算得到 n 次多项式的系数
78 | n: 系数的个数
79 | ata: 线性矩阵
80 | sumxy: 线性方程组的Y值
81 | p: 返回拟合的结果
82 | ============================================================*/
83 | void gauss_solve(int n, float A[], float x[], float b[])
84 | {
85 | int i, j, k, r;
86 | float max;
87 | for (k = 0; k < n - 1; k++)
88 | {
89 | max = fabs(A[k * n + k]); // find maxmum
90 | r = k;
91 | for (i = k + 1; i < n - 1; i++)
92 | {
93 | if (max < fabs(A[i * n + i]))
94 | {
95 | max = fabs(A[i * n + i]);
96 | r = i;
97 | }
98 | }
99 | if (r != k)
100 | {
101 | for (i = 0; i < n; i++) //change array:A[k]&A[r]
102 | {
103 | max = A[k * n + i];
104 | A[k * n + i] = A[r * n + i];
105 | A[r * n + i] = max;
106 | }
107 | max = b[k]; //change array:b[k]&b[r]
108 | b[k] = b[r];
109 | b[r] = max;
110 | }
111 |
112 | for (i = k + 1; i < n; i++)
113 | {
114 | for (j = k + 1; j < n; j++)
115 | A[i * n + j] -= A[i * n + k] * A[k * n + j] / A[k * n + k];
116 | b[i] -= A[i * n + k] * b[k] / A[k * n + k];
117 | }
118 | }
119 |
120 | for (i = n - 1; i >= 0; x[i] /= A[i * n + i], i--)
121 | {
122 | for (j = i + 1, x[i] = b[i]; j < n; j++)
123 | x[i] -= A[i * n + j] * x[j];
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/v1.03/Display.ino:
--------------------------------------------------------------------------------
1 | //********** 显示决策 **********
2 | uint32_t system_sleep_db_time = 0; //系统进入睡眠对比时间
3 | void display()
4 | {
5 | if (xp_state == 0) //正常显示
6 | {
7 | if (display_count == ZJM) zjm();
8 | else if (display_count == SZJM) szjm();
9 | else if (display_count == SZJM_PID) szjm_pid();
10 | else if (display_count == SZJM_SLEEP) szjm_sleep();
11 | else if (display_count == SZJM_OLED) szjm_oled();
12 | else if (display_count == SZJM_POWER) szjm_power();
13 | else if (display_count == SZJM_LAOTIE) szjm_laotie();
14 | else if (display_count == SZJM_JIAOZHUN) szjm_jiaozhun();
15 | }
16 | else xpjm(); //显示息屏界面
17 | }
18 |
19 | void draw_page(void)
20 | {
21 | static uint8_t is_next_page = 0;
22 | // 调用第一页,如果需要
23 | if ( is_next_page == 0 )
24 | {
25 | u8g2.firstPage();
26 | is_next_page = 1;
27 | }
28 | // 画我们的屏幕
29 | display();
30 | // 调用下一页
31 | if ( u8g2.nextPage() == 0 )
32 | {
33 | is_next_page = 0; // 确保调用了第一个页面
34 | }
35 | }
36 |
37 | void display_hfccsz() //恢复出厂设置进度显示界面
38 | {
39 | uint16_t x_old = 0;
40 | for (int i = 0 ; i < EEPROM.length() ; i++)
41 | {
42 | __asm__ __volatile__ ("wdr"); //防止没清除完因看门狗没喂狗导致重启
43 | uint16_t x_new = map(i, 0, EEPROM.length(), 0, 100);
44 | if (x_new - x_old >= 5)
45 | {
46 | u8g2.firstPage();
47 | do {
48 | u8g2.setCursor(50, 16);
49 | u8g2.print(x_new);
50 | u8g2.setCursor(75, 16);
51 | u8g2.print("%");
52 | x_old = x_new;
53 | } while ( u8g2.nextPage() );
54 | }
55 | EEPROM.write(i, 0); //清除所有EEPROM
56 | }
57 | set_wdt_mod(1, 0); //利用看门狗实现软重启
58 | }
59 |
60 | void kj_display() //开机显示版本号
61 | {
62 | u8g2.firstPage();
63 | do {
64 | u8g2.setFont(chinese15);
65 | u8g2.setCursor(50, 21);
66 | u8g2.print(version);
67 | } while ( u8g2.nextPage() );
68 | }
69 |
70 | void xpjm() //息屏界面
71 | {
72 | if (xp_x - xp_x_old > 0)
73 | {
74 | if (xp_x_old != xp_x) xp_x_old++;
75 | }
76 | else if (xp_x - xp_x_old < 0 )
77 | {
78 | if (xp_x_old != xp_x) xp_x_old--;
79 | }
80 |
81 | if (xp_y - xp_y_old > 0)
82 | {
83 | if (xp_y_old != xp_y) xp_y_old++;
84 | }
85 | else if (xp_y - xp_y_old < 0 )
86 | {
87 | if (xp_y_old != xp_y) xp_y_old--;
88 | }
89 |
90 | u8g2.setFont(chinese15);
91 | u8g2.setCursor(xp_x_old, xp_y_old);
92 | u8g2.print(tc1047_temp, 1);
93 | u8g2.setCursor(xp_x_old + 27, xp_y_old - 1);
94 | u8g2.print("℃");
95 | }
96 |
97 | /*u8g2.firstPage();
98 | do {
99 | u8g2.setFont(chinese15);
100 | u8g2.setCursor(xp_x, xp_y);
101 | u8g2.print(tc1047_temp, 1);
102 | u8g2.setCursor(xp_x + 27, xp_y - 1);
103 | u8g2.print("℃");
104 | } while ( u8g2.nextPage() );*/
105 |
--------------------------------------------------------------------------------
/v1.03/DisplayMain.ino:
--------------------------------------------------------------------------------
1 | //********** 画主界面 **********
2 | uint8_t zjm_x1 = 0;
3 | uint8_t zjm_x2 = 100;
4 | #define zjm_x3 75
5 | #define zjm_x4 zjm_x3+4
6 |
7 | #define zjm_y1 7
8 | #define zjm_y2 19
9 | #define zjm_y3 32
10 | #define zjm_y4 14
11 | boolean zjm_dh_run = 0; //主界面动画状态 0-不允许 1-允许
12 | uint32_t zjm_dh_time1 = 0; //动画1运转对比时间
13 | uint32_t zjm_dh_time2 = 0; //动画2运转对比时间
14 | //热、停切换动画变量
15 | uint8_t zjm_dh_x1 = 0;
16 | uint8_t zjm_dh_y1 = 0;
17 | uint8_t zjm_dh_r1 = 1;
18 | //pwm动效动画
19 | uint8_t zjm_dh_l[14];
20 | //开机过度动画y增量
21 | int8_t zjm_dh_y = 32;
22 | void zjm()
23 | {
24 | //****** 画当前温度及烙铁错误提示
25 | if (t12_error == 0 && t12_adc_error == 0) //正常画面
26 | {
27 | u8g2.setFont(u8g2_font_bubble_tn);
28 | if (t12_temp >= 99)u8g2.setCursor(0, zjm_dh_y + 18);
29 | else u8g2.setCursor(10, zjm_dh_y + 18);
30 | if (t12_switch == 1 && (thisError_average <= 4 && thisError_average >= -4)) u8g2.print(t12_temp_average);
31 | else u8g2.print(t12_temp);
32 | }
33 | else if (t12_adc_error == 1) zjm_error2(); //T12ADC超出测量范围画面
34 | else if (t12_error == 1) zjm_error3(); //手柄未接显示画面
35 | //****** 画设置温度进度条
36 | u8g2.setFont(u8g2_font_saikyosansbold8_8n);
37 | //自动获取设置温度的范围
38 | set_temp_max = ((sz_temp[3]) / 10 ) * 10;
39 | set_temp_min = ((sz_temp[0]) / 10) * 10;
40 | zjm_x1 = map(set_temp, set_temp_min, set_temp_max, 3, 57);
41 | u8g2.drawDisc(zjm_x1, zjm_dh_y + 28, 2);//画实心圆
42 | u8g2.drawBox(0, zjm_dh_y + 30, 61, 2); //画实心框
43 | if (set_temp <= 260)u8g2.setCursor(zjm_x1 + 4, zjm_dh_y + 29); //画设置温度
44 | else u8g2.setCursor(zjm_x1 - 26, zjm_dh_y + 29); //画设置温度
45 | u8g2.print(set_temp);
46 |
47 | //****** 画加热提示及切换动画
48 | u8g2.setFont(chinese15);
49 | if (zjm_dh_y != 0) //开机过渡动画变量变化
50 | {
51 | zjm_dh_y --;
52 | u8g2.setCursor(50, zjm_dh_y - 11);
53 | u8g2.print(version);
54 | }
55 | if (/*millis() - zjm_dh_time1 > 30 &&*/ zjm_dh_run == 1)
56 | {
57 | if (zjm_dh_x1 < 7)
58 | {
59 | zjm_dh_x1++;
60 | zjm_dh_y1++;
61 | if (zjm_dh_x1 == 7)
62 | {
63 | zjm_dh_r1 = 0;
64 | if (t12_switch == 1 && zjm_sleep_ts == 0) EEPROM.put(set_temp_eeprom, set_temp); //停止时保存当前的设置温度
65 | t12_switch = !t12_switch; //动画播放完,切换T12工作状态
66 | MsTimer2::stop(); //停止一次 然后在MsTimer2_rw1()里自动切换定时的中断任务
67 | }
68 | zjm_dh_time1 = millis();
69 | }
70 | else if (zjm_dh_x1 >= 7 && millis() - zjm_dh_time1 > 300)
71 | {
72 | zjm_dh_x1 = 0;
73 | zjm_dh_y1 = 0;
74 | zjm_dh_r1 = 1;
75 | zjm_dh_run = 0; //关闭动画
76 | }
77 | }
78 | u8g2.drawRFrame(zjm_x3 - 3, zjm_dh_y + zjm_y4 - 14, 18, 18, 3); //空心圆角方形
79 | u8g2.setCursor(zjm_x3, zjm_dh_y + zjm_y4);
80 | if (t12_switch == 1 && zjm_sleep_ts == 0) u8g2.print("热");
81 | else if (t12_switch == 1 && zjm_sleep_ts == 1) u8g2.print("休");
82 | else u8g2.print("停");
83 | if (zjm_dh_x1 == 7)u8g2.setDrawColor(2);
84 | u8g2.drawRBox(80 - zjm_dh_x1, zjm_dh_y + 8 - zjm_dh_y1, 2 + zjm_dh_x1 * 2, 2 + zjm_dh_y1 * 2, zjm_dh_r1); //实心圆角方形
85 | if (zjm_dh_x1 == 7)u8g2.setDrawColor(1);
86 |
87 | //****** 画PWM输出比例动画
88 | if (t12_switch == 1)
89 | {
90 | uint16_t zjm_pwmdh_time = map(pid_out, pwm_min, pwm_max, 450, 150); //输出比例决定刷新时间
91 | uint8_t zjm_pwmdh_l = map(pid_out, pwm_min, pwm_max, 3, 12); //输出比例决定L的最大值
92 | if (millis() - zjm_dh_time2 > zjm_pwmdh_time)
93 | {
94 | for (uint8_t i = 0; i < 14; i++)
95 | {
96 | zjm_dh_l[i] = random(1, zjm_pwmdh_l);
97 | }
98 | zjm_dh_time2 = millis();
99 | }
100 |
101 | for (uint8_t i = 0; i < 14; i++)
102 | {
103 | u8g2.drawLine(74 + i, zjm_dh_y + 32, 74 + i, zjm_dh_y + 32 - zjm_dh_l[i]); //绘制垂直线,X,Y,长度
104 | //delay(100);
105 | }
106 | }
107 | else u8g2.drawHLine(74, zjm_dh_y + 31, 14);
108 |
109 | //****** 画室温-电压-电流-工作状态
110 | if (vin_error == 1) zjm_error1(); //电压电流有一个报警就显示 报警提示画面
111 | else zjm_vin_ec_temp_state(); //显示正常画面
112 |
113 | //****** 调试信息显示
114 | //u8g2.setCursor(75, 32);
115 | //u8g2.print(zjm_ca_count);
116 | }
117 |
118 |
119 | void zjm_vin_ec_temp_state() //画室温-电压-电流-工作状态
120 | {
121 | //画室温-电压
122 | u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
123 | u8g2.setCursor(zjm_x2, zjm_dh_y + zjm_y1);
124 | u8g2.print(tc1047_temp, 1);
125 | u8g2.drawCircle(zjm_x2 + 21, zjm_dh_y + zjm_y1 - 6, 1, U8G2_DRAW_ALL); //画空心圆
126 | u8g2.setCursor(zjm_x2 + 23, zjm_dh_y + zjm_y1);
127 | u8g2.print("C");
128 |
129 | u8g2.setCursor(zjm_x2, zjm_dh_y + zjm_y2);
130 | u8g2.print(vin, 1);
131 | u8g2.setCursor(zjm_x2 + 22, zjm_dh_y + zjm_y2);
132 | u8g2.print("V");
133 |
134 | u8g2.setCursor(zjm_x2, zjm_dh_y + zjm_y3);
135 | u8g2.print(pid_out_bfb);
136 | u8g2.setCursor(zjm_x2 + 20, zjm_dh_y + zjm_y3);
137 | u8g2.print("%");
138 |
139 | //u8g2.setCursor(70, 27);
140 | //u8g2.print(t12_ad,0);
141 |
142 | //u8g2.setCursor(45, 27);
143 | //u8g2.print(sleep_count);
144 | //u8g2.setCursor(65, 27);
145 | //u8g2.print(xp_time_count);
146 |
147 | /*u8g2.setCursor(55, 13);
148 | u8g2.print(sleep_MsTimer2_state);*/
149 |
150 | //u8g2.setCursor(50, 27);
151 | //u8g2.print(pid_out);
152 |
153 | //u8g2.setCursor(0, 29);
154 | //u8g2.print(t12_temp_read_time);
155 |
156 | //u8g2.setCursor(0, 29);
157 | //u8g2.print(analogRead(tc1047_pin));
158 | }
159 | void zjm_error1() //主界面 电压电流报警 提示
160 | {
161 | u8g2.setFont(chinese15);
162 | if (vin_error == 1)
163 | {
164 | u8g2.setCursor(95, zjm_dh_y + 13);
165 | u8g2.print("电 压");
166 | u8g2.setCursor(95, zjm_dh_y + 29);
167 | u8g2.print("过 低");
168 | }
169 | u8g2.setDrawColor(2);
170 | u8g2.drawBox(95 - 2, zjm_dh_y + 0, 40, 32); //实心方形
171 | u8g2.setDrawColor(1);
172 | }
173 | void zjm_error2() //主界面 温度超出测量范围 错误提示
174 | {
175 | u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
176 | u8g2.setCursor(12, zjm_dh_y + 8);
177 | u8g2.print("T12 ADC");
178 | u8g2.setCursor(23, zjm_dh_y + 17);
179 | u8g2.print("HIGH");
180 | u8g2.setDrawColor(2);
181 | u8g2.drawBox(0, zjm_dh_y + 0, 61, 18); //实心方形
182 | u8g2.setDrawColor(1);
183 | }
184 | void zjm_error3() //主界面 手柄未接显示界面 错误提示
185 | {
186 | u8g2.setFont(chinese15);
187 | u8g2.setCursor(5, zjm_dh_y + 14);
188 | u8g2.print("手柄未接");
189 |
190 | u8g2.setDrawColor(2);
191 | u8g2.drawBox(0, zjm_dh_y + 0, 61, 18); //实心方形
192 | u8g2.setDrawColor(1);
193 | }
194 |
--------------------------------------------------------------------------------
/v1.03/DisplaySet.ino:
--------------------------------------------------------------------------------
1 | //********** 画设置主界面及其他界面 **********
2 | #define szjm_y1 21
3 | int16_t szjm_dh_x[6] = {0, 50, 100, 150, 200, 250};
4 | int16_t szjm_dh_x_count = 0; //设置界面动画x增量记录
5 |
6 | #define szjm_dh_bc 5 //变化步长,只能为5的倍数
7 | void szjm()
8 | {
9 | //画十字坐标
10 | //u8g2.drawHLine(0, 15, 128);
11 | //u8g2.drawVLine(63, 0, 32);
12 | //********** 线性滚动动画
13 | if (szjm_kxxk_L == 1) //顺时针滚动
14 | {
15 | szjm_dh_x_count += szjm_dh_bc; //记录变化次数
16 | for (uint8_t i = 0; i < 6; i++) //开始变化
17 | {
18 | szjm_dh_x[i] += szjm_dh_bc; //步长5
19 | }
20 | for (uint8_t i = 0; i < 6; i++) //数值限制
21 | {
22 | if (szjm_dh_x[i] > 250)szjm_dh_x[i] = -45;
23 | }
24 | if (szjm_dh_x_count >= 50) //变化完毕
25 | {
26 | szjm_kxxk_L = 0; //释放状态
27 | szjm_dh_x_count = 0; //变化次数清零
28 | if (szjm_kxxk_count >= 6) szjm_kxxk_count = 0; //数值限制
29 | }
30 | }
31 | else if (szjm_kxxk_R == 1) //逆时针滚动
32 | {
33 | szjm_dh_x_count -= szjm_dh_bc; //记录变化次数
34 | for (uint8_t i = 0; i < 6; i++) //开始变化
35 | {
36 | szjm_dh_x[i] -= szjm_dh_bc; //步长5
37 | }
38 | for (uint8_t i = 0; i < 6; i++) //数值限制
39 | {
40 | if (szjm_dh_x[i] < -150)szjm_dh_x[i] = 145;
41 | }
42 | if (szjm_dh_x_count <= -50) //变化完毕
43 | {
44 | szjm_kxxk_R = 0; //释放状态
45 | szjm_dh_x_count = 0; //变化次数清零
46 | if (szjm_kxxk_count <= -6) szjm_kxxk_count = 0; //数值限制
47 | }
48 | }
49 | //**************************************************
50 | //********** 画文字和框框
51 | //调试信息显示
52 | //u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
53 | //u8g2.setCursor(0, 31);
54 | //u8g2.print(szjm_dh_x_count);
55 | //u8g2.setCursor(100, 31);
56 | //u8g2.print(szjm_kxxk_count);
57 | //u8g2.setCursor(50, 31);
58 | //u8g2.print(szjm_dh_x[0]);
59 |
60 | u8g2.setFont(chinese15);
61 | if (szjm_dh_x[0] >= -50 && szjm_dh_x[0] <= 150)
62 | {
63 | u8g2.setCursor(szjm_dh_x[0], szjm_y1);
64 | u8g2.print("PID");
65 | }
66 | if (szjm_dh_x[1] >= -50 && szjm_dh_x[1] <= 150)
67 | {
68 | u8g2.setCursor(szjm_dh_x[1], szjm_y1);
69 | u8g2.print("休眠");
70 | }
71 | if (szjm_dh_x[2] >= -50 && szjm_dh_x[2] <= 150)
72 | {
73 | u8g2.setCursor(szjm_dh_x[2], szjm_y1);
74 | u8g2.print("屏幕");
75 | }
76 | if (szjm_dh_x[3] >= -50 && szjm_dh_x[3] <= 150)
77 | {
78 | u8g2.setCursor(szjm_dh_x[3], szjm_y1);
79 | u8g2.print("电源");
80 | }
81 | if (szjm_dh_x[4] >= -50 && szjm_dh_x[4] <= 150)
82 | {
83 | u8g2.setCursor(szjm_dh_x[4], szjm_y1);
84 | u8g2.print("校准");
85 | }
86 | if (szjm_dh_x[5] >= -50 && szjm_dh_x[5] <= 150)
87 | {
88 | u8g2.setCursor(szjm_dh_x[5], szjm_y1);
89 | u8g2.print("烙铁");
90 | }
91 | u8g2.setDrawColor(2);
92 | u8g2.drawRBox(43, 6, 40, 20, 1); //空心圆角方形
93 | u8g2.setDrawColor(1);
94 | }
95 |
96 | //********** PID设置界面 **********
97 | #define szjm_pid_x1 2
98 | #define szjm_pid_x2 14
99 |
100 | #define szjm_pid_x3 82
101 | #define szjm_pid_x4 94
102 |
103 | #define szjm_pid_y1 14
104 | #define szjm_pid_y2 29
105 | void szjm_pid()
106 | {
107 | u8g2.setCursor(szjm_pid_x1, szjm_pid_y1);
108 | u8g2.print("P");
109 | u8g2.setCursor(szjm_pid_x2, szjm_pid_y1);
110 | u8g2.print(p, 1);
111 |
112 | u8g2.setCursor(szjm_pid_x3, szjm_pid_y1);
113 | u8g2.print("I");
114 | u8g2.setCursor(szjm_pid_x4, szjm_pid_y1);
115 | u8g2.print(i, 1);
116 |
117 | u8g2.setCursor(szjm_pid_x1, szjm_pid_y2);
118 | u8g2.print("D");
119 | u8g2.setCursor(szjm_pid_x2, szjm_pid_y2);
120 | u8g2.print(d, 1);
121 |
122 | //画选框
123 | switch (szjm_pid_kxxk_count) //空心选框的位置
124 | {
125 | case 1: //p
126 | if (szjm_pid_sxxk_count == szjm_pid_kxxk_count)
127 | {
128 | u8g2.setDrawColor(2);
129 | u8g2.drawBox(szjm_pid_x1 - 2, szjm_pid_y1 - 13, 48, 16); //实心方形
130 | //画水平线,标识进入小数点模式
131 | if (dec_state == 1) u8g2.drawHLine(szjm_pid_x2 + 4 + (get_num_digit(p) * 6), szjm_pid_y1 + 1, 10);
132 | u8g2.setDrawColor(1);
133 | }
134 | else u8g2.drawFrame(szjm_pid_x1 - 2, szjm_pid_y1 - 13, 48, 16); //空心方形
135 | break;
136 | case 2: //i
137 | if (szjm_pid_sxxk_count == szjm_pid_kxxk_count)
138 | {
139 | u8g2.setDrawColor(2);
140 | u8g2.drawBox(szjm_pid_x3 - 2, szjm_pid_y1 - 13, 48, 16); //实心方形
141 | //画水平线,标识进入小数点模式
142 | if (dec_state == 1) u8g2.drawHLine(szjm_pid_x4 + 4 + (get_num_digit(i) * 6), szjm_pid_y1 + 1, 10);
143 | u8g2.setDrawColor(1);
144 | }
145 | else u8g2.drawFrame(szjm_pid_x3 - 2, szjm_pid_y1 - 13, 48, 16); //空心方形
146 | break;
147 | case 3: //d
148 | if (szjm_pid_sxxk_count == szjm_pid_kxxk_count)
149 | {
150 | u8g2.setDrawColor(2);
151 | u8g2.drawBox(szjm_pid_x1 - 2, szjm_pid_y2 - 13, 48, 16); //实心方形
152 | //画水平线,标识进入小数点模式
153 | if (dec_state == 1) u8g2.drawHLine(szjm_pid_x2 + 4 + (get_num_digit(d) * 6), szjm_pid_y2 + 1, 10);
154 | u8g2.setDrawColor(1);
155 | }
156 | else u8g2.drawFrame(szjm_pid_x1 - 2, szjm_pid_y2 - 13, 48, 16); //空心方形
157 | break;
158 | }
159 | }
160 |
161 | //********** 休眠设置界面 **********
162 | #define szjm_sleep_x1 2
163 | #define szjm_sleep_x2 105
164 | #define szjm_sleep_y1 14
165 | #define szjm_sleep_y2 29
166 | void szjm_sleep()
167 | {
168 | u8g2.setCursor(szjm_sleep_x1, szjm_sleep_y1);
169 | u8g2.print("休眠时间(S)");
170 | u8g2.setCursor(szjm_sleep_x2, szjm_sleep_y1);
171 | u8g2.print(sleep_time);
172 |
173 | u8g2.setCursor(szjm_sleep_x1, szjm_sleep_y2);
174 | u8g2.print("休眠温度(℃)");
175 | u8g2.setCursor(szjm_sleep_x2, szjm_sleep_y2);
176 | u8g2.print(sleep_temp);
177 |
178 | //画选框
179 | switch (szjm_sleep_kxxk_count) //空心选框的位置
180 | {
181 | case 1: //设置温度
182 | if (szjm_sleep_sxxk_count == szjm_sleep_kxxk_count)
183 | {
184 | u8g2.setDrawColor(2);
185 | u8g2.drawBox(szjm_sleep_x1 - 2, szjm_sleep_y1 - 13, 128, 16); //实心方形
186 | u8g2.setDrawColor(1);
187 | }
188 | else u8g2.drawFrame(szjm_sleep_x1 - 2, szjm_sleep_y1 - 13, 128, 16); //空心方形
189 | break;
190 | case 2: //设置温度
191 | if (szjm_sleep_sxxk_count == szjm_sleep_kxxk_count)
192 | {
193 | u8g2.setDrawColor(2);
194 | u8g2.drawBox(szjm_sleep_x1 - 2, szjm_sleep_y2 - 13, 128, 16); //实心方形
195 | u8g2.setDrawColor(1);
196 | }
197 | else u8g2.drawFrame(szjm_sleep_x1 - 2, szjm_sleep_y2 - 13, 128, 16); //空心方形
198 | break;
199 | }
200 | }
201 |
202 | //********** OLED亮度设置界面 **********
203 | #define szjm_oled_x1 2
204 | #define szjm_oled_x2 106
205 | #define szjm_oled_x3 86
206 | #define szjm_oled_y1 14
207 | #define szjm_oled_y2 29
208 | void szjm_oled()
209 | {
210 | if (szjm_oled_kxxk_count == 3) //第2页
211 | {
212 | u8g2.setCursor(szjm_oled_x1, szjm_oled_y1);
213 | u8g2.print("旋转方向");
214 | u8g2.setCursor(szjm_oled_x3, szjm_oled_y1);
215 | if (xzbmq_fx == 0) u8g2.print("顺+逆-");
216 | else u8g2.print("顺-逆+");
217 | }
218 | else //第1页
219 | {
220 | u8g2.setCursor(szjm_oled_x1, szjm_oled_y1);
221 | u8g2.print("屏幕亮度");
222 | u8g2.setCursor(szjm_oled_x2, szjm_oled_y1);
223 | u8g2.print(oled_ld);
224 |
225 | u8g2.setCursor(szjm_oled_x1, szjm_oled_y2);
226 | u8g2.print("屏幕方向");
227 | u8g2.setCursor(szjm_oled_x2, szjm_oled_y2);
228 | if (oled_fx == 0) u8g2.print("0");
229 | else u8g2.print("180");
230 | }
231 | //画选框
232 | switch (szjm_oled_kxxk_count) //空心选框的位置
233 | {
234 | case 1: //OLED亮度
235 | if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
236 | {
237 | u8g2.setDrawColor(2);
238 | u8g2.drawBox(szjm_oled_x1 - 2, szjm_oled_y1 - 13, 128, 16); //实心方形
239 | u8g2.setDrawColor(1);
240 | }
241 | else u8g2.drawFrame(szjm_oled_x1 - 2, szjm_oled_y1 - 13, 128, 16); //空心方形
242 | break;
243 | case 2: //OLED方向
244 | if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
245 | {
246 | u8g2.setDrawColor(2);
247 | u8g2.drawBox(szjm_oled_x1 - 2, szjm_oled_y2 - 13, 128, 16); //实心方形
248 | u8g2.setDrawColor(1);
249 | }
250 | else u8g2.drawFrame(szjm_oled_x1 - 2, szjm_oled_y2 - 13, 128, 16); //空心方形
251 | break;
252 | case 3: //旋转方向
253 | if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
254 | {
255 | u8g2.setDrawColor(2);
256 | u8g2.drawBox(szjm_oled_x1 - 2, szjm_oled_y1 - 13, 128, 16); //实心方形
257 | u8g2.setDrawColor(1);
258 | }
259 | else u8g2.drawFrame(szjm_oled_x1 - 2, szjm_oled_y1 - 13, 128, 16); //空心方形
260 | break;
261 | }
262 | }
263 |
264 | //********** 电源设置界面 **********
265 | #define szjm_power_x1 2
266 | #define szjm_power_x2 100
267 | #define szjm_power_y1 14
268 | #define szjm_power_y2 29
269 | void szjm_power()
270 | {
271 | if (szjm_power_kxxk_count == 3) //第2页
272 | {
273 | u8g2.setCursor(szjm_power_x1, szjm_power_y1);
274 | u8g2.print("低压报警(V)");
275 | u8g2.setCursor(szjm_power_x2, szjm_power_y1);
276 | if (vin_low >= 3.3) u8g2.print(vin_low, 1);
277 | else if (vin_low < 3.3) u8g2.print("关");
278 | }
279 | else //第1页
280 | {
281 | u8g2.setCursor(szjm_power_x1, szjm_power_y1);
282 | u8g2.print("基准电压(V)");
283 | u8g2.setCursor(szjm_power_x2, szjm_power_y1);
284 | u8g2.print(vcc_refer);
285 | u8g2.setCursor(szjm_power_x1, szjm_power_y2);
286 | u8g2.print("电源电压(V)");
287 | if (vin_refer >= 0)
288 | {
289 | u8g2.setCursor(szjm_power_x2 - 8, szjm_power_y2);
290 | u8g2.print("+");
291 | u8g2.setCursor(szjm_power_x2, szjm_power_y2);
292 | u8g2.print(vin_refer);
293 | }
294 | else
295 | {
296 | u8g2.setCursor(szjm_power_x2 - 6, szjm_power_y2);
297 | u8g2.print(vin_refer);
298 | }
299 | }
300 | //画选框
301 | switch (szjm_power_kxxk_count) //空心选框的位置
302 | {
303 | case 1: //基准电压(V)
304 | if (szjm_power_sxxk_count == szjm_power_kxxk_count)
305 | {
306 | u8g2.setDrawColor(2);
307 | u8g2.drawBox(szjm_power_x1 - 2, szjm_power_y1 - 13, 128, 16); //实心方形
308 | u8g2.setDrawColor(1);
309 | }
310 | else u8g2.drawFrame(szjm_power_x1 - 2, szjm_power_y1 - 13, 128, 16); //空心方形
311 | break;
312 | case 2: //基准电压(V)
313 | if (szjm_power_sxxk_count == szjm_power_kxxk_count)
314 | {
315 | u8g2.setDrawColor(2);
316 | u8g2.drawBox(szjm_power_x1 - 2, szjm_power_y2 - 13, 128, 16); //实心方形
317 | u8g2.setDrawColor(1);
318 | }
319 | else u8g2.drawFrame(szjm_power_x1 - 2, szjm_power_y2 - 13, 128, 16); //空心方形
320 | break;
321 | case 3: //电源电压(V)
322 | if (szjm_power_sxxk_count == szjm_power_kxxk_count)
323 | {
324 | u8g2.setDrawColor(2);
325 | u8g2.drawBox(szjm_power_x1 - 2, szjm_power_y1 - 13, 128, 16); //实心方形
326 | u8g2.setDrawColor(1);
327 | }
328 | else u8g2.drawFrame(szjm_power_x1 - 2, szjm_power_y1 - 13, 128, 16); //空心方形
329 | break;
330 | }
331 | }
332 | //********** 烙铁设置界面 **********
333 | #define szjm_laotie_x1 2
334 | #define szjm_laotie_x4 105
335 |
336 | #define szjm_laotie_y1 14
337 | #define szjm_laotie_y2 29
338 |
339 | void szjm_laotie()
340 | {
341 |
342 | if (szjm_laotie_kxxk_count == 3) //第2页
343 | {
344 | u8g2.setCursor(szjm_laotie_x1, szjm_laotie_y1);
345 | u8g2.print("重置");
346 | u8g2.setCursor(szjm_laotie_x4, szjm_laotie_y1);
347 | if (hfccsz_state == 1) u8g2.print("YES");
348 | else u8g2.print("NO");
349 | }
350 | else //第1页
351 | {
352 | u8g2.setCursor(szjm_laotie_x1, szjm_laotie_y1);
353 | u8g2.print("冷端补偿(℃)");
354 | if (tc1047_refer <= -10) u8g2.setCursor(szjm_laotie_x4, szjm_laotie_y1);
355 | else u8g2.setCursor(szjm_laotie_x4, szjm_laotie_y1);
356 | u8g2.print(tc1047_refer);
357 |
358 | u8g2.setCursor(szjm_laotie_x1, szjm_laotie_y2);
359 | u8g2.print("开机加热");
360 | u8g2.setCursor(szjm_laotie_x4, szjm_laotie_y2);
361 | if (t12_kj_jr == 1) u8g2.print("YES");
362 | else u8g2.print("NO");
363 | }
364 |
365 | //画选框
366 | switch (szjm_laotie_kxxk_count) //空心选框的位置
367 | {
368 | case 1: //冷端补偿
369 | if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
370 | {
371 | u8g2.setDrawColor(2);
372 | u8g2.drawBox(szjm_laotie_x1 - 2, szjm_laotie_y1 - 13, 128, 16); //实心方形
373 | u8g2.setDrawColor(1);
374 | }
375 | else u8g2.drawFrame(szjm_laotie_x1 - 2, szjm_laotie_y1 - 13, 128, 16); //空心方形
376 | break;
377 | case 2: //开机加热?
378 | if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
379 | {
380 | u8g2.setDrawColor(2);
381 | u8g2.drawBox(szjm_laotie_x1 - 2, szjm_laotie_y2 - 13, 128, 16); //实心方形
382 | u8g2.setDrawColor(1);
383 | }
384 | else u8g2.drawFrame(szjm_laotie_x1 - 2, szjm_laotie_y2 - 13, 128, 16); //空心方形
385 | break;
386 | case 3: //恢复出厂设置
387 | if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
388 | {
389 | u8g2.setDrawColor(2);
390 | u8g2.drawBox(szjm_laotie_x1 - 2, szjm_laotie_y1 - 13, 128, 16); //实心方形
391 | u8g2.setDrawColor(1);
392 | }
393 | else u8g2.drawFrame(szjm_laotie_x1 - 2, szjm_laotie_y1 - 13, 128, 16); //空心方形
394 | break;
395 | }
396 | }
397 | //********** 校准设置界面 **********
398 | #define szjm_jiaozhun_x1 0
399 |
400 | #define szjm_jiaozhun_x2 30
401 | #define szjm_jiaozhun_x3 54
402 | #define szjm_jiaozhun_x4 80
403 | #define szjm_jiaozhun_x5 106
404 |
405 | #define szjm_jiaozhun_x6 102
406 |
407 | #define szjm_jiaozhun_y1 7
408 | #define szjm_jiaozhun_y2 18
409 | #define szjm_jiaozhun_y3 31
410 | void szjm_jiaozhun()
411 | {
412 | u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
413 | if (szjm_jiaozhun_kxxk_count == 6)
414 | {
415 | u8g2.setCursor(0, 7);
416 | u8g2.print("P0:");
417 | u8g2.setCursor(25, 7);
418 | u8g2.print(sz_p[0], 10);
419 |
420 | u8g2.setCursor(0, 15);
421 | u8g2.print("P1:");
422 | u8g2.setCursor(25, 15);
423 | u8g2.print(sz_p[1], 10);
424 |
425 | u8g2.setCursor(0, 24);
426 | u8g2.print("P2:");
427 | u8g2.setCursor(25, 24);
428 | u8g2.print(sz_p[2], 10);
429 |
430 | u8g2.setCursor(0, 32);
431 | u8g2.print("P3:");
432 | u8g2.setCursor(25, 32);
433 | u8g2.print(sz_p[3], 10);
434 | }
435 | else
436 | {
437 | u8g2.setCursor(szjm_jiaozhun_x1, szjm_jiaozhun_y1);
438 | u8g2.print("ADC 10 350 650 940");
439 | u8g2.setCursor(szjm_jiaozhun_x1, szjm_jiaozhun_y2);
440 | u8g2.print("Temp");
441 | u8g2.setCursor(szjm_jiaozhun_x2, szjm_jiaozhun_y2);
442 | u8g2.print(sz_temp[0]);
443 | u8g2.setCursor(szjm_jiaozhun_x3, szjm_jiaozhun_y2);
444 | u8g2.print(sz_temp[1]);
445 | u8g2.setCursor(szjm_jiaozhun_x4, szjm_jiaozhun_y2);
446 | u8g2.print(sz_temp[2]);
447 | u8g2.setCursor(szjm_jiaozhun_x5, szjm_jiaozhun_y2);
448 | u8g2.print(sz_temp[3]);
449 |
450 | u8g2.drawHLine(0, 22, 128);
451 |
452 | u8g2.setCursor(szjm_jiaozhun_x1, szjm_jiaozhun_y3);
453 | u8g2.print("Now ADC:");
454 | u8g2.setCursor(48, szjm_jiaozhun_y3);
455 | u8g2.print(t12_ad, 0);
456 |
457 | u8g2.setCursor(szjm_jiaozhun_x6, szjm_jiaozhun_y3);
458 | u8g2.print("Save");
459 | }
460 | //画选框
461 | switch (szjm_jiaozhun_kxxk_count) //空心选框的位置
462 | {
463 | case 1: //深圳头1段温度
464 | if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
465 | {
466 | u8g2.setDrawColor(2);
467 | u8g2.drawBox(szjm_jiaozhun_x2 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //实心方形
468 | u8g2.setDrawColor(1);
469 | }
470 | else u8g2.drawFrame(szjm_jiaozhun_x2 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //空心方形
471 | break;
472 | case 2: //深圳头2段温度
473 | if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
474 | {
475 | u8g2.setDrawColor(2);
476 | u8g2.drawBox(szjm_jiaozhun_x3 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //实心方形
477 | u8g2.setDrawColor(1);
478 | }
479 | else u8g2.drawFrame(szjm_jiaozhun_x3 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //空心方形
480 | break;
481 | case 3: //深圳头3段温度
482 | if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
483 | {
484 | u8g2.setDrawColor(2);
485 | u8g2.drawBox(szjm_jiaozhun_x4 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //实心方形
486 | u8g2.setDrawColor(1);
487 | }
488 | else u8g2.drawFrame(szjm_jiaozhun_x4 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //空心方形
489 | break;
490 | case 4: //深圳头4段温度
491 | if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
492 | {
493 | u8g2.setDrawColor(2);
494 | u8g2.drawBox(szjm_jiaozhun_x5 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //实心方形
495 | u8g2.setDrawColor(1);
496 | }
497 | else u8g2.drawFrame(szjm_jiaozhun_x5 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //空心方形
498 | break;
499 | case 5: //保存
500 | u8g2.setDrawColor(2);
501 | u8g2.drawBox(szjm_jiaozhun_x6 - 2, szjm_jiaozhun_y3 - 8, 28, 9); //实心方形
502 | u8g2.setDrawColor(1);
503 | break;
504 | }
505 | }
506 |
--------------------------------------------------------------------------------
/v1.03/EEPROM.ino:
--------------------------------------------------------------------------------
1 | //******************* 自动刷写eeprom *******************
2 | void eerpom_auto()
3 | {
4 | EEPROM.get(auto_get_eeprom, auto_get); //获取自动刷写的状态
5 | if (auto_get > 1) auto_get = 0; //防止eeprom第0位不为0
6 | if (auto_get == 0) //状态为0开启刷写
7 | {
8 | EEPROM.put(p_eeprom, p); //pid-p
9 | EEPROM.put(i_eeprom, i); //pid-i
10 | EEPROM.put(d_eeprom, d); //pid-d
11 | EEPROM.put(sleep_time_eeprom, sleep_time); //休眠时间
12 | EEPROM.put(sleep_temp_eeprom, sleep_temp); //休眠温度
13 | EEPROM.put(oled_ld_eeprom, oled_ld); //OLED亮度
14 | EEPROM.put(vcc_refer_eeprom, vcc_refer); //基准电压
15 | EEPROM.put(vin_refer_eeprom, vin_refer); //电源电压校准值
16 | EEPROM.put(t12_kj_jr_eeprom, t12_kj_jr); //是否开机就加热
17 | EEPROM.put(vin_low_eeprom, vin_low); //输入电压过底报警阈值
18 | EEPROM.put(tc1047_refer_eeprom, tc1047_refer); //T12环境参考温度校准值
19 | EEPROM.put(oled_fx_eeprom, oled_fx); //OLED方向
20 | EEPROM.put(xzbmq_fx_eeprom, xzbmq_fx); //旋转编码器方向
21 | //写入曲线的4段温度
22 | EEPROM.put(sz_temp0_eeprom, sz_temp[0]);
23 | EEPROM.put(sz_temp1_eeprom, sz_temp[1]);
24 | EEPROM.put(sz_temp2_eeprom, sz_temp[2]);
25 | EEPROM.put(sz_temp3_eeprom, sz_temp[3]);
26 | //写入设置温度
27 | EEPROM.put(set_temp_eeprom, set_temp);
28 | //刷写完,记录auto_get的状态,防止下次开机再次刷写
29 | EEPROM.put(auto_get_eeprom, 1);
30 | auto_get = 1;
31 | }
32 | if (auto_get == 1)//状态为1只读取
33 | {
34 | EEPROM.get(p_eeprom, p); //pid-p
35 | EEPROM.get(i_eeprom, i); //pid-i
36 | EEPROM.get(d_eeprom, d); //pid-d
37 | EEPROM.get(sleep_time_eeprom, sleep_time); //休眠时间
38 | EEPROM.get(sleep_temp_eeprom, sleep_temp); //休眠温度
39 | EEPROM.get(oled_ld_eeprom, oled_ld); //OLED亮度
40 | EEPROM.get(vcc_refer_eeprom, vcc_refer); //基准电压
41 | EEPROM.get(vin_refer_eeprom, vin_refer); //电源电压校准值
42 | EEPROM.get(t12_kj_jr_eeprom, t12_kj_jr); //是否开机就加热
43 | EEPROM.get(vin_low_eeprom, vin_low); //输入电压过底报警阈值
44 | EEPROM.get(tc1047_refer_eeprom, tc1047_refer); //T12环境参考温度校准值
45 | EEPROM.get(oled_fx_eeprom, oled_fx); //OLED方向
46 | EEPROM.get(xzbmq_fx_eeprom, xzbmq_fx); //旋转编码器方向
47 | //获取曲线的4段温度
48 | EEPROM.get(sz_temp0_eeprom, sz_temp[0]);
49 | EEPROM.get(sz_temp1_eeprom, sz_temp[1]);
50 | EEPROM.get(sz_temp2_eeprom, sz_temp[2]);
51 | EEPROM.get(sz_temp3_eeprom, sz_temp[3]);
52 | //获取设置温度
53 | EEPROM.get(set_temp_eeprom, set_temp);
54 | }
55 | }
56 | //******************************************************
57 |
--------------------------------------------------------------------------------
/v1.03/InterruptKey.ino:
--------------------------------------------------------------------------------
1 | //********** 编码器按键决策 **********
2 | #define xklv_time 120 //切换选框的滤波时间
3 | #define szlv_time 20 //切换选框的滤波时间
4 | #define szjm_qrcs 2;
5 |
6 | void xuan_zhaun() //旋转中断 选框决策
7 | {
8 |
9 | /*Serial.print("DT "); Serial.print(digitalRead(DT));
10 | Serial.print(" | ");
11 | Serial.print("CLK "); Serial.print(digitalRead(CLK));
12 | Serial.print(" | ");
13 | Serial.print("SW "); Serial.print(digitalRead(SW));
14 | Serial.println(" ");*/
15 | if ((millis() - xzbmq_time) < szlv_time) return;
16 | buzzer(100, 70); //时间,次数
17 | if (display_count == ZJM)
18 | {
19 | zjm_xz_key();
20 | buzzer_temp_average_state = 0; //准备好到达温度提示声
21 | sleep_count = 0; //休眠计数归零
22 | zjm_sleep_ts = 0; //提示主界面退出显示休眠状态
23 | t12_adc_error = 0; //清除温度超出测量范围提示
24 | xp_state = 0; //结束息屏
25 | xp_time_count = 0; //清除息屏计数
26 | xp_time_count_old = 0; //清除息屏计数旧
27 | }
28 | else if (display_count == SZJM) szjm_xz_key();
29 | else if (display_count == SZJM_PID) pid_xz_key();
30 | else if (display_count == SZJM_SLEEP) sleep_xz_key();
31 | else if (display_count == SZJM_OLED) oled_xz_key();
32 | else if (display_count == SZJM_POWER) power_xz_key();
33 | else if (display_count == SZJM_LAOTIE) laotie_xz_key();
34 | else if (display_count == SZJM_JIAOZHUN) jiaozhun_xz_key();
35 | xzbmq_time = millis();
36 | }
37 |
38 | void an_xia()
39 | {
40 | if ((millis() - xzbmq_time) < 160) return;
41 | qj_sw_key(); //全局长按进入设置界面 或 退出至主界面
42 | }
43 | //************************ 全局长按进入设置界面 或 退出至主界面 ************************
44 | void qj_sw_key()
45 | {
46 | //长按计数增加
47 | if (digitalRead(SW) == 0)
48 | {
49 | qj_ca_count++; //计数加一
50 | buzzer(80, 150); //时间,次数
51 |
52 | if (display_count == ZJM) t12_adc_error = 0; //清除温度超出测量范围提示
53 | xp_state = 0; //结束息屏
54 | xp_time_count = 0; //清除息屏计数
55 | xp_time_count_old = 0; //清除息屏计数旧
56 |
57 | xzbmq_time = millis();
58 | }
59 | //判断按了几次 该做些什么
60 | if (qj_ca_count >= 5) //进入设置界面
61 | {
62 | if (display_count == ZJM)
63 | {
64 | display_count = SZJM; //在主界面时进入设置界面
65 | buzzer_szjm_state = 1;
66 | }
67 | else if (display_count != SZJM_JIAOZHUN)
68 | {
69 | display_count = ZJM; //在其他界面是退出至主界面
70 | buzzer_zjm_state = 1;
71 | }
72 | qj_ca_count = 0; //计数清零
73 | }
74 | else if ((millis() - xzbmq_time) > 260) //等待一段时间,确定松手了
75 | {
76 | //在主界面的按下决策
77 | if (display_count == ZJM) zjm_sw_key();
78 | //在设置界面的按下决策
79 | else if (display_count == SZJM) szjm_sw_key();
80 | //在PID界面的按下决策
81 | else if (display_count == SZJM_PID) pid_sw_key();
82 | //在休眠界面的按下决策
83 | else if (display_count == SZJM_SLEEP) sleep_sw_key();
84 | //在OLED亮度界面的按下决策
85 | else if (display_count == SZJM_OLED) oled_sw_key();
86 | //在电源校准界面的按下决策
87 | else if (display_count == SZJM_POWER) power_sw_key();
88 | //在烙铁界面的按下决策
89 | else if (display_count == SZJM_LAOTIE) laotie_sw_key();
90 | //在校准界面的按下决策
91 | else if (display_count == SZJM_JIAOZHUN) jiaozhun_sw_key();
92 | qj_ca_count = 0;//计数清零
93 | }
94 | }
95 | //************************ 主界面 ************************
96 | void zjm_sw_key()
97 | {
98 | if (qj_ca_count == 2 && vin_error == 0 && t12_error == 0) // 启动或停止加热
99 | {
100 | zjm_dh_run = 1; //允许播放动画 ,动画播放完在DisplayMain里切换T12工作状态
101 | zjm_sleep_ts = 0; //提示主界面退出显示休眠状态
102 | buzzer_temp_average_state = 0; //准备好到达温度提示声
103 | }
104 | }
105 | void zjm_xz_key() //主界面 旋转
106 | {
107 | if (digitalRead(DT) == xzbmq_fx) set_temp += 10;
108 | else if (digitalRead(CLK) == xzbmq_fx) set_temp -= 10;
109 | //自动获取设置温度的范围
110 | set_temp_max = ((sz_temp[3]) / 10 ) * 10;
111 | set_temp_min = ((sz_temp[0]) / 10) * 10;
112 | if (set_temp > set_temp_max) set_temp = set_temp_min;
113 | else if (set_temp < set_temp_min) set_temp = set_temp_max;
114 | }
115 | //************************ 设置界面 ************************
116 | void szjm_sw_key() //设置界面 按下
117 | {
118 | if (qj_ca_count == 1) //进入二级菜单
119 | {
120 | if (szjm_kxxk_count == 0) display_count = SZJM_SLEEP; //进入休眠设置菜单
121 | else if (szjm_kxxk_count == -5 || szjm_kxxk_count == 1) display_count = SZJM_PID; //进入PID设置菜单
122 | else if (szjm_kxxk_count == -1 || szjm_kxxk_count == 5) display_count = SZJM_OLED; //进入OELD亮度设置菜单
123 | else if (szjm_kxxk_count == -2 || szjm_kxxk_count == 4) display_count = SZJM_POWER; //进入电源设置菜单
124 | else if (szjm_kxxk_count == -4 || szjm_kxxk_count == 2) display_count = SZJM_LAOTIE;//进入烙铁设置菜单
125 | else if (szjm_kxxk_count == -3 || szjm_kxxk_count == 3)
126 | {
127 | //使用比较柔和的pid参数,退出校准界面时记得恢复正常的PID策略
128 | p = p_jz; //比例系数
129 | i = i_jz; //积分系数
130 | d = d_jz; //微分系数
131 | display_count = SZJM_JIAOZHUN;//进入烙铁设置菜单
132 | }
133 | }
134 | }
135 | void szjm_xz_key() //设置界面 旋转
136 | {
137 | if (digitalRead(DT) == xzbmq_fx)
138 | {
139 | if (szjm_kxxk_L == 0 && szjm_kxxk_R == 0) //顺时针
140 | {
141 | szjm_kxxk_L = 1; //允许播放动画
142 | szjm_kxxk_count++; //下一项
143 | }
144 | }
145 | else if (digitalRead(CLK) == xzbmq_fx)
146 | {
147 | if (szjm_kxxk_L == 0 && szjm_kxxk_R == 0) //逆时针
148 | {
149 | szjm_kxxk_R = 1; //允许播放动画
150 | szjm_kxxk_count--; //上一项
151 | }
152 | }
153 | }
154 | //************************ PID设置界面 ************************
155 | void pid_sw_key() //设置界面 按下
156 | {
157 | if (qj_ca_count == 1) //返回或进入调节框
158 | {
159 | switch (szjm_pid_kxxk_count)
160 | {
161 | case 0: //返回至设置界面
162 | display_count = SZJM;
163 | break;
164 | case 1: //p 存储
165 | if (szjm_pid_sxxk_count == 0) szjm_pid_sxxk_count = szjm_pid_kxxk_count;
166 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 0) dec_state = 1;
167 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 1)
168 | {
169 | EEPROM.put(p_eeprom, p);
170 | dec_state = 0;
171 | szjm_pid_sxxk_count = 0;
172 | }
173 | break;
174 | case 2: //i 存储
175 | if (szjm_pid_sxxk_count == 0) szjm_pid_sxxk_count = szjm_pid_kxxk_count;
176 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 0) dec_state = 1;
177 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 1)
178 | {
179 | EEPROM.put(i_eeprom, i);
180 | dec_state = 0;
181 | szjm_pid_sxxk_count = 0;
182 | }
183 | break;
184 | case 3: //d 存储
185 | if (szjm_pid_sxxk_count == 0) szjm_pid_sxxk_count = szjm_pid_kxxk_count;
186 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 0) dec_state = 1;
187 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 1)
188 | {
189 | EEPROM.put(d_eeprom, d);
190 | dec_state = 0;
191 | szjm_pid_sxxk_count = 0;
192 | }
193 | break;
194 | }
195 | }
196 | }
197 | void pid_xz_key() //设置界面 旋转
198 | {
199 | if (szjm_pid_sxxk_count == 0) //选框移动
200 | {
201 | if (digitalRead(DT) == xzbmq_fx) szjm_pid_kxxk_count++;
202 | else if (digitalRead(CLK) == xzbmq_fx) szjm_pid_kxxk_count--;
203 | }
204 | else if (szjm_pid_sxxk_count == 1) //p加减
205 | {
206 | if (digitalRead(DT) == xzbmq_fx && dec_state == 0) p += 1;
207 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 0) p -= 1;
208 | else if (digitalRead(DT) == xzbmq_fx && dec_state == 1) p += 0.1;
209 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 1) p -= 0.1;
210 | }
211 | else if (szjm_pid_sxxk_count == 2) //i加减
212 | {
213 | if (digitalRead(DT) == xzbmq_fx && dec_state == 0) i += 1;
214 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 0) i -= 1;
215 | else if (digitalRead(DT) == xzbmq_fx && dec_state == 1) i += 0.1;
216 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 1) i -= 0.1;
217 | }
218 | else if (szjm_pid_sxxk_count == 3) //d加减
219 | {
220 | if (digitalRead(DT) == xzbmq_fx && dec_state == 0) d += 1;
221 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 0) d -= 1;
222 | else if (digitalRead(DT) == xzbmq_fx && dec_state == 1) d += 0.1;
223 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 1) d -= 0.1;
224 | }
225 | if (szjm_pid_kxxk_count > 3) szjm_pid_kxxk_count = 0;
226 | else if (szjm_pid_kxxk_count < 0) szjm_pid_kxxk_count = 3;
227 | }
228 | //************************ 休眠设置界面 ************************
229 | void sleep_sw_key() //设置界面 按下
230 | {
231 | if (qj_ca_count == 1) //返回或进入调节框
232 | {
233 | switch (szjm_sleep_kxxk_count)
234 | {
235 | case 0: //返回至设置界面
236 | display_count = SZJM;
237 | break;
238 | case 1: //休眠时间 存储
239 | if (szjm_sleep_sxxk_count == 0) szjm_sleep_sxxk_count = szjm_sleep_kxxk_count;
240 | else if (szjm_sleep_sxxk_count == szjm_sleep_kxxk_count)
241 | {
242 | EEPROM.put(sleep_time_eeprom, sleep_time); //休眠时间
243 | szjm_sleep_sxxk_count = 0;
244 | }
245 | break;
246 | case 2: //休眠温度 存储
247 | if (szjm_sleep_sxxk_count == 0) szjm_sleep_sxxk_count = szjm_sleep_kxxk_count;
248 | else if (szjm_sleep_sxxk_count == szjm_sleep_kxxk_count)
249 | {
250 | EEPROM.put(sleep_temp_eeprom, sleep_temp); //休眠温度
251 | szjm_sleep_sxxk_count = 0;
252 | }
253 | break;
254 | }
255 | }
256 | }
257 | void sleep_xz_key() //设置界面 旋转
258 | {
259 | if (szjm_sleep_sxxk_count == 0) //选框移动
260 | {
261 | if (digitalRead(DT) == xzbmq_fx) szjm_sleep_kxxk_count++;
262 | else if (digitalRead(CLK) == xzbmq_fx) szjm_sleep_kxxk_count--;
263 | }
264 | else if (szjm_sleep_sxxk_count == 1) //休眠时间加减
265 | {
266 | if (digitalRead(DT) == xzbmq_fx) sleep_time += 1;
267 | else if (digitalRead(CLK) == xzbmq_fx) sleep_time -= 1;
268 | }
269 | else if (szjm_sleep_sxxk_count == 2) //休眠温度加减
270 | {
271 | if (digitalRead(DT) == xzbmq_fx) sleep_temp += 1;
272 | else if (digitalRead(CLK) == xzbmq_fx) sleep_temp -= 1;
273 | }
274 | if (szjm_sleep_kxxk_count > 2) szjm_sleep_kxxk_count = 0;
275 | else if (szjm_sleep_kxxk_count < 0) szjm_sleep_kxxk_count = 2;
276 | else if (sleep_time > 999) sleep_time = 10;
277 | else if (sleep_time < 10) sleep_time = 999;
278 | }
279 | //************************ OLED亮度设置界面 ************************
280 | void oled_sw_key() //设置界面 按下
281 | {
282 | if (qj_ca_count == 1) //返回或进入调节框
283 | {
284 | switch (szjm_oled_kxxk_count)
285 | {
286 | case 0: //返回至设置界面
287 | display_count = SZJM;
288 | break;
289 | case 1: //OLED亮度 存储
290 | if (szjm_oled_sxxk_count == 0) szjm_oled_sxxk_count = szjm_oled_kxxk_count;
291 | else if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
292 | {
293 | EEPROM.put(oled_ld_eeprom, oled_ld); //OLED亮度
294 | szjm_oled_sxxk_count = 0;
295 | }
296 | break;
297 | case 2: //OLED亮度 存储
298 | if (szjm_oled_sxxk_count == 0) szjm_oled_sxxk_count = szjm_oled_kxxk_count;
299 | else if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
300 | {
301 | EEPROM.put(oled_fx_eeprom, oled_fx); //OLED方向
302 | if (oled_fx == 1)u8g2.setDisplayRotation(U8G2_R2); //旋转180度
303 | else u8g2.setDisplayRotation(U8G2_R0); //0度,默认方向
304 | szjm_oled_sxxk_count = 0;
305 | }
306 | break;
307 | case 3: //旋转编码器方向 存储
308 | if (szjm_oled_sxxk_count == 0) szjm_oled_sxxk_count = szjm_oled_kxxk_count;
309 | else if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
310 | {
311 | EEPROM.put(xzbmq_fx_eeprom, xzbmq_fx); //OLED方向
312 | EEPROM.get(xzbmq_fx_eeprom, xzbmq_fx); //OLED方向
313 | szjm_oled_sxxk_count = 0;
314 | }
315 | break;
316 | }
317 | }
318 | }
319 |
320 | void oled_xz_key() //设置界面 旋转
321 | {
322 | if (szjm_oled_sxxk_count == 0) //选框移动
323 | {
324 | if (digitalRead(DT) == xzbmq_fx) szjm_oled_kxxk_count++;
325 | else if (digitalRead(CLK) == xzbmq_fx) szjm_oled_kxxk_count--;
326 | if (szjm_oled_kxxk_count > 3) szjm_oled_kxxk_count = 0;
327 | else if (szjm_oled_kxxk_count < 0) szjm_oled_kxxk_count = 3;
328 | }
329 | else if (szjm_oled_sxxk_count == 1) //OLED亮度 加减
330 | {
331 | if (digitalRead(DT) == xzbmq_fx) oled_ld += 5;
332 | else if (digitalRead(CLK) == xzbmq_fx) oled_ld -= 5;
333 | if (oled_ld > 1 && oled_ld < 5) oled_ld = 5;
334 | else if (oled_ld == 0)oled_ld = 255;
335 | }
336 | else if (szjm_oled_sxxk_count == 2) //OLED方向 状态切换
337 | {
338 | if (digitalRead(DT) == xzbmq_fx) oled_fx = !oled_fx;
339 | else if (digitalRead(CLK) == xzbmq_fx) oled_fx = !oled_fx;
340 | }
341 | else if (szjm_oled_sxxk_count == 3) //旋转编码器方向 状态切换
342 | {
343 | if (digitalRead(DT) == xzbmq_fx) xzbmq_fx = !xzbmq_fx;
344 | else if (digitalRead(CLK) == xzbmq_fx) xzbmq_fx = !xzbmq_fx;
345 | }
346 | }
347 | //************************ 电源校准界面 ************************
348 | void power_sw_key() //设置界面 按下
349 | {
350 | if (qj_ca_count == 1) //返回或进入调节框
351 | {
352 | switch (szjm_power_kxxk_count)
353 | {
354 | case 0: //返回至设置界面
355 | display_count = SZJM;
356 | break;
357 | case 1: //基准电压 存储
358 | if (szjm_power_sxxk_count == 0) szjm_power_sxxk_count = szjm_power_kxxk_count;
359 | else if (szjm_power_sxxk_count == szjm_power_kxxk_count)
360 | {
361 | EEPROM.put(vcc_refer_eeprom, vcc_refer);
362 | szjm_power_sxxk_count = 0;
363 | }
364 | break;
365 | case 2: //电源电压校准值 存储
366 | if (szjm_power_sxxk_count == 0) szjm_power_sxxk_count = szjm_power_kxxk_count;
367 | else if (szjm_power_sxxk_count == szjm_power_kxxk_count)
368 | {
369 | EEPROM.put(vin_refer_eeprom, vin_refer);
370 | szjm_power_sxxk_count = 0;
371 | }
372 | break;
373 | case 3: //低压报警阈值 存储
374 | if (szjm_power_sxxk_count == 0) szjm_power_sxxk_count = szjm_power_kxxk_count;
375 | else if (szjm_power_sxxk_count == szjm_power_kxxk_count)
376 | {
377 | EEPROM.put(vin_low_eeprom, vin_low);
378 | szjm_power_sxxk_count = 0;
379 | }
380 | break;
381 | }
382 | }
383 | }
384 |
385 | void power_xz_key() //设置界面 旋转
386 | {
387 | if (szjm_power_sxxk_count == 0) //选框移动
388 | {
389 | if (digitalRead(DT) == xzbmq_fx) szjm_power_kxxk_count++;
390 | else if (digitalRead(CLK) == xzbmq_fx) szjm_power_kxxk_count--;
391 | if (szjm_power_kxxk_count > 3) szjm_power_kxxk_count = 0;
392 | else if (szjm_power_kxxk_count < 0) szjm_power_kxxk_count = 3;
393 | }
394 | else if (szjm_power_sxxk_count == 1) //基准电压 加减
395 | {
396 | if (digitalRead(DT) == xzbmq_fx) vcc_refer += 0.01;
397 | else if (digitalRead(CLK) == xzbmq_fx) vcc_refer -= 0.01;
398 | }
399 | else if (szjm_power_sxxk_count == 2) //电源电压校准值 加减
400 | {
401 | if (digitalRead(DT) == xzbmq_fx) vin_refer += 0.1;
402 | else if (digitalRead(CLK) == xzbmq_fx) vin_refer -= 0.1;
403 | }
404 | else if (szjm_power_sxxk_count == 3) //低压报警阈值 加减
405 | {
406 | if (digitalRead(DT) == xzbmq_fx) vin_low += 0.1;
407 | else if (digitalRead(CLK) == xzbmq_fx) vin_low -= 0.1;
408 | if (vin_low > 30)vin_low = 3.2;
409 | else if (vin_low < 3.2)vin_low = 30;
410 | }
411 | }
412 |
413 | //************************ 烙铁界面 ************************
414 | void laotie_sw_key() //设置界面 按下
415 | {
416 | if (qj_ca_count == 1) //返回或进入调节框
417 | {
418 | switch (szjm_laotie_kxxk_count)
419 | {
420 | case 0: //返回至设置界面
421 | display_count = SZJM;
422 | break;
423 | case 1: //冷端补偿 存储
424 | if (szjm_laotie_sxxk_count == 0) szjm_laotie_sxxk_count = szjm_laotie_kxxk_count;
425 | else if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
426 | {
427 | EEPROM.put(tc1047_refer_eeprom, tc1047_refer);
428 | szjm_laotie_sxxk_count = 0;
429 | }
430 | break;
431 | case 2: //开机加热 存储
432 | if (szjm_laotie_sxxk_count == 0)
433 | {
434 | t12_kj_jr = !t12_kj_jr;
435 | EEPROM.put(t12_kj_jr_eeprom, t12_kj_jr);
436 | }
437 | break;
438 | case 3: //恢复出厂设置 存储
439 | if (szjm_laotie_sxxk_count == 0) szjm_laotie_sxxk_count = szjm_laotie_kxxk_count;
440 | else if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
441 | {
442 | if (hfccsz_state == 1) display_hfccsz();
443 | szjm_laotie_sxxk_count = 0;
444 | }
445 | break;
446 | }
447 | }
448 | }
449 | void laotie_xz_key() //设置界面 旋转
450 | {
451 | if (szjm_laotie_sxxk_count == 0) //选框移动
452 | {
453 | if (digitalRead(DT) == xzbmq_fx) szjm_laotie_kxxk_count++;
454 | else if (digitalRead(CLK) == xzbmq_fx) szjm_laotie_kxxk_count--;
455 | if (szjm_laotie_kxxk_count > 3) szjm_laotie_kxxk_count = 0;
456 | else if (szjm_laotie_kxxk_count < 0) szjm_laotie_kxxk_count = 3;
457 | }
458 | else if (szjm_laotie_sxxk_count == 1) //冷端补偿校准值 加减
459 | {
460 | if (digitalRead(DT) == xzbmq_fx) tc1047_refer += 1;
461 | else if (digitalRead(CLK) == xzbmq_fx) tc1047_refer -= 1;
462 | if (tc1047_refer > 99)tc1047_refer = 0;
463 | else if (tc1047_refer < -99) tc1047_refer = 0;
464 | }
465 | else if (szjm_laotie_sxxk_count == 3) //恢复出厂设置 状态切换
466 | {
467 | if (digitalRead(DT) == xzbmq_fx) hfccsz_state = !hfccsz_state;
468 | else if (digitalRead(CLK) == xzbmq_fx) hfccsz_state = !hfccsz_state;
469 | }
470 | }
471 | //************************ 校准界面 ************************
472 | void jiaozhun_sw_key() //设置界面 按下
473 | {
474 | if (qj_ca_count == 1) //返回或进入调节框
475 | {
476 | switch (szjm_jiaozhun_kxxk_count)
477 | {
478 | case 0: //返回至设置界面,并恢复正常PID参数
479 | display_count = SZJM;
480 | szjm_jiaozhun_kxxk_count = 0;
481 | EEPROM.get(p_eeprom, p); //pid-p
482 | EEPROM.get(i_eeprom, i); //pid-i
483 | EEPROM.get(d_eeprom, d); //pid-d
484 | break;
485 | case 1: //深圳校准温度1段 存储
486 | if (szjm_jiaozhun_sxxk_count == 0)
487 | {
488 | szjm_jiaozhun_sxxk_count = szjm_jiaozhun_kxxk_count;
489 | t12_switch = 1; //打开加热
490 | }
491 | else if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
492 | {
493 | EEPROM.put(sz_temp0_eeprom, sz_temp[0]);
494 | szjm_jiaozhun_sxxk_count = 0;
495 | t12_switch = 0; //关闭加热
496 | }
497 | break;
498 | case 2: //深圳校准温度2段 存储
499 | if (szjm_jiaozhun_sxxk_count == 0)
500 | {
501 | szjm_jiaozhun_sxxk_count = szjm_jiaozhun_kxxk_count;
502 | t12_switch = 1; //打开加热
503 | }
504 | else if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
505 | {
506 | EEPROM.put(sz_temp1_eeprom, sz_temp[1]);
507 | szjm_jiaozhun_sxxk_count = 0;
508 | t12_switch = 0; //关闭加热
509 | }
510 | break;
511 | case 3: //深圳校准温度3段 存储
512 | if (szjm_jiaozhun_sxxk_count == 0)
513 | {
514 | szjm_jiaozhun_sxxk_count = szjm_jiaozhun_kxxk_count;
515 | t12_switch = 1; //打开加热
516 | }
517 | else if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
518 | {
519 | EEPROM.put(sz_temp2_eeprom, sz_temp[2]);
520 | szjm_jiaozhun_sxxk_count = 0;
521 | t12_switch = 0; //关闭加热
522 | }
523 | break;
524 | case 4: //深圳校准温度4段 存储
525 | if (szjm_jiaozhun_sxxk_count == 0)
526 | {
527 | szjm_jiaozhun_sxxk_count = szjm_jiaozhun_kxxk_count;
528 | t12_switch = 1; //打开加热
529 | }
530 | else if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
531 | {
532 | EEPROM.put(sz_temp3_eeprom, sz_temp[3]);
533 | szjm_jiaozhun_sxxk_count = 0;
534 | t12_switch = 0; //关闭加热
535 | }
536 | break;
537 | case 5: //开始曲线拟合系数计算
538 | qxnh_run(); //计算曲线拟合系数
539 | szjm_jiaozhun_kxxk_count = 6;
540 | break;
541 | case 6: //返回至设置界面,并恢复正常PID参数
542 | display_count = SZJM;
543 | szjm_jiaozhun_kxxk_count = 0;
544 | EEPROM.get(p_eeprom, p); //pid-p
545 | EEPROM.get(i_eeprom, i); //pid-i
546 | EEPROM.get(d_eeprom, d); //pid-d
547 | break;
548 | }
549 | }
550 | }
551 | void jiaozhun_xz_key() //设置界面 旋转
552 | {
553 | if (szjm_jiaozhun_sxxk_count == 0) //选框移动
554 | {
555 | if (digitalRead(DT) == xzbmq_fx) szjm_jiaozhun_kxxk_count++;
556 | else if (digitalRead(CLK) == xzbmq_fx) szjm_jiaozhun_kxxk_count--;
557 | if (szjm_jiaozhun_kxxk_count > 6) szjm_jiaozhun_kxxk_count = 0;
558 | else if (szjm_jiaozhun_kxxk_count < 0) szjm_jiaozhun_kxxk_count = 6;
559 | }
560 | else if (szjm_jiaozhun_sxxk_count == 1) //选框移动
561 | {
562 | if (digitalRead(DT) == xzbmq_fx) sz_temp[0] += 1;
563 | else if (digitalRead(CLK) == xzbmq_fx) sz_temp[0] -= 1;
564 | }
565 | else if (szjm_jiaozhun_sxxk_count == 2) //选框移动
566 | {
567 | if (digitalRead(DT) == xzbmq_fx) sz_temp[1] += 1;
568 | else if (digitalRead(CLK) == xzbmq_fx) sz_temp[1] -= 1;
569 | }
570 | else if (szjm_jiaozhun_sxxk_count == 3) //选框移动
571 | {
572 | if (digitalRead(DT) == xzbmq_fx) sz_temp[2] += 1;
573 | else if (digitalRead(CLK) == xzbmq_fx) sz_temp[2] -= 1;
574 | }
575 | else if (szjm_jiaozhun_sxxk_count == 4) //选框移动
576 | {
577 | if (digitalRead(DT) == xzbmq_fx) sz_temp[3] += 1;
578 | else if (digitalRead(CLK) == xzbmq_fx) sz_temp[3] -= 1;
579 | }
580 | }
581 |
--------------------------------------------------------------------------------
/v1.03/MsTimer2.ino:
--------------------------------------------------------------------------------
1 | //定时器2
2 | uint32_t t12_sleep_old_time = 0;
3 | void MsTimer2_rw1()
4 | {
5 | if (t12_switch == 1) //烙铁启动,打开休眠判断决策
6 | {
7 | if (bitRead(TIMSK2, TOIE2) == 0)
8 | {
9 | sleep_count = 0;
10 | xp_time_count = 0;
11 | MsTimer2::set(1000, sleep_timing); // 1000ms 运行一次
12 | MsTimer2::start(); //打开定时器2计数
13 | }
14 | if (millis() - t12_sleep_old_time > 700)
15 | {
16 | t12_sleep(); //T12休眠决策
17 | t12_sleep_old_time = millis();
18 | }
19 | }
20 | else if (t12_switch == 0)
21 | {
22 | if (bitRead(TIMSK2, TOIE2) == 0)
23 | {
24 | sleep_count = 0;
25 | xp_time_count = 0;
26 | MsTimer2::set(1000, xp_timing); // 1000ms 运行一次
27 | MsTimer2::start(); //打开定时器2计数
28 | }
29 | system_sleep(); //系统休眠决策
30 | }
31 | }
32 |
33 | void sleep_timing() //休眠定时任务
34 | {
35 | sleep_count++; //烙铁没动,计数增加
36 | }
37 |
38 | void xp_timing() //息屏定时任务,校准界面不息屏
39 | {
40 | if (display_count != SZJM_JIAOZHUN) xp_time_count++; //烙铁没动,计数增加
41 | }
42 |
--------------------------------------------------------------------------------
/v1.03/PID.ino:
--------------------------------------------------------------------------------
1 | //********** PID算法 **********
2 | //算法来至https://blog.csdn.net/foxclever/article/details/105006205 By foxclever
3 | void pid()
4 | {
5 | if (t12_switch == 1 && vin_error == 0 && t12_error == 0) //加热开关开启
6 | {
7 | //计算设定值与平均温度的差值
8 | int16_t ek_average = set_temp - t12_temp_average;
9 | //平均差值小于3,发出声音提示一下
10 | if (ek_average >= -3 && ek_average <= 3 && buzzer_temp_average_state == 0)
11 | {
12 | buzzer(120, 300);
13 | buzzer_temp_average_state = 1;
14 | }
15 | if (display_count == SZJM_JIAOZHUN)
16 | PIDRegulator(t12_ad); //在校准界面时使用T12的ADC作为PID的目标值
17 | else
18 | PIDRegulator(t12_temp); //在其他界面时使用T12的温度值作为PID的目标值
19 | }
20 | else
21 | {
22 | pid_out = 0;
23 | lasterror = 0;
24 | preerror = 0;
25 | t12_temp_read_time = 450;
26 | }
27 | pwm_1b(pid_out);
28 | pid_out_bfb = (pid_out / (pwm_max - pwm_min)) * 100;
29 | }
30 |
31 | void PIDRegulator(float PV)
32 | {
33 | float factor = 0.0; //变积分系数
34 | float increment = 0.0;
35 | float pError = 0.0, dError = 0.0, iError = 0.0;
36 | if (display_count == SZJM_JIAOZHUN) //在校准界面时使用T12的ADC作为PID的目标值 ,计算偏差
37 | {
38 | if (szjm_jiaozhun_sxxk_count == 1) thisError = sz_adc0 - PV;
39 | else if (szjm_jiaozhun_sxxk_count == 2) thisError = sz_adc1 - PV;
40 | else if (szjm_jiaozhun_sxxk_count == 3) thisError = sz_adc2 - PV;
41 | else if (szjm_jiaozhun_sxxk_count == 4) thisError = sz_adc3 - PV;
42 | }
43 | else //在其他界面时使用T12的温度值作为PID的目标值 ,计算偏差
44 | {
45 | thisError = set_temp - PV; //得到偏差值
46 | thisError_average = set_temp - t12_temp_average; //得到平均值的偏差值
47 | }
48 | //规定采样时间
49 | if (thisError < -5) t12_temp_read_time = 150;
50 | else if (thisError >= -5 && thisError <= 10) t12_temp_read_time = 400;
51 | else if (thisError > 10 && thisError <= 30) t12_temp_read_time = 500;
52 | else t12_temp_read_time = 800;
53 | if (thisError <= 30 && thisError > -15)
54 | {
55 | if (fabs(thisError) > deadband)
56 | {
57 | pError = thisError - lasterror;
58 | iError = float((thisError + lasterror)) / 2.0;
59 | dError = thisError - 2 * (lasterror) + preerror;
60 |
61 | //变积分系数获取
62 | factor = get_factor(thisError, errorabsmax, errorabsmin);
63 |
64 | //计算微分项增量带不完全微分
65 | deltadiff = d * (1 - alpha) * dError + alpha * deltadiff;
66 |
67 | increment = p * pError + i * factor * iError + deltadiff; //增量计算
68 | }
69 | else
70 | {
71 | if ((fabs(set_temp - pwm_min) < deadband) && (fabs(PV - pwm_min) < deadband))
72 | {
73 | pid_out = pwm_min;
74 | }
75 | increment = 0.0;
76 | }
77 |
78 | pid_out = pid_out + increment;
79 |
80 | /*对输出限值,避免超调和积分饱和问题*/
81 | if (pid_out >= pwm_max)
82 | {
83 | if (thisError <= 0) pid_out = pwm_min;
84 | else pid_out = pwm_max;
85 | }
86 | else if (pid_out <= pwm_min) pid_out = pwm_min;
87 |
88 | }
89 | else if (thisError > 30) pid_out = pwm_max;
90 | else if (thisError < -15) pid_out = pwm_min;
91 | preerror = lasterror; //存放偏差用于下次运算
92 | lasterror = thisError;
93 | }
94 |
95 | float get_factor(float ek0, float absmax, float absmin) //变积分系数获取
96 | {
97 | float factor1 = 0.0;
98 | factor1 = map(ek0, absmax, absmin, 0.0, 1.0);
99 | if (abs(ek0) >= absmax) factor1 = 0.0;
100 | else if (abs(ek0) <= absmin) factor1 = 1.0;
101 | return factor1;
102 | }
103 |
104 | void pwm_1b(uint16_t val)//自定义PWM,使用相位和频率校正模式,2048级控温
105 | {
106 | //输出通道B 占空比: (OCR1B+1) / (OCR1A+1)
107 | //占空比不能大于OCR1A
108 |
109 | if (val >= pwm_max) digitalWrite(t12_pwm_pin, 1);
110 | else if (val <= pwm_min) digitalWrite(t12_pwm_pin, 0);
111 | else
112 | {
113 | //pinMode(10, OUTPUT); //pin10连接至B通道
114 | //bitWrite(DDRB, 2, 1); //设置pin10为输出
115 | //相位和频率校正PWM,分频比64,频率: 16000000/2*256*(OCR1A+1) = 15HZ
116 | TCCR1A = B00100001;
117 | TCCR1B = B00010100;
118 | OCR1A = pwm_max; //从0开始数到0CR1A,0-65535,设置周期和频率
119 | OCR1B = val; //用来设置比较器,占空比
120 | }
121 | //ec_read(); //读取电流
122 | }
123 | /*时钟输出 | Arduino输出Pin | 芯片Pin | Pin 名字
124 | OC0A 6 12 PD6
125 | OC0B 5 11 PD5
126 | OC1A 9 15 PB1
127 | OC1B 10 16 PB2
128 | OC2A 11 17 PB3
129 | OC2B 3 5 PD3
130 |
131 | 脉冲生成模式控制位(WGM):用来设置PWM的模式或CTC模式
132 | 时钟选择位(CS):设置时钟的预分频
133 | 输出模式控制位(COMnA和COMnB):使能/禁用/反相 输出A和输出B
134 | 输出比较器(OCRnA和OCRnB):当计数器等于这两个值时,输出值根据不同的模式进行变化
135 |
136 | 快速PWM(0-255 0-255 数完归零)
137 | 相位修正PWM(0-255 255-0 数完倒数)
138 |
139 | 8位(定时器0/2)
140 | CSn0 001 = 1
141 | CSn1 010 = 8
142 | CSn2 011= 32
143 | CSn3 100= 64
144 | CSn4 101= 128
145 | CSn5 110= 256
146 | CSn6 111= 1024
147 | 16位(定时器1)
148 | CSn0 001 = 1
149 | CSn1 010 = 8
150 | CSn2 011= 64
151 | CSn3 100= 256
152 | CSn4 101= 1024
153 |
154 | COMnA1 COMnB1 = 占空比AB都可控
155 | 从0数到2047 0时输出高电平
156 | OCRnA 当数到OCRnA,输出低电平,即A的占空比=OCRnA的值
157 | OCRnB 当数到OCRnB,输出低电平,即B的占空比=OCRnB的值
158 |
159 | COMnA0 COMnB1 = A当数到头是反相 占空比A50% B可控
160 | OCRnA 从0数到OCRnA 0时输出高电平
161 | OCRnB 当OCRnA=OCRnB,输出低电平
162 | 输出通道B 占空比: (OCR1B+1) / (OCR1A+1)
163 | 占空比不能大于OCR1A
164 | pinMode(10, OUTPUT); //B
165 | bitWrite(DDRB, 2, 1); //设置pin10为输出
166 | 快速PWM,分频比64,频率: 16000000/64*(OCR1A+1) = 976HZ
167 | TCCR1A = B00100011;
168 | TCCR1B = B00011011;
169 | 相位和频率校正PWM,分频比8,频率: 16000,000/2*8*(OCR1A+1) = 488HZ
170 | TCCR1A = B00100001;
171 | TCCR1B = B00010010;
172 | 相位校正PWM,分频比256,频率: 16000000/2*256*(OCR1A+1) = 61HZ
173 | TCCR1A = B00100011;
174 | TCCR1B = B00010100;
175 | OCR1A = 2047; //从0开始数到0CR1A,0-65535,设置周期和频率
176 | OCR1B = val; //用来设置比较器,占空比*/
177 |
--------------------------------------------------------------------------------
/v1.03/Sleep.ino:
--------------------------------------------------------------------------------
1 | //********** T12休眠判断决策 **********
2 | void t12_sleep()
3 | {
4 | if (sleep_state != digitalRead(t12_sleep_pin))//烙铁动了,计数清零
5 | {
6 | sleep_state = !sleep_state; //状态取反
7 | sleep_count = 0; //计数清零
8 | if (zjm_sleep_ts == 1)
9 | {
10 | zjm_sleep_ts = 0; //提示主界面退出显示休眠状态
11 | set_temp = sleep_temp_cache;
12 | sleep_temp_cache = 0;
13 | buzzer_temp_average_state = 0; //准备好到达温度提示声
14 | buzzer(150, 300); //提示一下
15 | }
16 | }
17 | if (sleep_count == sleep_time && zjm_sleep_ts == 0) //达到休眠的阈值,进入休眠
18 | {
19 | EEPROM.put(set_temp_eeprom, set_temp); //自动保存当前设置温度
20 | zjm_sleep_ts = 1; //提示主界面显示休眠中
21 | buzzer(150, 300); //提示一下
22 |
23 | if (set_temp > sleep_temp) //大于设置的休眠温度
24 | {
25 | sleep_temp_cache = set_temp; //休眠前将温度记录下来,记录和调温
26 | set_temp = sleep_temp; //将温度调至休眠温度
27 | }
28 | else if (set_temp <= sleep_temp) //小于等于设置的休眠温度,只记录不调温
29 | sleep_temp_cache = set_temp; //休眠前将温度记录下来
30 | }
31 | else if (sleep_count > 1800) //半小时没操作,关闭加热
32 | {
33 | MsTimer2::stop();
34 | set_temp = sleep_temp_cache;
35 | sleep_temp_cache = 0;
36 | t12_switch = 0;
37 | sleep_count = 0;
38 | zjm_sleep_ts = 0; //提示主界面退出休眠
39 | buzzer(150, 1000); //提示一下
40 | }
41 | }
42 |
43 | //********** 系统休眠判断决策 **********
44 | void system_sleep()
45 | {
46 | if (xp_time_count >= 180) //无加热无操作超过180秒就显示息屏界面
47 | {
48 | if (xp_time_count - xp_time_count_old > 3) //每隔3秒刷新一次位置
49 | {
50 | display_count = ZJM;//退出至主界面
51 | xp_state = 1; //标记息屏状态
52 | xp_x = random(0, 90);
53 | xp_y = random(11, 31);
54 | xp_time_count_old = xp_time_count;
55 | }
56 | else if (xp_time_count >= 65530) //防止数值溢出
57 | {
58 | xp_time_count = 180;
59 | xp_time_count_old = 0;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/v1.03/WDT.ino:
--------------------------------------------------------------------------------
1 | //********** 看门狗函数 **********
2 | void set_wdt_mod(uint8_t mod, uint8_t ii) //模式,超时时间
3 | {
4 | /*
5 | WDCE
6 | 该位在定时序列中用于更改WDE和预分频器位
7 | 要清除WDE位或更改预分频器位,必须将WDCE置1。
8 | 一旦写入1,硬件将在四个时钟周期后清除WDCE。
9 | 0=16ms,1=32ms,2=64ms,3=128ms,4=250ms
10 | 5=500ms,6=1s,7=2s,8=4s,9=8s
11 | */
12 | if (ii > 9 ) ii = 9;
13 | byte bb;
14 | bb = ii & 7;
15 | if (ii > 7) bb |= (1 << 5);
16 | bb |= (1 << WDCE);
17 |
18 | switch (mod) {
19 | case 0: //关闭看门狗
20 | __asm__ __volatile__ ("wdr"); //看门狗复位
21 | MCUSR = 0x00; //看门狗复位标志清零
22 | WDTCSR = (1 << WDCE) | (1 << WDE); //打开允许修改使能,并WDE置1
23 | WDTCSR = 0x00; //清除所有预分频位
24 | break;
25 |
26 | case 1: //打开看门狗,设置复位模式
27 | __asm__ __volatile__ ("wdr"); //看门狗复位
28 | MCUSR &= ~(1 << WDRF); //MUUSR中的WDRF清零,清除复位标志
29 | WDTCSR |= (1 << WDCE) | (1 << WDE); //打开允许修改使能,并WDE置1
30 | //设置新的看门狗超时值bb
31 | WDTCSR = bb; //8秒时bb=0011 0001
32 | WDTCSR |= _BV(WDE); //设置复位模式
33 | break;
34 |
35 | case 2: //打开看门狗,设置中断模式
36 | __asm__ __volatile__ ("wdr"); //看门狗复位
37 | MCUSR &= ~(1 << WDRF); //MUUSR中的WDRF清零,清除复位标志
38 | WDTCSR |= (1 << WDCE) | (1 << WDE); //打开允许修改使能,并WDE置1
39 | //设置新的看门狗超时值bb
40 | WDTCSR = bb; //8秒时bb=0011 0001
41 | WDTCSR |= _BV(WDIE); //设置中断模式
42 | break;
43 |
44 | case 3: //打开看门狗,设置中断+复位模式
45 | __asm__ __volatile__ ("wdr"); //看门狗复位
46 | MCUSR &= ~(1 << WDRF); //MUUSR中的WDRF清零,清除复位标志
47 | WDTCSR |= (1 << WDCE) | (1 << WDE); //打开允许修改使能,并WDE置1
48 | //设置新的看门狗超时值bb
49 | WDTCSR = bb; //8秒时bb=0011 0001
50 | WDTCSR |= _BV(WDIE); //设置中断模式
51 | WDTCSR |= _BV(WDE); //设置复位模式
52 | break;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/v1.03/analogRead.ino:
--------------------------------------------------------------------------------
1 | //********** 读取电压、电流、温度 **********
2 | float vin_cache = 0.0;
3 | uint8_t vin_cache_count = 0;
4 |
5 | float tc1047_cache = 0.0;
6 | uint8_t tc1047_cache_count = 0;
7 |
8 | #define cycs 10 //时间平均滤波的采样次数 采样周期 = 采样次数*定时执行任务的时间
9 | uint8_t t12_adc_error_count = 0; //t12ADC超出检测范围错误计数
10 | void read_timing() //定时读取电源电压和机内温度
11 | {
12 | if (millis() - vin_read_time > t12_temp_read_time)
13 | {
14 | read_t12_temp();
15 | vin_read_time = millis();
16 | }
17 | }
18 | void read_timing2()
19 | {
20 | vin_read(); //读取电压
21 | tc1047_temp_read(); //读取室温
22 | if (szjm_oled_sxxk_count == 1) u8g2.setContrast(oled_ld); //改变亮度
23 | }
24 | void read_t12_temp() //定时读取T12的温度
25 | {
26 | float t12_ad_nwe = 0.0; //临时AD
27 | digitalWrite(t12_pwm_pin, 0);
28 | read_timing2();
29 | delay(1);
30 | t12_ad_nwe = denoiseAnalog(t12_temp_pin); //读取即时AD
31 | //t12_ad_nwe = analogRead(t12_temp_pin); //读取即时AD
32 | t12_ad += (t12_ad_nwe - t12_ad) * 0.7; //平滑滤波
33 | //if (digitalRead(t12_sleep_pin) == 1) t12_ad += 2; //补偿上拉噪声干扰
34 | //计算温度,温度曲线由校准程序自动计算
35 | t12_temp = sz_p[3] * t12_ad * t12_ad * t12_ad + sz_p[2] * t12_ad * t12_ad + sz_p[1] * t12_ad + sz_p[0];
36 | t12_temp += (tc1047_temp - tc1047_refer); //环境温度补偿
37 |
38 | //记录平均温度
39 | t12_temp_average_cache += t12_temp;
40 | t12_temp_average_count++;
41 | if (t12_temp_average_count == 8)
42 | {
43 | t12_temp_average = t12_temp_average_cache >> 3;
44 | t12_temp_average_cache = 0; //累计缓存温度清零
45 | t12_temp_average_count = 0; //计数清零
46 | }
47 | //运行PID
48 | pid();
49 |
50 | //手柄检测及超出测量范围检测
51 | if (t12_switch == 0 && t12_ad >= 1020) //无手柄
52 | {
53 | t12_error = 1;
54 | t12_switch = 0;
55 | }
56 | else if (t12_switch == 1 && t12_ad >= 1020) //超出测量范围检测,延时检测
57 | {
58 | t12_adc_error_count++;
59 | if (t12_adc_error_count >= 8)
60 | {
61 | MsTimer2::stop(); //停止一次 然后在MsTimer2_rw1()里自动切换定时的中断任务
62 | t12_adc_error_count = 0; //清除计数
63 | t12_adc_error = 1;
64 | t12_switch = 0;
65 | }
66 | }
67 | else if (t12_switch == 1 && t12_ad < 1020)
68 | {
69 | t12_adc_error = 0;
70 | t12_adc_error_count = 0; //清除计数
71 | }
72 | else t12_error = 0;
73 | }
74 |
75 | void vin_read()
76 | {
77 | /*
78 | 串联电阻的中点电压计算公式
79 | Eout 中点电压
80 | Vcc 输入电压(两端施加电压)
81 | R1、R2 两个串联的分压电阻
82 | Eout = Vcc * R2/(R1+R2) R1靠近电源 R2靠近地
83 | */
84 | /*vin = (denoiseAnalog(vin_pin) / 0.1282) * vcc_refer_fl; //计算电源电压 10/68+10=0.1282
85 | 板子实际R2是62k,所以是10/(62+10)=0.1389
86 | if (vin < vin_low && vin_low >= 3.3) //电压过低提示
87 | {
88 | vin_error = 1;
89 | t12_switch = 0;
90 | }*/
91 |
92 | vin_cache += (denoiseAnalog(vin_pin) / 0.1389) * vcc_refer_fl;
93 | vin_cache_count++;
94 | if (vin_cache_count >= cycs)
95 | {
96 | vin = vin_cache / cycs + vin_refer;
97 | vin_cache_count = 0;
98 | vin_cache = 0;
99 | //电压过低提示
100 | if (vin < vin_low && vin_low >= 3.3)
101 | {
102 | vin_error = 1;
103 | t12_switch = 0;
104 | }
105 | else vin_error = 0;
106 | }
107 | }
108 |
109 | void tc1047_temp_read() //读取tc1047温度
110 | {
111 | //tc1047_temp = ((denoiseAnalog(tc1047_pin) * vcc_refer_fl) - 0.5) * 100;
112 |
113 | tc1047_cache += ((denoiseAnalog(tc1047_pin) * vcc_refer_fl) - 0.5) * 100;
114 | tc1047_cache_count++;
115 | if (tc1047_cache_count >= cycs)
116 | {
117 | tc1047_temp = tc1047_cache / cycs;
118 | tc1047_cache_count = 0;
119 | tc1047_cache = 0;
120 | }
121 | }
122 |
123 | /*uint16_t denoiseAnalog(uint8_t pin)
124 | {
125 | uint8_t low, high;
126 | if (pin >= A0) pin -= A0; //设置端口
127 | ADMUX = (0x0F & pin) | bit(REFS0); //设置基准电压为5V,设置端口
128 | ADCSRA |= bit (ADEN) | bit (ADIF); //启用ADC,关闭任何挂起的中断
129 | set_sleep_mode (SLEEP_MODE_ADC); //在取样时进行睡眠以降低噪音,需要开启ADC中断进行唤醒
130 | sleep_mode(); //进入休眠自动启动转换
131 | //bitSet(ADCSRA, ADSC); //ADSC 写1启动AD转换
132 | while (bitRead(ADCSRA, ADSC)); //等待转换结束
133 | low = ADCL;
134 | high = ADCH;
135 | bitClear (ADCSRA, ADEN); // 禁用ADC
136 | return (high << 8) | low; //返回数值
137 | }*/
138 | uint16_t denoiseAnalog (byte port)
139 | {
140 | uint16_t result = 0;
141 | if (port >= A0) port -= A0; //设置端口
142 | ADMUX = (0x0F & port) | bit(REFS0); //设置基准电压为5V,设置端口
143 | ADCSRA |= bit (ADEN) | bit (ADIF); //启用ADC,关闭任何挂起的中断
144 | set_sleep_mode (SLEEP_MODE_ADC); //在取样时进行睡眠以降低噪音,需要开启ADC中断进行唤醒
145 | for (uint8_t i = 0; i < 16; i++) { // get 32 readings
146 | sleep_mode(); // go to sleep while taking ADC sample
147 | while (bitRead(ADCSRA, ADSC)); // 等待转换结束
148 | result += ADC; // add them up
149 | }
150 | bitClear (ADCSRA, ADEN); // 禁用ADC
151 | return (result >> 4); // devide by 32 and return value
152 | }
153 | //ADC中断服务
154 | EMPTY_INTERRUPT (ADC_vect); // 这里没什么可做的
155 |
--------------------------------------------------------------------------------
/v1.03/v1.03.ino:
--------------------------------------------------------------------------------
1 | /*项目代码修改自 甘草酸不酸 开源https://github.com/jie326513988/mini-T12
2 | *PCB及BOM开源链接https://github.com/zxcvbnm1421899466/328P-MiNi-T12
3 | * _樱下小渚花田汐_ https://space.bilibili.com/34620092 修改
4 | * 编码器控制改为按键控制
5 | */
6 |
7 | /*
8 | 默认支持深圳头,更换其他厂商的头需要自行校准温度曲线
9 | 一定要使用我提供的U8g2库,否者无法显示中文和提示内存过大无法编译!!!
10 | */
11 | /*程序更新说明
12 | * v1.03
13 | 1.增大旋转的音调音量,修改进入和退出设置界面的音调音量
14 | 2.降低烙铁唤醒烙铁的灵敏度
15 | 3.优化pid,并不是很明显
16 | * v1.02
17 | 1.新增停止时记录当前的设置温度(休眠时也会自动保存)
18 | v1.01
19 | 1.调节PID运行间隔
20 | 2.降低PWM频率为15HZ,手柄和mos的声音几乎没有了!之前为61HZ,声音还是有一点的。
21 | v1.00(此版本需要更新U8G2库)
22 | 1.缩小一点点的内存
23 | 2.修复T12 ADC HIGH报警时无法进入息屏的BUG
24 | v0.99
25 | 1.开机就加热的模式下PWM动画会向下鬼畜,所以将开机过渡动画改为向上过渡,这样就看不到鬼畜啦
26 | 2.开机加热模式的选择改为按下确认键就切换模式,取消原实心选框旋转选择
27 | 3.添加只有在主界面下才能清除T12 ADC 超出读取读取范围的提示
28 | v0.98
29 | 1.温度曲线适配最新版本的PCB
30 | v0.97
31 | 1.优化校准界面的PID策略
32 | v0.96
33 | 1.优化内存
34 | v0.95
35 | 1.平滑的开机过度效果
36 | v0.94
37 | 1.曲线拟合改为3项式,以更加准确的绘制温度曲线
38 | v0.93
39 | 1.动态PID
40 | 2.取消电流传感器,主界面取消电流显示改为显示PWM百分比
41 | 3.设置菜单增加曲线拟合校准
42 | 4.休眠计时和息屏倒计时改用定时器2计时
43 | 5.息屏显示,无加热无操作3分钟后进入,息屏时显示环境温度
44 | 6.开机提示音和开机画面
45 | 7.休眠时自动保存当前设置温度到eeprom
46 | 8.待机功耗8.8ma 息屏待机功耗6.4ma
47 | */
48 | /*
49 | 按键功能定义
50 | 长按操作(5下短音最后1下长音)
51 | 主界面:进入设置界面
52 | 其他界面:退出至主界面(校准界面除外)
53 | 双击操作(2下短音)
54 | 主界面:加热或停止状态切换
55 | 其他界面:无
56 | 单击(1下短音)
57 | 主界面:无
58 | 设置界面:进入二级菜单
59 | 二级菜单:切换数值更改的选中状态(空心选框或实心选框),或确认更改数值,无选框状态则退出至一级菜单
60 | 菜单选项
61 | PID
62 | P
63 | I
64 | D
65 | 休眠
66 | 休眠时间
67 | 休眠温度
68 | 屏幕
69 | 屏幕亮度
70 | 屏幕方向
71 | 编码器方向
72 | 电源
73 | 基准电压
74 | 电源电压
75 | 低压报警
76 | 校准
77 | 调节曲线1段温度
78 | 调节曲线2段温度
79 | 调节曲线2段温度
80 | 调节曲线3段温度
81 | 运行曲线拟合并校准曲线
82 | 烙铁
83 | 冷端补偿
84 | 开机加热
85 | 重置
86 | */
87 | #include
88 | #include //掉电数值存储库
89 | #include //休眠库
90 | #include //屏幕驱动库
91 | #ifdef U8X8_HAVE_HW_I2C
92 | #include
93 | #endif
94 | U8G2_SSD1306_128X32_UNIVISION_2_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
95 |
96 | //********** 版本号 **********
97 | #define version "v1.03"
98 | //********** 引脚定义 **********
99 | #define SW 4 //按下 ,可更改其他引脚
100 | #define CLK 3 //旋转 ,不可更改
101 | #define DT 2 //旋转 ,可更改其他引脚
102 | //除了10号脚不能改,其他都可以改,但模拟引脚只能改模拟引脚(休眠引脚除外)
103 | #define t12_sleep_pin A0 //t12休眠 模拟读取引脚
104 | #define t12_temp_pin A2 //t12温度 模拟读取引脚
105 | #define tc1047_pin A3 //机内温度 模拟读取引脚
106 | #define vin_pin A6 //电源电压 模拟读取引脚
107 | #define t12_pwm_pin 10 //t12加热 pwm输出引脚,定死不可更改
108 | #define buzzer_pin 8 //蜂鸣器 输出引脚
109 | //************ EEPROM地址定义 ************
110 | uint8_t auto_get = 0; //自动刷写eeprom的状态存储,判断是否首次开机 0-首次 1-非首次
111 | #define auto_get_eeprom 0 //自动刷写eeprom的状态存储,1位
112 | #define p_eeprom 1 //p地址,4位
113 | #define i_eeprom p_eeprom+4 //i地址,4位
114 | #define d_eeprom i_eeprom+4 //d地址,4位
115 | #define sleep_time_eeprom d_eeprom+4 //休眠时间,4位
116 | #define sleep_temp_eeprom sleep_time_eeprom+4 //休眠温度,1位
117 | #define oled_ld_eeprom sleep_temp_eeprom+1 //OLED亮度,1位
118 | #define vcc_refer_eeprom oled_ld_eeprom+1 //基准电压,4位
119 | #define vin_refer_eeprom vcc_refer_eeprom+4 //电源电压校准值,4位
120 | #define t12_kj_jr_eeprom vin_refer_eeprom+4 //是否开机就加热?,1位
121 | #define vin_low_eeprom t12_kj_jr_eeprom+1 //输入电压低压报警阈值,4位
122 | #define tc1047_refer_eeprom vin_low_eeprom+4 //冷端补偿校准值,1位
123 | #define oled_fx_eeprom tc1047_refer_eeprom+1 //OELD方向,1位
124 | #define xzbmq_fx_eeprom oled_fx_eeprom+1 //编码器旋转方向,1位
125 | #define sz_temp0_eeprom xzbmq_fx_eeprom+1 //深圳头曲线温度校准1段,4位
126 | #define sz_temp1_eeprom sz_temp0_eeprom+4 //深圳头曲线温度校准2段,4位
127 | #define sz_temp2_eeprom sz_temp1_eeprom+4 //深圳头曲线温度校准3段,4位
128 | #define sz_temp3_eeprom sz_temp2_eeprom+4 //深圳头曲线温度校准4段,4位
129 | #define set_temp_eeprom sz_temp3_eeprom+4 //t12设置温度,4位
130 | //T12及温度相关
131 | boolean t12_switch = 0; //T12加热开关
132 | boolean t12_kj_jr = 1; //是否开机就加热? 0-否 1-是
133 |
134 | float t12_ad = 0.0; //T12即时ADC值
135 | uint16_t t12_temp = 0.0; //T12即时温度
136 | boolean t12_error = 0; //手柄未接提示
137 | boolean t12_adc_error = 0; //温度超出测量范围
138 | uint16_t set_temp_max; //自动计算设置的温度最大值
139 | uint16_t set_temp_min; //自动计算设置的温度最小值
140 |
141 | int16_t t12_temp_average_cache = 0; //记录采集温度,缓存用
142 | int16_t t12_temp_average = 0; //8次内采集到的平均温度,显示用
143 | uint8_t t12_temp_average_count = 0; //平均温度采集计数
144 | boolean buzzer_temp_average_state = 0; //到达温度提示声
145 |
146 | //float tc1047_ad = 0.0; //tc1047ADC值
147 | float tc1047_temp = 0.0; //tc1047温度,机内温度
148 | int8_t tc1047_refer = 30; //T12环境参考温度校准值
149 |
150 | float vcc_refer = 4.95; //参考电压,稳压芯片输出的电压是多少就填多少
151 | float vin = 0.0; //电源电压
152 | float vin_refer = 0.0; //输入电压校准值
153 | float vin_low = 3.3; //低压报警阈值
154 | boolean vin_error = 0; //低压报警提示
155 | #define vcc_refer_fl vcc_refer/1023.0 //参考电压每级分量
156 |
157 | uint32_t xzbmq_time = 0; //编码器消抖对比时间
158 | uint32_t temp_read_time = 0; //定时读取温度对比时间
159 | uint32_t vin_read_time = 0; //定时读取输入电压时间
160 | uint32_t t12_temp_read_time = 450; //定时T12温度采样时间
161 |
162 | boolean buzzer_state = 0; //蜂鸣器准备状态
163 | uint16_t buzzer_time; //蜂鸣器响的时间
164 | uint16_t buzzer_count; //蜂鸣器响的次数
165 | boolean buzzer_szjm_state = 0; //进入设置界面的长音状态
166 | boolean buzzer_zjm_state = 0; //退出至主界面的长音状态
167 |
168 | boolean zjm_sleep_ts = 0; //主界面休眠提示 0-无 1-休眠中
169 | uint16_t sleep_time = 180; //进入休眠的时间阈值,单位秒
170 | uint8_t sleep_temp = 200; //休眠时的温度,单位摄氏度
171 | boolean sleep_state = 0; //休眠引脚状态 0低电平 1高电平
172 | uint16_t sleep_count = 0; //休眠计数
173 | uint16_t sleep_temp_cache = 0; //休眠前的温度缓存
174 |
175 | uint8_t oled_ld = 50; //OLED亮度
176 | boolean oled_fx = 0; //OLED方向 0-不旋转,横向显示 1-旋转180度
177 | boolean xzbmq_fx = 0; //编码器方向 0-顺加逆减 1-顺减逆加
178 | boolean hfccsz_state = 0; //恢复出厂设置 0-NO 1-YES
179 |
180 | boolean xp_state = 0; //息屏状态 0-无 1-息屏
181 | uint16_t xp_time_count = 0; //息屏计数
182 | uint16_t xp_time_count_old = 0; //上一次时间计数
183 | int8_t xp_x = 0; //息屏随机变化位置X
184 | int8_t xp_y = 0; //息屏随机变化位置Y
185 | int8_t xp_x_old = 50; //上一次息屏随机变化位置X
186 | int8_t xp_y_old = 21; //上一次息屏随机变化位置Y
187 |
188 | //深圳头曲线拟合的4段ADC
189 | #define sz_adc0 10
190 | #define sz_adc1 350
191 | #define sz_adc2 650
192 | #define sz_adc3 940
193 | uint16_t sz_temp[4] = {49, 262, 391, 486}; //深圳头曲线拟合的4段温度 Y
194 | float sz_p[4]; //深圳头曲线拟合的4个系数 P
195 | //********** 菜单标志位相关 **********
196 | #define ZJM 1 //主界面
197 | #define SZJM 2 //设置界面
198 | #define SZJM_PID 3 //PID设置界面
199 | #define SZJM_SLEEP 4 //休眠设置界面
200 | #define SZJM_OLED 5 //OLED设置界面
201 | #define SZJM_POWER 6 //电源设置界面
202 | #define SZJM_JIAOZHUN 7 //校准设置界面
203 | #define SZJM_LAOTIE 8 //烙铁头设置界面
204 |
205 | uint8_t display_count = 1; //默认要显示的界面
206 | boolean dec_state = 0; //小数点输入状态 0关闭 1开启
207 | uint8_t qj_ca_count = 0; //全局长按计数
208 |
209 | boolean szjm_kxxk_L = 0; //设置界面空心选框 顺时针转
210 | boolean szjm_kxxk_R = 0; //设置界面空心选框 逆时针转
211 | int8_t szjm_kxxk_count = 0; //设置界面空心选框
212 |
213 | int8_t szjm_pid_kxxk_count = 0; //pid界面空心选框
214 | int8_t szjm_pid_sxxk_count = 0; //pid界面实心选框
215 |
216 | int8_t szjm_sleep_kxxk_count = 0; //pid界面空心选框
217 | int8_t szjm_sleep_sxxk_count = 0; //pid界面实心选框
218 |
219 | int8_t szjm_oled_kxxk_count = 0; //oled界面空心选框
220 | int8_t szjm_oled_sxxk_count = 0; //oled界面实心选框
221 |
222 | int8_t szjm_power_kxxk_count = 0; //电源设置界面空心选框
223 | int8_t szjm_power_sxxk_count = 0; //电源设置界面实心选框
224 |
225 | int8_t szjm_pwm_kxxk_count = 0; //PWM界面空心选框
226 | int8_t szjm_pwm_sxxk_count = 0; //PWM界面实心选框
227 |
228 | int8_t szjm_laotie_kxxk_count = 0; //烙铁头设置界面空心选框
229 | int8_t szjm_laotie_sxxk_count = 0; //烙铁头设置界面实心选框
230 |
231 | int8_t szjm_jiaozhun_kxxk_count = 0; //烙铁头设置界面空心选框
232 | int8_t szjm_jiaozhun_sxxk_count = 0; //烙铁头设置界面实心选框
233 | //********** 动态调参PID **********
234 | float p = 25.0; //比例系数
235 | float i = 8.7; //积分系数
236 | float d = 2.6; //微分系数
237 |
238 | #define p_jz 12.0 //校准界面用的 比例系数
239 | #define i_jz 2.2 //校准界面用的 积分系数
240 | #define d_jz 1.2 //校准界面用的 微分系数
241 |
242 | uint16_t set_temp = 320; //设置温度
243 | int16_t thisError = 0; //本次误差
244 | int16_t thisError_average = 0; //平均值的误差
245 | int16_t lasterror = 0; //前一拍偏差
246 | int16_t preerror = 0; //前两拍偏差
247 | const int8_t deadband = 0; //死区
248 | int16_t pid_out = 0.0; //PID控制器计算结果
249 | uint8_t pid_out_bfb = 0.0; //输出值0-100%
250 | const float pwm_max = 2047.0; //输出值上限
251 | const float pwm_min = 0.0; //输出值下限
252 | const float errorabsmax = 2000.0; //偏差绝对值最大值
253 | const float errorabsmin = 50.0; //偏差绝对值最小值
254 | const float alpha = 0.2; //不完全微分系数
255 | float deltadiff = 0.0; //微分增量
256 |
257 | void setup()
258 | {
259 | //***** 首次开机自动刷写eeprom
260 | eerpom_auto();
261 | //***** 编码器配置
262 | pinMode(SW, INPUT_PULLUP); //按下
263 | pinMode(CLK, INPUT_PULLUP); //相位A
264 | pinMode(DT, INPUT_PULLUP); //相位B
265 | pinMode(t12_temp_pin, INPUT); //t12温度
266 | pinMode(t12_sleep_pin, INPUT_PULLUP); //t12休眠
267 | pinMode(vin_pin, INPUT); //电源电压
268 | pinMode(tc1047_pin, INPUT); //机内温度
269 | pinMode(buzzer_pin, OUTPUT); //蜂鸣器
270 | pinMode(t12_pwm_pin, OUTPUT); //t12加热,不可更改
271 |
272 | digitalWrite(t12_pwm_pin, 0); //默认关闭
273 | digitalWrite(buzzer_pin, 0); //默认关闭
274 | //***** OLED初始化
275 | u8g2.begin();
276 | u8g2.enableUTF8Print();
277 | u8g2.setContrast(oled_ld); //设置亮度1-255
278 | //u8g2.setBusClock(400000); //设置I2C通讯速度默认MAX400000
279 | //u8g2.setPowerSave(0); //0开启屏幕 1关闭屏幕
280 | if (oled_fx)u8g2.setDisplayRotation(U8G2_R2); //旋转180度
281 | else u8g2.setDisplayRotation(U8G2_R0); //0度,默认方向
282 | //***** ADC初始化
283 | //ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2); // 设置ADC分频 128倍
284 | ADCSRA |= bit (ADPS1) | bit (ADPS2); //设置ADC分频 64倍
285 | ADCSRA |= bit (ADIE); // 开启ADC中断
286 | interrupts(); // 开启全局中断
287 | //***** 打开外部中断
288 | attachInterrupt(digitalPinToInterrupt(CLK), xuan_zhaun, FALLING); //PIN3,选择编码器 旋转,下降沿触发 FALLING
289 | attachInterrupt(digitalPinToInterrupt(DT), xuan_zhaun, FALLING);
290 |
291 | //***** 播放开机画面和开机声
292 | kj_display();
293 | buzzer(600, 200); //时间,次数
294 | buzzer_run();
295 | buzzer(400, 300); //时间,次数
296 | buzzer_run();
297 | buzzer(130, 1000); //时间,次数
298 | buzzer_run();
299 | //读取电压/温度
300 | for (uint8_t i = 0; i < 10; i++) //读取初始值
301 | {
302 | vin_read();
303 | tc1047_temp_read();
304 | read_t12_temp();
305 | }
306 | //***** 开启看门狗
307 | //set_wdt_mod(1, 7);
308 | //***** 是否开机加热
309 | if (t12_kj_jr == 1) t12_switch = 1;
310 | else t12_switch = 0;
311 | //***** 开机计算曲线拟合系数
312 | qxnh_run();
313 | //Serial.begin(9600); //打开串口调试
314 | }
315 |
316 | void loop()
317 | {
318 | //uint32_t time0 = micros();
319 |
320 | __asm__ __volatile__ ("wdr"); //看门狗复位
321 | an_xia(); //编码器按下决策
322 | draw_page(); //刷新屏幕
323 | buzzer_run(); //蜂鸣器运行决策
324 | read_timing(); //定时读取任务
325 | MsTimer2_rw1(); //定时器2任务
326 |
327 | //uint32_t time1 = micros();
328 | //Serial.println(time1 - time0);
329 | }
330 |
--------------------------------------------------------------------------------
/v1.20.1/A_ReadMe.ino:
--------------------------------------------------------------------------------
1 | /*
2 | 校准温度曲线的方法
3 | 1.先校准基准电压,测量串口的5V接口就是基准电压
4 | 2.准备好能测量0-500摄氏度的设备,探头建议使用裸装,以免外壳热传导导致热量损失测量不准
5 | 3.将探头紧压住烙铁头发热前段(上锡部分再下来一点),一定要紧紧压住,不然也会测量不准
6 | 4.放置好烙铁头以免校准时烫伤手或物品!
7 | 5.接上电源,进入‘烙台’界面,将室温设置为当前的冷端补偿温度,再进入‘校准’界面,将空心选框移动至第1段温度处(即对应的ADC 10下面)
8 | 6.按下确认键,此时空心选框变成实心选框,烙铁头开始加热,等待最下方的‘Now ADC’值稳定在一定的范围,与第一行相应的ADC值差不多即可(此时是ADC 10)
9 | 7.使用测量设备测量烙铁头的温度,将第1段温度调至测量得到的温度(实心选框状态可旋转旋钮调节数值)
10 | 8.依次测量剩下的第2段、第3段、第4段温度并输入至控制器
11 | 9.测量完4段温度后将光标移至Save,按下确认键,等待程序计时温度曲线
12 | 10.计算完会显示P系数界面,,再按下确认键即可退出校准界面
13 | 11.在主界面准备进行二次校准
14 | 12.在主界面开启加热至第二段校准的温度,如265,则加热至260度,若不对则进入校准界面加减对应的计算温度,直至自己满意为止。
15 | 13.依次加热至第三、第四、第一、第四段温度并校准,直至自己满意为止。
16 | */
17 |
18 | /*
19 | 长按操作(5下短音最后1下长音)
20 | 主界面,进入设置界面
21 | 其他界面,退出至主界面
22 | 双击操作(2下短音)
23 | 主界面,加热或停止状态切换
24 | 其他界面,无
25 | 单击(1下短音)
26 | 主界面,无
27 | 设置界面,进入二级菜单
28 | 二级菜单,切换数值更改选中状态,或确认更改数值,无选框状态则退出至一级菜单
29 | */
30 |
--------------------------------------------------------------------------------
/v1.20.1/Buzzer.ino:
--------------------------------------------------------------------------------
1 | //********** 控制蜂鸣器发声的频率和时间,系统延时法,占用系统速度大 **********
2 | uint32_t error_buzzer_db_time = 0;
3 | void buzzer_run()
4 | {
5 | pinMode(buzzer_pin, OUTPUT);
6 | if (buzzer_state == 1)
7 | {
8 | for (uint16_t i = 0; i < buzzer_count; i++)
9 | {
10 | digitalWrite(buzzer_pin, 1);
11 | delayMicroseconds(buzzer_time);
12 | digitalWrite(buzzer_pin, 0);
13 | if (i < buzzer_count - 1) delayMicroseconds(buzzer_time); //最后一次不需要延时
14 | }
15 | buzzer_state = 0;
16 | }
17 | //错误提示报警音
18 | if (vin_error == 1 || t12_adc_error == 1)
19 | {
20 | if (millis() - error_buzzer_db_time > 1000)
21 | {
22 | buzzer(120, 300);
23 | error_buzzer_db_time = millis();
24 | }
25 | }
26 |
27 | if (buzzer_szjm_state == 1) //进入设置界面时发出声音提示一下
28 | {
29 | buzzer(150, 720);
30 | buzzer_szjm_state = 0;
31 | }
32 | else if (buzzer_zjm_state == 1) //退出至主界面时发出声音提示一下
33 | {
34 | buzzer(150, 720);
35 | buzzer_zjm_state = 0;
36 | }
37 | pinMode(buzzer_pin, INPUT);
38 | }
39 |
40 | void buzzer(uint16_t time, uint16_t count)
41 | {
42 | buzzer_state = 1; //准备好蜂鸣器
43 | buzzer_time = time; //设置时间
44 | buzzer_count = count; //设置次数
45 | }
46 | //*********************************************************
47 |
48 | //****** 控制蜂鸣器发声的频率和时间,内部中断法,占用系统速度小 ******
49 |
50 | /*void buzzer(uint16_t time, uint16_t count) //时间单位ms
51 | {
52 | if (buzzer_state == 0 && digitalRead(buzzer_pin) == 0) //蜂鸣器停止状态才能设置定时器
53 | {
54 | buzzer_count = count; //设置次数
55 | Timer1.initialize(time); //设置时间
56 | Timer1.attachInterrupt(buzzer_isr); //设置定时器中断函数
57 | Timer1.start(); //启动定时器
58 | }
59 | }
60 | void buzzer_isr()
61 | {
62 | buzzer_isr_count++;
63 | bitWrite(PINB, 0, 1); //设置pin8为输出 PINX写1翻转状态
64 | buzzer_state = 1; //标识蜂鸣器正在工作
65 | if (buzzer_isr_count >= buzzer_count)
66 | {
67 | buzzer_isr_count = 0; // 清除计数
68 | buzzer_state = 0; //标识蜂鸣器已停止
69 | digitalWrite(buzzer_pin, 0); //关闭蜂鸣器
70 | Timer1.stop(); //停止中断
71 | }
72 | }*/
73 | //*********************************************************
74 | uint8_t get_num_digit(uint32_t num)//获取数字的位数
75 | {
76 | uint8_t count = 0;
77 | if (num == 0) count = 1;
78 | while (num != 0)
79 | {
80 | // n = n/10
81 | num /= 10;
82 | ++count;
83 | }
84 | return count;
85 | }
86 |
--------------------------------------------------------------------------------
/v1.20.1/CurveFitting.ino:
--------------------------------------------------------------------------------
1 | //********** 曲线拟合程序 **********
2 | //曲线拟合算法来至https://blog.csdn.net/m0_37362454/article/details/82456616 by欧阳小俊
3 | void qxnh_run() //曲线拟合运行
4 | {
5 | int16_t i, sizenum;
6 | float P[4];
7 | int8_t dimension = 3; //3次多项式拟合
8 | // 要拟合的数据
9 | int xx[] = {sz_adc0, sz_adc1, sz_adc2, sz_adc3}; //t12 adc
10 | //int yy[] = {45, 219, 366, 435}; //测量设备的温度
11 |
12 | sizenum = sizeof(xx) / sizeof(xx[0]); //拟合数据的维数
13 | polyfit(sizenum, xx, sz_temp, dimension, P);
14 |
15 | sz_p[0] = P[0];
16 | sz_p[1] = P[1];
17 | sz_p[2] = P[2];
18 | sz_p[3] = P[3];
19 | /*
20 | 得出系数:P[0],P[1],P[2]
21 | 曲线公式:y = P[3]*X*X*X+P[2]*X*X + P[1]*X + P[0]
22 | 曲线公式:t12_temp =P[3]* t12_ad * t12_ad* t12_ad + P[2] * t12_ad * t12_ad + P[1] * t12_ad + P[0];
23 | */
24 | }
25 |
26 | /*==================polyfit(n,x,y,poly_n,a)===================*/
27 | /*=======拟合y=a0+a1*x+a2*x^2+……+apoly_n*x^poly_n========*/
28 | /*=====n是数据个数 xy是数据值 poly_n是多项式的项数======*/
29 | /*===返回a0,a1,a2,……a[poly_n],系数比项数多一(常数项)=====*/
30 | void polyfit(int n, int x[], int y[], int poly_n, float p[])
31 | {
32 | int i, j;
33 | float *tempx, *tempy, *sumxx, *sumxy, *ata;
34 |
35 | tempx = (float *)calloc(n , sizeof(float));
36 | sumxx = (float *)calloc((poly_n * 2 + 1) , sizeof(float));
37 | tempy = (float *)calloc(n , sizeof(float));
38 | sumxy = (float *)calloc((poly_n + 1) , sizeof(float));
39 | ata = (float *)calloc( (poly_n + 1) * (poly_n + 1) , sizeof(float) );
40 | for (i = 0; i < n; i++)
41 | {
42 | tempx[i] = 1;
43 | tempy[i] = y[i];
44 | }
45 | for (i = 0; i < 2 * poly_n + 1; i++)
46 | {
47 | for (sumxx[i] = 0, j = 0; j < n; j++)
48 | {
49 | sumxx[i] += tempx[j];
50 | tempx[j] *= x[j];
51 | }
52 | }
53 | for (i = 0; i < poly_n + 1; i++)
54 | {
55 | for (sumxy[i] = 0, j = 0; j < n; j++)
56 | {
57 | sumxy[i] += tempy[j];
58 | tempy[j] *= x[j];
59 | }
60 | }
61 | for (i = 0; i < poly_n + 1; i++)
62 | {
63 | for (j = 0; j < poly_n + 1; j++)
64 | {
65 | ata[i * (poly_n + 1) + j] = sumxx[i + j];
66 | }
67 | }
68 | gauss_solve(poly_n + 1, ata, p, sumxy);
69 |
70 | free(tempx);
71 | free(sumxx);
72 | free(tempy);
73 | free(sumxy);
74 | free(ata);
75 | }
76 | /*============================================================
77 | 高斯消元法计算得到 n 次多项式的系数
78 | n: 系数的个数
79 | ata: 线性矩阵
80 | sumxy: 线性方程组的Y值
81 | p: 返回拟合的结果
82 | ============================================================*/
83 | void gauss_solve(int n, float A[], float x[], float b[])
84 | {
85 | int i, j, k, r;
86 | float max;
87 | for (k = 0; k < n - 1; k++)
88 | {
89 | max = fabs(A[k * n + k]); // find maxmum
90 | r = k;
91 | for (i = k + 1; i < n - 1; i++)
92 | {
93 | if (max < fabs(A[i * n + i]))
94 | {
95 | max = fabs(A[i * n + i]);
96 | r = i;
97 | }
98 | }
99 | if (r != k)
100 | {
101 | for (i = 0; i < n; i++) //change array:A[k]&A[r]
102 | {
103 | max = A[k * n + i];
104 | A[k * n + i] = A[r * n + i];
105 | A[r * n + i] = max;
106 | }
107 | max = b[k]; //change array:b[k]&b[r]
108 | b[k] = b[r];
109 | b[r] = max;
110 | }
111 |
112 | for (i = k + 1; i < n; i++)
113 | {
114 | for (j = k + 1; j < n; j++)
115 | A[i * n + j] -= A[i * n + k] * A[k * n + j] / A[k * n + k];
116 | b[i] -= A[i * n + k] * b[k] / A[k * n + k];
117 | }
118 | }
119 |
120 | for (i = n - 1; i >= 0; x[i] /= A[i * n + i], i--)
121 | {
122 | for (j = i + 1, x[i] = b[i]; j < n; j++)
123 | x[i] -= A[i * n + j] * x[j];
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/v1.20.1/Display.ino:
--------------------------------------------------------------------------------
1 | //********** 显示决策 **********
2 | uint32_t system_sleep_db_time = 0; //系统进入睡眠对比时间
3 | void display()
4 | {
5 | if (xp_state == 0) //正常显示
6 | {
7 | if (display_count == ZJM) zjm();
8 | else if (display_count == SZJM) szjm();
9 | else if (display_count == SZJM_PID) szjm_pid();
10 | else if (display_count == SZJM_SLEEP) szjm_sleep();
11 | else if (display_count == SZJM_OLED) szjm_oled();
12 | else if (display_count == SZJM_POWER) szjm_power();
13 | else if (display_count == SZJM_LAOTIE) szjm_laotie();
14 | else if (display_count == SZJM_JIAOZHUN) szjm_jiaozhun();
15 | }
16 | else xpjm(); //显示息屏界面
17 | }
18 |
19 | void draw_page(void)
20 | {
21 | static uint8_t is_next_page = 0;
22 | // 调用第一页,如果需要
23 | if ( is_next_page == 0 )
24 | {
25 | u8g2.firstPage();
26 | is_next_page = 1;
27 | }
28 | // 画我们的屏幕
29 | display();
30 | // 调用下一页
31 | if ( u8g2.nextPage() == 0 )
32 | {
33 | is_next_page = 0; // 确保调用了第一个页面
34 | }
35 | }
36 |
37 | void display_hfccsz() //恢复出厂设置进度显示界面
38 | {
39 | uint16_t x_old = 0;
40 | for (int i = 0 ; i < EEPROM.length() ; i++)
41 | {
42 | __asm__ __volatile__ ("wdr"); //防止没清除完因看门狗没喂狗导致重启
43 | uint16_t x_new = map(i, 0, EEPROM.length(), 0, 100);
44 | if (x_new - x_old >= 5)
45 | {
46 | u8g2.firstPage();
47 | do {
48 | u8g2.setCursor(50, 16);
49 | u8g2.print(x_new);
50 | u8g2.setCursor(75, 16);
51 | u8g2.print("%");
52 | x_old = x_new;
53 | } while ( u8g2.nextPage() );
54 | }
55 | EEPROM.write(i, 0); //清除所有EEPROM
56 | }
57 | set_wdt_mod(1, 0); //利用看门狗实现软重启
58 | }
59 |
60 | void kj_display() //开机显示版本号
61 | {
62 | u8g2.firstPage();
63 | do {
64 | u8g2.setFont(chinese_t12);
65 | u8g2.setCursor(50, 21);
66 | u8g2.print(version);
67 | } while ( u8g2.nextPage() );
68 | }
69 |
70 | void xpjm() //息屏界面
71 | {
72 | if (xp_x - xp_x_old > 0)
73 | {
74 | if (xp_x_old != xp_x) xp_x_old++;
75 | }
76 | else if (xp_x - xp_x_old < 0 )
77 | {
78 | if (xp_x_old != xp_x) xp_x_old--;
79 | }
80 |
81 | if (xp_y - xp_y_old > 0)
82 | {
83 | if (xp_y_old != xp_y) xp_y_old++;
84 | }
85 | else if (xp_y - xp_y_old < 0 )
86 | {
87 | if (xp_y_old != xp_y) xp_y_old--;
88 | }
89 |
90 | u8g2.setFont(chinese_t12);
91 | u8g2.setCursor(xp_x_old, xp_y_old);
92 | u8g2.print(tc1047_temp, 1);
93 | u8g2.setCursor(xp_x_old + 27, xp_y_old - 1);
94 | u8g2.print("℃");
95 | }
96 |
97 | /*u8g2.firstPage();
98 | do {
99 | u8g2.setFont(chinese_t12);
100 | u8g2.setCursor(xp_x, xp_y);
101 | u8g2.print(tc1047_temp, 1);
102 | u8g2.setCursor(xp_x + 27, xp_y - 1);
103 | u8g2.print("℃");
104 | } while ( u8g2.nextPage() );*/
105 |
--------------------------------------------------------------------------------
/v1.20.1/DisplayMain.ino:
--------------------------------------------------------------------------------
1 | //********** 画主界面 **********
2 | uint8_t zjm_x1 = 0;
3 | uint8_t zjm_x2 = 100;
4 | #define zjm_x3 75
5 | #define zjm_x4 zjm_x3+4
6 |
7 | #define zjm_y1 7
8 | #define zjm_y2 19
9 | #define zjm_y3 32
10 | #define zjm_y4 14
11 | boolean zjm_dh_run = 0; //主界面动画状态 0-不允许 1-允许
12 | uint32_t zjm_dh_time1 = 0; //动画1运转对比时间
13 | uint32_t zjm_dh_time2 = 0; //动画2运转对比时间
14 | //热、停切换动画变量
15 | uint8_t zjm_dh_x1 = 0;
16 | uint8_t zjm_dh_y1 = 0;
17 | uint8_t zjm_dh_r1 = 1;
18 | //pwm动效动画
19 | uint8_t zjm_dh_l[14];
20 | //开机过度动画y增量
21 | int8_t zjm_dh_y = 32;
22 | void zjm()
23 | {
24 | //****** 画当前温度及烙铁错误提示
25 | if (t12_error == 0 && t12_adc_error == 0) //正常画面
26 | {
27 | //显示当前烙铁温度
28 | /*u8g2.setFont(u8g2_font_bubble_tn);
29 | if (t12_temp >= 99)u8g2.setCursor(0, zjm_dh_y + 18);
30 | else u8g2.setCursor(10, zjm_dh_y + 18);
31 | if (t12_switch == 1 && (thisError_average <= 4 && thisError_average >= -4)) u8g2.print(t12_temp_average);
32 | else u8g2.print(t12_temp);*/
33 |
34 | u8g2.setFont(u8g2_font_bubble_tn);
35 | if (t12_temp >= 99)u8g2.setCursor(0, zjm_dh_y + 18);
36 | else u8g2.setCursor(10, zjm_dh_y + 18);
37 |
38 | if (t12_switch == 1 && (thisError_average <= 4 && thisError_average >= -4)) {
39 | if (t12_temp_average - t12_temp_display > 0) t12_temp_display += 1;
40 | else if (t12_temp_average - t12_temp_display < 0) t12_temp_display -= 1;
41 | u8g2.print(t12_temp_display);
42 | }
43 |
44 | else {
45 | if (t12_temp - t12_temp_display > 0) t12_temp_display += 1;
46 | else if (t12_temp - t12_temp_display < 0) t12_temp_display -= 1;
47 | u8g2.print(t12_temp_display);
48 | }
49 | }
50 | else if (t12_adc_error == 1) zjm_error2(); //T12ADC超出测量范围画面
51 | else if (t12_error == 1) zjm_error3(); //手柄未接显示画面
52 | //****** 画设置温度进度条
53 | //u8g2.setFont(u8g2_font_saikyosansbold8_8n);
54 | u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
55 | zjm_x1 = map(set_temp, set_temp_min, set_temp_max, 3, 57);
56 | u8g2.drawDisc(zjm_x1, zjm_dh_y + 28, 2);//画实心圆
57 | u8g2.drawBox(0, zjm_dh_y + 30, 61, 2); //画实心框
58 | if (set_temp <= 310)u8g2.setCursor(zjm_x1 + 5, zjm_dh_y + 29); //画设置温度
59 | else u8g2.setCursor(zjm_x1 - 21, zjm_dh_y + 29); //画设置温度
60 | u8g2.print(set_temp);
61 |
62 | //****** 画加热提示及切换动画
63 | u8g2.setFont(chinese_t12);
64 | if (zjm_dh_y != 0) //开机过渡动画变量变化
65 | {
66 | zjm_dh_y --;
67 | u8g2.setCursor(50, zjm_dh_y - 11);
68 | u8g2.print(version);
69 | }
70 | if (/*millis() - zjm_dh_time1 > 30 &&*/ zjm_dh_run == 1)
71 | {
72 | if (zjm_dh_x1 < 7)
73 | {
74 | zjm_dh_x1++;
75 | zjm_dh_y1++;
76 | if (zjm_dh_x1 == 7)
77 | {
78 | zjm_dh_r1 = 0;
79 | if (t12_switch == 1 && zjm_sleep_ts == 0) EEPROM.put(set_temp_eeprom, set_temp); //停止时保存当前的设置温度
80 | t12_switch = !t12_switch; //动画播放完,切换T12工作状态
81 | MsTimer2::stop(); //停止一次 然后在MsTimer2_rw1()里自动切换定时的中断任务
82 | }
83 | zjm_dh_time1 = millis();
84 | }
85 | else if (zjm_dh_x1 >= 7 && millis() - zjm_dh_time1 > 300)
86 | {
87 | zjm_dh_x1 = 0;
88 | zjm_dh_y1 = 0;
89 | zjm_dh_r1 = 1;
90 | zjm_dh_run = 0; //关闭动画
91 | }
92 | }
93 | u8g2.drawRFrame(zjm_x3 - 3, zjm_dh_y + zjm_y4 - 14, 18, 18, 3); //空心圆角方形
94 | u8g2.setCursor(zjm_x3, zjm_dh_y + zjm_y4);
95 | if (t12_switch == 1 && zjm_sleep_ts == 0) u8g2.print("热");
96 | else if (t12_switch == 1 && zjm_sleep_ts == 1) u8g2.print("休");
97 | else u8g2.print("停");
98 | if (zjm_dh_x1 == 7)u8g2.setDrawColor(2);
99 | u8g2.drawRBox(80 - zjm_dh_x1, zjm_dh_y + 8 - zjm_dh_y1, 2 + zjm_dh_x1 * 2, 2 + zjm_dh_y1 * 2, zjm_dh_r1); //实心圆角方形
100 | if (zjm_dh_x1 == 7)u8g2.setDrawColor(1);
101 |
102 | //****** 画PWM输出比例动画
103 | if (t12_switch == 1)
104 | {
105 | uint16_t zjm_pwmdh_time = map(pid_out, pwm_min, pwm_max, 450, 150); //输出比例决定刷新时间
106 | uint8_t zjm_pwmdh_l = map(pid_out, pwm_min, pwm_max, 3, 12); //输出比例决定L的最大值
107 | if (millis() - zjm_dh_time2 > zjm_pwmdh_time)
108 | {
109 | for (uint8_t i = 0; i < 14; i++)
110 | {
111 | zjm_dh_l[i] = random(1, zjm_pwmdh_l);
112 | }
113 | zjm_dh_time2 = millis();
114 | }
115 |
116 | for (uint8_t i = 0; i < 14; i++)
117 | {
118 | u8g2.drawLine(74 + i, zjm_dh_y + 32, 74 + i, zjm_dh_y + 32 - zjm_dh_l[i]); //绘制垂直线,X,Y,长度
119 | //delay(100);
120 | }
121 | }
122 | else u8g2.drawHLine(74, zjm_dh_y + 31, 14);
123 |
124 | //****** 画室温-电压-电流-工作状态
125 | if (vin_error == 1) zjm_error1(); //电压电流有一个报警就显示 报警提示画面
126 | else zjm_vin_ec_temp_state(); //显示正常画面
127 |
128 | //****** 调试信息显示
129 | //u8g2.setCursor(75, 32);
130 | //u8g2.print(zjm_ca_count);
131 | }
132 |
133 |
134 | void zjm_vin_ec_temp_state() //画室温-电压-电流-工作状态
135 | {
136 | //画室温-电压
137 | u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
138 | u8g2.setCursor(zjm_x2, zjm_dh_y + zjm_y1);
139 | u8g2.print(tc1047_temp, 1);
140 | u8g2.drawCircle(zjm_x2 + 21, zjm_dh_y + zjm_y1 - 6, 1, U8G2_DRAW_ALL); //画空心圆
141 | u8g2.setCursor(zjm_x2 + 23, zjm_dh_y + zjm_y1);
142 | u8g2.print("C");
143 |
144 | u8g2.setCursor(zjm_x2, zjm_dh_y + zjm_y2);
145 | u8g2.print(vin, 1);
146 | u8g2.setCursor(zjm_x2 + 22, zjm_dh_y + zjm_y2);
147 | u8g2.print("V");
148 |
149 | u8g2.setCursor(zjm_x2, zjm_dh_y + zjm_y3);
150 | u8g2.print(pid_out_bfb);
151 | u8g2.setCursor(zjm_x2 + 20, zjm_dh_y + zjm_y3);
152 | u8g2.print("%");
153 |
154 | //u8g2.setCursor(70, 27);
155 | //u8g2.print(t12_ad,0);
156 |
157 | //u8g2.setCursor(45, 27);
158 | //u8g2.print(sleep_count);
159 | //u8g2.setCursor(65, 27);
160 | //u8g2.print(xp_time_count);
161 |
162 | /*u8g2.setCursor(55, 13);
163 | u8g2.print(sleep_MsTimer2_state);*/
164 |
165 | //u8g2.setCursor(50, 27);
166 | //u8g2.print(pid_out);
167 |
168 | //u8g2.setCursor(0, 29);
169 | //u8g2.print(t12_temp_read_time);
170 |
171 | //u8g2.setCursor(0, 29);
172 | //u8g2.print(analogRead(tc1047_pin));
173 | }
174 | void zjm_error1() //主界面 电压电流报警 提示
175 | {
176 | u8g2.setFont(chinese_t12);
177 | if (vin_error == 1)
178 | {
179 | u8g2.setCursor(95, zjm_dh_y + 13);
180 | u8g2.print("电 压");
181 | u8g2.setCursor(95, zjm_dh_y + 29);
182 | u8g2.print("过 低");
183 | }
184 | u8g2.setDrawColor(2);
185 | u8g2.drawBox(95 - 2, zjm_dh_y + 0, 40, 32); //实心方形
186 | u8g2.setDrawColor(1);
187 | }
188 | void zjm_error2() //主界面 温度超出测量范围 错误提示
189 | {
190 | u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
191 | u8g2.setCursor(12, zjm_dh_y + 8);
192 | u8g2.print("T12 ADC");
193 | u8g2.setCursor(23, zjm_dh_y + 17);
194 | u8g2.print("HIGH");
195 | u8g2.setDrawColor(2);
196 | u8g2.drawBox(0, zjm_dh_y + 0, 61, 18); //实心方形
197 | u8g2.setDrawColor(1);
198 | }
199 | void zjm_error3() //主界面 手柄未接显示界面 错误提示
200 | {
201 | u8g2.setFont(chinese_t12);
202 | u8g2.setCursor(5, zjm_dh_y + 14);
203 | u8g2.print("手柄未接");
204 |
205 | u8g2.setDrawColor(2);
206 | u8g2.drawBox(0, zjm_dh_y + 0, 61, 18); //实心方形
207 | u8g2.setDrawColor(1);
208 | }
209 |
--------------------------------------------------------------------------------
/v1.20.1/DisplaySet.ino:
--------------------------------------------------------------------------------
1 | //********** 画设置主界面及其他界面 **********
2 | #define szjm_y1 21
3 | int16_t szjm_dh_x[6] = {0, 50, 100, 150, 200, 250};
4 | int16_t szjm_dh_x_count = 0; //设置界面动画x增量记录
5 |
6 | #define szjm_dh_bc 5 //变化步长,只能为5的倍数
7 | void szjm()
8 | {
9 | //画十字坐标
10 | //u8g2.drawHLine(0, 15, 128);
11 | //u8g2.drawVLine(63, 0, 32);
12 | //********** 线性滚动动画
13 | if (szjm_kxxk_L == 1) //顺时针滚动
14 | {
15 | szjm_dh_x_count += szjm_dh_bc; //记录变化次数
16 | for (uint8_t i = 0; i < 6; i++) //开始变化
17 | {
18 | szjm_dh_x[i] += szjm_dh_bc; //步长5
19 | }
20 | for (uint8_t i = 0; i < 6; i++) //数值限制
21 | {
22 | if (szjm_dh_x[i] > 250)szjm_dh_x[i] = -45;
23 | }
24 | if (szjm_dh_x_count >= 50) //变化完毕
25 | {
26 | szjm_kxxk_L = 0; //释放状态
27 | szjm_dh_x_count = 0; //变化次数清零
28 | if (szjm_kxxk_count >= 6) szjm_kxxk_count = 0; //数值限制
29 | }
30 | }
31 | else if (szjm_kxxk_R == 1) //逆时针滚动
32 | {
33 | szjm_dh_x_count -= szjm_dh_bc; //记录变化次数
34 | for (uint8_t i = 0; i < 6; i++) //开始变化
35 | {
36 | szjm_dh_x[i] -= szjm_dh_bc; //步长5
37 | }
38 | for (uint8_t i = 0; i < 6; i++) //数值限制
39 | {
40 | if (szjm_dh_x[i] < -150)szjm_dh_x[i] = 145;
41 | }
42 | if (szjm_dh_x_count <= -50) //变化完毕
43 | {
44 | szjm_kxxk_R = 0; //释放状态
45 | szjm_dh_x_count = 0; //变化次数清零
46 | if (szjm_kxxk_count <= -6) szjm_kxxk_count = 0; //数值限制
47 | }
48 | }
49 | //**************************************************
50 | //********** 画文字和框框
51 | //调试信息显示
52 | //u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
53 | //u8g2.setCursor(0, 31);
54 | //u8g2.print(szjm_dh_x_count);
55 | //u8g2.setCursor(100, 31);
56 | //u8g2.print(szjm_kxxk_count);
57 | //u8g2.setCursor(50, 31);
58 | //u8g2.print(szjm_dh_x[0]);
59 |
60 | u8g2.setFont(chinese_t12);
61 | if (szjm_dh_x[0] >= -50 && szjm_dh_x[0] <= 150)
62 | {
63 | u8g2.setCursor(szjm_dh_x[0], szjm_y1);
64 | u8g2.print("PID");
65 | }
66 | if (szjm_dh_x[1] >= -50 && szjm_dh_x[1] <= 150)
67 | {
68 | u8g2.setCursor(szjm_dh_x[1], szjm_y1);
69 | u8g2.print("休眠");
70 | }
71 | if (szjm_dh_x[2] >= -50 && szjm_dh_x[2] <= 150)
72 | {
73 | u8g2.setCursor(szjm_dh_x[2], szjm_y1);
74 | u8g2.print("屏幕");
75 | }
76 | if (szjm_dh_x[3] >= -50 && szjm_dh_x[3] <= 150)
77 | {
78 | u8g2.setCursor(szjm_dh_x[3], szjm_y1);
79 | u8g2.print("电源");
80 | }
81 | if (szjm_dh_x[4] >= -50 && szjm_dh_x[4] <= 150)
82 | {
83 | u8g2.setCursor(szjm_dh_x[4], szjm_y1);
84 | u8g2.print("校准");
85 | }
86 | if (szjm_dh_x[5] >= -50 && szjm_dh_x[5] <= 150)
87 | {
88 | u8g2.setCursor(szjm_dh_x[5], szjm_y1);
89 | u8g2.print("烙铁");
90 | }
91 | u8g2.setDrawColor(2);
92 | u8g2.drawRBox(43, 6, 40, 20, 1); //空心圆角方形
93 | u8g2.setDrawColor(1);
94 | }
95 |
96 | //********** PID设置界面 **********
97 | #define szjm_pid_x1 2
98 | #define szjm_pid_x2 14
99 |
100 | #define szjm_pid_x3 82
101 | #define szjm_pid_x4 94
102 |
103 | #define szjm_pid_y1 14
104 | #define szjm_pid_y2 29
105 | void szjm_pid()
106 | {
107 | u8g2.setCursor(szjm_pid_x1, szjm_pid_y1);
108 | u8g2.print("P");
109 | u8g2.setCursor(szjm_pid_x2, szjm_pid_y1);
110 | u8g2.print(p, 1);
111 |
112 | u8g2.setCursor(szjm_pid_x3, szjm_pid_y1);
113 | u8g2.print("I");
114 | u8g2.setCursor(szjm_pid_x4, szjm_pid_y1);
115 | u8g2.print(i, 1);
116 |
117 | u8g2.setCursor(szjm_pid_x1, szjm_pid_y2);
118 | u8g2.print("D");
119 | u8g2.setCursor(szjm_pid_x2, szjm_pid_y2);
120 | u8g2.print(d, 1);
121 |
122 | //画选框
123 | switch (szjm_pid_kxxk_count) //空心选框的位置
124 | {
125 | case 1: //p
126 | if (szjm_pid_sxxk_count == szjm_pid_kxxk_count)
127 | {
128 | u8g2.setDrawColor(2);
129 | u8g2.drawBox(szjm_pid_x1 - 2, szjm_pid_y1 - 13, 48, 16); //实心方形
130 | //画水平线,标识进入小数点模式
131 | if (dec_state == 1) u8g2.drawHLine(szjm_pid_x2 + 4 + (get_num_digit(p) * 6), szjm_pid_y1 + 1, 10);
132 | u8g2.setDrawColor(1);
133 | }
134 | else u8g2.drawFrame(szjm_pid_x1 - 2, szjm_pid_y1 - 13, 48, 16); //空心方形
135 | break;
136 | case 2: //i
137 | if (szjm_pid_sxxk_count == szjm_pid_kxxk_count)
138 | {
139 | u8g2.setDrawColor(2);
140 | u8g2.drawBox(szjm_pid_x3 - 2, szjm_pid_y1 - 13, 48, 16); //实心方形
141 | //画水平线,标识进入小数点模式
142 | if (dec_state == 1) u8g2.drawHLine(szjm_pid_x4 + 4 + (get_num_digit(i) * 6), szjm_pid_y1 + 1, 10);
143 | u8g2.setDrawColor(1);
144 | }
145 | else u8g2.drawFrame(szjm_pid_x3 - 2, szjm_pid_y1 - 13, 48, 16); //空心方形
146 | break;
147 | case 3: //d
148 | if (szjm_pid_sxxk_count == szjm_pid_kxxk_count)
149 | {
150 | u8g2.setDrawColor(2);
151 | u8g2.drawBox(szjm_pid_x1 - 2, szjm_pid_y2 - 13, 48, 16); //实心方形
152 | //画水平线,标识进入小数点模式
153 | if (dec_state == 1) u8g2.drawHLine(szjm_pid_x2 + 4 + (get_num_digit(d) * 6), szjm_pid_y2 + 1, 10);
154 | u8g2.setDrawColor(1);
155 | }
156 | else u8g2.drawFrame(szjm_pid_x1 - 2, szjm_pid_y2 - 13, 48, 16); //空心方形
157 | break;
158 | }
159 | }
160 |
161 | //********** 休眠设置界面 **********
162 | #define szjm_sleep_x1 2
163 | #define szjm_sleep_x2 105
164 | #define szjm_sleep_y1 14
165 | #define szjm_sleep_y2 29
166 | void szjm_sleep()
167 | {
168 | u8g2.setCursor(szjm_sleep_x1, szjm_sleep_y1);
169 | u8g2.print("休眠时间 S");
170 | u8g2.setCursor(szjm_sleep_x2, szjm_sleep_y1);
171 | if (sleep_time != 999)u8g2.print(sleep_time);
172 | else u8g2.print("关");
173 |
174 | u8g2.setCursor(szjm_sleep_x1, szjm_sleep_y2);
175 | u8g2.print("休眠温度 ℃");
176 | u8g2.setCursor(szjm_sleep_x2, szjm_sleep_y2);
177 | u8g2.print(sleep_temp);
178 |
179 | //画选框
180 | switch (szjm_sleep_kxxk_count) //空心选框的位置
181 | {
182 | case 1: //设置温度
183 | if (szjm_sleep_sxxk_count == szjm_sleep_kxxk_count)
184 | {
185 | u8g2.setDrawColor(2);
186 | u8g2.drawBox(szjm_sleep_x1 - 2, szjm_sleep_y1 - 13, 128, 16); //实心方形
187 | u8g2.setDrawColor(1);
188 | }
189 | else u8g2.drawFrame(szjm_sleep_x1 - 2, szjm_sleep_y1 - 13, 128, 16); //空心方形
190 | break;
191 | case 2: //设置温度
192 | if (szjm_sleep_sxxk_count == szjm_sleep_kxxk_count)
193 | {
194 | u8g2.setDrawColor(2);
195 | u8g2.drawBox(szjm_sleep_x1 - 2, szjm_sleep_y2 - 13, 128, 16); //实心方形
196 | u8g2.setDrawColor(1);
197 | }
198 | else u8g2.drawFrame(szjm_sleep_x1 - 2, szjm_sleep_y2 - 13, 128, 16); //空心方形
199 | break;
200 | }
201 | }
202 |
203 | //********** OLED亮度设置界面 **********
204 | #define szjm_oled_x1 2
205 | #define szjm_oled_x2 106
206 | #define szjm_oled_x3 86
207 | #define szjm_oled_y1 14
208 | #define szjm_oled_y2 29
209 | void szjm_oled()
210 | {
211 | if (szjm_oled_kxxk_count == 3) //第2页
212 | {
213 | u8g2.setCursor(szjm_oled_x1, szjm_oled_y1);
214 | u8g2.print("旋转方向");
215 | u8g2.setCursor(szjm_oled_x3, szjm_oled_y1);
216 | if (xzbmq_fx == 0) u8g2.print("顺+逆-");
217 | else u8g2.print("顺-逆+");
218 | }
219 | else //第1页
220 | {
221 | u8g2.setCursor(szjm_oled_x1, szjm_oled_y1);
222 | u8g2.print("屏幕亮度");
223 | u8g2.setCursor(szjm_oled_x2, szjm_oled_y1);
224 | u8g2.print(oled_ld);
225 |
226 | u8g2.setCursor(szjm_oled_x1, szjm_oled_y2);
227 | u8g2.print("屏幕方向");
228 | u8g2.setCursor(szjm_oled_x2, szjm_oled_y2);
229 | if (oled_fx == 0) u8g2.print("0");
230 | else u8g2.print("180");
231 | }
232 | //画选框
233 | switch (szjm_oled_kxxk_count) //空心选框的位置
234 | {
235 | case 1: //OLED亮度
236 | if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
237 | {
238 | u8g2.setDrawColor(2);
239 | u8g2.drawBox(szjm_oled_x1 - 2, szjm_oled_y1 - 13, 128, 16); //实心方形
240 | u8g2.setDrawColor(1);
241 | }
242 | else u8g2.drawFrame(szjm_oled_x1 - 2, szjm_oled_y1 - 13, 128, 16); //空心方形
243 | break;
244 | case 2: //OLED方向
245 | if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
246 | {
247 | u8g2.setDrawColor(2);
248 | u8g2.drawBox(szjm_oled_x1 - 2, szjm_oled_y2 - 13, 128, 16); //实心方形
249 | u8g2.setDrawColor(1);
250 | }
251 | else u8g2.drawFrame(szjm_oled_x1 - 2, szjm_oled_y2 - 13, 128, 16); //空心方形
252 | break;
253 | case 3: //旋转方向
254 | u8g2.drawFrame(szjm_oled_x1 - 2, szjm_oled_y1 - 13, 128, 16); //空心方形
255 | break;
256 | }
257 | }
258 |
259 | //********** 电源设置界面 **********
260 | #define szjm_power_x1 2
261 | #define szjm_power_x2 100
262 | #define szjm_power_y1 14
263 | #define szjm_power_y2 29
264 | void szjm_power()
265 | {
266 | if (szjm_power_kxxk_count == 3) //第2页
267 | {
268 | u8g2.setCursor(szjm_power_x1, szjm_power_y1);
269 | u8g2.print("低压报警 V");
270 | u8g2.setCursor(szjm_power_x2, szjm_power_y1);
271 | if (vin_low >= 3.3) u8g2.print(vin_low, 1);
272 | else if (vin_low < 3.3) u8g2.print("关");
273 | }
274 | else //第1页
275 | {
276 | u8g2.setCursor(szjm_power_x1, szjm_power_y1);
277 | u8g2.print("基准电压 V");
278 | u8g2.setCursor(szjm_power_x2, szjm_power_y1);
279 | u8g2.print(vcc_refer);
280 | u8g2.setCursor(szjm_power_x1, szjm_power_y2);
281 | u8g2.print("电源电压 V");
282 | if (vin_refer >= 0)
283 | {
284 | u8g2.setCursor(szjm_power_x2 - 8, szjm_power_y2);
285 | u8g2.print("+");
286 | u8g2.setCursor(szjm_power_x2, szjm_power_y2);
287 | u8g2.print(vin_refer);
288 | }
289 | else
290 | {
291 | u8g2.setCursor(szjm_power_x2 - 6, szjm_power_y2);
292 | u8g2.print(vin_refer);
293 | }
294 | }
295 | //画选框
296 | switch (szjm_power_kxxk_count) //空心选框的位置
297 | {
298 | case 1: //基准电压(V)
299 | if (szjm_power_sxxk_count == szjm_power_kxxk_count)
300 | {
301 | u8g2.setDrawColor(2);
302 | u8g2.drawBox(szjm_power_x1 - 2, szjm_power_y1 - 13, 128, 16); //实心方形
303 | u8g2.setDrawColor(1);
304 | }
305 | else u8g2.drawFrame(szjm_power_x1 - 2, szjm_power_y1 - 13, 128, 16); //空心方形
306 | break;
307 | case 2: //基准电压(V)
308 | if (szjm_power_sxxk_count == szjm_power_kxxk_count)
309 | {
310 | u8g2.setDrawColor(2);
311 | u8g2.drawBox(szjm_power_x1 - 2, szjm_power_y2 - 13, 128, 16); //实心方形
312 | u8g2.setDrawColor(1);
313 | }
314 | else u8g2.drawFrame(szjm_power_x1 - 2, szjm_power_y2 - 13, 128, 16); //空心方形
315 | break;
316 | case 3: //电源电压(V)
317 | if (szjm_power_sxxk_count == szjm_power_kxxk_count)
318 | {
319 | u8g2.setDrawColor(2);
320 | u8g2.drawBox(szjm_power_x1 - 2, szjm_power_y1 - 13, 128, 16); //实心方形
321 | u8g2.setDrawColor(1);
322 | }
323 | else u8g2.drawFrame(szjm_power_x1 - 2, szjm_power_y1 - 13, 128, 16); //空心方形
324 | break;
325 | }
326 | }
327 | //********** 烙铁设置界面 **********
328 | #define szjm_laotie_x1 2
329 | #define szjm_laotie_x4 105
330 |
331 | #define szjm_laotie_y1 14
332 | #define szjm_laotie_y2 29
333 |
334 | void szjm_laotie()
335 | {
336 |
337 | if (szjm_laotie_kxxk_count == 3) //第2页
338 | {
339 | u8g2.setCursor(szjm_laotie_x1, szjm_laotie_y1);
340 | u8g2.print("重置");
341 | u8g2.setCursor(szjm_laotie_x4, szjm_laotie_y1);
342 | if (hfccsz_state) u8g2.print("是");
343 | else u8g2.print("否");
344 | }
345 | else //第1页
346 | {
347 | u8g2.setCursor(szjm_laotie_x1, szjm_laotie_y1);
348 | u8g2.print("冷端补偿 ℃");
349 | if (tc1047_refer <= -10) u8g2.setCursor(szjm_laotie_x4, szjm_laotie_y1);
350 | else u8g2.setCursor(szjm_laotie_x4, szjm_laotie_y1);
351 | u8g2.print(tc1047_refer);
352 |
353 | u8g2.setCursor(szjm_laotie_x1, szjm_laotie_y2);
354 | u8g2.print("开机加热");
355 | u8g2.setCursor(szjm_laotie_x4, szjm_laotie_y2);
356 | if (t12_kj_jr) u8g2.print("是");
357 | else u8g2.print("否");
358 | }
359 |
360 | //画选框
361 | switch (szjm_laotie_kxxk_count) //空心选框的位置
362 | {
363 | case 1: //冷端补偿
364 | if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
365 | {
366 | u8g2.setDrawColor(2);
367 | u8g2.drawBox(szjm_laotie_x1 - 2, szjm_laotie_y1 - 13, 128, 16); //实心方形
368 | u8g2.setDrawColor(1);
369 | }
370 | else u8g2.drawFrame(szjm_laotie_x1 - 2, szjm_laotie_y1 - 13, 128, 16); //空心方形
371 | break;
372 | case 2: //开机加热
373 | u8g2.drawFrame(szjm_laotie_x1 - 2, szjm_laotie_y2 - 13, 128, 16); //空心方形
374 | break;
375 | case 3: //恢复出厂设置
376 | if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
377 | {
378 | u8g2.setDrawColor(2);
379 | u8g2.drawBox(szjm_laotie_x1 - 2, szjm_laotie_y1 - 13, 128, 16); //实心方形
380 | u8g2.setDrawColor(1);
381 | }
382 | else u8g2.drawFrame(szjm_laotie_x1 - 2, szjm_laotie_y1 - 13, 128, 16); //空心方形
383 | break;
384 | }
385 | }
386 | //********** 校准设置界面 **********
387 | #define szjm_jiaozhun_x1 0
388 |
389 | #define szjm_jiaozhun_x2 30
390 | #define szjm_jiaozhun_x3 54
391 | #define szjm_jiaozhun_x4 80
392 | #define szjm_jiaozhun_x5 106
393 |
394 | #define szjm_jiaozhun_x6 102
395 |
396 | #define szjm_jiaozhun_y1 7
397 | #define szjm_jiaozhun_y2 18
398 | #define szjm_jiaozhun_y3 31
399 | void szjm_jiaozhun()
400 | {
401 | u8g2.setFont(u8g2_font_lucasfont_alternate_tr);
402 | if (szjm_jiaozhun_kxxk_count == 6)
403 | {
404 | u8g2.setCursor(0, 7);
405 | u8g2.print("P0:");
406 | u8g2.setCursor(25, 7);
407 | u8g2.print(sz_p[0], 10);
408 |
409 | u8g2.setCursor(0, 15);
410 | u8g2.print("P1:");
411 | u8g2.setCursor(25, 15);
412 | u8g2.print(sz_p[1], 10);
413 |
414 | u8g2.setCursor(0, 24);
415 | u8g2.print("P2:");
416 | u8g2.setCursor(25, 24);
417 | u8g2.print(sz_p[2], 10);
418 |
419 | u8g2.setCursor(0, 32);
420 | u8g2.print("P3:");
421 | u8g2.setCursor(25, 32);
422 | u8g2.print(sz_p[3], 10);
423 | }
424 | else
425 | {
426 | u8g2.setCursor(szjm_jiaozhun_x1, szjm_jiaozhun_y1);
427 | u8g2.print("ADC 10 350 650 950");
428 | u8g2.setCursor(szjm_jiaozhun_x1, szjm_jiaozhun_y2);
429 | u8g2.print("Temp");
430 | u8g2.setCursor(szjm_jiaozhun_x2, szjm_jiaozhun_y2);
431 | u8g2.print(sz_temp[0]);
432 | u8g2.setCursor(szjm_jiaozhun_x3, szjm_jiaozhun_y2);
433 | u8g2.print(sz_temp[1]);
434 | u8g2.setCursor(szjm_jiaozhun_x4, szjm_jiaozhun_y2);
435 | u8g2.print(sz_temp[2]);
436 | u8g2.setCursor(szjm_jiaozhun_x5, szjm_jiaozhun_y2);
437 | u8g2.print(sz_temp[3]);
438 |
439 | u8g2.drawHLine(0, 22, 128);
440 |
441 | u8g2.setCursor(szjm_jiaozhun_x1, szjm_jiaozhun_y3);
442 | u8g2.print("Now ADC:");
443 | u8g2.setCursor(48, szjm_jiaozhun_y3);
444 | u8g2.print(t12_ad, 0);
445 |
446 | u8g2.setCursor(szjm_jiaozhun_x6, szjm_jiaozhun_y3);
447 | u8g2.print("Save");
448 | }
449 | //画选框
450 | switch (szjm_jiaozhun_kxxk_count) //空心选框的位置
451 | {
452 | case 1: //深圳头1段温度
453 | if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
454 | {
455 | u8g2.setDrawColor(2);
456 | u8g2.drawBox(szjm_jiaozhun_x2 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //实心方形
457 | u8g2.setDrawColor(1);
458 | }
459 | else u8g2.drawFrame(szjm_jiaozhun_x2 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //空心方形
460 | break;
461 | case 2: //深圳头2段温度
462 | if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
463 | {
464 | u8g2.setDrawColor(2);
465 | u8g2.drawBox(szjm_jiaozhun_x3 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //实心方形
466 | u8g2.setDrawColor(1);
467 | }
468 | else u8g2.drawFrame(szjm_jiaozhun_x3 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //空心方形
469 | break;
470 | case 3: //深圳头3段温度
471 | if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
472 | {
473 | u8g2.setDrawColor(2);
474 | u8g2.drawBox(szjm_jiaozhun_x4 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //实心方形
475 | u8g2.setDrawColor(1);
476 | }
477 | else u8g2.drawFrame(szjm_jiaozhun_x4 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //空心方形
478 | break;
479 | case 4: //深圳头4段温度
480 | if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
481 | {
482 | u8g2.setDrawColor(2);
483 | u8g2.drawBox(szjm_jiaozhun_x5 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //实心方形
484 | u8g2.setDrawColor(1);
485 | }
486 | else u8g2.drawFrame(szjm_jiaozhun_x5 - 2, szjm_jiaozhun_y2 - 9, 21, 11); //空心方形
487 | break;
488 | case 5: //保存
489 | u8g2.setDrawColor(2);
490 | u8g2.drawBox(szjm_jiaozhun_x6 - 2, szjm_jiaozhun_y3 - 8, 28, 9); //实心方形
491 | u8g2.setDrawColor(1);
492 | break;
493 | }
494 | }
495 |
--------------------------------------------------------------------------------
/v1.20.1/EEPROM.ino:
--------------------------------------------------------------------------------
1 | //******************* 自动刷写eeprom *******************
2 | void eerpom_auto()
3 | {
4 | EEPROM.get(auto_get_eeprom, auto_get); //获取自动刷写的状态
5 | if (auto_get > 1) auto_get = 0; //防止eeprom第0位不为0
6 | if (auto_get == 0) //状态为0开启刷写
7 | {
8 | EEPROM.put(p_eeprom, p); //pid-p
9 | EEPROM.put(i_eeprom, i); //pid-i
10 | EEPROM.put(d_eeprom, d); //pid-d
11 | EEPROM.put(sleep_time_eeprom, sleep_time); //休眠时间
12 | EEPROM.put(sleep_temp_eeprom, sleep_temp); //休眠温度
13 | EEPROM.put(oled_ld_eeprom, oled_ld); //OLED亮度
14 | EEPROM.put(vcc_refer_eeprom, vcc_refer); //基准电压
15 | EEPROM.put(vin_refer_eeprom, vin_refer); //电源电压校准值
16 | EEPROM.put(t12_kj_jr_eeprom, t12_kj_jr); //是否开机就加热
17 | EEPROM.put(vin_low_eeprom, vin_low); //输入电压过底报警阈值
18 | EEPROM.put(tc1047_refer_eeprom, tc1047_refer); //T12环境参考温度校准值
19 | EEPROM.put(oled_fx_eeprom, oled_fx); //OLED方向
20 | EEPROM.put(xzbmq_fx_eeprom, xzbmq_fx); //旋转编码器方向
21 | //写入曲线的4段温度
22 | EEPROM.put(sz_temp0_eeprom, sz_temp[0]);
23 | EEPROM.put(sz_temp1_eeprom, sz_temp[1]);
24 | EEPROM.put(sz_temp2_eeprom, sz_temp[2]);
25 | EEPROM.put(sz_temp3_eeprom, sz_temp[3]);
26 | //写入设置温度
27 | EEPROM.put(set_temp_eeprom, set_temp);
28 | //刷写完,记录auto_get的状态,防止下次开机再次刷写
29 | EEPROM.put(auto_get_eeprom, 1);
30 | auto_get = 1;
31 | }
32 | if (auto_get == 1)//状态为1只读取
33 | {
34 | EEPROM.get(p_eeprom, p); //pid-p
35 | EEPROM.get(i_eeprom, i); //pid-i
36 | EEPROM.get(d_eeprom, d); //pid-d
37 | EEPROM.get(sleep_time_eeprom, sleep_time); //休眠时间
38 | EEPROM.get(sleep_temp_eeprom, sleep_temp); //休眠温度
39 | EEPROM.get(oled_ld_eeprom, oled_ld); //OLED亮度
40 | EEPROM.get(vcc_refer_eeprom, vcc_refer); //基准电压
41 | EEPROM.get(vin_refer_eeprom, vin_refer); //电源电压校准值
42 | EEPROM.get(t12_kj_jr_eeprom, t12_kj_jr); //是否开机就加热
43 | EEPROM.get(vin_low_eeprom, vin_low); //输入电压过底报警阈值
44 | EEPROM.get(tc1047_refer_eeprom, tc1047_refer); //T12环境参考温度校准值
45 | EEPROM.get(oled_fx_eeprom, oled_fx); //OLED方向
46 | EEPROM.get(xzbmq_fx_eeprom, xzbmq_fx); //旋转编码器方向
47 | //获取曲线的4段温度
48 | EEPROM.get(sz_temp0_eeprom, sz_temp[0]);
49 | EEPROM.get(sz_temp1_eeprom, sz_temp[1]);
50 | EEPROM.get(sz_temp2_eeprom, sz_temp[2]);
51 | EEPROM.get(sz_temp3_eeprom, sz_temp[3]);
52 | //获取设置温度
53 | EEPROM.get(set_temp_eeprom, set_temp);
54 | }
55 | }
56 | //******************************************************
57 |
--------------------------------------------------------------------------------
/v1.20.1/InterruptKey.ino:
--------------------------------------------------------------------------------
1 | //********** 编码器按键决策 **********
2 | void xuan_zhaun() //旋转中断 选框决策
3 | {
4 |
5 | /*Serial.print("DT "); Serial.print(digitalRead(DT));
6 | Serial.print(" | ");
7 | Serial.print("CLK "); Serial.print(digitalRead(CLK));
8 | Serial.print(" | ");
9 | Serial.print("SW "); Serial.print(digitalRead(SW));
10 | Serial.println(" ");*/
11 | if ((millis() - xzbmq_time) < 20) return; //旋转响应间隔 20ms
12 | buzzer(100, 70); //时间,次数
13 | if (display_count == ZJM)
14 | {
15 | zjm_xz_key();
16 | buzzer_temp_average_state = 0; //准备好到达温度提示声
17 | sleep_count = 0; //休眠计数归零
18 | zjm_sleep_ts = 0; //提示主界面退出显示休眠状态
19 | t12_adc_error = 0; //清除温度超出测量范围提示
20 | xp_state = 0; //结束息屏
21 | xp_time_count = 0; //清除息屏计数
22 | xp_time_count_old = 0; //清除息屏计数旧
23 | }
24 | else if (display_count == SZJM) szjm_xz_key();
25 | else if (display_count == SZJM_PID) pid_xz_key();
26 | else if (display_count == SZJM_SLEEP) sleep_xz_key();
27 | else if (display_count == SZJM_OLED) oled_xz_key();
28 | else if (display_count == SZJM_POWER) power_xz_key();
29 | else if (display_count == SZJM_LAOTIE) laotie_xz_key();
30 | else if (display_count == SZJM_JIAOZHUN) jiaozhun_xz_key();
31 | xzbmq_time = millis();
32 | }
33 |
34 | void an_xia() //按下
35 | {
36 | if ((millis() - xzbmq_time) < 160) return;
37 | qj_sw_key(); //全局长按进入设置界面 或 退出至主界面
38 | }
39 | //************************ 全局长按进入设置界面 或 退出至主界面 ************************
40 | void qj_sw_key() //全局长按计数
41 | {
42 | //长按计数增加
43 | if (digitalRead(SW) == 0)
44 | {
45 | qj_ca_count++; //计数加一
46 | buzzer(80, 150); //时间,次数
47 |
48 | if (display_count == ZJM) t12_adc_error = 0; //清除温度超出测量范围提示
49 | xp_state = 0; //结束息屏
50 | xp_time_count = 0; //清除息屏计数
51 | xp_time_count_old = 0; //清除息屏计数旧
52 |
53 | xzbmq_time = millis();
54 | }
55 | //判断按了几次 该做些什么
56 | if (qj_ca_count >= 5) //进入设置界面
57 | {
58 | if (display_count == ZJM)
59 | {
60 | display_count = SZJM; //在主界面时进入设置界面
61 | buzzer_szjm_state = 1;
62 | }
63 | else if (display_count != SZJM_JIAOZHUN)
64 | {
65 | display_count = ZJM; //在其他界面是退出至主界面
66 | buzzer_zjm_state = 1;
67 | }
68 | qj_ca_count = 0; //计数清零
69 | }
70 | else if ((millis() - xzbmq_time) > 260) //等待一段时间,确定松手了
71 | {
72 | //在主界面的按下决策
73 | if (display_count == ZJM) zjm_sw_key();
74 | //在设置界面的按下决策
75 | else if (display_count == SZJM) szjm_sw_key();
76 | //在PID界面的按下决策
77 | else if (display_count == SZJM_PID) pid_sw_key();
78 | //在休眠界面的按下决策
79 | else if (display_count == SZJM_SLEEP) sleep_sw_key();
80 | //在OLED亮度界面的按下决策
81 | else if (display_count == SZJM_OLED) oled_sw_key();
82 | //在电源校准界面的按下决策
83 | else if (display_count == SZJM_POWER) power_sw_key();
84 | //在烙铁界面的按下决策
85 | else if (display_count == SZJM_LAOTIE) laotie_sw_key();
86 | //在校准界面的按下决策
87 | else if (display_count == SZJM_JIAOZHUN) jiaozhun_sw_key();
88 | qj_ca_count = 0;//计数清零
89 | }
90 | }
91 | //************************ 主界面 ************************
92 | void zjm_sw_key()
93 | {
94 | if (qj_ca_count == 2 && vin_error == 0 && t12_error == 0) // 启动或停止加热
95 | {
96 | zjm_dh_run = 1; //允许播放动画 ,动画播放完在DisplayMain里切换T12工作状态
97 | zjm_sleep_ts = 0; //提示主界面退出显示休眠状态
98 | buzzer_temp_average_state = 0; //准备好到达温度提示声
99 | }
100 | }
101 | void zjm_xz_key() //主界面 旋转
102 | {
103 | if (digitalRead(DT) == xzbmq_fx) set_temp += 10;
104 | else if (digitalRead(CLK) == xzbmq_fx) set_temp -= 10;
105 | auto_get_set_temp();//自动获取设置温度的范围
106 | if (set_temp > set_temp_max) set_temp = set_temp_min;
107 | else if (set_temp < set_temp_min) set_temp = set_temp_max;
108 | }
109 | //************************ 设置界面 ************************
110 | void szjm_sw_key() //设置界面 按下
111 | {
112 | if (qj_ca_count == 1) //进入二级菜单
113 | {
114 | if (szjm_kxxk_count == 0) display_count = SZJM_SLEEP; //进入休眠设置菜单
115 | else if (szjm_kxxk_count == -5 || szjm_kxxk_count == 1) display_count = SZJM_PID; //进入PID设置菜单
116 | else if (szjm_kxxk_count == -1 || szjm_kxxk_count == 5) display_count = SZJM_OLED; //进入OELD亮度设置菜单
117 | else if (szjm_kxxk_count == -2 || szjm_kxxk_count == 4) display_count = SZJM_POWER; //进入电源设置菜单
118 | else if (szjm_kxxk_count == -4 || szjm_kxxk_count == 2) display_count = SZJM_LAOTIE;//进入烙铁设置菜单
119 | else if (szjm_kxxk_count == -3 || szjm_kxxk_count == 3)
120 | {
121 | //使用比较柔和的pid参数,退出校准界面时记得恢复正常的PID策略
122 | p = p_jz; //比例系数
123 | i = i_jz; //积分系数
124 | d = d_jz; //微分系数
125 | display_count = SZJM_JIAOZHUN;//进入烙铁设置菜单
126 | }
127 | }
128 | }
129 | void szjm_xz_key() //设置界面 旋转
130 | {
131 | if (digitalRead(DT) == xzbmq_fx)
132 | {
133 | if (szjm_kxxk_L == 0 && szjm_kxxk_R == 0) //顺时针
134 | {
135 | szjm_kxxk_L = 1; //允许播放动画
136 | szjm_kxxk_count++; //下一项
137 | }
138 | }
139 | else if (digitalRead(CLK) == xzbmq_fx)
140 | {
141 | if (szjm_kxxk_L == 0 && szjm_kxxk_R == 0) //逆时针
142 | {
143 | szjm_kxxk_R = 1; //允许播放动画
144 | szjm_kxxk_count--; //上一项
145 | }
146 | }
147 | }
148 | //************************ PID设置界面 ************************
149 | void pid_sw_key() //设置界面 按下
150 | {
151 | if (qj_ca_count == 1) //返回或进入调节框
152 | {
153 | switch (szjm_pid_kxxk_count)
154 | {
155 | case 0: //返回至设置界面
156 | display_count = SZJM;
157 | break;
158 | case 1: //p 存储
159 | if (szjm_pid_sxxk_count == 0) szjm_pid_sxxk_count = szjm_pid_kxxk_count;
160 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 0) dec_state = 1;
161 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 1)
162 | {
163 | EEPROM.put(p_eeprom, p);
164 | dec_state = 0;
165 | szjm_pid_sxxk_count = 0;
166 | }
167 | break;
168 | case 2: //i 存储
169 | if (szjm_pid_sxxk_count == 0) szjm_pid_sxxk_count = szjm_pid_kxxk_count;
170 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 0) dec_state = 1;
171 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 1)
172 | {
173 | EEPROM.put(i_eeprom, i);
174 | dec_state = 0;
175 | szjm_pid_sxxk_count = 0;
176 | }
177 | break;
178 | case 3: //d 存储
179 | if (szjm_pid_sxxk_count == 0) szjm_pid_sxxk_count = szjm_pid_kxxk_count;
180 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 0) dec_state = 1;
181 | else if (szjm_pid_sxxk_count == szjm_pid_kxxk_count && dec_state == 1)
182 | {
183 | EEPROM.put(d_eeprom, d);
184 | dec_state = 0;
185 | szjm_pid_sxxk_count = 0;
186 | }
187 | break;
188 | }
189 | }
190 | }
191 | void pid_xz_key() //设置界面 旋转
192 | {
193 | if (szjm_pid_sxxk_count == 0) //选框移动
194 | {
195 | if (digitalRead(DT) == xzbmq_fx) szjm_pid_kxxk_count++;
196 | else if (digitalRead(CLK) == xzbmq_fx) szjm_pid_kxxk_count--;
197 | }
198 | else if (szjm_pid_sxxk_count == 1) //p加减
199 | {
200 | if (digitalRead(DT) == xzbmq_fx && dec_state == 0) p += 1;
201 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 0) p -= 1;
202 | else if (digitalRead(DT) == xzbmq_fx && dec_state == 1) p += 0.1;
203 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 1) p -= 0.1;
204 | }
205 | else if (szjm_pid_sxxk_count == 2) //i加减
206 | {
207 | if (digitalRead(DT) == xzbmq_fx && dec_state == 0) i += 1;
208 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 0) i -= 1;
209 | else if (digitalRead(DT) == xzbmq_fx && dec_state == 1) i += 0.1;
210 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 1) i -= 0.1;
211 | }
212 | else if (szjm_pid_sxxk_count == 3) //d加减
213 | {
214 | if (digitalRead(DT) == xzbmq_fx && dec_state == 0) d += 1;
215 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 0) d -= 1;
216 | else if (digitalRead(DT) == xzbmq_fx && dec_state == 1) d += 0.1;
217 | else if (digitalRead(CLK) == xzbmq_fx && dec_state == 1) d -= 0.1;
218 | }
219 | if (szjm_pid_kxxk_count > 3) szjm_pid_kxxk_count = 0;
220 | else if (szjm_pid_kxxk_count < 0) szjm_pid_kxxk_count = 3;
221 | }
222 | //************************ 休眠设置界面 ************************
223 | void sleep_sw_key() //设置界面 按下
224 | {
225 | if (qj_ca_count == 1) //返回或进入调节框
226 | {
227 | switch (szjm_sleep_kxxk_count)
228 | {
229 | case 0: //返回至设置界面
230 | display_count = SZJM;
231 | break;
232 | case 1: //休眠时间 存储
233 | if (szjm_sleep_sxxk_count == 0) szjm_sleep_sxxk_count = szjm_sleep_kxxk_count;
234 | else if (szjm_sleep_sxxk_count == szjm_sleep_kxxk_count)
235 | {
236 | EEPROM.put(sleep_time_eeprom, sleep_time); //休眠时间
237 | szjm_sleep_sxxk_count = 0;
238 | }
239 | break;
240 | case 2: //休眠温度 存储
241 | if (szjm_sleep_sxxk_count == 0) szjm_sleep_sxxk_count = szjm_sleep_kxxk_count;
242 | else if (szjm_sleep_sxxk_count == szjm_sleep_kxxk_count)
243 | {
244 | EEPROM.put(sleep_temp_eeprom, sleep_temp); //休眠温度
245 | szjm_sleep_sxxk_count = 0;
246 | }
247 | break;
248 | }
249 | }
250 | }
251 | void sleep_xz_key() //设置界面 旋转
252 | {
253 | if (szjm_sleep_sxxk_count == 0) //选框移动
254 | {
255 | if (digitalRead(DT) == xzbmq_fx) szjm_sleep_kxxk_count++;
256 | else if (digitalRead(CLK) == xzbmq_fx) szjm_sleep_kxxk_count--;
257 | }
258 | else if (szjm_sleep_sxxk_count == 1) //休眠时间加减
259 | {
260 | if (digitalRead(DT) == xzbmq_fx) sleep_time += 30;
261 | else if (digitalRead(CLK) == xzbmq_fx) sleep_time -= 30;
262 | }
263 | else if (szjm_sleep_sxxk_count == 2) //休眠温度加减
264 | {
265 | if (digitalRead(DT) == xzbmq_fx) sleep_temp += 1;
266 | else if (digitalRead(CLK) == xzbmq_fx) sleep_temp -= 1;
267 | }
268 | if (szjm_sleep_kxxk_count > 2) szjm_sleep_kxxk_count = 0;
269 | else if (szjm_sleep_kxxk_count < 0) szjm_sleep_kxxk_count = 2;
270 | else if (sleep_time > 999) sleep_time = 30;
271 | else if (sleep_time < 30) sleep_time = 999;
272 | }
273 | //************************ OLED亮度设置界面 ************************
274 | void oled_sw_key() //设置界面 按下
275 | {
276 | if (qj_ca_count == 1) //返回或进入调节框
277 | {
278 | switch (szjm_oled_kxxk_count)
279 | {
280 | case 0: //返回至设置界面
281 | display_count = SZJM;
282 | break;
283 | case 1: //OLED亮度 存储
284 | if (szjm_oled_sxxk_count == 0) szjm_oled_sxxk_count = szjm_oled_kxxk_count;
285 | else if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
286 | {
287 | EEPROM.put(oled_ld_eeprom, oled_ld); //OLED亮度
288 | szjm_oled_sxxk_count = 0;
289 | }
290 | break;
291 | case 2: //OLED亮度 存储
292 | if (szjm_oled_sxxk_count == 0) szjm_oled_sxxk_count = szjm_oled_kxxk_count;
293 | else if (szjm_oled_sxxk_count == szjm_oled_kxxk_count)
294 | {
295 | EEPROM.put(oled_fx_eeprom, oled_fx); //OLED方向
296 | if (oled_fx == 1)u8g2.setDisplayRotation(U8G2_R2); //旋转180度
297 | else u8g2.setDisplayRotation(U8G2_R0); //0度,默认方向
298 | szjm_oled_sxxk_count = 0;
299 | }
300 | break;
301 | case 3: //旋转编码器方向 存储
302 | if (szjm_oled_sxxk_count == 0)
303 | {
304 | xzbmq_fx = !xzbmq_fx;
305 | EEPROM.put(xzbmq_fx_eeprom, xzbmq_fx); //OLED方向
306 | EEPROM.get(xzbmq_fx_eeprom, xzbmq_fx); //OLED方向
307 | }
308 | break;
309 | }
310 | }
311 | }
312 |
313 | void oled_xz_key() //设置界面 旋转
314 | {
315 | if (szjm_oled_sxxk_count == 0) //选框移动
316 | {
317 | if (digitalRead(DT) == xzbmq_fx) szjm_oled_kxxk_count++;
318 | else if (digitalRead(CLK) == xzbmq_fx) szjm_oled_kxxk_count--;
319 | if (szjm_oled_kxxk_count > 3) szjm_oled_kxxk_count = 0;
320 | else if (szjm_oled_kxxk_count < 0) szjm_oled_kxxk_count = 3;
321 | }
322 | else if (szjm_oled_sxxk_count == 1) //OLED亮度 加减
323 | {
324 | if (digitalRead(DT) == xzbmq_fx) oled_ld += 5;
325 | else if (digitalRead(CLK) == xzbmq_fx) oled_ld -= 5;
326 | if (oled_ld > 1 && oled_ld < 5) oled_ld = 5;
327 | else if (oled_ld == 0)oled_ld = 255;
328 | }
329 | else if (szjm_oled_sxxk_count == 2) //OLED方向 状态切换
330 | {
331 | if (digitalRead(DT) == xzbmq_fx) oled_fx = !oled_fx;
332 | else if (digitalRead(CLK) == xzbmq_fx) oled_fx = !oled_fx;
333 | }
334 | }
335 | //************************ 电源校准界面 ************************
336 | void power_sw_key() //设置界面 按下
337 | {
338 | if (qj_ca_count == 1) //返回或进入调节框
339 | {
340 | switch (szjm_power_kxxk_count)
341 | {
342 | case 0: //返回至设置界面
343 | display_count = SZJM;
344 | break;
345 | case 1: //基准电压 存储
346 | if (szjm_power_sxxk_count == 0) szjm_power_sxxk_count = szjm_power_kxxk_count;
347 | else if (szjm_power_sxxk_count == szjm_power_kxxk_count)
348 | {
349 | EEPROM.put(vcc_refer_eeprom, vcc_refer);
350 | szjm_power_sxxk_count = 0;
351 | }
352 | break;
353 | case 2: //电源电压校准值 存储
354 | if (szjm_power_sxxk_count == 0) szjm_power_sxxk_count = szjm_power_kxxk_count;
355 | else if (szjm_power_sxxk_count == szjm_power_kxxk_count)
356 | {
357 | EEPROM.put(vin_refer_eeprom, vin_refer);
358 | szjm_power_sxxk_count = 0;
359 | }
360 | break;
361 | case 3: //低压报警阈值 存储
362 | if (szjm_power_sxxk_count == 0) szjm_power_sxxk_count = szjm_power_kxxk_count;
363 | else if (szjm_power_sxxk_count == szjm_power_kxxk_count)
364 | {
365 | EEPROM.put(vin_low_eeprom, vin_low);
366 | szjm_power_sxxk_count = 0;
367 | }
368 | break;
369 | }
370 | }
371 | }
372 |
373 | void power_xz_key() //设置界面 旋转
374 | {
375 | if (szjm_power_sxxk_count == 0) //选框移动
376 | {
377 | if (digitalRead(DT) == xzbmq_fx) szjm_power_kxxk_count++;
378 | else if (digitalRead(CLK) == xzbmq_fx) szjm_power_kxxk_count--;
379 | if (szjm_power_kxxk_count > 3) szjm_power_kxxk_count = 0;
380 | else if (szjm_power_kxxk_count < 0) szjm_power_kxxk_count = 3;
381 | }
382 | else if (szjm_power_sxxk_count == 1) //基准电压 加减
383 | {
384 | if (digitalRead(DT) == xzbmq_fx) vcc_refer += 0.01;
385 | else if (digitalRead(CLK) == xzbmq_fx) vcc_refer -= 0.01;
386 | }
387 | else if (szjm_power_sxxk_count == 2) //电源电压校准值 加减
388 | {
389 | if (digitalRead(DT) == xzbmq_fx) vin_refer += 0.1;
390 | else if (digitalRead(CLK) == xzbmq_fx) vin_refer -= 0.1;
391 | }
392 | else if (szjm_power_sxxk_count == 3) //低压报警阈值 加减
393 | {
394 | if (digitalRead(DT) == xzbmq_fx) vin_low += 0.1;
395 | else if (digitalRead(CLK) == xzbmq_fx) vin_low -= 0.1;
396 | if (vin_low > 30)vin_low = 3.2;
397 | else if (vin_low < 3.2)vin_low = 30;
398 | }
399 | }
400 |
401 | //************************ 烙铁界面 ************************
402 | void laotie_sw_key() //设置界面 按下
403 | {
404 | if (qj_ca_count == 1) //返回或进入调节框
405 | {
406 | switch (szjm_laotie_kxxk_count)
407 | {
408 | case 0: //返回至设置界面
409 | display_count = SZJM;
410 | break;
411 | case 1: //冷端补偿 存储
412 | if (szjm_laotie_sxxk_count == 0) szjm_laotie_sxxk_count = szjm_laotie_kxxk_count;
413 | else if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
414 | {
415 | EEPROM.put(tc1047_refer_eeprom, tc1047_refer);
416 | szjm_laotie_sxxk_count = 0;
417 | }
418 | break;
419 | case 2: //开机加热 存储
420 | if (szjm_laotie_sxxk_count == 0)
421 | {
422 | t12_kj_jr = !t12_kj_jr;
423 | EEPROM.put(t12_kj_jr_eeprom, t12_kj_jr);
424 | }
425 | break;
426 | case 3: //恢复出厂设置 存储
427 | if (szjm_laotie_sxxk_count == 0) szjm_laotie_sxxk_count = szjm_laotie_kxxk_count;
428 | else if (szjm_laotie_sxxk_count == szjm_laotie_kxxk_count)
429 | {
430 | if (hfccsz_state == 1) display_hfccsz();
431 | szjm_laotie_sxxk_count = 0;
432 | }
433 | break;
434 | }
435 | }
436 | }
437 | void laotie_xz_key() //设置界面 旋转
438 | {
439 | if (szjm_laotie_sxxk_count == 0) //选框移动
440 | {
441 | if (digitalRead(DT) == xzbmq_fx) szjm_laotie_kxxk_count++;
442 | else if (digitalRead(CLK) == xzbmq_fx) szjm_laotie_kxxk_count--;
443 | if (szjm_laotie_kxxk_count > 3) szjm_laotie_kxxk_count = 0;
444 | else if (szjm_laotie_kxxk_count < 0) szjm_laotie_kxxk_count = 3;
445 | }
446 | else if (szjm_laotie_sxxk_count == 1) //冷端补偿校准值 加减
447 | {
448 | if (digitalRead(DT) == xzbmq_fx) tc1047_refer += 1;
449 | else if (digitalRead(CLK) == xzbmq_fx) tc1047_refer -= 1;
450 | if (tc1047_refer > 99)tc1047_refer = 0;
451 | else if (tc1047_refer < -99) tc1047_refer = 0;
452 | }
453 | else if (szjm_laotie_sxxk_count == 3) //恢复出厂设置 状态切换
454 | {
455 | if (digitalRead(DT) == xzbmq_fx) hfccsz_state = !hfccsz_state;
456 | else if (digitalRead(CLK) == xzbmq_fx) hfccsz_state = !hfccsz_state;
457 | }
458 | }
459 | //************************ 校准界面 ************************
460 | void jiaozhun_sw_key() //设置界面 按下
461 | {
462 | if (qj_ca_count == 1) //返回或进入调节框
463 | {
464 | switch (szjm_jiaozhun_kxxk_count)
465 | {
466 | case 0: //返回至设置界面,并恢复正常PID参数和获取设置温度范围
467 | display_count = SZJM;
468 | szjm_jiaozhun_kxxk_count = 0;
469 | EEPROM.get(p_eeprom, p); //pid-p
470 | EEPROM.get(i_eeprom, i); //pid-i
471 | EEPROM.get(d_eeprom, d); //pid-d
472 |
473 | break;
474 | case 1: //深圳校准温度1段 存储
475 | if (szjm_jiaozhun_sxxk_count == 0)
476 | {
477 | szjm_jiaozhun_sxxk_count = szjm_jiaozhun_kxxk_count;
478 | t12_switch = 1; //打开加热
479 | }
480 | else if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
481 | {
482 | EEPROM.put(sz_temp0_eeprom, sz_temp[0]);
483 | szjm_jiaozhun_sxxk_count = 0;
484 | t12_switch = 0; //关闭加热
485 | }
486 | break;
487 | case 2: //深圳校准温度2段 存储
488 | if (szjm_jiaozhun_sxxk_count == 0)
489 | {
490 | szjm_jiaozhun_sxxk_count = szjm_jiaozhun_kxxk_count;
491 | t12_switch = 1; //打开加热
492 | }
493 | else if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
494 | {
495 | EEPROM.put(sz_temp1_eeprom, sz_temp[1]);
496 | szjm_jiaozhun_sxxk_count = 0;
497 | t12_switch = 0; //关闭加热
498 | }
499 | break;
500 | case 3: //深圳校准温度3段 存储
501 | if (szjm_jiaozhun_sxxk_count == 0)
502 | {
503 | szjm_jiaozhun_sxxk_count = szjm_jiaozhun_kxxk_count;
504 | t12_switch = 1; //打开加热
505 | }
506 | else if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
507 | {
508 | EEPROM.put(sz_temp2_eeprom, sz_temp[2]);
509 | szjm_jiaozhun_sxxk_count = 0;
510 | t12_switch = 0; //关闭加热
511 | }
512 | break;
513 | case 4: //深圳校准温度4段 存储
514 | if (szjm_jiaozhun_sxxk_count == 0)
515 | {
516 | szjm_jiaozhun_sxxk_count = szjm_jiaozhun_kxxk_count;
517 | t12_switch = 1; //打开加热
518 | }
519 | else if (szjm_jiaozhun_sxxk_count == szjm_jiaozhun_kxxk_count)
520 | {
521 | EEPROM.put(sz_temp3_eeprom, sz_temp[3]);
522 | szjm_jiaozhun_sxxk_count = 0;
523 | t12_switch = 0; //关闭加热
524 | }
525 | break;
526 | case 5: //开始曲线拟合系数计算
527 | qxnh_run(); //计算曲线拟合系数
528 | szjm_jiaozhun_kxxk_count = 6;
529 | break;
530 | case 6: //返回至设置界面,并恢复正常PID参数
531 | display_count = SZJM;
532 | szjm_jiaozhun_kxxk_count = 0;
533 | EEPROM.get(p_eeprom, p); //pid-p
534 | EEPROM.get(i_eeprom, i); //pid-i
535 | EEPROM.get(d_eeprom, d); //pid-d
536 | break;
537 | }
538 | }
539 | }
540 | void jiaozhun_xz_key() //设置界面 旋转
541 | {
542 | if (szjm_jiaozhun_sxxk_count == 0) //选框移动
543 | {
544 | if (digitalRead(DT) == xzbmq_fx) szjm_jiaozhun_kxxk_count++;
545 | else if (digitalRead(CLK) == xzbmq_fx) szjm_jiaozhun_kxxk_count--;
546 | if (szjm_jiaozhun_kxxk_count > 6) szjm_jiaozhun_kxxk_count = 0;
547 | else if (szjm_jiaozhun_kxxk_count < 0) szjm_jiaozhun_kxxk_count = 6;
548 | }
549 | else if (szjm_jiaozhun_sxxk_count == 1) //选框移动
550 | {
551 | if (digitalRead(DT) == xzbmq_fx) sz_temp[0] += 1;
552 | else if (digitalRead(CLK) == xzbmq_fx) sz_temp[0] -= 1;
553 | }
554 | else if (szjm_jiaozhun_sxxk_count == 2) //选框移动
555 | {
556 | if (digitalRead(DT) == xzbmq_fx) sz_temp[1] += 1;
557 | else if (digitalRead(CLK) == xzbmq_fx) sz_temp[1] -= 1;
558 | }
559 | else if (szjm_jiaozhun_sxxk_count == 3) //选框移动
560 | {
561 | if (digitalRead(DT) == xzbmq_fx) sz_temp[2] += 1;
562 | else if (digitalRead(CLK) == xzbmq_fx) sz_temp[2] -= 1;
563 | }
564 | else if (szjm_jiaozhun_sxxk_count == 4) //选框移动
565 | {
566 | if (digitalRead(DT) == xzbmq_fx) sz_temp[3] += 1;
567 | else if (digitalRead(CLK) == xzbmq_fx) sz_temp[3] -= 1;
568 | }
569 | }
570 |
--------------------------------------------------------------------------------
/v1.20.1/MsTimer2.ino:
--------------------------------------------------------------------------------
1 | //定时器2
2 | uint32_t t12_sleep_old_time = 0;
3 | void MsTimer2_rw1()
4 | {
5 | if (t12_switch == 1) //烙铁启动,打开休眠判断决策
6 | {
7 | if (bitRead(TIMSK2, TOIE2) == 0) //检测定时是否有打开 1-打开 0-无
8 | {
9 | sleep_count = 0;
10 | xp_time_count = 0;
11 | MsTimer2::set(1000, sleep_timing); // 1000ms 运行一次
12 | MsTimer2::start(); //打开定时器2计数
13 | }
14 | if (millis() - t12_sleep_old_time > 700)
15 | {
16 | t12_sleep(); //T12休眠决策
17 | t12_sleep_old_time = millis();
18 | }
19 | }
20 | else if (t12_switch == 0)
21 | {
22 | if (bitRead(TIMSK2, TOIE2) == 0)
23 | {
24 | sleep_count = 0;
25 | xp_time_count = 0;
26 | MsTimer2::set(1000, xp_timing); // 1000ms 运行一次
27 | MsTimer2::start(); //打开定时器2计数
28 | }
29 | system_sleep(); //系统休眠决策
30 | }
31 | }
32 |
33 | void sleep_timing() //休眠定时任务
34 | {
35 | sleep_count++; //烙铁没动,计数增加
36 | }
37 |
38 | void xp_timing() //息屏定时任务,校准界面不息屏
39 | {
40 | if (display_count != SZJM_JIAOZHUN) xp_time_count++; //烙铁没动,计数增加
41 | }
42 |
--------------------------------------------------------------------------------
/v1.20.1/PID.ino:
--------------------------------------------------------------------------------
1 | //********** PID算法 **********
2 | //算法来至https://blog.csdn.net/foxclever/article/details/105006205 By foxclever
3 | void pid()
4 | {
5 | if (t12_switch == 1 && vin_error == 0 && t12_error == 0) //加热开关开启
6 | {
7 | //计算设定值与平均温度的差值
8 | int16_t ek_average = set_temp - t12_temp_average;
9 | //平均差值小于3,发出声音提示一下
10 | if (ek_average >= -3 && ek_average <= 3 && buzzer_temp_average_state == 0)
11 | {
12 | buzzer(120, 300);
13 | buzzer_temp_average_state = 1;
14 | }
15 | if (display_count == SZJM_JIAOZHUN)
16 | PIDRegulator(t12_ad); //在校准界面时使用T12的ADC作为PID的目标值
17 | else
18 | PIDRegulator(t12_temp); //在其他界面时使用T12的温度值作为PID的目标值
19 | }
20 | else
21 | {
22 | pid_out = 0;
23 | lasterror = 0;
24 | preerror = 0;
25 | t12_temp_read_time = 450;
26 | }
27 | pwm_1b(pid_out);
28 | pid_out_bfb = (pid_out / (pwm_max - pwm_min)) * 100;
29 | }
30 |
31 | void PIDRegulator(float PV)
32 | {
33 | float factor = 0.0; //变积分系数
34 | float increment = 0.0;
35 | float pError = 0.0, dError = 0.0, iError = 0.0;
36 | if (display_count == SZJM_JIAOZHUN) //在校准界面时使用T12的ADC作为PID的目标值 ,计算偏差
37 | {
38 | if (szjm_jiaozhun_sxxk_count == 1) thisError = sz_adc0 - PV;
39 | else if (szjm_jiaozhun_sxxk_count == 2) thisError = sz_adc1 - PV;
40 | else if (szjm_jiaozhun_sxxk_count == 3) thisError = sz_adc2 - PV;
41 | else if (szjm_jiaozhun_sxxk_count == 4) thisError = sz_adc3 - PV;
42 | }
43 | else //在其他界面时使用T12的温度值作为PID的目标值 ,计算偏差
44 | {
45 | thisError = set_temp - PV; //得到偏差值
46 | thisError_average = set_temp - t12_temp_average; //得到平均值的偏差值
47 | }
48 | //规定采样时间
49 | if (thisError < -5) t12_temp_read_time = 150;
50 | else if (thisError >= -5 && thisError <= 10) t12_temp_read_time = 400;
51 | else if (thisError > 10 && thisError <= 30) t12_temp_read_time = 500;
52 | else t12_temp_read_time = 800;
53 | if (thisError <= 30 && thisError > -15)
54 | {
55 | if (fabs(thisError) > deadband)
56 | {
57 | pError = thisError - lasterror;
58 | iError = float((thisError + lasterror)) / 2.0;
59 | dError = thisError - 2 * (lasterror) + preerror;
60 |
61 | //变积分系数获取
62 | factor = get_factor(thisError, errorabsmax, errorabsmin);
63 |
64 | //计算微分项增量带不完全微分
65 | deltadiff = d * (1 - alpha) * dError + alpha * deltadiff;
66 |
67 | increment = p * pError + i * factor * iError + deltadiff; //增量计算
68 | }
69 | else
70 | {
71 | if ((fabs(set_temp - pwm_min) < deadband) && (fabs(PV - pwm_min) < deadband))
72 | {
73 | pid_out = pwm_min;
74 | }
75 | increment = 0.0;
76 | }
77 |
78 | pid_out = pid_out + increment;
79 |
80 | /*对输出限值,避免超调和积分饱和问题*/
81 | if (pid_out >= pwm_max)
82 | {
83 | if (thisError <= 0) pid_out = pwm_min;
84 | else pid_out = pwm_max;
85 | }
86 | else if (pid_out <= pwm_min) pid_out = pwm_min;
87 |
88 | }
89 | else if (thisError > 30) pid_out = pwm_max;
90 | else if (thisError < -15) pid_out = pwm_min;
91 | preerror = lasterror; //存放偏差用于下次运算
92 | lasterror = thisError;
93 | }
94 |
95 | float get_factor(float ek0, float absmax, float absmin) //变积分系数获取
96 | {
97 | float factor1 = 0.0;
98 | factor1 = map(ek0, absmax, absmin, 0.0, 1.0);
99 | if (abs(ek0) >= absmax) factor1 = 0.0;
100 | else if (abs(ek0) <= absmin) factor1 = 1.0;
101 | return factor1;
102 | }
103 |
104 | void pwm_1b(uint16_t val)//自定义PWM,使用相位和频率校正模式,2048级控温
105 | {
106 | //输出通道B 占空比: (OCR1B+1) / (OCR1A+1)
107 | //占空比不能大于OCR1A
108 |
109 | if (val >= pwm_max) digitalWrite(t12_pwm_pin, 1);
110 | else if (val <= pwm_min) digitalWrite(t12_pwm_pin, 0);
111 | else
112 | {
113 | //pinMode(10, OUTPUT); //pin10连接至B通道
114 | //bitWrite(DDRB, 2, 1); //设置pin10为输出
115 | //相位和频率校正PWM,分频比64,频率: 16000000/2*256*(OCR1A+1) = 15HZ
116 | TCCR1A = B00100001;
117 | TCCR1B = B00010100;
118 | OCR1A = pwm_max; //从0开始数到0CR1A,0-65535,设置周期和频率
119 | OCR1B = val; //用来设置比较器,占空比
120 | }
121 | //ec_read(); //读取电流
122 | }
123 | /*时钟输出 | Arduino输出Pin | 芯片Pin | Pin 名字
124 | OC0A 6 12 PD6
125 | OC0B 5 11 PD5
126 | OC1A 9 15 PB1
127 | OC1B 10 16 PB2
128 | OC2A 11 17 PB3
129 | OC2B 3 5 PD3
130 |
131 | 脉冲生成模式控制位(WGM):用来设置PWM的模式或CTC模式
132 | 时钟选择位(CS):设置时钟的预分频
133 | 输出模式控制位(COMnA和COMnB):使能/禁用/反相 输出A和输出B
134 | 输出比较器(OCRnA和OCRnB):当计数器等于这两个值时,输出值根据不同的模式进行变化
135 |
136 | 快速PWM(0-255 0-255 数完归零)
137 | 相位修正PWM(0-255 255-0 数完倒数)
138 |
139 | 8位(定时器0/2)
140 | CSn0 001 = 1
141 | CSn1 010 = 8
142 | CSn2 011= 32
143 | CSn3 100= 64
144 | CSn4 101= 128
145 | CSn5 110= 256
146 | CSn6 111= 1024
147 | 16位(定时器1)
148 | CSn0 001 = 1
149 | CSn1 010 = 8
150 | CSn2 011= 64
151 | CSn3 100= 256
152 | CSn4 101= 1024
153 |
154 | COMnA1 COMnB1 = 占空比AB都可控
155 | 从0数到2047 0时输出高电平
156 | OCRnA 当数到OCRnA,输出低电平,即A的占空比=OCRnA的值
157 | OCRnB 当数到OCRnB,输出低电平,即B的占空比=OCRnB的值
158 |
159 | COMnA0 COMnB1 = A当数到头是反相 占空比A50% B可控
160 | OCRnA 从0数到OCRnA 0时输出高电平
161 | OCRnB 当OCRnA=OCRnB,输出低电平
162 | 输出通道B 占空比: (OCR1B+1) / (OCR1A+1)
163 | 占空比不能大于OCR1A
164 | pinMode(10, OUTPUT); //B
165 | bitWrite(DDRB, 2, 1); //设置pin10为输出
166 | 快速PWM,分频比64,频率: 16000000/64*(OCR1A+1) = 976HZ
167 | TCCR1A = B00100011;
168 | TCCR1B = B00011011;
169 | 相位和频率校正PWM,分频比8,频率: 16000,000/2*8*(OCR1A+1) = 488HZ
170 | TCCR1A = B00100001;
171 | TCCR1B = B00010010;
172 | 相位校正PWM,分频比256,频率: 16000000/2*256*(OCR1A+1) = 61HZ
173 | TCCR1A = B00100011;
174 | TCCR1B = B00010100;
175 | OCR1A = 2047; //从0开始数到0CR1A,0-65535,设置周期和频率
176 | OCR1B = val; //用来设置比较器,占空比*/
177 |
--------------------------------------------------------------------------------
/v1.20.1/Sleep.ino:
--------------------------------------------------------------------------------
1 | //********** T12休眠判断决策 **********
2 | void t12_sleep()
3 | {
4 | if(sleep_time==999) return;
5 | if (sleep_state != digitalRead(t12_sleep_pin))//烙铁动了,计数清零
6 | {
7 | sleep_state = !sleep_state; //状态取反
8 | sleep_count = 0; //计数清零
9 | if (zjm_sleep_ts == 1)
10 | {
11 | zjm_sleep_ts = 0; //提示主界面退出显示休眠状态
12 | set_temp = sleep_temp_cache;
13 | sleep_temp_cache = 0;
14 | buzzer_temp_average_state = 0; //准备好到达温度提示声
15 | buzzer(150, 300); //提示一下
16 | }
17 | }
18 | if (sleep_count == sleep_time && zjm_sleep_ts == 0) //达到休眠的阈值,进入休眠
19 | {
20 | EEPROM.put(set_temp_eeprom, set_temp); //自动保存当前设置温度
21 | zjm_sleep_ts = 1; //提示主界面显示休眠中
22 | buzzer(150, 300); //提示一下
23 |
24 | if (set_temp > sleep_temp) //大于设置的休眠温度
25 | {
26 | sleep_temp_cache = set_temp; //休眠前将温度记录下来,记录和调温
27 | set_temp = sleep_temp; //将温度调至休眠温度
28 | }
29 | else if (set_temp <= sleep_temp) //小于等于设置的休眠温度,只记录不调温
30 | sleep_temp_cache = set_temp; //休眠前将温度记录下来
31 | }
32 | else if (sleep_count > 1800) //半小时没操作,关闭加热
33 | {
34 | MsTimer2::stop();
35 | set_temp = sleep_temp_cache;
36 | sleep_temp_cache = 0;
37 | t12_switch = 0;
38 | sleep_count = 0;
39 | zjm_sleep_ts = 0; //提示主界面退出休眠
40 | buzzer(150, 1000); //提示一下
41 | }
42 | }
43 |
44 | //********** 系统休眠判断决策 **********
45 | void system_sleep()
46 | {
47 | if (xp_time_count >= 180) //无加热无操作超过180秒就显示息屏界面
48 | {
49 | if (xp_time_count - xp_time_count_old > 3) //每隔3秒刷新一次位置
50 | {
51 | display_count = ZJM;//退出至主界面
52 | xp_state = 1; //标记息屏状态
53 | xp_x = random(0, 90);
54 | xp_y = random(11, 31);
55 | xp_time_count_old = xp_time_count;
56 | }
57 | else if (xp_time_count >= 65530) //防止数值溢出
58 | {
59 | xp_time_count = 180;
60 | xp_time_count_old = 0;
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/v1.20.1/WDT.ino:
--------------------------------------------------------------------------------
1 | //********** 看门狗函数 **********
2 | void set_wdt_mod(uint8_t mod, uint8_t ii) //模式,超时时间
3 | {
4 | /*
5 | WDCE
6 | 该位在定时序列中用于更改WDE和预分频器位
7 | 要清除WDE位或更改预分频器位,必须将WDCE置1。
8 | 一旦写入1,硬件将在四个时钟周期后清除WDCE。
9 | 0=16ms,1=32ms,2=64ms,3=128ms,4=250ms
10 | 5=500ms,6=1s,7=2s,8=4s,9=8s
11 | */
12 | if (ii > 9 ) ii = 9;
13 | byte bb;
14 | bb = ii & 7;
15 | if (ii > 7) bb |= (1 << 5);
16 | bb |= (1 << WDCE);
17 |
18 | switch (mod) {
19 | case 0: //关闭看门狗
20 | __asm__ __volatile__ ("wdr"); //看门狗复位
21 | MCUSR = 0x00; //看门狗复位标志清零
22 | WDTCSR = (1 << WDCE) | (1 << WDE); //打开允许修改使能,并WDE置1
23 | WDTCSR = 0x00; //清除所有预分频位
24 | break;
25 |
26 | case 1: //打开看门狗,设置复位模式
27 | __asm__ __volatile__ ("wdr"); //看门狗复位
28 | MCUSR &= ~(1 << WDRF); //MUUSR中的WDRF清零,清除复位标志
29 | WDTCSR |= (1 << WDCE) | (1 << WDE); //打开允许修改使能,并WDE置1
30 | //设置新的看门狗超时值bb
31 | WDTCSR = bb; //8秒时bb=0011 0001
32 | WDTCSR |= _BV(WDE); //设置复位模式
33 | break;
34 |
35 | case 2: //打开看门狗,设置中断模式
36 | __asm__ __volatile__ ("wdr"); //看门狗复位
37 | MCUSR &= ~(1 << WDRF); //MUUSR中的WDRF清零,清除复位标志
38 | WDTCSR |= (1 << WDCE) | (1 << WDE); //打开允许修改使能,并WDE置1
39 | //设置新的看门狗超时值bb
40 | WDTCSR = bb; //8秒时bb=0011 0001
41 | WDTCSR |= _BV(WDIE); //设置中断模式
42 | break;
43 |
44 | case 3: //打开看门狗,设置中断+复位模式
45 | __asm__ __volatile__ ("wdr"); //看门狗复位
46 | MCUSR &= ~(1 << WDRF); //MUUSR中的WDRF清零,清除复位标志
47 | WDTCSR |= (1 << WDCE) | (1 << WDE); //打开允许修改使能,并WDE置1
48 | //设置新的看门狗超时值bb
49 | WDTCSR = bb; //8秒时bb=0011 0001
50 | WDTCSR |= _BV(WDIE); //设置中断模式
51 | WDTCSR |= _BV(WDE); //设置复位模式
52 | break;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/v1.20.1/analogRead.ino:
--------------------------------------------------------------------------------
1 | //********** 读取电压、电流、温度 **********
2 | float vin_cache = 0.0;
3 | uint8_t vin_cache_count = 0;
4 |
5 | float tc1047_cache = 0.0;
6 | uint8_t tc1047_cache_count = 0;
7 |
8 | #define cycs 10 //时间平均滤波的采样次数 采样周期 = 采样次数*定时执行任务的时间
9 | uint8_t t12_adc_error_count = 0; //t12ADC超出检测范围错误计数
10 | void read_timing() //定时读取电源电压和机内温度
11 | {
12 | if (millis() - vin_read_time > t12_temp_read_time)
13 | {
14 | read_t12_temp();
15 | vin_read_time = millis();
16 | }
17 | }
18 | void read_timing2()
19 | {
20 | vin_read(); //读取电压
21 | tc1047_temp_read(); //读取室温
22 | if (szjm_oled_sxxk_count == 1) u8g2.setContrast(oled_ld); //改变亮度
23 | }
24 | void read_t12_temp() //定时读取T12的温度
25 | {
26 | float t12_ad_nwe = 0.0; //临时AD
27 | digitalWrite(t12_pwm_pin, 0);
28 | read_timing2();
29 | delay(1);
30 | t12_ad_nwe = denoiseAnalog(t12_temp_pin); //读取即时AD
31 | //t12_ad_nwe = analogRead(t12_temp_pin); //读取即时AD
32 | t12_ad += (t12_ad_nwe - t12_ad) * 0.7; //平滑滤波
33 | //if (digitalRead(t12_sleep_pin) == 1) t12_ad += 2; //补偿上拉噪声干扰
34 | //计算温度,温度曲线由校准程序自动计算
35 | t12_temp = sz_p[3] * t12_ad * t12_ad * t12_ad + sz_p[2] * t12_ad * t12_ad + sz_p[1] * t12_ad + sz_p[0];
36 | t12_temp += (tc1047_temp - tc1047_refer); //环境温度补偿
37 |
38 | //记录平均温度
39 | t12_temp_average_cache += t12_temp;
40 | t12_temp_average_count++;
41 | if (t12_temp_average_count == 8)
42 | {
43 | t12_temp_average = t12_temp_average_cache >> 3;
44 | t12_temp_average_cache = 0; //累计缓存温度清零
45 | t12_temp_average_count = 0; //计数清零
46 | }
47 | //运行PID
48 | pid();
49 |
50 | //手柄检测及超出测量范围检测
51 | #define ADCMax 1000
52 | if (t12_switch == 0 && t12_ad >= ADCMax) //无手柄
53 | {
54 | t12_error = 1;
55 | t12_switch = 0;
56 | }
57 | else if (t12_switch == 1 && t12_ad >= ADCMax) //超出测量范围检测,延时检测
58 | {
59 | t12_adc_error_count++;
60 | if (t12_adc_error_count >= 10)
61 | {
62 | MsTimer2::stop(); //停止一次 然后在MsTimer2_rw1()里自动切换定时的中断任务
63 | t12_adc_error_count = 0; //清除计数
64 | t12_adc_error = 1;
65 | t12_switch = 0;
66 | }
67 | }
68 | else if (t12_switch == 1 && t12_ad < ADCMax)
69 | {
70 | t12_adc_error = 0;
71 | t12_adc_error_count = 0; //清除计数
72 | }
73 | else t12_error = 0;
74 | }
75 |
76 | void vin_read()
77 | {
78 | /*
79 | 串联电阻的中点电压计算公式
80 | Eout 中点电压
81 | Vcc 输入电压(两端施加电压)
82 | R1、R2 两个串联的分压电阻
83 | Eout = Vcc * R2/(R1+R2) R1靠近电源 R2靠近地
84 | */
85 | /*vin = (denoiseAnalog(vin_pin) / 0.1282) * vcc_refer_fl; //计算电源电压 10/68+10=0.1282
86 | if (vin < vin_low && vin_low >= 3.3) //电压过低提示
87 | {
88 | vin_error = 1;
89 | t12_switch = 0;
90 | }*/
91 |
92 | vin_cache += (denoiseAnalog(vin_pin) / 0.1389) * vcc_refer_fl;
93 | vin_cache_count++;
94 | if (vin_cache_count >= cycs)
95 | {
96 | vin = vin_cache / cycs + vin_refer;
97 | vin_cache_count = 0;
98 | vin_cache = 0;
99 | //电压过低提示
100 | if (vin < vin_low && vin_low >= 3.3)
101 | {
102 | vin_error = 1;
103 | t12_switch = 0;
104 | }
105 | else vin_error = 0;
106 | }
107 | }
108 |
109 | void tc1047_temp_read() //读取tc1047温度
110 | {
111 | //tc1047_temp = ((denoiseAnalog(tc1047_pin) * vcc_refer_fl) - 0.5) * 100;
112 |
113 | tc1047_cache += ((denoiseAnalog(tc1047_pin) * vcc_refer_fl) - 0.5) * 100;
114 | tc1047_cache_count++;
115 | if (tc1047_cache_count >= cycs)
116 | {
117 | tc1047_temp = tc1047_cache / cycs;
118 | tc1047_cache_count = 0;
119 | tc1047_cache = 0;
120 | }
121 | }
122 | void auto_get_set_temp() //自动获取设置温度的范围
123 | {
124 | set_temp_max = ((sz_temp[3]) / 10 ) * 10 - 20;
125 | if (set_temp_max > 450) set_temp_max = 450;
126 | set_temp_min = ((sz_temp[0]) / 10) * 10;
127 | }
128 | /*uint16_t denoiseAnalog(uint8_t pin)
129 | {
130 | uint8_t low, high;
131 | if (pin >= A0) pin -= A0; //设置端口
132 | ADMUX = (0x0F & pin) | bit(REFS0); //设置基准电压为5V,设置端口
133 | ADCSRA |= bit (ADEN) | bit (ADIF); //启用ADC,关闭任何挂起的中断
134 | set_sleep_mode (SLEEP_MODE_ADC); //在取样时进行睡眠以降低噪音,需要开启ADC中断进行唤醒
135 | sleep_mode(); //进入休眠自动启动转换
136 | //bitSet(ADCSRA, ADSC); //ADSC 写1启动AD转换
137 | while (bitRead(ADCSRA, ADSC)); //等待转换结束
138 | low = ADCL;
139 | high = ADCH;
140 | bitClear (ADCSRA, ADEN); // 禁用ADC
141 | return (high << 8) | low; //返回数值
142 | }*/
143 | uint16_t denoiseAnalog (byte port)
144 | {
145 | uint16_t result = 0;
146 | if (port >= A0) port -= A0; //设置端口
147 | ADMUX = (0x0F & port) | bit(REFS0); //设置基准电压为5V,设置端口
148 | ADCSRA |= bit (ADEN) | bit (ADIF); //启用ADC,关闭任何挂起的中断
149 | set_sleep_mode (SLEEP_MODE_ADC); //在取样时进行睡眠以降低噪音,需要开启ADC中断进行唤醒
150 | for (uint8_t i = 0; i < 16; i++) { // get 32 readings
151 | sleep_mode(); // go to sleep while taking ADC sample
152 | while (bitRead(ADCSRA, ADSC)); // 等待转换结束
153 | result += ADC; // add them up
154 | }
155 | bitClear (ADCSRA, ADEN); // 禁用ADC
156 | return (result >> 4); // devide by 32 and return value
157 | }
158 | //ADC中断服务
159 | EMPTY_INTERRUPT (ADC_vect); // 这里没什么可做的
160 |
--------------------------------------------------------------------------------
/v1.20.1/font.c:
--------------------------------------------------------------------------------
1 | //#include
2 | #include
3 | const uint8_t chinese_t12[1591] U8G2_FONT_SECTION("chinese_t12") =
4 | "A\0\3\2\4\4\2\4\5\14\14\0\377\11\375\12\376\0\0\0\0\0\337 \5\0\242\5+\13w\346"
5 | "]\134\33\206,\256\1-\6\26\362\305\1.\6\42c\305\20\60\13\226\342\315\220\204~L\206\4\61\11"
6 | "\225\242\305\330O\203\0\62\13\226\342\315\220\204b_\207\1\63\16\226\342\315\220\204iiN\305dH\0"
7 | "\64\17\226\342\235\226D]\262$K\206\61M\0\65\16\226\342\305!M\7\71M\305dH\0\66\17\226"
8 | "\342\315\220\204j\262h\242\61\31\22\0\67\13\226\342\305\61\15\323bZ\3\70\17\226\342\315\220\204\306d"
9 | "HBc\62$\0\71\17\226\342\315\220\204\306dPS\61\31\22\0D\15\227\42\306 \205I\352c\62"
10 | "H\0I\10\223\42\305\22\365eP\14\226\342\305\240\204\216\303\222V\1S\17\226\342\315\220\204j<\304"
11 | "\251\230\14\11\0V\17\227\42FjM\262(\253\204I\32g\0\0\0\0\4\377\377!\3\27\271_O"
12 | "\16$\321T\13s Gr$Gr(G\262t\1N\256\34\314^w:\274\245\351\60\344\224\341\240"
13 | "\344P\22\15R\230\345@\26\207Q\42\17O\21\35\314^_\35\310\342\60N\206!\22+\331\232\255Q"
14 | "R\214\222b\22\325\264R\30\2ON\33\314^_*&C\32U\243\242TK\242a\210Z\243j\324"
15 | "KS\64I\35P\134\35\314^_\35\10\323d\30\244\34\223\206\245\24f\311\60HI\34E\303\226v"
16 | "\333\0P\177\37\314^_\22\325\242\244\226V\206AQb%\32\266\34L\206A\12\343\254e\30\244j"
17 | "\0Qs\31\313^WZ\313\201$\35\316\71\226\16\7\65\207\222\34\310\322\222\16\10Q\267\34\314^w"
18 | "\232\252Y\24Fa(eR\230&\303\20\351@V\12C\265\216f\0Q\306\42\314^G\230\244Y\24"
19 | "&\311\60dI\224&R\32\15\213\26\205\331\60eQ\230Ea\66\14i\14R\240$\314^_\16\346"
20 | "\310\60$C\26%Q\26%Q\26%Q\26%Q-\211jITK\242$L\6M*S\213\33\314"
21 | "^\327p\210r\260\34\306a\234\14C\26\306a\22\226\252Q\65\214\206\3T\21\32\312_g\216\304\303"
22 | "AGtD\32\42\251$\225\244!\322\21\71\321\201\4T&\31\273^\307\203\250#\255QI\313\324\60"
23 | "\32\206\60\15\323p\30\302\64\2W\372\31\313^_m\70h\345A\316\342A\316\262\341 \65)\203\242"
24 | "\246\303A\134O\35\314^\327p\313\201l\270%a\251:\34\242\326\250:\34\222,\12\243\254\24f\0"
25 | "^U\34\313^_m\70h\325a\10\323p\30\302$\213\206\203\324\64\34\244\306(\221\0^\246\36\314"
26 | "^\77\20\17\207\250\26\16\207\250\26F\203\230\203\311\60dQVL\302p\213\266\1_\0\34\314^\317"
27 | "pH\263\34\310r \313\201,\33\36\263\34\310\342\60\16\323b\234\1bK\30\313^\367\20\15:\226"
28 | "c\361p\316\261t\70\250\71\226#u(\6b\245!\314^W\64lQ\230Ea\62Lb\224#\321"
29 | "\260)\245dJ\242,J\212Q-\211\222Zfc\245\37\314^WZ\32\206(\253\14R\22F\303\20"
30 | "\245\251\62\34\302(+\205\241\226\204I\226\31e\271\27\314^o\216\246\303c\16\346\340\60\207i\307\70"
31 | "\13\223,\16\1e\313\42\314^W\230\3Y\70
107 | #include //掉电数值存储库
108 | #include //休眠库
109 | #include //屏幕驱动库
110 | #ifdef U8X8_HAVE_HW_I2C
111 | #include
112 | #endif
113 |
114 | U8G2_SSD1306_128X32_UNIVISION_2_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //SSD1306 0.96寸OLED
115 | //U8G2_SSD1316_128X32_2_HW_I2C u8g2(U8G2_R0,/* reset=*/ U8X8_PIN_NONE); //SSD1316 0.87寸OLED
116 |
117 | //调用字库
118 | #include "font.c"
119 | //声明外部变量
120 | extern const uint8_t chinese_t12[1591] U8G2_FONT_SECTION("chinese19");
121 |
122 | //********** 引脚定义 **********
123 | #define SW 4 //按下 ,可更改其他引脚
124 | #define CLK 3 //减,只可修改为2或3
125 | #define DT 2 //加,只可修改为2或3
126 | //除了10号脚不能改,其他都可以改,但模拟引脚只能改模拟引脚(休眠引脚除外)
127 | #define t12_sleep_pin A0 //t12休眠 模拟读取引脚
128 | #define t12_temp_pin A2 //t12温度 模拟读取引脚
129 | #define tc1047_pin A3 //机内温度 模拟读取引脚
130 | #define vin_pin A6 //电源电压 模拟读取引脚
131 | #define t12_pwm_pin 10 //t12加热 pwm输出引脚,定死不可更改
132 | #define buzzer_pin 8 //蜂鸣器 输出引脚
133 | //************ EEPROM地址定义 ************
134 | uint8_t auto_get = 0; //自动刷写eeprom的状态存储,判断是否首次开机 0-首次 1-非首次
135 | #define auto_get_eeprom 0 //自动刷写eeprom的状态存储,1位
136 | #define p_eeprom 1 //p地址,4位
137 | #define i_eeprom p_eeprom+4 //i地址,4位
138 | #define d_eeprom i_eeprom+4 //d地址,4位
139 | #define sleep_time_eeprom d_eeprom+4 //休眠时间,4位
140 | #define sleep_temp_eeprom sleep_time_eeprom+4 //休眠温度,1位
141 | #define oled_ld_eeprom sleep_temp_eeprom+1 //OLED亮度,1位
142 | #define vcc_refer_eeprom oled_ld_eeprom+1 //基准电压,4位
143 | #define vin_refer_eeprom vcc_refer_eeprom+4 //电源电压校准值,4位
144 | #define t12_kj_jr_eeprom vin_refer_eeprom+4 //是否开机就加热?,1位
145 | #define vin_low_eeprom t12_kj_jr_eeprom+1 //输入电压低压报警阈值,4位
146 | #define tc1047_refer_eeprom vin_low_eeprom+4 //冷端补偿校准值,1位
147 | #define oled_fx_eeprom tc1047_refer_eeprom+1 //OELD方向,1位
148 | #define xzbmq_fx_eeprom oled_fx_eeprom+1 //编码器旋转方向,1位
149 | #define sz_temp0_eeprom xzbmq_fx_eeprom+1 //深圳头曲线温度校准1段,4位
150 | #define sz_temp1_eeprom sz_temp0_eeprom+4 //深圳头曲线温度校准2段,4位
151 | #define sz_temp2_eeprom sz_temp1_eeprom+4 //深圳头曲线温度校准3段,4位
152 | #define sz_temp3_eeprom sz_temp2_eeprom+4 //深圳头曲线温度校准4段,4位
153 | #define set_temp_eeprom sz_temp3_eeprom+4 //t12设置温度,4位
154 | //T12及温度相关
155 | boolean t12_switch = 0; //T12加热开关
156 | boolean t12_kj_jr = 0; //是否开机就加热? 0-否 1-是
157 |
158 | float t12_ad = 0.0; //T12即时ADC值
159 | int16_t t12_temp = 0; //T12即时温度
160 | int16_t t12_temp_display = 0; //T12显示温度
161 |
162 | boolean t12_error = 0; //手柄未接提示
163 | boolean t12_adc_error = 0; //温度超出测量范围
164 | int16_t set_temp_max; //自动计算设置的温度最大值
165 | int16_t set_temp_min; //自动计算设置的温度最小值
166 |
167 | int16_t t12_temp_average_cache = 0; //记录采集温度,缓存用
168 | int16_t t12_temp_average = 0; //8次内采集到的平均温度,显示用
169 | uint8_t t12_temp_average_count = 0; //平均温度采集计数
170 | boolean buzzer_temp_average_state = 0; //到达温度提示声
171 |
172 | //float tc1047_ad = 0.0; //tc1047ADC值
173 | float tc1047_temp = 0.0; //tc1047温度,机内温度
174 | int8_t tc1047_refer = 30; //T12环境参考温度校准值
175 |
176 | float vcc_refer = 4.98; //参考电压,稳压芯片输出的电压是多少就填多少
177 | float vin = 0.0; //电源电压
178 | float vin_refer = 0.0; //输入电压校准值
179 | float vin_low = 3.3; //低压报警阈值
180 | boolean vin_error = 0; //低压报警提示
181 | #define vcc_refer_fl vcc_refer/1023.0 //参考电压每级分量
182 |
183 | uint32_t xzbmq_time = 0; //编码器消抖对比时间
184 | uint32_t temp_read_time = 0; //定时读取温度对比时间
185 | uint32_t vin_read_time = 0; //定时读取输入电压时间
186 | uint32_t t12_temp_read_time = 450; //定时T12温度采样时间
187 |
188 | boolean buzzer_state = 0; //蜂鸣器准备状态
189 | uint16_t buzzer_time; //蜂鸣器响的时间
190 | uint16_t buzzer_count; //蜂鸣器响的次数
191 | boolean buzzer_szjm_state = 0; //进入设置界面的长音状态
192 | boolean buzzer_zjm_state = 0; //退出至主界面的长音状态
193 |
194 | boolean zjm_sleep_ts = 0; //主界面休眠提示 0-无 1-休眠中
195 | uint16_t sleep_time = 150; //进入休眠的时间阈值,单位秒
196 | uint8_t sleep_temp = 200; //休眠时的温度,单位摄氏度
197 | boolean sleep_state = 0; //休眠引脚状态 0低电平 1高电平
198 | uint16_t sleep_count = 0; //休眠计数
199 | uint16_t sleep_temp_cache = 0; //休眠前的温度缓存
200 |
201 | uint8_t oled_ld = 50; //OLED亮度
202 | boolean oled_fx = 0; //OLED方向 0-不旋转,横向显示 1-旋转180度
203 | boolean xzbmq_fx = 0; //编码器方向 0-顺加逆减 1-顺减逆加
204 | boolean hfccsz_state = 0; //恢复出厂设置 0-NO 1-YES
205 |
206 | boolean xp_state = 0; //息屏状态 0-无 1-息屏
207 | uint16_t xp_time_count = 0; //息屏计数
208 | uint16_t xp_time_count_old = 0; //上一次时间计数
209 | int8_t xp_x = 0; //息屏随机变化位置X
210 | int8_t xp_y = 0; //息屏随机变化位置Y
211 | int8_t xp_x_old = 50; //上一次息屏随机变化位置X
212 | int8_t xp_y_old = 21; //上一次息屏随机变化位置Y
213 |
214 | //深圳头曲线拟合的4段ADC
215 | #define sz_adc0 10
216 | #define sz_adc1 350
217 | #define sz_adc2 650
218 | #define sz_adc3 940 //原950
219 | //uint16_t sz_temp[4] = {36, 224, 347, 446}; //深圳头曲线拟合的4段温度 Y 390倍
220 | //uint16_t sz_temp[4] = {43, 259, 382, 490}; //深圳头曲线拟合的4段温度 Y 330倍
221 | uint16_t sz_temp[4] = {49, 262, 391, 486}; //深圳头曲线拟合的4段温度 Y 1.03版本程序移植
222 | float sz_p[4]; //深圳头曲线拟合的4个系数 P
223 | //********** 菜单标志位相关 **********
224 | #define ZJM 1 //主界面
225 | #define SZJM 2 //设置界面
226 | #define SZJM_PID 3 //PID设置界面
227 | #define SZJM_SLEEP 4 //休眠设置界面
228 | #define SZJM_OLED 5 //OLED设置界面
229 | #define SZJM_POWER 6 //电源设置界面
230 | #define SZJM_JIAOZHUN 7 //校准设置界面
231 | #define SZJM_LAOTIE 8 //烙铁头设置界面
232 |
233 | uint8_t display_count = 1; //默认要显示的界面
234 | boolean dec_state = 0; //小数点输入状态 0关闭 1开启
235 | uint8_t qj_ca_count = 0; //全局长按计数
236 |
237 | boolean szjm_kxxk_L = 0; //设置界面空心选框 顺时针转
238 | boolean szjm_kxxk_R = 0; //设置界面空心选框 逆时针转
239 | int8_t szjm_kxxk_count = 0; //设置界面空心选框
240 |
241 | int8_t szjm_pid_kxxk_count = 0; //pid界面空心选框
242 | int8_t szjm_pid_sxxk_count = 0; //pid界面实心选框
243 |
244 | int8_t szjm_sleep_kxxk_count = 0; //pid界面空心选框
245 | int8_t szjm_sleep_sxxk_count = 0; //pid界面实心选框
246 |
247 | int8_t szjm_oled_kxxk_count = 0; //oled界面空心选框
248 | int8_t szjm_oled_sxxk_count = 0; //oled界面实心选框
249 |
250 | int8_t szjm_power_kxxk_count = 0; //电源设置界面空心选框
251 | int8_t szjm_power_sxxk_count = 0; //电源设置界面实心选框
252 |
253 | int8_t szjm_pwm_kxxk_count = 0; //PWM界面空心选框
254 | int8_t szjm_pwm_sxxk_count = 0; //PWM界面实心选框
255 |
256 | int8_t szjm_laotie_kxxk_count = 0; //烙铁头设置界面空心选框
257 | int8_t szjm_laotie_sxxk_count = 0; //烙铁头设置界面实心选框
258 |
259 | int8_t szjm_jiaozhun_kxxk_count = 0; //烙铁头设置界面空心选框
260 | int8_t szjm_jiaozhun_sxxk_count = 0; //烙铁头设置界面实心选框
261 | //********** 动态调参PID **********
262 | float p = 25.0; //比例系数
263 | float i = 8.7; //积分系数
264 | float d = 2.6; //微分系数
265 |
266 | #define p_jz 12.0 //校准界面用的 比例系数
267 | #define i_jz 2.2 //校准界面用的 积分系数
268 | #define d_jz 1.2 //校准界面用的 微分系数
269 |
270 | uint16_t set_temp = 320; //设置温度
271 | int16_t thisError = 0; //本次误差
272 | int16_t thisError_average = 0; //累积误差的平均值
273 | int16_t lasterror = 0; //前一拍偏差
274 | int16_t preerror = 0; //前两拍偏差
275 | const int8_t deadband = 0; //死区
276 | int16_t pid_out = 0.0; //PID控制器计算结果
277 | uint8_t pid_out_bfb = 0.0; //输出值0-100%
278 | const float pwm_max = 2047.0; //输出值上限
279 | const float pwm_min = 0.0; //输出值下限
280 | const float errorabsmax = 2000.0; //偏差绝对值最大值
281 | const float errorabsmin = 50.0; //偏差绝对值最小值
282 | const float alpha = 0.2; //不完全微分系数
283 | float deltadiff = 0.0; //微分增量
284 |
285 | void setup()
286 | {
287 | //***** 首次开机自动刷写eeprom
288 | eerpom_auto();
289 | //***** 编码器配置
290 | pinMode(SW, INPUT_PULLUP); //按下
291 | pinMode(CLK, INPUT_PULLUP); //相位A
292 | pinMode(DT, INPUT_PULLUP); //相位B
293 | pinMode(t12_temp_pin, INPUT); //t12温度
294 | pinMode(t12_sleep_pin, INPUT_PULLUP); //t12休眠
295 | pinMode(vin_pin, INPUT); //电源电压
296 | pinMode(tc1047_pin, INPUT); //机内温度
297 | pinMode(buzzer_pin, OUTPUT); //蜂鸣器
298 | pinMode(t12_pwm_pin, OUTPUT); //t12加热,不可更改
299 |
300 | digitalWrite(t12_pwm_pin, 0); //默认关闭
301 | digitalWrite(buzzer_pin, 0); //默认关闭
302 | //***** OLED初始化
303 | u8g2.begin();
304 | u8g2.enableUTF8Print();
305 | u8g2.setContrast(oled_ld); //设置亮度1-255
306 | //u8g2.setBusClock(400000); //设置I2C通讯速度默认MAX400000
307 | //u8g2.setPowerSave(0); //0开启屏幕 1关闭屏幕
308 | if (oled_fx)u8g2.setDisplayRotation(U8G2_R2); //旋转180度
309 | else u8g2.setDisplayRotation(U8G2_R0); //0度,默认方向
310 | //***** ADC初始化
311 | //ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2); // 设置ADC分频 128倍
312 | ADCSRA |= bit (ADPS1) | bit (ADPS2); //设置ADC分频 64倍
313 | ADCSRA |= bit (ADIE); // 开启ADC中断
314 | interrupts(); // 开启全局中断
315 | //***** 打开外部中断
316 | attachInterrupt(digitalPinToInterrupt(CLK), xuan_zhaun, FALLING);
317 | attachInterrupt(digitalPinToInterrupt(DT), xuan_zhaun, FALLING);
318 |
319 | //***** 播放开机画面和开机声
320 | kj_display();
321 | buzzer(600, 200); //时间,次数
322 | buzzer_run();
323 | buzzer(400, 300); //时间,次数
324 | buzzer_run();
325 | buzzer(130, 1000); //时间,次数
326 | buzzer_run();
327 | //读取电压/温度
328 | for (uint8_t i = 0; i < 10; i++) //读取初始值
329 | {
330 | vin_read();
331 | tc1047_temp_read();
332 | read_t12_temp();
333 | }
334 | //自动获取设置温度的范围
335 | auto_get_set_temp();
336 | //***** 开启看门狗
337 | //set_wdt_mod(1, 7);
338 | //***** 是否开机加热
339 | if (t12_kj_jr == 1) t12_switch = 1;
340 | else t12_switch = 0;
341 | //***** 开机计算曲线拟合系数
342 | qxnh_run();
343 | //Serial.begin(9600); //打开串口调试
344 | }
345 |
346 | void loop()
347 | {
348 | //uint32_t time0 = micros();
349 |
350 | __asm__ __volatile__ ("wdr"); //看门狗复位
351 | an_xia(); //编码器按下决策
352 | draw_page(); //刷新屏幕
353 | buzzer_run(); //蜂鸣器运行决策
354 | read_timing(); //定时读取任务
355 | MsTimer2_rw1(); //定时器2任务
356 |
357 | //uint32_t time1 = micros();
358 | //Serial.println(time1 - time0);
359 | }
360 |
--------------------------------------------------------------------------------
/v1.20.1/v1.20.1.ino.eep:
--------------------------------------------------------------------------------
1 | :00000001FF
2 |
--------------------------------------------------------------------------------
/用到的库/MsTimer2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/用到的库/MsTimer2.zip
--------------------------------------------------------------------------------
/用到的库/U8g2-2020-11-15.7z:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sakura-ushio/328P-MiNi-T12/cc4f56ff197394a046ffdd6df54034baf6ea7b17/用到的库/U8g2-2020-11-15.7z
--------------------------------------------------------------------------------