带 Arduino 和蓝牙的智能咖啡机
组件和用品
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
应用和在线服务
| ||||
|
关于这个项目
简介
带Graph的智能全自动咖啡机,可通过蓝牙控制...或只需加载新鲜水,系统将自动启动!
每一个零件都是手工制作的,所有的功能都是我自己的想法。
我也编码了“测试模式”,因此控制器可以用作带有外部温度传感器的多功能温度计。
在 Arduino 上开发 Nano / Uno,使用 ST7920 显示 , HC-05 蓝牙 适配器,达拉斯 DS18B20 温度传感器 , 继电器控制加热器线圈,带 LED 的按钮,蜂鸣器和 CD4017BE 十进制计数器驱动 LED 条。
如何开始
- 自动启动 :在待机模式下,系统会在后台循环测量温度。加载淡水导致温度下降 , 系统将启动。
此功能可以通过从智能手机发送“自动”来启用/禁用,设置将存储在 EEPROM 内存中。 - 按下按钮 :开始/中断咖啡制作,或退出测试模式。
- 发送“开始”消息 从您的智能手机,或“停止 ".
视频
显示所有工作方式。
照片库
它是如何制作的,它的样子......只需点击/点击下方!
图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图> 图>
咖啡制作过程中的一次性分析
启动 60 秒后,MCU 会比较存储的初始温度值和当前温度值,以便仅根据温度和经过时间得出结论,可以是:
- "你忘记喝水了。 " - (温度过高)
- "两人份咖啡。 “ - (更少的水 - 更多的温度升高)
- "六人咖啡。 “ - (更多的水 - 降低温度升高)
- "加热线圈错误! " -(没有明显的温度升高)
此外传感器错误检测 只要咖啡机打开,就可以连续工作。
可以看出,六剂水需要更多的时间才能达到相同的温度,而小剂量的水则要快得多。
无水启动导致温度非常高,但平线表示温度不变,因此加热器线圈错误。
更改测量单位
可以通过发送“c”更改测量单位 " 或 "f " 来自智能手机,即使在咖啡制作过程中,并且它不会在图表上留下任何标记 .
存储的初始和以前的温度值将被转换 通过我编码的程序函数调用 - 用于统计和分析。此设置也存储在 EEPROM 存储器中。
动态屏幕元素
如果屏幕已满,则图形开始向左滚动。
某些屏幕元素可能会妨碍测量值,具体取决于测量值。为了避免碰撞,它们的位置是动态的。
这六个小动画图像 显示我编码的内容:
嗯,这是一个愉快的消遣:
测试模式
当我创建所有这些时,想法出现了,为什么不将图表用于其他目的?
所以我编写了测试模式;只需外接温度传感器,系统即可作为带图形的多用途温度计使用。
在这种工作方式中,图表的极值是 -20°C (-4°F) 和 +128°C (+262°F) .
在 1 之间从智能手机发送号码 和 999999 将被接受为以秒为单位的测量间隔,因此图形的宽度在 128 秒之间 和 11.57 天 .
蓝牙通讯
接受命令并发送报告,检测智能手机是否连接或断开连接。
已发送消息为蓝色,响应/报告消息为咖啡机发送的绿色。
LED控制
CD4027BE 十进制计数器驱动 LED 条,在每次温度测量时从 MCU 接收 CLK,并增加位置。如果新的咖啡制作程序或测试模式启动,Atmega 328P 会发送 RST 信号以设置默认位置。
按钮有一个双色LED,只有两个引脚,所以我的简单有趣的解决方案可以在代码中看到,如何控制它。
- 纯绿色 :待机或咖啡已准备好,线圈关闭
- 纯红色 :正在制作咖啡,加热器线圈开启
- 红/绿交替 :测试模式
- 闪烁的红色 :发生错误,可能是
-传感器错误,
-加热器线圈错误,或
-您忘记放水,因此咖啡制作过程被系统中断
代码
- 智能咖啡机 - Ősi Gyula
智能咖啡机 - Ősi GyulaArduino
// 程序代码 - 智能咖啡机。在 Arduino Nano 上开发,使用 ST7920 显示器、HC-05 蓝牙适配器、//达拉斯 DS18B20 温度传感器、继电器、按钮、LED、蜂鸣器和 CD4017BE 十进制计数器。//// 可以通过发送命令和工作参数通过蓝牙进行控制或者使用按钮...或者直接加载淡水!//// Functions:// -Graph:屏幕上的动态温度图// -Autostart:加载淡水导致温度下降,系统将启动//这个功能可以通过发送“自动”来启用/禁用,设置将存储在 EEPROM 存储器中// - 咖啡制作过程中分析:系统启动后 60 秒比较当前和初始温度值// 并得出结论be:// 1. 您忘记了水(温度太高)// 2. 两人份咖啡(水少 - 温度升高)// 3. 六人咖啡(水多 - 温度升高少)// 4.加热线圈错误(从开始没有显着的温度升高)// -传感器错误检测(获取异常值)// -C elsius 或 Fahrenheit 工作:可以通过从智能手机发送 C 或 F 来切换,即使在咖啡制作过程中。// 初始和先前的温度值将被转换用于统计和分析。// 此设置存储在 EEPROM 内存中.// - 测试模式:连接外部温度传感器,系统可用作多功能温度计。// 在此模式下,图形间隔在 -20C / -4F 和 +128C / +262F 之间。// 发送数值1 到 999999 之间将被接受为以秒为单位的测量间隔,因此 // 图形宽度可以介于 128 秒和 11.57 天之间。// - 蓝牙通信:接受命令并发送报告,检测智能手机是否连接或断开 // - LED条控制:MCU控制一个CD4027BE十进制计数器,LED条将在所有温度测量周期内步进// ------------------------- -------------------------------------------------- -------------------------------------------------- ---// // 设计、建造t 和编程 // 由 Gyula Osi //// 版权所有。// ---- Display #include "U8glib.h"//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE); // OLED 显示 I2C 总线,SDA(TX) A4,SCL(RX) A5U8GLIB_ST7920_128X64 u8g(11, 10, 9, U8G_PIN_NONE); // 显示构造函数 PIN6-D11, PIN5-D10, PIN4-D9byte frame =0; // 启动徽标指针 // ---- 端口和受控外设// A0 上的红色 LED // A1const 上的 grn 指示灯 int Bright[2] ={0, 500};const byte buzzer =3;const byte cd4017beCLK =4; // 控制CD4017BE 十进制计数器const byte cd4017beRST =5;const byte btn =13;const byte relay =12;// ---- System Strings#define strSize 3String str[strSize]; // 系统事件和报告打印#define reportSize 5const String reportStr[reportSize] ={"Starting...", "Going Stands Soon...", "Stopped.", " *** TEST MODE ***", "普通模式。"};//#define standbySize 5//const String standbyStr[standbySize] ={"Press key", ">", "or", "send", "start"};const String autostartStr[2 ] ={"Autostart off.", "Autostart on."};// ---- 系统状态二进制标志数组的结构 #define flagElements 6bool binFlags[flagElements] ={0, 1, 1, 0, 0, 0 }; // ---- 元素 [i] 目的初始化/待机模式 val // 0 检查 0 // 1 完成 1 // 2 待机 1 // 3 待机消息发送 0 // 4 线圈/传感器错误 0 // 5 测试mode 0// ---- 温度测量及相关特性#include "OneWire.h" #include "DallasTemperature.h"#define DS18B20 2 // 在 D2OneWire temprWire(DS18B20) 上设置 OneWire 总线; // 设置 DS18B20 以在 OneWire 总线上工作达拉斯温度传感器(&temprWire);float tempr; // 测量值float temprInit; // 一次比较测量值的副本float temprPrev; // 循环比较测量值的副本#define mUnit 2float temprBottomLim[mUnit] ={ 0, 26}; // 自动启动在临时分析和临时分析下的临时分析 char unit[mUnit] ={'F', 'C'};const String unitStr[mUnit] ={"Fahrenheit mode.", "Celsius mode."};浮动趋势传感器[mUnit] ={ 0, 0.1}; // +/- 范围 (F/C),它将被评估为恒温 // *** 华氏参考值将在启动时计算!bool 趋势 [2] ={1, 0}; // 描述温度趋势如下 // ---- 元素 [i] 目的 // 0 变化 // 1 趋势 #define checkSize 7const String checkStr[checkSize] ={“检测到水!”,“加热线圈错误!”, “六人咖啡”、“两人咖啡”、“你忘记放水了!”、“传感器错误!”、“你的咖啡准备好了。”};float temprCheck[mUnit][checkSize] ={{ }, {- 0.15, 5, 17, 28, 60, -127, 110}}; // |<-- REL -->|<--CONST-->| // [j] F / C // ---------------------------------------- ----- // ---- 元素 [i] 用途用作 // 0 自动启动 rel 值 // 1 个线圈错误检测 rel 值 // 2 个水用于六个 rel 值 // 3 个水用于两个 rel 值 // 4 无水检测 rel 值 // 5 D2 常量引用上无信号 // 6 沸点常量引用// ---- 图声明和变量#define posYsize 128byte posY[posYsize];byte pointer =0;#define refrElements 42float temprRefr[refrElements];#define rangeElements 2 // min / max#define mode 2 // normal / test modefloat graphRange[mUnit][mode][rangeElements] ={{{ }, { }}, {{24, 127.938889 + 2},{-20,graphRange[1][0][1]}}}; // [k] 0 1 0 1 // [j] | 0 | 1 // ---- 元素 [i] | | | | // 0 minFnorm maxFnorm minFtest maxFtest // 1 minCnorm maxCnorm minCtest maxCtestfloat graphDiff[mUnit][mode]; // 温度的垂直步长 // ---- 系统定时器、控制和分析#includeelapsedMillis timer0; // 8 位,PWM 定时器,由函数 elapsedMillis() 使用 unsigned long tmrPrev =0; // 当间隔为 upbool cyclic =0;const long tmrInt[5] ={500, 2000, 60000, 640000, 800000}; // ---- 元素 [i] 目的 // 0 测量间隔(测试模式),led ctrl // 1 测量间隔(正常模式)// 2 一次分析(正常模式,在咖啡制作过程中)/循环分析(待机模式) // 3 发送待机消息(正常模式,咖啡制作后)// 4 系统待机(正常模式,咖啡制作后)long copyof_tmrInt0 =tmrInt[0]; const String tmrInt0Str ="间隔改变。"; // ---- 串口通信配置const byte btState =6;bool conn =0;const String connStr[2] ={"Connection lost.", "Smartphone connected."};#include const int RX1 =7;const int TX1 =8;SoftwareSerial sUART(RX1,TX1); #define exRXSize 6char exRX[exRXSize]; // 从串口接收数据的变量// ---- Memory Management#include #define occBytes 2const byte addr[occBytes] ={ 0, 1};bool sysSettings[occBytes]; // ---- 内存映射 addr[i] |数据|描述 |存储值 // ---------------------------------------------- ------- // 0 |布尔 |自动启动 | 0:不自动启动,1:自动启动 // 1 |布尔 |测量单位| 0:华氏度, 1:摄氏度// ---- 终结者与清理 Crewconst char termCharSpc =' ';const String termStr;const byte termByte =0;const bool termBool =0;const uint8_t frame0[] U8G_PROGMEM ={ 0xFF, 0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFC, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF,0xFF,0xFF 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFC, 0xFF, 0x7F, 0xF0, 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF、0xFF、0x8F、0xFF、0xFF、0xFF , 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0x8F, 0xFF, 0x1F, 0x7F, 0x8C, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF , 0x00, 0x18, 0xC0, 0x8F, 0xFF, 0x1F, 0x7F, 0x8C, 0x3F, 0x1E, 0xFF, 0x00, 0xFE, 0x1F, 0xFF, 0xF1, 0xF, 0xC, 0xF, 0xC, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xC, 0xF , 0x1E, 0xFF, 0xFF, 0xF8, 0x1F, 0xFF, 0x31, 0xFE, 0x7F, 0xFC, 0x8F, 0xFF, 0x1F, 0x1F, 0x0C, 0x3E, 0x,7FF,0x,Fx,7FF,0x,F0x,7FF,0x1E, 0xFE, 0x1E , 0xFC, 0x0F, 0x0E, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0xFC, 0x00, 0xF8, 0x1F, 0x7C, 0x30, 0xFE, 0x7F,0xE,0xE,0xE,0xE,0xE,0xF,0xE,0xF,0xF,0xF,0xF,0xF,0xF,0x ,0x00时,0xF8的,为0x1F,0x7C,的0x30,0xFE的,0x7F的,0XF0,为0x0F,0xFE的,为0x18,0x1F的,0x0C,0x3E的,0X1E,为0x3C,0x3E的,0xF8的,为0x1F,0x7C,0XF0,0x00时,0x7E的,0XF0,为0x0F ,0xFE的,为0x18,0x1F的,0x0C,0x3E的,0X1E,为0x3C,0x3E的,0xF8的,为0x1F,0x7C,0XF0,0x00时,0x7E的,0XF0,为0x0F,0xFE的,为0x18,0x1F的,0x0C,0x3E的,0X1E,为0x3C,0x3E的,0xF8的, 0x1F, 0x7C, 0xF0, 0x3F, 0x78, 0xF0, 0x0F, 0xFE, 0x18, 0x1F, 0x0C, 0x3E, 0x1E, 0x3C, 0x3E的,0xF8的,为0x1F,0x7C,0XF0,0x3F的,0x78,0XF0,为0x0F,0xFE的,为0x18,0x1F的,0x0C,0x3E的,0X1E,为0x3C,0x3E的,0xF8的,为0x1F,0x7C,0XF0,0x3F的,0x78,0XF0,为0x0F, 0xFE的,为0x18,0x1F的,0x0C,0x3E的,0X1E,为0x3C,0x3E的,0xF8的,为0x1F,0x7C,0XF0,0x3F的,0x78,0XF0,0x3F的,0×00,的0x7E,0x00时,为0x3C,0x80的,0×07,0XF0,0x00时,0xF8的, 0x7F, 0x00, 0x3C, 0x00, 0x1E, 0xC0, 0x3F, 0x00, 0x7E, 0x00, 0x3C, 0x80, 0x07, 0xF0, 0x00, 0x7,0FF, 0xC,0FF,0x,0FF,0x,0FF, 0x,0FF, 0x, 0x, 0x, 0x, 0x, 0x, 0x, 0x 0x1F、0xFC、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0x1F、0xFC、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF 0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0x FF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x,0,0000, 0x,00000为0x00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,为0x00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00 ,为0x00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00 ,为0x00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00 ,为0x00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x7E的,0×06,0xE6,0x3F的,0×06,0xC6,0x7F的,0xFE的,0xE7,0x3F的,的0x7E,0xFE的,0xC7,0x7F的,0x00时,0×00,的0x30,0×06,0x66,0x60的,0×06,0x66,0x00时,0x60的,0x60的,0x60的,的0x30,0×06,0x60的,为0x00,0x00时,0×00,的0x30,0×06,0x66,0x60的,0×06,0x66,0x00时,0x60的,0x60的,0x60的,的0x30,0×06,0x60的,0×00,0x00时,0×00,的0x30,0X1E,0x66,0x60的,0×06,0x66 , 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x30, 0x3E, 0x66, 0x60, 0 x06, 0x66, 0x00, 0x60, 0x60, 0x60, 0x30, 0x06, 0x60, 0x00, 0x00, 0x00, 0x3C, 0x7E, 0xE6, 0x61, 0xE, 0xE, 0xF, 0xE, 0xE, 0xE, 0xF, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE, 0xE 0x3F, 0x00, 0x00, 0x3C, 0x7E, 0xE6, 0x61, 0x1E, 0xC7, 0x3F, 0x70, 0xE0, 0x3F, 0x3C, 0xFE, 0x3,0xE,0xE,0xE,0xE,0xE,0xE,0xE,0xE,0xE,0xE,0x 0x70,0x70,取0xE0,0x1D,为0x3C,0X1E,0x00时,0x70,0x00时,0×00,为0x3C,0X1E,0xE7,0x61,0X1E,0×07,0x70,0x70,取0xE0,0X31,为0x3C,0X1E,0x00时,0x70,0x00时, 0x00时,为0x3C,0X1E,0xE6,0x61,0X1E,0×07,0x70,0x70,取0xE0,0x61,为0x3C,0X1E,0x00时,0x70,0x00时,0×00,为0x3C,0X1E,0xE6,0x61,0X1E,0×07,0x70,0x70, 0xE0, 0x61, 0x3C, 0x1E, 0x00, 0x70, 0x00, 0x00, 0x7F, 0x1E, 0xE6, 0x3F, 0xFC, 0xE3, 0x3F, 0x70,0x,0x,0x,0x,0x,0x,0x,0x,0x,0x,0x,0x,0x,0为0x00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x,0,0x,0,0,0x,0,0,0,0x,0,0,0x,0,0为0x00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00,0x00时,0×00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0 0x00, 0x00, 0x00, 0x00, 0x00, 0 内存={0xF8的,// 11111000 00 0×21,// 00100001 01为0x22,// 00100010 02 0X24,// 00100100 03 0x08时,// 00001000 04为0x10,// 00010000 05 0X24,// 00100100 06 0×44,// 01000100 07 0x0F, // 00001111 08 0x04, // 00000100 09 0x04, // 00000100 10 0x03, // 00000011 11};const uint8_t frame2[] PROGMEM, // 0x10, // 010, // 010, // 010 00111110 02 0x7F, // 01111111 03};const uint8_t frame3[] PROGMEM ={ 0x7F, // 01111111 00 0x3E, // 00111110 01 0x1C, 008 0x111, // 008 008 08 08 08 08 。开始();填充数组(); pinMode(cd4017beCLK,输出); pinMode(cd4017beRST,输出); CD4017BE(0); // 发送复位到十进制计数器 IC pinMode(btState, INPUT); pinMode(btn, 输入); pinMode(继电器,输出);串口.开始(9600);备忘录(2); // 从 EEPROM 传感器加载系统设置。开始(); // 启动 DS18B20 temprMeas(); temprInit =tempr;图(2); // 初始化图 ledHandler(0);}void loop() { sysControl(); checkBtn(); checkConn(); RX(); u8g.firstPage();做{画(); } while(u8g.nextPage());如果(帧 ==0){ 延迟(3000);帧 =1; scrClr(); }} // ---- 内存管理 // 调用参数 // 2:启动时读取 // 0, 1:写入正确的地址 //void memo(byte op) { switch(op) { case 2:for (字节 i =0; i tmrInt[2]) &&(!binFlags[5])) { if (binFlags[2]) { temprMeas(); if ((tempr - temprInit <=temprCheck[sysSettings[1]][0]) &&(tempr =temprCheck[sysSettings[1]][6]) &&(!binFlags[1])) { // 检查沸点线圈(0); strSelector(0, 6); } if ((timer0> tmrInt[3]) &&(!binFlags[2]) &&(!binFlags[3])) { // 进入待机状态和第二次安全检查 strSelector(1, 1); binFlags[3] =1; if (!binFlags[1]) { // for case if the coil went broken after the One Time Analysis coil(0); // and therefore there was no boiling point strSelector(0, 1); } } if (timer0> tmrInt[4]) { // the system goes standby binFlags[2] =1; strSelector(6, 0); } }void temprMeas() { temprPrev =tempr; sensors.requestTemperatures(); // update sensor readings if (sysSettings[1]) { tempr =sensors.getTempCByIndex(0); // read remperature } else { tempr =sensors.getTempFByIndex(0); } if (tempr>=temprPrev + trendSens[sysSettings[1]]) { trend[0] =0; trend[1] =1; } if (tempr <=temprPrev + trendSens[sysSettings[1]]) { trend[0] =0; trend[1] =0; } if ((tempr temprPrev - trendSens[sysSettings[1]])) { trend[0] =1; }} // ---- Coil Control // 0:power off // 1:power onvoid coil(byte op) { switch (op) { case 0:digitalWrite(relay, 0); binFlags[1] =1; strSelector(1, 2); ledHandler(0);休息; case 1:digitalWrite(relay, 1); strSelector(6, 0); CD4017BE(0); graph(1); for (byte i =0; i 0; i--) { str[i] =termStr; } return; } TX(); for (byte i =(strSize - 1); i> 0; i--) { // roll for printout str[i] =str[i - 1]; } buzz(4, 1); }void draw(void) { if (frame ==0) { u8g.drawXBMP( 0, 0, 128, 64, frame0); } else { if (frame ==1) { scr(); } }}void scr(void) { if (binFlags[2]) { #define standbySize 4 const String standbyStr[standbySize] ={"Press key>>>>", "or", "send", "start"}; u8g.setFont(u8g_font_courB10); u8g.setPrintPos(2, 12); u8g.print(standbyStr[0]); u8g.setPrintPos(14, 26); u8g.print(standbyStr[1]); u8g.setPrintPos(30, 40); u8g.print(standbyStr[2]); u8g.setColorIndex(!cyclic); u8g.drawBox(74, 28, 50, 14); u8g.setColorIndex(cyclic); u8g.setPrintPos(76, 40); u8g.print(standbyStr[3]); u8g.setColorIndex(1); } else { if ((posY[0]>=20) || (posY[13]>=20)) { u8g.drawBitmapP( 5, 0, 1, 12, frame1); } else { u8g.drawBitmapP( 5, 25, 1, 12, frame1); } if ((posY[54]>=30) || (posY[112]>=30)) { u8g.drawHLine(69, 40, 53); scrTempr(72, 12); } else { scrTempr(72, 44); } for (byte i =0; i 0) { u8g.drawVLine(i, posY[i], 2); } } } u8g.setFont(u8g_font_6x12); byte y =53; for (byte i =(strSize - 1); i> 0; i--) { u8g.setPrintPos(0, y); y =y + 9; u8g.print(str[i]); } }void scrTempr (byte tX, byte tY) { u8g.drawVLine(2, 4, 39); u8g.drawHLine(0, 40, 69); u8g.drawHLine(0, posY[pointer - 1], 5); byte tXrel =2; byte tYrel =11; if ((tempr <100) &&(tempr> -10)) { u8g.drawFrame(tX - tXrel, tY - tYrel, 45, 13); u8g.drawHLine(116, 40, 12); } else { u8g.drawFrame(tX - tXrel, tY - tYrel, 51, 13); u8g.drawHLine(122, 40, 6); } u8g.setFont(u8g_font_6x12); u8g.setPrintPos(tX, tY); u8g.print(tempr); u8g.print(char(176)); u8g.print(unit[sysSettings[1]]); if (trend[0]) { return; } tXrel =12; if (trend[1]) { u8g.drawBitmapP(tX - tXrel, tY - tYrel, 1, 4, frame2); } else { u8g.drawBitmapP(tX - tXrel, tY - tYrel, 1, 4, frame3); }}void scrClr(){ u8g.firstPage(); do { } while(u8g.nextPage());} // ---- Maintenance of Graph Arrays // call param // 0:step &fill // 1:clr // 2:initvoid graph(byte op) { switch (op) { case 0:if (pointer ==posYsize) { for (byte i =0; i <(posYsize - 1); i++) { posY[i] =posY[i + 1]; posY[i + 1] =termByte; } pointer =posYsize - 1; } for (byte i =0; i =temprRefr[i + 1])) { posY[pointer] =i;返回; } } break; case 1:for (byte i =0; i 0) &&(atof(exRX)>=1) &&(atof(exRX) <=999999)) { copyof_tmrInt0 =(atof(exRX) * 1000); strSelector(5, 0); } for (byte i =0; i
示意图
制造工艺