基于ESP32+AMG8833+微信小程序的可联网红外线感应仪
时间:2022-12-21 23:30:00
背景:
在新冠肺炎疫情时代的背景下,保持安全距离,避免密切接触是环境造成的。同时,测量体温也是公共场所不可或缺的一部分,因此有必要实施非接触测温。
这个项目开发了一个Arduino基于开发环境esp32以及AMG8833红外热成像传感器可实现新冠肺炎疫情下的非接触测温和区域热成像功能。传感器收集信息后,可通过液晶屏实时显示热成像和区域最高、最低温度和中心点温度。低功耗模式下关闭红外成像模块可实时显示全球疫情数据。
项目效果:
点击查看展示视频(B站)
下联网在低功耗模式下显示全球疫情数据
红外成像效果
小程序界面(前四个按钮是蓝牙连接,后两个控制esp32切换模式)
项目技术栈:
系统流程:
全部代码:
一、Arduino代码
第一次用Arduino开发esp32请点击配置基本环境
ESP32开发板 |
按键开关 |
TFT-LCD |
AMG8833 |
3V3 |
|
VCC |
|
23 |
SDA |
||
26 |
RES |
||
18 |
SCL |
||
27 |
DC |
||
5 |
CS |
||
GND |
GND |
GND |
|
21 |
SDA |
||
22 |
SCL |
||
5V |
VIM |
本项目采用的TFT屏幕尺寸为128×160,不同的屏幕需要在文件中设置屏幕尺寸以及引脚映射,可以参考TFT_eSPI库驱动ST7789
1.主文件(ino)
tips:本项目引用的"<>"格式的库文件都能通过直接在Arduino环境中添加库完成,不会请点这里;
除此之外还引用了两个自建的头文件“HanZi16.h”(负责存储要显示的汉字)
和"interpolation.h"(用插值算法将amg8833返回的8×8点阵拓展为32×32)
#include // ST7735 or ST7735S驱动
#include
#include "HanZi16.h"
TFT_eSPI tft = TFT_eSPI();
#include
#include
#include
#include
#include
#include
#include
#include
#include "interpolation.h"
BLECharacteristic *pCharacteristic;
bool deviceConnected = false;
uint32_t buff =0;
char time1[30]={0};
char quezhen1[30]={0};
char quezhen2[30]={0};
char siwang1[30]={0};
char siwang2[30]={0};
char zhiyu1[30]={0};
char zhiyu2[30]={0};
char yin[30]="100636";
char ba[30]="66017";
char ge[30]="28971";
uint32_t cnt = 0;
#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID
#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
#define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
/*256位的温度颜色对照表*/
const uint16_t 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,};
//low range of the sensor (this will be blue on the screen)
#define MINTEMP 14
//high range of the sensor (this will be red on the screen)
#define MAXTEMP 30
/*32*32为优化后的分辨率,不宜太高,提升分辨率修改此处即可*/
#define INTERPOLATED_COLS 32
#define INTERPOLATED_ROWS 32
#define AMG_COLS 8
#define AMG_ROWS 8
Adafruit_AMG88xx amg;
unsigned long delayTime;
float pixels[AMG_COLS * AMG_ROWS];
uint16_t displayPixelWidth, displayPixelHeight;
uint16_t displayPixelX, displayPixelY;
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
buff=1;
Serial.print("------>Received Value: ");
if(rxValue[0]=='a'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
time1[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='b'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
quezhen1[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='c'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
quezhen2[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='d'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
siwang1[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='e'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
siwang2[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='f'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
zhiyu1[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='g'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
zhiyu2[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='h'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
yin[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='i'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
ba[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='j'){
for (int i = 1; i < rxValue.length(); i++) {
Serial.print(rxValue[i]);
ge[i-1]=rxValue[i];
};
Serial.println();
};
if(rxValue[0]=='k'){
Serial.print(rxValue[0]);
buff=0;
};
}
}
};
/* 画热成像素点 */
void drawpixels(float *p, uint8_t rows, uint8_t cols, uint8_t boxWidth, uint8_t boxHeight, boolean showVal) {
int colorTemp;
float curMax = get_point(p, rows, cols, 0, 0),
curMin = get_point(p, rows, cols, 0, 0),
curMid = get_point(p, rows, cols, cols/2, rows/2);
uint16_t colorMax = camColors[0],
colorMin = camColors[0],
colorMid = camColors[0];
//画热成像
for (int y=0; y= MAXTEMP)
colorTemp = MAXTEMP;
else if(val <= MINTEMP)
colorTemp = MINTEMP;
else
colorTemp = val;
uint8_t colorIndex = map(colorTemp, MINTEMP, MAXTEMP, 0, 255);
colorIndex = constrain(colorIndex, 0, 255);
//draw the pixels!
tft.fillRect( boxWidth * x, displayPixelY + boxHeight * y, boxWidth, boxHeight, camColors[colorIndex]);
//取最大值
if(val >= curMax){
curMax = val;
colorMax = camColors[colorIndex];
}
//取最小值
if(val <= curMin){
curMin = val;
colorMin = camColors[colorIndex];
}
//取中心点
if(y == rows/2 && x == cols/2){
colorMid = camColors[colorIndex];
}
if (showVal) {
tft.setCursor(boxWidth * y + boxWidth/2 - 12, 40 + boxHeight * x + boxHeight/2 - 4);
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE);
tft.print(val,1);
}
}
}
//画中心点十字
uint8_t midX = cols*boxWidth/2;
uint8_t midY = displayPixelY+rows*boxHeight/2;
tft.drawLine(midX-5, midY, midX+5, midY, TFT_WHITE);
tft.drawLine(midX, midY-5, midX, midY+5, TFT_WHITE);
char temp[7];
tft.setTextSize(1);
tft.setTextColor(TFT_WHITE);
//显示最高温度
tft.drawLine(128, 10, 159, 10, TFT_WHITE);
tft.drawLine(128, 40, 159, 40, TFT_WHITE);
tft.drawLine(128, 10, 128, 40, TFT_WHITE);
tft.drawLine(159, 10, 159, 40, TFT_WHITE);
tft.setTextDatum(TL_DATUM);
tft.drawString(F("max"), tft.width()-28, 0);
tft.fillRect(129, 11, 30, 29, colorMax);
tft.setTextDatum(CL_DATUM);
memset(temp, 0, sizeof(temp));
sprintf(temp, "%0.1f", curMax);
tft.drawString(String(temp), tft.width()-28, 25);
//显示最低温度
tft.drawLine(128, 10+40, 159, 10+40, TFT_WHITE);
tft.drawLine(128, 40+40, 159, 40+40, TFT_WHITE);
tft.drawLine(128, 10+40, 128, 40+40, TFT_WHITE);
tft.drawLine(159, 10+40, 159, 40+40, TFT_WHITE);
tft.setTextDatum(TL_DATUM);
tft.drawString(F("min"), tft.width()-28, 40);
tft.fillRect(129, 51, 30, 29, colorMin);
tft.setTextDatum(CL_DATUM);
memset(temp, 0, sizeof(temp));
sprintf(temp, "%0.1f", curMin);
tft.drawString(String(temp), tft.width()-28, 65);
//显示中心点温度
tft.drawLine(128, 10+40+40, 159, 10+40+40, TFT_WHITE);
tft.drawLine(128, 40+40+40, 159, 40+40+40, TFT_WHITE);
tft.drawLine(128, 10+40+40, 128, 40+40+40, TFT_WHITE);
tft.drawLine(159, 10+40+40, 159, 40+40+40, TFT_WHITE);
tft.setTextDatum(TL_DATUM);
tft.drawString(F("center"), tft.width()-32, 80);
tft.fillRect(129, 91, 30, 29, colorMid);
tft.setTextDatum(CL_DATUM);
memset(temp, 0, sizeof(temp));
sprintf(temp, "%0.1f", curMid);
tft.drawString(String(temp), tft.width()-28, 105);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
displayPixelWidth = tft.height() / 8;
displayPixelHeight = tft.height() / 8;
displayPixelX = (tft.width() - displayPixelWidth*8)/2;
displayPixelY = (tft.height() - displayPixelHeight*8)/2;
//drawTemperateBar();
bool status;
// default settings
status = amg.begin();
if (!status) {
Serial.println("Could not find a valid AMG8833 sensor, check wiring!");
while (1);
}
Serial.println("-- Thermal Camera Test --");
delay(100); // let sensor boot up
// Create the BLE Device
BLEDevice::init("红外成像仪");
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID);
// Create a BLE Characteristic
pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
pCharacteristic->addDescriptor(new BLE2902());
BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
pCharacteristic->setCallbacks(new MyCallbacks());
// Start the service
pService->start();
// Start advertising
pServer->getAdvertising()->start();
Serial.println("Waiting a client connection to notify...");
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
}
void drawquezhen(){
tft.init();
tft.setTextColor(TFT_BLACK, TFT_DARKGREEN); // 新字体不画背景色 Note: the new fonts do not draw the background colour
tft.fillRoundRect(8, 8, 144, 112, 8, TFT_DARKGREEN);
char str[] = "全球疫情数据";
drawHanziS(32, 16, str, TFT_LIGHTGREY);
tft.fillRoundRect(20, 48, 128, 64, 4, TFT_LIGHTGREY);
char str1[] = "累计确诊";
drawHanziS(48, 50, str1, TFT_YELLOW);
char str2[] = "较昨日";
drawHanziS(20, 92, str2, TFT_YELLOW);
tft.setTextSize(1);
tft.setTextColor(TFT_BLACK, TFT_DARKGREEN);
tft.drawString(String(time1), 14, 36);
tft.setTextSize(2);
tft.setTextColor(TFT_MAROON, TFT_LIGHTGREY);
tft.drawString(String(quezhen1), 24, 72);
tft.setTextSize(2);
tft.setTextColor(TFT_RED, TFT_LIGHTGREY);
tft.drawString(String(quezhen2), 70, 92);
}
void drawsiwang(){
tft.init();
tft.setTextColor(TFT_BLACK, TFT_DARKGREEN); // 新字体不画背景色 Note: the new fonts do not draw the background colour
tft.fillRoundRect(8, 8, 144, 112, 8, TFT_DARKGREEN);
char str[] = "全球疫情数据";
drawHanziS(32, 16, str, TFT_LIGHTGREY);
tft.fillRoundRect(20, 48, 128, 64, 4, TFT_LIGHTGREY);
char str1[] = "累计死亡";
drawHanziS(48, 50, str1, TFT_YELLOW);
char str2[] = "较昨日";
drawHanziS(20, 92, str2, TFT_YELLOW);
tft.setTextSize(1);
tft.setTextColor(TFT_BLACK, TFT_DARKGREEN);
tft.drawString(String(time1), 14, 36);
tft.setTextSize(2);
tft.setTextColor(TFT_BLACK, TFT_LIGHTGREY);
tft.drawString(String(siwang1), 24, 72);
tft.setTextSize(2);
tft.setTextColor(TFT_DARKGREY, TFT_LIGHTGREY);
tft.drawString(String(siwang2), 70, 92);
}
void drawzhiyu(){
tft.init();
tft.setTextColor(TFT_BLACK, TFT_DARKGREEN); // 新字体不画背景色 Note: the new fonts do not draw the background colour
tft.fillRoundRect(8, 8, 144, 112, 8, TFT_DARKGREEN);
char str[] = "全球疫情数据";
drawHanziS(32, 16, str, TFT_LIGHTGREY);
tft.fillRoundRect(20, 48, 128, 64, 4, TFT_LIGHTGREY);
char str1[] = "累计治愈";
drawHanziS(48, 50, str1, TFT_YELLOW);
char str2[] = "较昨日";
drawHanziS(20, 92, str2, TFT_YELLOW);
tft.setTextSize(1);
tft.setTextColor(TFT_BLACK, TFT_DARKGREEN);
tft.drawString(String(time1), 14, 36);
tft.setTextSize(2);
tft.setTextColor(TFT_DARKGREEN, TFT_LIGHTGREY);
tft.drawString(String(zhiyu1), 24, 72);
tft.setTextSize(2);
tft.setTextColor(TFT_GREEN , TFT_LIGHTGREY);
tft.drawString(String(zhiyu2), 70, 92);
}
void drawguojia(){
tft.init();
tft.fillRoundRect(8, 8, 144, 112, 8, TFT_DARKGREY);
tft.setTextSize(2);
tft.setTextColor(TFT_LIGHTGREY , TFT_DARKGREY);
tft.drawString(String("TOP3"), 50, 16);
tft.setTextSize(1);
tft.setTextDatum(TL_DATUM);
tft.setTextColor(TFT_LIGHTGREY , TFT_DARKGREY);
tft.drawString(String(time1), 14, 36);
char str[] = "印度";
drawHanziS(16, 60, str, TFT_LIGHTGREY);
tft.setTextColor(TFT_LIGHTGREY , TFT_RED);
//tft.drawString(String(yin), 80, 60);
tft.fillRect(80, 60, 64, 16, TFT_RED);
char str1[] = "巴西";
drawHanziS(16, 80, str1, TFT_LIGHTGREY);
tft.setTextColor(TFT_LIGHTGREY , TFT_RED);
//tft.drawString(String(ba), 80, 80);
tft.fillRect(80, 80, 50, 16, TFT_RED);
char str2[] = "哥伦比亚";
drawHanziS(16, 100, str2, TFT_LIGHTGREY);
tft.setTextColor(TFT_LIGHTGREY , TFT_RED);
//tft.drawString(String(ge), 80, 100);
tft.fillRect(80, 100, 25, 16, TFT_RED);
tft.setTextSize(1);
tft.setTextDatum(TL_DATUM);
}
void loop() {
amg.readPixels(pixels);
float dest_2d[INTERPOLATED_ROWS * INTERPOLATED_COLS];
//int32_t t = millis();
interpolate_image(pixels, AMG_ROWS, AMG_COLS, dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS);
uint16_t boxsize = min(tft.width() / INTERPOLATED_COLS, tft.height() / INTERPOLATED_COLS);
if (buff) {
tft.fillScreen(TFT_BLACK);
drawquezhen();
delay(5000);
};
if(buff){
tft.fillScreen(TFT_BLACK);
drawsiwang();
delay(5000);
};
if(buff){
tft.fillScreen(TFT_BLACK);
drawzhiyu();
delay(5000);
};
if(buff){
tft.fillScreen(TFT_BLACK);
drawguojia();
delay(10000);
};
if(!buff){
drawpixels(dest_2d, INTERPOLATED_ROWS, INTERPOLATED_COLS, boxsize, boxsize, false);};
}
void drawHanzi(int32_t x, int32_t y, const char c[3], uint32_t color) { //显示单一汉字
for (int k = 0; k < 25; k++)
if (hanzi16[k].Index[0] == c[0] && hanzi16[k].Index[1] == c[1] && hanzi16[k].Index[2] == c[2])
{ tft.drawBitmap(x, y, hanzi16[k].hz16_Id, hanzi16[k].hz_width, 16, color);
}
}
void drawHanziS(int32_t x, int32_t y, const char str[], uint32_t color) { //显示整句汉字,字库目前有限,比较简单,没有换行功能,上下输出,左右输出是在函数内实现
int y0 = y;
int x0 = x;
for (int i = 0; i < strlen(str); i += 3) {
drawHanzi(x0, y, str+i, color);
x0 += 16;
}
}
2.HanZi16.h代码
#include
PROGMEM const unsigned char hz16_1[] =
{
0x01,0x00,0x01,0x00,0x02,0x80,0x04,0x40,0x08,0x20,0x10,0x10,0x2F,0xE8,0xC1,0x06,
0x01,0x00,0x01,0x00,0x1F,0xF0,0x01,0x00,0x01,0x00,0x01,0x00,0x7F,0xFC,0x00,0x00
};
PROGMEM const unsigned char hz16_2[] =
{
0x00,0x28,0x00,0x24,0xFC,0x24,0x10,0x20,0x13,0xFE,0x10,0x20,0x11,0x20,0x7C,0xB2,
0x10,0xB4,0x10,0x68,0x10,0xA8,0x11,0x24,0x1E,0x22,0xE0,0x20,0x40,0xA0,0x00,0x40
};
PROGMEM const unsigned char hz16_3[] =
{
0x00,0x80,0x00,0x40,0x1F,0xFE,0x10,0x00,0x93,0xF0,0x52,0x10,0x52,0x10,0x14,0x0E,
0x38,0x00,0x57,0xF8,0x92,0x08,0x11,0x10,0x20,0xA0,0x20,0x40,0x41,0xB0,0x8E,0x0E
};
PROGMEM const unsigned char hz16_4[] =
{
0x10,0x40,0x10,0x40,0x17,0xFC,0x10,0x40,0x1B,0xF8,0x54,0x40,0x57,0xFE,0x50,0x00,
0x93,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x13,0xF8,0x12,0x08,0x12,0x28,0x12,0x10
};
PROGMEM const unsigned char hz16_5[] =
{
0x08,0x20,0x49,0x20,0x2A,0x20,0x08,0x3E,0xFF,0x44,0x2A,0x44,0x49,0x44,0x88,0xA4,
0x10,0x28,0xFE,0x28,0x22,0x10,0x42,0x10,0x64,0x28,0x18,0x28,0x34,0x44,0xC2,0x82
};
PROGMEM const unsigned char hz16_6[] =
{
0x20,0x00,0x23,0xFC,0x22,0x04,0x22,0x04,0xFB,0xFC,0x22,0x20,0x22,0x20,0x2B,0xFE,
0x32,0x20,0xE2,0x20,0x22,0xFC,0x22,0x84,0x22,0x84,0x24,0x84,0xA4,0xFC,0x48,0x84
};
PROGMEM const unsigned char hz16_7[] =
{
0x00,0x00,0x3F,0xF8,0x21,0x08,0x3F,0xF8,0x21,0x08,0x3F,0xF8,0x02,0x00,0x04,0x20,
0x1F,0xC0,0x01,0x80,0x06,0x10,0x3F,0xF8,0x01,0x08,0x11,0x20,0x25,0x10,0x42,0x08
};
PROGMEM const unsigned char hz16_8[] =
{
0x00,0x40,0x20,0x40,0x10,0x40,0x10,0x40,0x00,0x40,0x00,0x40,0xF7,0xFE,0x10,0x40,
0x10,0x40,0x10,0x40,0x10,0x40,0x10,0x40,0x14,0x40,0x18,0x40,0x10,0x40,0x00,0x40
};
PROGMEM const unsigned char hz16_9[] =
{
0x00,0x40,0x00,0x40,0xFC,0x7C,0x10,0x84,0x11,0x08,0x22,0xFE,0x3C,0x92,0x64,0x92,
0x64,0xFE,0xA4,0x92,0x24,0x92,0x24,0xFE,0x3C,0x92,0x25,0x12,0x21,0x0A,0x02,0x04
};
PROGMEM const unsigned char hz16_10[] =
{
0x00,0x40,0x40,0x40,0x20,0xA0,0x21,0x10,0x02,0x08,0x04,0x26,0xE0,0x40,0x20,0x80,
0x23,0x10,0x20,0x20,0x20,0x40,0x28,0x88,0x33,0x10,0x20,0x20,0x00,0xC0,0x07,0x00
};
PROGMEM const unsigned char hz16_11[] =
{
0x20,0x40,0x20,0x20,0x20,0x20,0xFD,0xFE,0x40,0x00,0x50,0x88,0x91,0x04,0xFE,0x02,
0x10,0x88,0x10,0x88,0x1C,0x50,0xF0,0x50,0x50,0x20,0x10,0x50,0x10,0x88,0x13,0x06
};
PROGMEM const unsigned char hz16_12[] =
{
0x01,0x00,0x01,0x00,0x79,0x00,0x49,0xFE,0x4A,0x80,0x4A,0x80,0x4C,0x80,0x78,0xF8,
0x48,0x80,0x48,0x80,0x48,0x80,0x48,0xFC,0x78,0x80,0x48,0x80,0x00,0x80,0x00,0x80
};
PROGMEM const unsigned char hz16_13[] =
{
0x00,0x00,0x1F,0xF0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10
};
PROGMEM const unsigned char hz16_14[] =
{
0x00,0x00,0xFF,0xFC,0x10,0x80,0x10,0x80,0x10,0x84,0x1E,0x88,0x22,0x90,0x22,0xA0,
0x52,0xC0,0x8C,0x80,0x04,0x80,0x08,0x84,0x08,0x84,0x10,0x84,0x20,0x7C,0x40,0x00
};
PROGMEM const unsigned char hz16_15[] =
{
0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0xFF,0xFE,0x10,0x00,0x10,0x00,0x10,0x00,
0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x1F,0xFC,0x00,0x00
};
PROGMEM const unsigned char hz16_16[] =
{
0x00,0x40,0x20,0x40,0x10,0x80,0x11,0x10,0x82,0x08,0x47,0xFC,0x40,0x04,0x10,0x00,
0x13,0xF8,0x22,0x08,0xE2,0x08,0x22,0x08,0x22,0x08,0x22,0x08,0x23,0xF8,0x02,0x08
};
PROGMEM const unsigned char hz16_17[] =
{
0x01,0x00,0x02,0x80,0x0C,0x60,0x37,0xD8,0xC0,0x06,0x3E,0x08,0x22,0x48,0x3E,0x48,
0x22,0x48,0x3E,0x48,0x22,0x08,0x26,0x18,0x01,0x00,0x48,0x84,0x48,0x12,0x87,0xF2
};
PROGMEM const unsigned char hz16_18[] =
{
0x00,0x00,0x06,0x00,0x78,0xFC,0x40,0x84,0x40,0x84,0x40,0x84,0x7E,0x84,0x40,0x84,
0x40,0x84,0x40,0x84,0x40,0x84,0x4E,0xA8,0x70,0x90,0x00,0x80,0x00,0x80,0x00,0x80
};
PROGMEM const unsigned char hz16_19[] =
{
0x01,0x00,0x00,0x80,0x3F,0xFE,0x22,0x20,0x22,0x20,0x3F,0xFC,0x22,0x20,0x22,0x20,
0x23,0xE0,0x20,0x00,0x2F,0xF0,0x24,0x10,0x42,0x20,0x41,0xC0,0x86,0x30,0x38,0x0E
};
PROGMEM const unsigned char hz16_20[] =
{
0x00,0x00,0x3F,0xF8,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x3F,0xF8,
0x20,0x08,0x20,0x00,0x20,0x00,0x20,0x02,0x20,0x02,0x20,0x02,0x1F,0xFE,0x00,0x00
};
PROGMEM const unsigned char hz16_21[] =
{
0x00,0x00,0xFF,0xFE,0x04,0x40,0x04,0x40,0x04,0x40,0x3F,0xF8,0x24,0x48,0x24,0x48,
0x24,0x48,0x24,0x48,0x28,0x38,0x30,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x20,0x08
};
PROGMEM const unsigned char hz16_22[] =
{
0x00,0x00,0x7F,0xFC,0x00,0x10,0x1F,0x90,0x10,0x90,0x10,0x90,0x1F,0x90,0x00,0x00,
0xFF,0xFE,0x00,0x10,0x1F,0x90,0x10,0x90,0x10,0x90,0x1F,0x90,0x00,0x50,0x00,0x20
};
PROGMEM const unsigned char hz16_23[] =
{
0x08,0x40,0x08,0x40,0x08,0xA0,0x10,0xA0,0x11,0x10,0x32,0x08,0x34,0x06,0x51,0x10,
0x91,0x20,0x11,0x40,0x11,0x80,0x11,0x00,0x11,0x04,0x11,0x04,0x10,0xFC,0x10,0x00
};
PROGMEM const unsigned char hz16_24[] =
{
0x00,0x80,0x20,0x80,0x20,0x80,0x20,0x84,0x20,0x88,0x20,0x90,0x3E,0xA0,0x20,0xC0,
0x20,0x80,0x20,0x80,0x20,0x80,0x20,0x82,0x26,0x82,0x38,0x82,0x20,0x7E,0x00,0x00
};
PROGMEM const unsigned char hz16_25[] =
{
0x00,0x00,0x7F,0xFC,0x04,0x40,0x04,0x40,0x04,0x40,0x04,0x40,0x44,0x44,0x24,0x44,
0x24,0x48,0x14,0x48,0x14,0x50,0x04,0x40,0x04,0x40,0x04,0x40,0xFF,0xFE,0x00,0x00
};
struct FNT_HZ16 // 汉字字模数据结构
{
char Index[4]; // 汉字内码索引,存放内码,如"中",在UTF-8编码下,每个汉字占3个字节,第四个是结束符0
const unsigned char* hz16_Id; // 点阵码数据 存放内码后对应的 点阵序列 每个字需要32个字节的点阵序列
unsigned char hz_width;
};
PROGMEM const FNT_HZ16 hanzi16[] =
{
{"全", hz16_1,16}, {"球", hz16_2,16}, {"疫", hz16_3,16}, {"情", hz16_4,16}, {"数", hz16_5,16}, {"据", hz16_6,16},
{"累", hz16_7,16},{"计", hz16_8,16},{"确", hz16_9,16},{"诊", hz16_10,16},{"较", hz16_11,16},{"昨", hz16_12,16}
,{"日", hz16_13,16},{"死", hz16_14,16},{"亡", hz16_15,16},{"治", hz16_16,16},{"愈", hz16_17,16},{"印", hz16_18,16}
,{"度", hz16_19,16},{"巴", hz16_20,16},{"西", hz16_21,16},{"哥", hz16_22,16},{"伦", hz16_23,16},{"比", hz16_24,16},
{"亚", hz16_25,16}
};
3.interpolation.h代码
#ifndef __INTERPOLATION__H__
#define __INTERPOLATION__H__
#include
float get_point(float *p, uint8_t rows, uint8_t cols, int8_t x, int8_t y);
void set_point(float *p, uint8_t rows, uint8_t cols, int8_t x, int8_t y, float f);
void get_adjacents_1d(float *src, float *dest, uint8_t rows, uint8_t cols, int8_t x, int8_t y);
void get_adjacents_2d(float *src, float *dest, uint8_t rows, uint8_t cols, int8_t x, int8_t y);
float cubicInterpolate(float p[], float x);
float bicubicInterpolate(float p[], float x, float y);
void interpolate_image(float *src, uint8_t src_rows, uint8_t src_cols,
float *dest, uint8_t dest_rows, uint8_t dest_cols);
#endif
二、微信小程序代码
1.js代码
tips:本项目通过爬取腾讯云全球疫情信息来实时获取疫情数据的,详细方法点这里
// pages/lanyatest/lanyatest.js
Page({
/**
* 页面的初始数据
*/
data: {
info:"未初始化蓝牙适配器",
connectedDeviceId:"",
deviceId:"",
services:"",
servicesUUID:"6E400001-B5A3-F393-E0A9-E50E24DCCA9E",
serviceId:"",
notifyCharacteristicsId:"",
writeCharacteristicsId: "",
sendmsg:"",
res:"",
foreignData:{},
countryListLength: 0,
nation: 0,
addConfirm: 0,
num: 0,
rateSum:0.0
},
lanyatest1(event){
var that = this;
wx.openBluetoothAdapter({
success: function (res) {
console.log('初始化蓝牙适配器成功')
//页面日志显示
that.setData({
info: '初始化蓝牙适配器成功'
})
},
fail: function (res) {
console.log('请打开蓝牙和定位功能')
that.setData({
info: '请打开蓝牙和定位功能'
})
}
})
wx.getBluetoothAdapterState({
success: function (res) {
//打印相关信息
console.log(JSON.stringify(res.errMsg) + "\n蓝牙是否可用:" + res.available);
that.setData({
info: JSON.stringify(res.errMsg) +"\n蓝牙是否可用:" + res.available
})
},
fail: function (res) {
//打印相关信息
console.log(JSON.stringify(res.errMsg) + "\n蓝牙是否可用:" + res.available);
that.setData({
info: JSON.stringify(res.errMsg) + "\n蓝牙是否可用:" + res.available
})
}
})
wx.startBluetoothDevicesDiscovery({
//services: ['FEE7'], //如果填写了此UUID,那么只会搜索出含有这个UUID的设备,建议一开始先不填写或者注释掉这一句
//services: ['00001801-0000-1000-8000-00805F9B34FB','00001800-0000-1000-8000-00805F9B34FB','6E400001-B5A3-F393-E0A9-E50E24DCCA9E'], //如果填写了此UUID,那么只会搜索出含有这个UUID的设备,建议一开始先不填写或者注释掉这一句
success: function (res) {
that.setData({
info: "搜索设备" + JSON.stringify(res),
})
console.log('搜索设备返回' + JSON.stringify(res))
}
})
wx.getBluetoothDevices({
success: function (res) {
that.setData({
info: "设备列表\n" + JSON.stringify(res.devices),
devices: res.devices
})
console.log('搜设备数目:' + res.devices.length)
console.log('设备信息:\n' + JSON.stringify(res.devices)+"\n")
}
})
},
lanyaconnect(event){
var that = this;
wx.createBLEConnection({
deviceId: event.currentTarget.id,
success: function (res) {
console.log('调试信息:' + res.errMsg);
that.setData({
connectedDeviceId: event.currentTarget.id,
info: "MAC地址:" + event.currentTarget.id + ' 调试信息:' + res.errMsg,
})
},
fail: function () {
console.log("连接失败");
},
})
},
lanyatest6(event){
var that = this;
wx.stopBluetoothDevicesDiscovery({
success: function (res) {
console.log("停止搜索" + JSON.stringify(res.errMsg));
that.setData({
info: "停止搜索" + JSON.stringify(res.errMsg),
})
}
})
this.lanyatest7();
},
lanyatest7(event){
var that = this;
wx.getBLEDeviceServices({
// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: that.data.connectedDeviceId,
success: function (res) {
console.log('services UUID:\n', JSON.stringify(res.services));
for (var i = 0; i < res.services.length; i++) {
console.log("第"+(i+1) + "个UUID:" + res.services[i].uuid+"\n")
}
that.setData({
services: res.services,
info: JSON.stringify(res.services),
})
}
})
},
lanyatest8(event){
var that = this;
var myUUID = that.data.servicesUUID;//具有写、通知属性的服务uuid
myUUID="6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
console.log('这是UUID:' + myUUID)
wx.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要在上面的接口中获取
deviceId: that.data.connectedDeviceId,
// 这里的 serviceId 需要在上面的 接口中获取
serviceId: myUUID,
success: function (res) {
console.log("获得Characteristics成功", "color:red;");
for (var i = 0; i < res.characteristics.length; i++) {
console.log('特征值:' + res.characteristics[i].uuid)
if (res.characteristics[i].properties.notify) {
console.log("notifyServicweId:", myUUID);
console.log("notifyCharacteristicsId:", res.characteristics[i].uuid);
that.setData({
notifyServicweId: myUUID,
notifyCharacteristicsId: "6E400003-B5A3-F393-E0A9-E50E24DCCA9E",//手动设置notifyCharacteristicsId为这个UUID,为了方便写死在这里
})
}
if (res.characteristics[i].properties.write) {
console.log("writeServicweId:", myUUID);
console.log("writeCharacteristicsId:", res.characteristics[i].uuid);
that.setData({
writeServicweId: myUUID,
//writeCharacteristicsId: res.characteristics[i].uuid,
writeCharacteristicsId: "6E400002-B5A3-F393-E0A9-E50E24DCCA9E",//手动设置writeCharacteristicsId为这个UUID,为了方便写死在这里
})
}
}
console.log('device getBLEDeviceCharacteristics:', res.characteristics);
that.setData({
msg: JSON.stringify(res.characteristics),
})
},
fail: function (res) {
console.log(res);
},
})
},
//必须先启用notifyCharacteristicsId才能监听characteristicValueChange事件
lanyatest9(event){
var that = this;
console.log(that.data)
var notifyServicweId = that.data.servicesUUID; //具有写、通知属性的服务uuid
var notifyCharacteristicsId = that.data.notifyCharacteristicsId;
console.log("启用notify的serviceId", notifyServicweId);
console.log("启用notify的notifyCharacteristicsId", notifyCharacteristicsId);
wx.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
deviceId: that.data.connectedDeviceId,
// 这里的 serviceId 就是that.data.servicesUUID
serviceId: notifyServicweId,
characteristicId: that.data.notifyCharacteristicsId,
success: function (res) {
//console.log('notifyBLECharacteristicValueChange success', res.errMsg)
//var msg = '启动notify:' + res.errMsg
that.setData({
info: "开启notify成功"
})
},
fail: function (res) {
console.log('启动notify:' + res.errMsg);
},
})
this.lanyatest10();
},
lanyatest10(event){
var that = this;
console.log("开始接收数据");
wx.onBLECharacteristicValueChange(function (res) {
console.log("characteristicId:" + res.characteristicId)
console.log("serviceId:" + res.serviceId)
console.log("deviceId" + res.deviceId)
console.log("Length:" + res.value.byteLength)
console.log("hexvalue:" + ab2hex(res.value))
that.setData({
info: that.data.info + ab2hex(res.value)
})
})
},
lanyatest11(event){
var that = this
var hex=this.strToHexCharCode(that.data.sendmsg)
//console.log(hex1)
//var hex = that.data.sendmsg //要发送的信息
console.log('要发送的信息是:'+hex)
var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16)
}))
console.log(typedArray)
var buffer1 = typedArray.buffer
wx.writeBLECharacteristicValue({
deviceId: that.data.connectedDeviceId,
serviceId: that.data.servicesUUID,
characteristicId: that.data.writeCharacteristicsId,
// 这里的value是ArrayBuffer类型
value: buffer1,
success: function (res) {
console.log('写入成功')
},
fail(res){
console.log('写入失败')
}
})
},
//ASCII码转16进制
strToHexCharCode(str) {
if (str === "") {
return "";
} else {
var hexCharCode = [];
//hexCharCode.push("0x");
for (var i = 0; i < str.length; i++) {
hexCharCode.push((str.charCodeAt(i)).toString(16));
}
return hexCharCode.join("");
}
},
//获取输入框的数据
getmsg(event){
this.setData({
sendmsg:event.detail.value
})
},
lanyatest12(event){
var that = this;
wx.closeBLEConnection({
deviceId: that.data.connectedDeviceId,
success: function (res) {
that.setData({
connectedDeviceId: "",
})
console.log('断开蓝牙设备成功:' + res.errMsg)
},
fail:function(res){
console.log('断开蓝牙设备失败:' + res.errMsg)
}
})
},
onLoad: function (options) {
// this.chinaMessage();
this.foreignMessage();
},
//中国
chinaMessage(){
var that=this;
wx.request({
url: 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5',
method: 'GET',
dataType: 'json',
success: function (res) {
// console.log(res) //json字符串转Json对象
that.setData({
eare: JSON.parse(res.data.data)
});
console.log("111")
console.log(that.data.eare)
}
})
},
//国外
foreignMessage() {
var that=this;
wx.request({
url: 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_foreign',
method: 'GET',
dataType: 'json',
success: function (res) {
that.setData({
foreignData: JSON.parse(res.data.data)
});
console.log("222")
console.log(that.data.foreignData.continentStatis[0].statis.亚洲)
that.countryAddConfirmRankList_fun()
}
})
},
sendsomething(num,event){
var that = this
var hex=this.strToHexCharCode(num+event)
//console.log(hex1)
//var hex = that.data.sendmsg //要发送的信息
console.log('要发送的信息是:'+hex)
var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16)
}))
console.log(typedArray)
var buffer1 = typedArray.buffer
wx.writeBLECharacteristicValue({
deviceId: that.data.connectedDeviceId,
serviceId: that.data.servicesUUID,
characteristicId: that.data.writeCharacteristicsId,
// 这里的value是ArrayBuffer类型
value: buffer1,
success: function (res) {
console.log('写入成功')
},
fail(res){
console.log('写入失败')
}
})
},
senttime(){
console.log(this.data.foreignData.globalStatis.lastUpdateTime)
var that = this
this.sendsomething("a",this.data.foreignData.globalStatis.lastUpdateTime)
this.sendsomething("b",this.data.foreignData.globalStatis.confirm)
this.sendsomething("c",this.data.foreignData.globalStatis.confirmAdd)
this.sendsomething("d",this.data.foreignData.globalStatis.dead)
this.sendsomething("e",this.data.foreignData.globalStatis.deadAdd)
this.sendsomething("f",this.data.foreignData.globalStatis.heal)
this.sendsomething("g",this.data.foreignData.globalStatis.healAdd)
this.sendsomething("h",this.data.foreignData.globalStatis.countryAddConfirmRankList[0].addConfirm)
this.sendsomething("i",this.data.foreignData.globalStatis.countryAddConfirmRankList[1].addConfirm)
this.sendsomething("j",this.data.foreignData.globalStatis.countryAddConfirmRankList[2].addConfirm)
this.sendsomething("k","k")
},
senttime2(){
this.sendsomething("k","k")
},
countryAddConfirmRankList_fun(){
console.log(this.data.foreignData)
var num1=0;
var num2=0.0;
for (var i = 0; i < this.data.foreignData.countryAddConfirmRankList.length;i++){
num1 += this.data.foreignData.countryAddConfirmRankList[i].addConfirm;
}
for (var i = 0; i < this.data.foreignData.countryConfirmWeekCompareRankList.length; i++) {
num2 += this.data.foreignData.countryConfirmWeekCompareRankList[i].rate*1.0;
}
this.setData({
num:num1
})
this.setData({
rateSum: num2
})
var query = wx.createSelectorQuery();
var that = this;
query.selectAll('.countryAddConfirmRankList .countryList').boundingClientRect(function (rect) {
that.setData({
countryListLength: rect[0].width
})
}).exec();
query.selectAll(' .countryList .nation').boundingClientRect(function (rect) {
that.setData({
nation: rect[0].width
})
}).exec();
query.selectAll(' .countryList .addConfirm').boundingClientRect(function (rect) {
that.setData({
addConfirm: rect[0].width
})
}).exec();
}
})
// 微信官方给的ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
var hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join(',');
}
2.wxml代码
3.wxss代码
/* pages/lanyatest/lanyatest.wxss */
.vertical{
display: flex;
flex-direction: column;
}
/**index.wxss**/
.horizontal{
display: flex;
flex-direction: row;
}
.btinfo{
height:100px;
}
.contentview {
margin: 0 10px;
}
.button {
margin: 5px;
}
.myview{
height:200px;
word-break:break-all;/* 自动换行 */
}
/**index.wxss**/
page {
padding: 0;
margin: 0;
}
.head {
width: 94%;
background-color: #00b26a;
border-radius: 18rpx;
margin-left: 3%;
display: flex;
flex-direction: column;
}
.head .title {
width: 100%;
height: 60rpx;
text-align: center;
line-height: 60rpx;
font-size: 35rpx;
margin-top: 10rpx;
}
.head .updateTime {
width: 100%;
height: 40rpx;
font-size: 25rpx;
line-height: 40rpx;
margin-left: 10rpx;
margin-bottom: 10rpx;
overflow: hidden;
border-left: solid yellow 6rpx;
padding-left: 5rpx;
}
.head .globalStatis {
display: flex;
flex-direction: row;
justify-content: space-around;
}
.head .globalStatis .confirm, .head .globalStatis .dead,
.head .globalStatis .heal, .head .globalStatis .nowConfirm {
width: 24%;
height: 110rpx;
border-radius: 5rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
opacity: 0.7;
margin-bottom: 25rpx;
}
.head .globalStatis .confirm .text, .head .globalStatis .dead .text,
.head .globalStatis .heal .text, .head .globalStatis .nowConfirm .text {
font-size: 25rpx;
margin-top: 5rpx;
}
.head .globalStatis .confirm .add, .head .globalStatis .dead .add,
.head .globalStatis .heal .add, .head .globalStatis .nowConfirm .add {
font-size: 22rpx;
display: flex;
flex-direction: row;
justify-content: center;
margin-bottom: 5rpx;
}
.head .globalStatis .confirm .num, .head .globalStatis .dead .num,
.head .globalStatis .heal .num, .head .globalStatis .nowConfirm .num {
font-size: 25rpx;
font-weight: bold;
}
.head .globalStatis .confirm {
background-color: rgb(255, 240, 241);
margin-left: 5rpx;
}
.head .globalStatis .dead {
background-color: rgb(242, 246, 247);
}
.head .globalStatis .heal {
background-color: rgb(240, 248, 244);
}
.head .globalStatis .nowConfirm {
background-color: rgb(255, 240, 241);
margin-right: 5rpx;
}
.head .globalStatis .confirm .num, .head .globalStatis .confirm .add-num,
.head .globalStatis .nowConfirm .num, .head .globalStatis .nowConfirm .add-num {
color: red;
}
.head .globalStatis .heal .num, .head .globalStatis .heal .add-num {
color: rgb(0, 178, 106);
}
.countryAddConfirmRankList {
width: 94%;
height: 480rpx;
margin-left: 3%;
background-color: rgb(240, 240, 240);
margin-top: 20rpx;
display: flex;
flex-direction: column;
border-radius: 12rpx;
}
.countryAddConfirmRankList swiper{
width: 100%;
height: 100%;
}
.countryAddConfirmRankList .title {
width: 100%;
height: 60rpx;
text-align: left;
line-height: 60rpx;
font-size: 35rpx;
margin-top: 10rpx;
border-left: solid 10rpx yellow;
padding-left: 5rpx;
}
.countryAddConfirmRankList .countryList {
width: 100%;
margin-top: 5rpx;
display: flex;
flex-direction: row;
font-size: 25rpx;
}
.countryAddConfirmRankList .countryList .nation {
width: 150rpx;
margin-right: 10rpx;
text-align: right;
}
.countryAddConfirmRankList .countryList .rank {
background-color: red;
}
.countryAddConfirmRankList .countryList .addConfirm {
width: 150rpx;
margin-left: 10rpx;
}
.continentStatis {
width: 94%;
margin-left: 3%;
background-color: rgb(240, 240, 240);
margin-top: 20rpx;
overflow: hidden;
white-space: nowrap;
border-radius: 12rpx;
height: 500rpx;
}
.continentStatis scroll-view {
height: 400rpx;
width: auto;
overflow: hidden;
}
.continentStatis .title {
width: 100%;
height: 60rpx;
text-align: left;
line-height: 60rpx;
font-size: 35rpx;
margin-top: 10rpx;
border-left: solid 10rpx yellow;
padding-left: 5rpx;
}
.continentStatis .first {
display: block;
font-size: 30rpx;
}
.continentStatis .first .lastData {
width: 150rpx;
display: inline-block;
text-align: center;
}
.continentStatis .first .zhou {
display: inline-block;
}
.continentStatis .first .zhou .zh{
width: 200rpx;
display: inline-block;
text-align: center;
}
.continentStatis .first .zongji {
width: 200rpx;
display: inline-block;
text-align: center;
}
.continentStatis .first .bg{
width: 100%;
}
引用与拓展学习:
本项目在做的过程中主要引用了下面几个博客,大家可以参考一下:
基于ESP32+AMG8833的物联网红外成像测温枪
ESP32 TTGO 1.14寸液晶屏使用 TFT_eSPI库驱动
微信小程序连接蓝牙ble教程(目录)ESP32 小程序与蓝牙通信/蓝牙配网/低功率蓝牙通信/Bluetooth