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

2020-02-162.4万
精华项目
AI 快速预览详细 收起
本项目介绍了一种在疫情期间自制红外测温枪的方法。使用Arduino Nano 328p作为主控,搭配MLX90614红外测温模块、Gravity: I2C 3.7V锂电池电量计和0.96寸OLED显示屏等组件。最终效果是能够显示体温、室温和电量,并且内置锂电池可充电。难度适中,适合有一定电子基础的DIY爱好者。
疫情期间在家自制一把红外测温枪,每天给家人量体温

——使用Arduino Nano和MLX90614红外测温模块



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

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

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

肺炎疫情期间,在家自制红外测温枪图3
材料清单:
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屏、电量计、激光头通过电子线焊接到主控板上
肺炎疫情期间,在家自制红外测温枪图4

第三步:制作锂电池一分二电源线、Micro USB延长线和USBA插头线
肺炎疫情期间,在家自制红外测温枪图5
一分二电源线用于分别给升压模块供电和电量计检测电量(拨动开关焊接到电源线上)

肺炎疫情期间,在家自制红外测温枪图6
USB延长线用于连接升压模块

肺炎疫情期间,在家自制红外测温枪图7
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]

第五步:安装各模块(使用热熔胶和美纹纸包裹端点,防止短路),完成组装
肺炎疫情期间,在家自制红外测温枪图8

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

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


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

项目附件下载:
下载附件Project file.zip

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(10)
这个人很菜
这个人很菜
好评大佬,电量显示很实用呢
aliteamer
aliteamer
作者
回复这个人很菜
哈哈,不然没电了就尴尬了
想成为蟑螂恶霸
想成为蟑螂恶霸
啊哈哈哈 这个可以 非常实用
laai
laai
顶起~好帖,用MIND+编程可以实现同样效果吗
aliteamer
aliteamer
作者
回复laai
用MIND+的话就得用DF的OLED屏了~
chenhanzhong
chenhanzhong
很赞!!!
DFrJ5KYVQaH
DFrJ5KYVQaH
太棒了,一定好好学习
kylinpoet
kylinpoet
又是一篇好文,支持。
rzegkly
rzegkly
喜欢,好文章!
aliteamer
aliteamer
作者
回复rzegkly
哈哈,第一次写,没什么经验,请前辈们多多指教
glwz007
glwz007
知道了,传感器自身输出两个温度。
aliteamer
aliteamer
作者
回复glwz007
对的,这个传感器可以测量目标温度和环境温度
glwz007
glwz007
请问环境温度怎么取得?
rzyzzxw
rzyzzxw
这个项目很棒啊
aliteamer
aliteamer
作者
回复rzyzzxw
谢谢版主的认可
- 没有更多了 -