11506| 15
|
[项目] 肺炎疫情期间,在家自制红外测温枪 |
疫情期间在家自制一把红外测温枪,每天给家人量体温 ——使用Arduino Nano和MLX90614红外测温模块 新冠肺炎疫情已经爆发一个多月了,各位老铁想必在家也快憋疯了。先前是口罩被抢购一空,现在测温枪也是不太好买,正好在家“自我隔离”,突然想起库存里还有一个红外测温模块,碰巧看到之前一位大神自制的红外测温枪,就借用了下大神设计的模型稍加改动(物理破坏),加上手边的一些元器件,做了一个测温枪。屏幕可显示体温(目标温度),室温(环境温度)、电量和体温情况,内置锂电池,可充电。 主控使用了Arduino Nano 328p(因为是手头最小的板子了),传感器使用了MLX90614红外测温模块(测温)和Gravity: I2C 3.7V锂电池电量计 (电量检测),显示屏使用了常见的0.96寸OLED屏(IIC)。因为制作之前没有拍照片,只有制作完成后的照片,所以各位看官老爷凑合看吧。 材料清单: 1.Arduino Nano 328p 1只 2.MLX90614非接触式红外温度传感器 1只 3.Gravity: I2C 3.7V锂电池电量计 1只 4.MP2636充电升压模块 1只 5.0.96寸OLED显示屏 1只 6.3.7V 1800mAh 锂电池 1只 7.USBType-A 公头、Micro USB公头、Micro USB母头 各1只 8.5V 6MM激光头 1只 9.拨动开关 1只 10.3D打印外壳 11.电子线、热缩管 若干 12.PH2.0公头2只、母头1只 工具: 1.TS100 烙铁 2.ANYCUBIC i3 Mega 3.热熔胶枪 软件: 1.Arduino IDE(我用的是1.6.6版本的) 2.PCtoLCD2002取模软件 3.Cura 15.04.6切片软件 制作过程: 第一步:将Nano板的排针全部拆下 第二步:将测温模块、OLED屏、电量计、激光头通过电子线焊接到主控板上 第三步:制作锂电池一分二电源线、Micro USB延长线和USBA插头线 一分二电源线用于分别给升压模块供电和电量计检测电量(拨动开关焊接到电源线上) USB延长线用于连接升压模块 USBA插头线给主板供电 第四步:上传程序(有一部分多余代码懒得删了) [mw_shl_code=c,false]#include "U8glib.h" U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI static const unsigned char shiwen[3][32] PROGMEM={ {0x40,0x00,0x80,0x00,0xFE,0x7F,0x02,0x40,0x01,0x20,0xFC,0x1F,0x20,0x00,0x10,0x04, 0xF8,0x0F,0x80,0x08,0x80,0x00,0xFC,0x1F,0x80,0x00,0x80,0x00,0xFF,0x7F,0x00,0x00},/*"室",0*/ /* (16 X 16 , 宋体 )*/ {0x00,0x00,0xC4,0x1F,0x48,0x10,0x48,0x10,0xC1,0x1F,0x42,0x10,0x42,0x10,0xC8,0x1F, 0x08,0x00,0xE4,0x3F,0x27,0x25,0x24,0x25,0x24,0x25,0x24,0x25,0xF4,0x7F,0x00,0x00},/*"温",1*/ /* (16 X 16 , 宋体 )*/ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00},/*":",2*/ /* (16 X 16 , 宋体 )*/ }; static const unsigned char tiwen[3][32] PROGMEM={ {0x10,0x02,0x10,0x02,0x10,0x02,0x08,0x02,0xE8,0x3F,0x0C,0x02,0x0C,0x07,0x0A,0x07, 0x89,0x0A,0x88,0x0A,0x48,0x12,0xA8,0x2F,0x18,0x42,0x08,0x02,0x08,0x02,0x08,0x02},/*"体",0*/ /* (16 X 16 , 宋体 )*/ {0x00,0x00,0xC4,0x1F,0x48,0x10,0x48,0x10,0xC1,0x1F,0x42,0x10,0x42,0x10,0xC8,0x1F, 0x08,0x00,0xE4,0x3F,0x27,0x25,0x24,0x25,0x24,0x25,0x24,0x25,0xF4,0x7F,0x00,0x00},/*"温",1*/ /* (16 X 16 , 宋体 )*/ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00},/*":",2*/ /* (16 X 16 , 宋体 )*/ }; static const unsigned char sheshidu[1][32] PROGMEM={ {0x06,0x00,0x89,0x2F,0x69,0x30,0x36,0x20,0x10,0x20,0x18,0x00,0x18,0x00,0x18,0x00, 0x18,0x00,0x18,0x00,0x18,0x00,0x10,0x00,0x30,0x20,0x60,0x10,0x80,0x0F,0x00,0x00},/*"℃",0*/ /* (16 X 16 , 宋体 )*/ }; static const unsigned char zhengchang[2][32] PROGMEM={ {0x00,0x00,0xFE,0x3F,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x88,0x00,0x88,0x1F, 0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0x88,0x00,0xFF,0x7F,0x00,0x00},/*"正",0*/ /* (16 X 16 , 宋体 )*/ {0x80,0x00,0x88,0x08,0x90,0x04,0xFE,0x7F,0x02,0x40,0xF9,0x2F,0x08,0x08,0xF8,0x0F, 0x80,0x00,0xFC,0x1F,0x84,0x10,0x84,0x10,0x84,0x14,0x84,0x08,0x80,0x00,0x80,0x00},/*"常",1*/ /* (16 X 16 , 宋体 )*/ }; static const unsigned char yichang[2][32] PROGMEM={ {0x00,0x00,0xFC,0x0F,0x04,0x08,0x04,0x08,0xFC,0x0F,0x04,0x20,0x04,0x20,0xF8,0x3F, 0x00,0x00,0x10,0x04,0x10,0x04,0xFF,0x7F,0x10,0x04,0x08,0x04,0x04,0x04,0x02,0x04},/*"异",0*/ /* (16 X 16 , 宋体 )*/ {0x80,0x00,0x88,0x08,0x90,0x04,0xFE,0x7F,0x02,0x40,0xF9,0x2F,0x08,0x08,0xF8,0x0F, 0x80,0x00,0xFC,0x1F,0x84,0x10,0x84,0x10,0x84,0x14,0x84,0x08,0x80,0x00,0x80,0x00},/*"常",1*/ /* (16 X 16 , 宋体 )*/ }; static const unsigned char dl[4][32] PROGMEM={ {0x80,0x00,0x80,0x00,0x80,0x00,0xFC,0x1F,0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F, 0x84,0x10,0x84,0x10,0x84,0x10,0xFC,0x1F,0x84,0x50,0x80,0x40,0x80,0x40,0x00,0x7F},/*"电",0*/ /* (16 X 16 , 宋体 )*/ {0x00,0x00,0xF8,0x0F,0x08,0x08,0xF8,0x0F,0x08,0x08,0xFF,0x7F,0x00,0x00,0xF8,0x0F, 0x88,0x08,0xF8,0x0F,0x88,0x08,0xF8,0x0F,0x80,0x00,0xF8,0x0F,0x80,0x00,0xFE,0x3F},/*"量",1*/ /* (16 X 16 , 宋体 )*/ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00},/*":",2*/ /* (16 X 16 , 宋体 )*/ {0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x08,0x62,0x04,0x63,0x04,0x63,0x02,0x62,0x01, 0x9C,0x3C,0x40,0x62,0x20,0x42,0x20,0x42,0x10,0x62,0x08,0x3C,0x00,0x00,0x00,0x00},/*"%",0*/ /* (16 X 16 , @宋体 )*/ }; #include <Wire.h> #include <IR_Thermometer_Sensor_MLX90614.h> #include "DFRobot_MAX17043.h" IR_Thermometer_Sensor_MLX90614 MLX90614 = IR_Thermometer_Sensor_MLX90614(); //电量检测模块初始化 #ifdef __AVR__ #define ALR_PIN 2 #else #define ALR_PIN D2 #endif #define PRINT_INTERVAL 2000 DFRobot_MAX17043 gauge; uint8_t intFlag = 0; void interruptCallBack() { intFlag = 1; } void draw(void) { // graphic commands to redraw the complete screen should be placed here u8g.setFont(u8g_font_fub14); //u8g.setFont(u8g_font_osb21); //u8g.drawStr( 0, 20, "Hello World!"); //体温显示 u8g.drawXBMP( 0, 4,16, 16, tiwen[0]); u8g.drawXBMP( 16, 4,16, 16, tiwen[1]); u8g.drawXBMP( 32, 4,16, 16, tiwen[2]); float O = MLX90614.GetObjectTemp_Celsius(); u8g.setPrintPos(40,19); u8g.print(O); u8g.drawXBMP( 92, 4,16, 16, sheshidu[0]); //室温显示 u8g.drawXBMP( 0, 24,16, 16, shiwen[0]); u8g.drawXBMP( 16, 24,16, 16, shiwen[1]); u8g.drawXBMP( 32, 24,16, 16, shiwen[2]); float A = MLX90614.GetAmbientTemp_Celsius(); u8g.setPrintPos(40,39); u8g.print(A); u8g.drawXBMP( 92, 24,16, 16, sheshidu[0]); //电量显示 u8g.drawXBMP( 0, 44,16, 16, dl[0]); u8g.drawXBMP( 16, 44,16, 16, dl[1]); u8g.drawXBMP( 32, 44,16, 16, dl[2]); u8g.setPrintPos(40,59); u8g.print(gauge.readPercentage()); u8g.drawXBMP( 92, 44,16, 16, dl[3]); //体温判断 u8g.drawXBMP( 111, 0,16, 16, tiwen[0]); u8g.drawXBMP( 111, 16,16, 16, tiwen[1]); u8g.drawXBMP( 111, 48,16, 16, zhengchang[1]); if(32 <= O && O <37.3){ u8g.drawXBMP( 111, 32,16, 16, zhengchang[0]); } else{ u8g.drawXBMP( 111, 32,16, 16, yichang[0]); } } void setup(void) { // flip screen, if required // u8g.setRot180(); // set SPI backup if required //u8g.setHardwareBackup(u8g_backup_avr_spi); // assign default color value if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255); // white } else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) { u8g.setColorIndex(3); // max intensity } else if ( u8g.getMode() == U8G_MODE_BW ) { u8g.setColorIndex(1); // pixel on } else if ( u8g.getMode() == U8G_MODE_HICOLOR ) { u8g.setHiColorByRGB(255,255,255); } MLX90614.begin(); Serial.begin(115200); while(!Serial); Serial.println(); Serial.println(); pinMode(ALR_PIN, INPUT_PULLUP); attachInterrupt(ALR_PIN, interruptCallBack, FALLING); //default alert is 32% while(gauge.begin() != 0) { Serial.println("gauge begin faild!"); delay(2000); } delay(2); Serial.println("gauge begin successful!"); //gauge.setInterrupt(32); //use this to modify alert threshold as 1% - 32% (integer) } void loop(void) { // picture loop u8g.firstPage(); do { draw(); } while( u8g.nextPage() ); // rebuild the picture after some delay delay(500); static unsigned long lastMillis = 0; if((millis() - lastMillis) > PRINT_INTERVAL) { lastMillis = millis(); Serial.println(); Serial.print("voltage: "); Serial.print(gauge.readVoltage()); Serial.println(" mV"); Serial.print("precentage: "); Serial.print(gauge.readPercentage()); Serial.println(" %"); } if(intFlag == 1) { intFlag = 0; gauge.clearInterrupt(); Serial.println("Low power alert interrupt!"); //put your battery low power alert interrupt service routine here }· } [/mw_shl_code] 第五步:安装各模块(使用热熔胶和美纹纸包裹端点,防止短路),完成组装 资料下载: 0.96寸OLED屏相关资料:示例程序、库文件、取模软件等 网盘链接 提取码:vktz 项目附件下载: Project file.zip |
© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed