用ESP32与Android 实现热成像

说明:通过ESP32获取AMG8833的温度数据(Arduino IDE),然后通过UDP通信与Android 通信,在Android 上采用双三次插值算法进行插值显示热成像。

先上效果:

  • 左图未插值,右图为插值64*64的结果

点击观看效果视频https://www.bilibili.com/video/BV1Cv411576m

AMG8833热成像模块简单介绍:

AMG8833模块是8*8的红外热传感器阵列,通过IIC通信返回64个独立的温度数据。它的测量温度范围为0~80度,分辨率为2.5度,刷新率为10HZ。供电3-3.6V(模块会带5V转3.3V),SCL、SDA是IIC接口,INT是中断阈值引脚。

ESP32获取AMG8833的数据并通过UDP进行发送:

ESP32获取AMG8833数据主要采用Adafruit AMG88xx Library库,可以直接在Arduino上搜索AMG8833即可找到。

/** ESP32端发送设置的温度Smin、Smax、实际的温度Tmin、Tmax、以及对应64个0-255颜色下标
*/
#include <Wire.h>
#include <Adafruit_AMG88xx.h>
#include <WiFi.h>
#include <AsyncUDP.h> //引用以使用异步UDP
#include <Ticker.h>//时间回调函数
#include <ArduinoJson.h>
//时间回调定义
Ticker ticker1; //声明Ticker对象Adafruit_AMG88xx amg;//WIFI常量定义
const char *ssid="xiaoluo";
const char *password="12345678";char UDPSend_data[100];float pixels[64];//传感器读取的64个数据int Smin=20;//设置的温度
int Smax=30;
int Tmin , Tmax;//实际的温度//UDP定义
AsyncUDP udp;                     //创建UDP对象
unsigned int localUdpPort = 8080; //本地端口号//接收到UDP客户端的信息处理,json格式处理
void onPacketCallBack(AsyncUDPPacket packet)
{StaticJsonBuffer<2048> jsonBuffer;JsonObject& root = jsonBuffer.parseObject(packet.data());int a= root["DICar"]["data"];if(a==1){Smin++;}else if(a==2){Smin--;}else if(a==3){Smax--;}else if(a==4){Smax++;}Serial.write(packet.data(), packet.length());Serial.println();//localUdpPort = packet.remotePort();//返回目标端口号//packet.print("reply data\r\n");
}//时间回调函数,2s发送一次数据
void callback1()
{//装载设置温度值UDPSend_data[0]=(char)Smin;UDPSend_data[1]=(char)Smax;//获取实际最大温度、最小温度Temp_get_max_min(pixels);//装载实际最大最小温度值UDPSend_data[2]=(char)Tmin;UDPSend_data[3]=(char)Tmax;Smax = Tmax+1;Smin = Tmin-4;//装载0-255的颜色对应for(int i=0;i<64;i++){int colorIndex = map(pixels[i], Smin, Smax, 0, 255);//映射函数colorIndex = constrain(colorIndex, 0, 255);//限制函数UDPSend_data[i+4]=(char)colorIndex;//装载对应颜色}//打印看效果Serial.println((int)UDPSend_data[0]);Serial.println((int)UDPSend_data[11]);Serial.println((int)UDPSend_data[2]);Serial.println((int)UDPSend_data[3]);for(int j=1;j<65;j++){Serial.print((int)UDPSend_data[j+3]);Serial.print(", ");if( j%8 == 0) Serial.println();}Serial.println("&&&&&");udp.broadcastTo(UDPSend_data, localUdpPort);
}
//获取最大最小值
void Temp_get_max_min(float temp[])
{Tmin = 100;Tmax = 0;for(int i=0;i<64;i++){if(Tmax<temp[i])Tmax=(int)temp[i];if(Tmin>temp[i])Tmin=(int)temp[i];}
}void setup() {Serial.begin(115200);Serial.println(F("AMG88xx pixels"));WiFi.softAP(ssid, password);//设置热点IPAddress myIP = WiFi.softAPIP();//获取本地IPSerial.println(myIP);udp.listen(localUdpPort);//监听udp端口udp.onPacket(onPacketCallBack); //注册收到数据包事件bool status;status = amg.begin();//sda,scl默认SDA 21,SCL22if (!status) {Serial.println("Could not find a valid AMG88xx sensor, check wiring!");while (1);}delay(100); // let sensor boot upticker1.detach(); //停止ticker1ticker1.attach_ms(200, callback1);//时间回调启动200ms
}void loop() { //读取温度amg.readPixels(pixels);delay(150);
}

在Android 上显示图像:

/*
* 对应ESP32_AMG8833_1
* */
package com.example.amg8833_01;import androidx.appcompat.app.AppCompatActivity;import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;public class MainActivity extends AppCompatActivity {private ImageView imageView;private TextView tv_show;private Button bt_inter_up;private Button bt_inter_down;private Button bt_max_up;private Button bt_max_down;private Button bt_min_up;private Button bt_min_down;private int data;private int interpolation =64;//插值大小63好private int T_max;//实际最大温度private int T_min;private int S_max;//设置的最大温度private int S_min;private int temp_64[]=new int[64];private float BiBubic_a = -1.85f;//BiCubic基函数-0.72private int data_pre[]=new int[interpolation*interpolation];//上一个数据private int data_now[]=new int[interpolation*interpolation];//现在的数据private int data_pre_2[]=new int[interpolation*interpolation];private Bitmap alter = null;private Paint paint = null;private Canvas canvas = null;/** UDP通信定义* */private String   SeverIP="192.168.4.1";//目标IPprivate   int    UDPSeverPort= 8080;//服务器端口private   int    UDPClientPort= 9000;//客户端端口private InetAddress UDPServerAddress = null;DatagramSocket UDPSendSocket =null;//定义UDP 发送socketDatagramSocket UDPReceiveSocket  =null;//定义UDP 接收socket,必须分开,不然公用会堵塞//the colors we will be useprivate int camColors[] = {0x480F,0x400F,0x400F,0x400F,0x4010,0x3810,0x3810,0x3810,0x3810,0x3010,0x3010,0x3010,0x2810,0x2810,0x2810,0x2810,0x2010,0x2010,0x2010,0x1810,0x1810,0x1811,0x1811,0x1011,0x1011,0x1011,0x0811,0x0811,0x0811,0x0011,0x0011,0x0011,0x0011,0x0011,0x0031,0x0031,0x0051,0x0072,0x0072,0x0092,0x00B2,0x00B2,0x00D2,0x00F2,0x00F2,0x0112,0x0132,0x0152,0x0152,0x0172,0x0192,0x0192,0x01B2,0x01D2,0x01F3,0x01F3,0x0213,0x0233,0x0253,0x0253,0x0273,0x0293,0x02B3,0x02D3,0x02D3,0x02F3,0x0313,0x0333,0x0333,0x0353,0x0373,0x0394,0x03B4,0x03D4,0x03D4,0x03F4,0x0414,0x0434,0x0454,0x0474,0x0474,0x0494,0x04B4,0x04D4,0x04F4,0x0514,0x0534,0x0534,0x0554,0x0554,0x0574,0x0574,0x0573,0x0573,0x0573,0x0572,0x0572,0x0572,0x0571,0x0591,0x0591,0x0590,0x0590,0x058F,0x058F,0x058F,0x058E,0x05AE,0x05AE,0x05AD,0x05AD,0x05AD,0x05AC,0x05AC,0x05AB,0x05CB,0x05CB,0x05CA,0x05CA,0x05CA,0x05C9,0x05C9,0x05C8,0x05E8,0x05E8,0x05E7,0x05E7,0x05E6,0x05E6,0x05E6,0x05E5,0x05E5,0x0604,0x0604,0x0604,0x0603,0x0603,0x0602,0x0602,0x0601,0x0621,0x0621,0x0620,0x0620,0x0620,0x0620,0x0E20,0x0E20,0x0E40,0x1640,0x1640,0x1E40,0x1E40,0x2640,0x2640,0x2E40,0x2E60,0x3660,0x3660,0x3E60,0x3E60,0x3E60,0x4660,0x4660,0x4E60,0x4E80,0x5680,0x5680,0x5E80,0x5E80,0x6680,0x6680,0x6E80,0x6EA0,0x76A0,0x76A0,0x7EA0,0x7EA0,0x86A0,0x86A0,0x8EA0,0x8EC0,0x96C0,0x96C0,0x9EC0,0x9EC0,0xA6C0,0xAEC0,0xAEC0,0xB6E0,0xB6E0,0xBEE0,0xBEE0,0xC6E0,0xC6E0,0xCEE0,0xCEE0,0xD6E0,0xD700,0xDF00,0xDEE0,0xDEC0,0xDEA0,0xDE80,0xDE80,0xE660,0xE640,0xE620,0xE600,0xE5E0,0xE5C0,0xE5A0,0xE580,0xE560,0xE540,0xE520,0xE500,0xE4E0,0xE4C0,0xE4A0,0xE480,0xE460,0xEC40,0xEC20,0xEC00,0xEBE0,0xEBC0,0xEBA0,0xEB80,0xEB60,0xEB40,0xEB20,0xEB00,0xEAE0,0xEAC0,0xEAA0,0xEA80,0xEA60,0xEA40,0xF220,0xF200,0xF1E0,0xF1C0,0xF1A0,0xF180,0xF160,0xF140,0xF100,0xF0E0,0xF0C0,0xF0A0,0xF080,0xF060,0xF040,0xF020,0xF800};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findID();Draw_init(320,240);初始化画笔等参数UDPReceive();/** 监听事件* */bt_inter_up.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {interpolation ++;}});bt_inter_down.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {interpolation --;}});bt_max_up.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {data = 4;sendData();}});bt_max_down.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {data = 3;sendData();}});bt_min_up.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {data = 1;sendData();}});bt_min_down.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {data = 2;sendData();}});}/** json数据打包发送方法* */private void sendData(){String sendData ;//创建接收缓存区;sendData = "{\"DICar\":{\"data\":"+data+"}}";UDPSend(sendData);}/** UDP发送数据* */private void UDPSend(final String send_data){//开启线程发送数据new Thread(new Runnable() {@Overridepublic void run() {try {UDPSendSocket = new DatagramSocket(UDPClientPort);UDPServerAddress = InetAddress.getByName(SeverIP);int length_data = send_data.length();DatagramPacket sendPacket = new DatagramPacket(send_data.getBytes(),length_data,UDPServerAddress,UDPSeverPort);UDPSendSocket.send(sendPacket);UDPSendSocket.close();} catch (SocketException | UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}).start();}//初始化画图工具private void Draw_init(int width,int height){// 创建一个画布alter = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);// ARGB_8888就是由4(ARGB)个8位组成即32位canvas = new Canvas(alter);//创建Canvas对象paint = new Paint();//创建画笔}//画一个像素 pixelprivate void Draw_pixel(float left , float top , float right , float bottom,int color){//画一个矩形像素,left top right bottom  确保bottom>top left<rightRectF rf = new RectF(left, top, right, bottom);paint.setColor(color);//   (低温)-1667185-- -65536(高温)//paint.setAlpha(1);//设置透明度canvas.drawRect(rf, paint);imageView.setImageBitmap(alter);//显示}//画一幅图,传入坐标数据private void Draw_picture(int[] image_data,int rate){int i ,j;float width = 320/rate,height =240/rate;int color ;//获取颜色对应值for(i = 0;i<rate;i++){for(j=0;j<rate;j++){color = camColors[image_data[i*rate+j]];color=Color_16to32(color);Draw_pixel(j*width,i*height,j*width+width,i*height+height,color);}}}/** 16位颜色转32位颜色* */private int Color_16to32(int Color_16){int Color_32 = 0xAA000000;int R,G,B;R = (Color_16>>8) & 0xF8;G = (Color_16>>4) & 0x7e;B = Color_16 & 0x1f;Color_32 = Color_32|(R<<16);Color_32 = Color_32|(G<<8);Color_32 = Color_32|B;return Color_32;}/** 限制函数* */private int Limit(int data , int max , int min){int return_data;if(data > max)return_data = max;else if(data < min)return_data = min;else return_data = data;return return_data;}/** 双三次插值* */private int[] Bicubic_interpolation(int []image_source ,int rate){int[] image_result = new int[rate * rate];//定义新的长度int Source_rate = (int) Math.sqrt(image_source.length);//获取来源图片长、宽,必须是n*n形float interpolation_x, interpolation_y;//插值的位置int Int_x ;//插值的位置int型int Int_y ;//插值的位置int型float delta_x ;//插值的位置小数部分float delta_y ;//插值的位置小数部分float Sum;//求和for (int row = 0; row < rate; row++) {  //行for (int column = 0; column < rate; column++) {  //列//获取插值位置
//                interpolation_x = (float) Source_rate/rate *row;
//                interpolation_y = (float) Source_rate/rate * column ;interpolation_x = (float) (Source_rate)/(rate) * (row + (float) 0.5) - (float) 0.5;//i*a/minterpolation_y = (float) (Source_rate)/(rate) * (column + (float) 0.5) - (float) 0.5;//得到位置整型Int_x = (int)Math.floor(interpolation_x);Int_y = (int)Math.floor(interpolation_y);delta_x = interpolation_x-Int_x;delta_y = interpolation_y-Int_y;Sum =0;//image_result[row * rate + column] = Int_x;//得到相邻的周围16个值for(int n=-1;n<3;n++){//-1,0,1,2for(int m=-1;m<3;m++){if((Int_x+n)<0|(Int_y+m)<0|(Int_x+n)>Source_rate-1|(Int_y+m)>Source_rate-1)continue;Sum = Sum+image_source[(Int_x+n)*Source_rate+(Int_y+m)]*BiBubic(n-delta_x)*BiBubic(m-delta_y);}}Sum = Limit((int)Sum,255,0);image_result[row * rate + column] = (int)Sum;}}return image_result;}//    //计算系数private float BiBubic(float x){float result ;x = Math.abs(x);//取绝对值
//        if(x>0&&x<1)
//        {//            result = (BiBubic_a + 2)*x * x* x - (BiBubic_a + 3)*x * x + 1;
//        }
//        else if(x>1&&x<2)
//        {//            result =  BiBubic_a*x  * x  * x  - 5 * BiBubic_a*x  * x + 8 * BiBubic_a*x  - 4 * BiBubic_a;
//        }
//下面是节约算力if(x>0&&x<1){result = (float) (1.4*x * x* x - 2.4*x * x + 1);}else if(x>1&&x<2){result = (float) (-0.6*x  * x  * x  +3*x  * x -4.8*x  +2.4);}else result =0;return result;}
//图片相加取平均,可以有效滤除随机噪声private void Picture_filter(){for(int i=0;i<interpolation;i++){for(int j=0;j<interpolation;j++){data_now[i*interpolation+j]= (data_pre[i*interpolation+j]+data_now[i*interpolation+j]+data_pre_2[i*interpolation+j])/3;//data_now[i*interpolation+j]= (data_pre[i*interpolation+j]+data_now[i*interpolation+j])/2;}}data_pre_2 = data_pre;data_pre = data_now;//把当前值给上一个}/** 数据提取* */private void Data_Get(byte[] data){//先提取设置温度值最小S_min = data[0]& 0xff;//先提取设置温度值最大S_max = data[1]& 0xff;//提取实际温度数据T_min = data[2]& 0xff;T_max = data[3]& 0xff;//提取温度对应颜色for(int i=0;i<64;i++){temp_64[i]=data[i+4]&0xff;;}}/** UDP接收数据* */private void UDPReceive(){//开启线程接收数据new Thread(new Runnable() {@Overridepublic void run() {byte[] Receive_buffer = new byte[1024];//创建接收缓存区try {UDPReceiveSocket = new DatagramSocket(UDPSeverPort);while(true){DatagramPacket receivePacket = new DatagramPacket(Receive_buffer,Receive_buffer.length);UDPReceiveSocket.receive(receivePacket);byte[] ReceiveBuffers= receivePacket.getData();//存储缓存if(ReceiveBuffers.length!=0){//数据提取Data_Get(ReceiveBuffers);//插值结果data_now=Bicubic_interpolation(temp_64,interpolation);//data_now=DL_interpolation(temp_64,interpolation);//图片均值滤波Picture_filter();runOnUiThread(new Runnable() {@Overridepublic void run() {//显示数据tv_show.setText(null);tv_show.append("当前最高温度:"+T_max+" 度\n当前最低温度:"+T_min+" 度\n 插值大小:"+interpolation+"\n设置的温度:\nMAX = "+S_max+" 度\nMIN= "+S_min+" 度");Draw_picture(data_now,interpolation);}});}}} catch (SocketException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}).start();}//查找IDprivate void findID(){tv_show=(TextView)findViewById(R.id.tv_show);bt_inter_down = (Button) findViewById(R.id.BT_INTER_DOWN);bt_inter_up = (Button) findViewById(R.id.BT_INTER_UP);bt_max_down = (Button) findViewById(R.id.BT_MAX_DOWN);bt_max_up = (Button) findViewById(R.id.BT_MAX_UP);bt_min_down = (Button) findViewById(R.id.BT_MIN_DOWN);bt_min_up = (Button) findViewById(R.id.BT_MIN_UP);imageView = (ImageView) findViewById(R.id.imageView);}
}

XML:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="56dp"><TextViewandroid:id="@+id/tv_show"android:layout_width="327dp"android:layout_height="151dp"android:layout_marginBottom="16dp"android:shadowColor="#FF0000"android:text="当前最高温度:0 度 \n当前最低温度:0 度 \n 插值大小:16 \n设置的温度:\nMAX = 0 度\nMIN= 0 度"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent" /><Buttonandroid:id="@+id/BT_MIN_DOWN"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="24dp"android:layout_marginRight="24dp"android:layout_marginBottom="26dp"android:text="MIN_DOWN"app:layout_constraintBottom_toTopOf="@+id/tv_show"app:layout_constraintEnd_toEndOf="parent" /><Buttonandroid:id="@+id/BT_MAX_UP"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="16dp"android:layout_marginLeft="16dp"android:layout_marginTop="19dp"android:text="MAX_UP"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/BT_INTER_UP" /><Buttonandroid:id="@+id/BT_MIN_UP"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="13dp"android:text="MIN_UP"app:layout_constraintBottom_toTopOf="@+id/BT_MIN_DOWN"app:layout_constraintStart_toStartOf="@+id/BT_MIN_DOWN" /><Buttonandroid:id="@+id/BT_INTER_UP"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="16dp"android:layout_marginLeft="16dp"android:text="INTER_UP"app:layout_constraintBottom_toBottomOf="@+id/BT_INTER_DOWN"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="@+id/BT_INTER_DOWN" /><Buttonandroid:id="@+id/BT_MAX_DOWN"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="16dp"android:layout_marginLeft="16dp"android:layout_marginTop="12dp"android:text="MAX_DOWN"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/BT_MAX_UP" /><Buttonandroid:id="@+id/BT_INTER_DOWN"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="21dp"android:text="INTER_DOWN"app:layout_constraintBottom_toTopOf="@+id/BT_MIN_UP"app:layout_constraintEnd_toEndOf="@+id/BT_MIN_UP" /><ImageViewandroid:id="@+id/imageView"android:layout_width="320dp"android:layout_height="240dp"android:layout_marginStart="45dp"android:layout_marginLeft="45dp"android:layout_marginTop="16dp"android:layout_marginEnd="45dp"android:layout_marginRight="45dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:srcCompat="@color/colorAccent" /></androidx.constraintlayout.widget.ConstraintLayout>

ESP32/ESP8266系列之AMG8833热成像相关推荐

  1. 免外围电路ESP32/ESP8266系列单片机串口一键下载方案

    一.概述 CH340X.CH343.CH342等USB转串口芯片支持免外围电路ESP32/ESP8266等单片机串口一键下载功能,对此类支持多模式启动的单片机,无需外围三极管等逻辑控制电路,将芯片提供 ...

  2. 启明云端分享|一款方便、实用的且适用于ESP32/ESP8266的USB-TTL转接板开发工具推荐

    ESP-T01 ESP-T01是一款适用ESP32/ESP8266的USB-TTL转接板, 支持一键下载程序,无需手动复位芯片与管脚拉低操作.配套的插接板与排针零件, 能够非常方便的为ESP32/ES ...

  3. 安信可分享 | 分享一个基于airkiss协议的配网小程序,实现小程序一键配网安信可ESP32C3\ESP8266\ESP32\ESP32S2系列的模组。(附带源码)

    文章目录 一.关于 WeChatAirkiss 1.1 应用场景 二.airkiss 简介 三.开始使用 四.API说明 五.FAQ 六.开源微信物联网控制一览表 联系我们 一.关于 WeChatAi ...

  4. 启明云端分享|ESP32/ESP8266 烧录器 USB-TTL转接板开发工具ESP-T01的使用教程,视频可参考B站

    提示:根据启明云端ESP32/ESP8266 烧录器 USB-TTL转接板开发工具ESP-T01编写的使用教程. 启明云端ESP-T01 烧录器,这是一款为了解决新老用户对ESP系列模组"烧 ...

  5. 图解Esp32/ESP8266进行组网开发所需了解的那些小概念

    图解Esp32/ESP8266进行组网开发所需了解的那些小概念 图解日程生活中常见网络操作背后的小概念 前情提要 过程中涉及的进行组网开发所需的小概念 漫画展示 预告:一个基于ESP32和ESP826 ...

  6. 安信可推荐 | 安信可ESP32-S3系列模组和ESP8266系列模组硬件参数对比。

    文章目录 前言 主要参数对比 功耗 产品实物图 联系我们 前言 安信可深耕无线模组多年,现已推出ESP32-S3系列模组,欢迎前来咨询. ESP32-S3 搭载 Xtensa 32 位 LX7 双核处 ...

  7. ESP32,ESP8266之间WiFi互联实验

    ▌ESP32,ESP8266模块互联 ESP32,ESP8266 模块具有很丰富的功能,便于设计一些现场需要联网的场合.基于此在AI视觉组基于ESP32的裁判系统第一版本设计要求 就使用了ESP32进 ...

  8. micropython做中继_MicroPython网络服务器使用ESP32/ESP8266远程控制家用交流电器

    背景知识视频教程 将继电器与ESP32或ESP8266配合使用是一种远程控制AC家用电器的好方法.本教程介绍了如何使用MicroPython固件通过ESP32或ESP8266控制继电器模块. 我们将研 ...

  9. ESP8266系列WIFI模块的使用·

    一.概述 ESP8266是由乐鑫公司出品的一款物联网芯片,因为价格较低,性能稳定等收到很大关注.该芯片可工作于三种种模式下,分别是:AP模式,station模式以及混合模式,通过常用的AT指令进行控制 ...

最新文章

  1. 使用VS Code新建编译Flutter项目
  2. 卫星导航精密单点定位(PPP)技术
  3. java使用集合模拟斗地主洗牌发牌案例
  4. iptables中文man文档
  5. mysql数据库被黑客删除,您做好防范了吗?
  6. esri.views.2d.layers.features.controllers.OnDemandController 记一次ArcGIS Server的问题
  7. 时间序列模式识别_空气质量传感器数据的时间序列模式识别
  8. 现代软件工程 学生阅读和调查作业
  9. transition属性详细讲解
  10. Codeforces Round #177 (Div. 1)C. Polo the Penguin and XOR operation【贪心】
  11. 95-140-128-源码-transform-算子maxMin
  12. asp.net的decimal保留两位小数
  13. 博文视点OpenParty第11期“世界黑客大会那些事儿”成功举办
  14. Guava学习笔记(二):Optional优雅的使用null
  15. 基于HTTP协议的轻量级开源简单消息队列服务:HTTPSQS
  16. WPS安装office自定义项安装期间出错
  17. html5 css3 JavaScript响应式中文静态网页模板js源代码
  18. 短视频源码开发,短视频系统源码搭建,从短视频系统起播过程入手
  19. java项目代码加密
  20. 关于Excel表格快捷键

热门文章

  1. 获取服务器主列表一直显示稍等,正在获取远程列表服务器信息
  2. python dict items iteritems_python字典中的items和iteritems
  3. 突发!华为某BG总裁猝死!执掌最大营收业务,东南大学毕业,在职已超26年
  4. 园区建筑3D建模三维模型,如何实现大屏可视化展示?
  5. PLSQL 14(64位)注册码
  6. 新手宝塔搭建网站,快速搭建网站的方法
  7. 唯美到心痛,樱空之雪是这世上最大的幸福
  8. OpenCV HSV颜色空间基本颜色范围
  9. (一)问候 HtmlUnit
  10. 树莓派电子开发套件及配件组图