aliteamer 发表于 2020-2-16 14:26:24

肺炎疫情期间,在家自制红外测温枪

疫情期间在家自制一把红外测温枪,每天给家人量体温
——使用Arduino Nano和MLX90614红外测温模块


新冠肺炎疫情已经爆发一个多月了,各位老铁想必在家也快憋疯了。先前是口罩被抢购一空,现在测温枪也是不太好买,正好在家“自我隔离”,突然想起库存里还有一个红外测温模块,碰巧看到之前一位大神自制的红外测温枪,就借用了下大神设计的模型稍加改动(物理破坏),加上手边的一些元器件,做了一个测温枪。屏幕可显示体温(目标温度),室温(环境温度)、电量和体温情况,内置锂电池,可充电。


主控使用了Arduino Nano 328p(因为是手头最小的板子了),传感器使用了MLX90614红外测温模块(测温)和Gravity: I2C 3.7V锂电池电量计 (电量检测),显示屏使用了常见的0.96寸OLED屏(IIC)。因为制作之前没有拍照片,只有制作完成后的照片,所以各位看官老爷凑合看吧。


材料清单:
1.Arduino Nano 328p1只
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插头线给主板供电

第四步:上传程序(有一部分多余代码懒得删了)
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);      // I2C / TWI

static const unsigned char shiwen 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 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 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 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 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 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);
u8g.drawXBMP( 16, 4,16, 16, tiwen);
u8g.drawXBMP( 32, 4,16, 16, tiwen);
float O = MLX90614.GetObjectTemp_Celsius();
u8g.setPrintPos(40,19);
u8g.print(O);
u8g.drawXBMP( 92, 4,16, 16, sheshidu);
//室温显示
   u8g.drawXBMP( 0, 24,16, 16, shiwen);
u8g.drawXBMP( 16, 24,16, 16, shiwen);
u8g.drawXBMP( 32, 24,16, 16, shiwen);
float A = MLX90614.GetAmbientTemp_Celsius();
u8g.setPrintPos(40,39);
u8g.print(A);
u8g.drawXBMP( 92, 24,16, 16, sheshidu);
//电量显示
   u8g.drawXBMP( 0, 44,16, 16, dl);
u8g.drawXBMP( 16, 44,16, 16, dl);
u8g.drawXBMP( 32, 44,16, 16, dl);
u8g.setPrintPos(40,59);
u8g.print(gauge.readPercentage());
u8g.drawXBMP( 92, 44,16, 16, dl);
//体温判断
u8g.drawXBMP( 111, 0,16, 16, tiwen);
    u8g.drawXBMP( 111, 16,16, 16, tiwen);
    u8g.drawXBMP( 111, 48,16, 16, zhengchang);
if(32 <= O && O <37.3){
    u8g.drawXBMP( 111, 32,16, 16, zhengchang);
    }
    else{
      u8g.drawXBMP( 111, 32,16, 16, yichang);
      }
}

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

}

第五步:安装各模块(使用热熔胶和美纹纸包裹端点,防止短路),完成组装







资料下载:
0.96寸OLED屏相关资料:示例程序、库文件、取模软件等 网盘链接 提取码:vktz

项目附件下载:

rzyzzxw 发表于 2020-2-16 15:37:44

这个项目很棒啊{:6_215:}

aliteamer 发表于 2020-2-16 16:03:03

rzyzzxw 发表于 2020-2-16 15:37
这个项目很棒啊

谢谢版主的认可{:6_204:}

glwz007 发表于 2020-2-16 21:00:00

请问环境温度怎么取得?

glwz007 发表于 2020-2-16 21:23:33

知道了,传感器自身输出两个温度。

rzegkly 发表于 2020-2-17 09:33:39

喜欢,好文章!{:6_213:}

aliteamer 发表于 2020-2-17 15:20:24

rzegkly 发表于 2020-2-17 09:33
喜欢,好文章!

哈哈,第一次写,没什么经验,请前辈们多多指教{:5_190:}

aliteamer 发表于 2020-2-17 15:47:12

glwz007 发表于 2020-2-16 21:23
知道了,传感器自身输出两个温度。

对的,这个传感器可以测量目标温度和环境温度

kylinpoet 发表于 2020-2-17 21:53:34

又是一篇好文,支持。

DFrJ5KYVQaH 发表于 2020-2-18 08:32:51

太棒了,一定好好学习

chenhanzhong 发表于 2020-2-18 13:22:28

很赞!!!

laai 发表于 2020-2-26 19:14:57

顶起~好帖,用MIND+编程可以实现同样效果吗

想成为蟑螂恶霸 发表于 2020-3-3 11:45:48

啊哈哈哈 这个可以 非常实用

aliteamer 发表于 2020-3-28 22:39:14

laai 发表于 2020-2-26 19:14
顶起~好帖,用MIND+编程可以实现同样效果吗

用MIND+的话就得用DF的OLED屏了~

Vibranium 发表于 2020-3-31 18:12:52

好评大佬,电量显示很实用呢

aliteamer 发表于 2020-4-1 00:59:03

Vibranium 发表于 2020-3-31 18:12
好评大佬,电量显示很实用呢

哈哈,不然没电了就尴尬了
页: [1]
查看完整版本: 肺炎疫情期间,在家自制红外测温枪