将热像仪连接到微控制器? 没问题! 特别是如果它是带有USB主机接口的STM32和Dadget的Seek热成像仪!
通过SeekThermal热成像仪的眼睛焊接烙铁引言
我认为每个人都曾经遇到过像热成像仪这样的小工具,至少他们已经读过了。 在这些设备中,有整个小配件的子类,它们不是独立的设备,而是用作计算机或智能手机的机顶盒。
今天,我们将讨论将
Seek热成像仪连接到STM32微控制器。 而Dadget公司为我提供了此设备。 在Geektimes的广阔发展中,人们不止一次地考虑了这种热成像仪:它主要涵盖了其在Android上的工作,以及有关将该设备连接到PC的文章。 在我的评论中,我想谈谈我自己通过USB主机将Seek热成像仪连接到STM32微控制器的经历。
硬件要求
没有那么具体! 您所有的STM32应该具有一个能够在主机模式下工作的USB接口和一些用于控制LCD屏幕的接口。 最明显的选择是采用STM32F4-发现。 我手上有STM32F746G-发现板。 因此,说明将针对该板,但是! 因为 如果代码是在CubeMX环境中生成的,则可以使用另一个EVM。 我认为我为此项目支付的款项过多。
软件部分
通过USB进行通信时,此热像仪不会实现任何类别。 所有交互都直接进行,批量请求通过端点进行。 通过将命令(请求)发送到控制端点,您可以打开热成像仪,进行校准,并使其传输一帧或几帧。 此
论坛中介绍了Seek Thermal的特别详细的工作。
因此,为了使热像仪能够与STM32微控制器一起使用,我们需要:
1)以任何您喜欢的板子的USB主机为例(我以STM32F7 CubeMX样本集中的STM32 USB主机CDC为例);
2)抛出设备类的初始化过程;
3)编写方便的包装程序,以使用读/写功能来控制端点和数据端点;
4)编写将原始数据转换为显示内容的函数;
5)使用LUT(彩色查找表)将单色图像着色。 这种缺陷出现在STM32系列微控制器中,可以用LCD屏幕独立控制。
首先,让我们做一些类似于libusb的文章,这将帮助我们用以下代码链接HAL库:
libusb的过程代码int libusb_control_transfer(libusb_device_handle* dev_handle, uint8_t request_type, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, unsigned char* data, uint16_t wLength, unsigned int timeout) { hUSBHost.Control.setup.b.bmRequestType = request_type; hUSBHost.Control.setup.b.bRequest = bRequest; hUSBHost.Control.setup.b.wValue.w = wValue; hUSBHost.Control.setup.b.wIndex.w = wIndex; hUSBHost.Control.setup.b.wLength.w = wLength; int status; do { status = USBH_CtlReq(&hUSBHost, data, wLength); } while (status == USBH_BUSY); if (status != USBH_OK) { hUSBHost.RequestState = CMD_SEND; return 0; } else { return wLength; } }
然后,我们在
这里 查看vendor_transfer过程。 另外,注意请求
struct Request的列表也没有什么害处。
vendor_transfer程序代码 int vendor_transfer(bool direction, uint8_t req, uint16_t value, uint16_t index, uint8_t * data, uint8_t size, int timeout) { int res; uint8_t bmRequestType = (direction ? LIBUSB_ENDPOINT_IN : LIBUSB_ENDPOINT_OUT) | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_INTERFACE; uint8_t bRequest = req; uint16_t wValue = value; uint16_t wIndex = index; uint8_t * aData = data; uint16_t wLength = size; if (!direction) {
接下来,我们编写接收图片的过程。 CDC示例中没有什么特别的要评论的。
USB数据接收程序 int CAM_ProcessReception(USBH_HandleTypeDef *phost) { USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE; uint16_t length = 0; uint8_t data_rx_state = CDC_RECEIVE_DATA; size = FRAME_WIDTH * FRAME_HEIGHT; int bufsize = size * sizeof(uint16_t); int bsize = 0; while (data_rx_state != CDC_IDLE) { switch(data_rx_state) { case CDC_RECEIVE_DATA: USBH_BulkReceiveData (phost, &rawdata[bsize], 512, InPipe); data_rx_state = CDC_RECEIVE_DATA_WAIT; break; case CDC_RECEIVE_DATA_WAIT: URB_Status = USBH_LL_GetURBState(phost, InPipe); if(URB_Status == USBH_URB_DONE ) { length = USBH_LL_GetLastXferSize(phost, InPipe); bsize+= length; if(((bufsize - length) > 0) && (bsize < bufsize))
另外,我们需要以某种方式在屏幕上绘制接收到的数据。 我注意到在数据的第20个字节(即16位像素阵列)中,存储了有关帧类型的信息。 有几种类型的框架。 我们对校准框架和工作框架感兴趣。 当热像仪关闭窗帘并拍摄“暗度”照片时,将获得校准帧。 拍摄普通照片时,快门会打开。 因此,在工作时,您总是会听到设备点击快门的声音。
屏幕绘制步骤 void BSP_LCD_DrawArray(uint32_t Xpos, uint32_t Ypos, uint32_t width, uint32_t height, uint8_t bit_pixel, uint8_t *pbmp) { uint32_t index = 0; uint32_t index2 = 0;
最后,从中可以看到主循环-剪切了什么地方,插入了什么地方。
主循环 #define DELAY1 10 #define USB_PIPE_NUMBER 0x81 #define FRAME_WIDTH 208 #define FRAME_HEIGHT 156 uint8_t OutPipe, InPipe; uint8_t usb_device_state; uint8_t rawdata[FRAME_HEIGHT*FRAME_WIDTH*2]; uint8_t data[64]; USBH_StatusTypeDef status; uint8_t transf_size; int size; int main(void) { CPU_CACHE_Enable(); HAL_Init(); SystemClock_Config(); CDC_InitApplication(); USBH_Init(&hUSBHost, USBH_UserProcess, 0);
结论
使用微控制器的
热像仪的操作看上去比使用智能手机的操作快得多。 我推荐这个小工具来评估电子设备的热图像。 热像仪的焦距可调,您甚至可以考虑板上的单个电子组件! 总之,您可以从该视频中评估热像仪的速度(大约8-9 fps)