GEC6818传感器模块(烟雾+GY39+RFID)——使用文字取模的方式实现数据显示

GEC6818传感器模块(烟雾+GY39+RFID)——使用文字取模的方式实现数据显示

完整的工程大家可以在我的gitee上进行下载
下载地址:GEC6818智能语音家居系统

文章目录

  • GEC6818传感器模块(烟雾+GY39+RFID)——使用文字取模的方式实现数据显示
    • 一、 文字取模实现数据显示
      • 1. `display_bg()`
      • 2. `display_word()`
      • 3. `display_digit()`
    • 二、 烟雾传感器
      • 2.1 烟雾传感器实现线程
      • 2.2 解析
    • 三、GY39
      • 3.1 GY39的线程代码
      • 3.2 解析
    • 四、 RFID
      • 4.1 RFID线程代码
      • 4.2 解析
    • 五、 完整代码

一、 文字取模实现数据显示

在许多嵌入式系统或特定的显示屏幕上,为了节省存储空间和减少数据传输量,字符通常不是直接以像素形式存储的,而是以“点阵”或“点阵字库”的形式存储。每个字符都由一组预定义的点阵数据来表示。当需要显示一个字符时,可以通过访问这些点阵数据来在显示屏上绘制该字符。

实现步骤:

  1. 定义点阵数据:

    • digits 数组定义了数字0到9的点阵数据。每个数字都是一个5x7的点阵,其中5代表宽度,7代表高度。
    • 其他变量(如guan, qian, wen等)定义了对应汉字的点阵数据。
  2. 字符取模:
    字符取模通常是指根据预定义的点阵数据来“绘制”或“显示”字符。为了从点阵数据中绘制字符,通常会使用两层嵌套循环遍历点阵数据的每一行和每一列,然后根据点阵数据的值来决定是否在显示屏上显示一个点(或像素)。

  3. 字符显示:
    使用点阵数据来绘制字符时,通常会有一个显示函数或方法来实际在屏幕上显示字符。该函数可能会使用点阵数据来决定应该在屏幕上的哪些位置显示像素。

总之,这种字符取模的方式提供了一种有效的方法来在显示屏上显示字符,特别是在资源有限的嵌入式系统中。通过预定义的点阵数据,可以节省存储空间,并减少绘制字符所需的计算量。


void display_bg(int x0, int y0,int x1, int y1 , int color)
{
    int i, j;
    for(i = x0; i < x1; i++)
    {
        for(j = y0; j < y1; j++)
        {
            point(j, i, color);
        }
    }    
}
void display_word(int color,int x0, int y0, char word[], int w, int h)
{
    int i, j, x, y;
    
    for(i = 0; i < w*h/8; i++)
    {
        for(j = 0; j < 8; j++)
        {
            if(word[i]>>(7-j) & 1 ==1)
            {
                x = i/(w/8) + x0;
                y = (i%(w/8))*8 + j + y0;
                point(y, x, color);
            }
        }
    }
}

void display_digit(int color, int x0, int y0, int number, int w, int h)
{
    int i, j, m = 0, a[100] = {0};
    if(number == 0)
    {
        display_word(blue, x0, y0, digits[0], w, h);
    }
    else
    {
        for(i = 0; number != 0; i++)
        {
            a[i] = number%10;
            number /= 10;
        }
        for(j = i - 1; j >= 0; j--)
        {
           // printf("%d\n", a[j]);    
            display_word(blue, x0, y0+m*8, digits[a[j]], w, h);
            m++;
        } 
    }
}


1. display_bg()

该函数旨在在显示器上的指定边界内绘制具有给定颜色的背景矩形。

  • 参数:

    • x0, y0:矩形的起始坐标(左上角)。
    • x1, y1:矩形的结束坐标(右下角)。
    • color:矩形的背景颜色。
  • 逻辑:

    • 嵌套循环遍历指定边界内的x和y坐标。
    • 在每个坐标(i, j)处,调用point(j, i, color)函数(可能是)来设置该像素的颜色。

2. display_word()

该函数旨在在显示器上显示一个字符(以比特矩阵的形式)。

  • 参数:

    • color:字符的颜色。
    • x0, y0:字符将被显示的起始坐标(左上角)。
    • word[]:以特定格式表示字符的数组。
    • w, h:字符的宽度和高度。
  • 逻辑:

    • 函数遍历字符矩阵的每个比特。
    • 对于每个比特,如果它被设置为1,那么相应的像素将设置为指定的颜色。
    • 从给定的字符宽度和高度中推导出要设置的像素的确切位置(x, y)的公式。

3. display_digit()

这是display_word()的一个专门版本,特别用于显示数字。

  • 参数:

    • color:数字的颜色。
    • x0, y0:数字将被显示的起始坐标(左上角)。
    • number:要显示的数字。
    • w, h:数字的宽度和高度。
  • 逻辑:

    • 如果给定的数字是0,它会直接使用display_word()显示数字0
    • 否则,它会将数字分解为各个数字,并逐个显示每个数字。这是通过反复将数字除以10并将余数存储在数组中来完成的。
    • 对于每个数字,都会调用display_word()来显示它。

二、 烟雾传感器

在这里插入图片描述

2.1 烟雾传感器实现线程

//烟雾传感器的线程
#define COM2 "/dev/ttySAC1"
void * yanwu(void *arg)
{
    pthread_detach(pthread_self());

    int fd = serial_init(COM2, 9600);
    int fd1 = open("/dev/pwm", O_RDWR);
    int ret;
    char beep_ctrl[1];

    if(fd == -1)
    {
        perror("serial_init error!\n");
        return (void *)-1;
    }
    if(fd1 == -1)
    {
        perror("open /dev/pwm error!\n");
        return (void *)-1;
    }
    
    while(1)
    {
        char w_buf[9] = {0xFF, 0X01, 0x86, 0, 0, 0, 0, 0, 0x79};
        write(fd, w_buf, 9);
        usleep(1000);
        char r_buf[9];
        int r = read(fd, r_buf, 9);
        if(r == 9 && r_buf[0] == 0xff && r_buf[1] == 0x86)
        {
            int n = r_buf[2]<<8 | r_buf[3];
            printf("n = %d\n", n);
            if(n > 138)
            {
                printf("蜂鸣器\n");
                beep_ctrl[0] = 1;  //不响
                ret = write(fd1,beep_ctrl,sizeof(beep_ctrl));
                if( ret == -1)
                {
                    perror("write");
                }
                sleep(1);
                
                beep_ctrl[0] = 0;  //响
                ret = write(fd1,beep_ctrl,sizeof(beep_ctrl));
                if( ret == -1)
                {
                    perror("write");
                }
                sleep(1);
            }
            else
            {
                beep_ctrl[0] = 0;  //响
                ret = write(fd1,beep_ctrl,sizeof(beep_ctrl));
                if( ret == -1)
                {
                    perror("write");
                }
            }
        }
        
        sleep(1);
    }
    
    //close(fd1);
    close(fd);
    return 0;
}

2.2 解析

这段代码定义了一个名为yanwu的线程函数,该函数用于处理烟雾传感器的数据和操作蜂鸣器。以下是对该函数的详细解析:

  1. 宏定义

    • 使用#define定义了串行通信端口COM2为"/dev/ttySAC1"
  2. 线程初始化

    • 调用pthread_detach函数使得线程在结束时能够自动释放其资源。
    • 使用serial_init函数初始化一个串行端口连接烟雾传感器。
    • 打开一个设备文件/dev/pwm来控制蜂鸣器。
  3. 错误检查

    • 检查串行端口和设备文件的打开情况,如果有错误则打印错误信息并返回。
  4. 主循环

    • 在一个无限循环中,不断地向烟雾传感器发送请求数据的命令,并读取其响应。
    • 如果接收到的数据满足预期格式(前两个字节是特定的值),则进行进一步处理。
  5. 数据解析

    • 从接收到的数据中提取出一个16位的数值n
    • 如果n大于138,表示检测到烟雾浓度超过了设定的阈值,这时蜂鸣器会响应,并进行一系列的响与不响的交替操作。
  6. 蜂鸣器控制

    • 根据烟雾浓度的不同,设置蜂鸣器的状态:当浓度高于阈值时,蜂鸣器会交替响和不响;否则,蜂鸣器会维持不响的状态。
  7. 资源释放

    • 代码中有一个注释掉的close(fd1);,这表示该代码段原先可能是用于关闭蜂鸣器设备文件的,但在当前版本中被注释掉了。
  8. 返回值

    • 函数最后返回0,这通常表示函数执行成功。

总的来说,该线程函数yanwu负责与烟雾传感器通信,根据检测到的烟雾浓度来控制蜂鸣器的响与不响,并在控制台打印相关的信息。

三、GY39

3.1 GY39的线程代码

//GY39 的线程
void * gy_39(void *arg)
{
/*    
 发送的信息:
  开发板发送给传感器的指令格式:帧头+指令+校验和(8bit)
  帧头和校验和是用来“验证身份”的
  指令才是用来表达此次通信的目的
  各占一个字节,共三个字节
  帧头:0xa5
  指令:
    只请求光照: 10000001 -> 0x81
    只请求温湿度气压海拔:10000010 -> 0x82
    两种都请求:10000011 -> 0x83
  检验和:
    等于帧头加上指令,只保存低8位
   0xa5 + 0x81  -> 0x26
*/

    pthread_detach(pthread_self());

    char led_ctrl[2];
    int fd1 = open("/dev/led_drv",O_RDWR);
    if(fd1 < 0)
 {
  printf("open led_drv failed\n");
  return (void*)-1;
 }
    int fd = serial_init(COM3, 9600);
    int m = 2;
    char w_buf[][3] ={{0xa5, 0x81, 0x26}, {0xa5, 0x82, 0x27}, {0xa5, 0x83, 0x28}};
    int Lux = 0, T = 0, P = 0, Hum = 0, H = 0;
    int t,r,ret;
    char r_buf[24];
    while (1)
    {

        t = write(fd, w_buf[m], 3);
        // printf("%d\n", t);
        usleep(1000);
        r = read(fd, r_buf, 24);

        if (r == 9 && r_buf[2] == 0x15)
        {
            Lux = (r_buf[4] << 24 | r_buf[5] << 16 | r_buf[6] << 8 | r_buf[7]) / 100;
        }
        else if (r == 15 && r_buf[2] == 0x45)
        {
            T = (r_buf[4] << 8 | r_buf[5]) / 100;
            P = (r_buf[6] << 24 | r_buf[7] << 16 | r_buf[8] << 8 | r_buf[9]) / 100;
            Hum = (r_buf[10] << 8 | r_buf[11]) / 100;
            H = (r_buf[12] << 8 | r_buf[13]) / 100;
        }
        else if (r == 24)
        {
            Lux = (r_buf[4] << 24 | r_buf[5] << 16 | r_buf[6] << 8 | r_buf[7]) / 100;
            T = (r_buf[13] << 8 | r_buf[14]) / 100;
            P = (r_buf[15] << 24 | r_buf[16] << 16 | r_buf[8] << 8 | r_buf[9]) / 100;
            Hum = (r_buf[10] << 8 | r_buf[11]) / 100;
            H = (r_buf[12] << 8 | r_buf[13]) / 100;
        }
        printf("Lux = %d, T = %d, P = %d, Hum = %d, H = %d\n", Lux, T, P, Hum, H);
        sleep(1);

        if (Lux < 6)
        {
            led_ctrl[1] = 9;  //D9
            led_ctrl[0] = 1; //on
            ret = write(fd1,led_ctrl,sizeof(led_ctrl));
            
            if( ret != 2)
            {
                perror("write");
            }
            sleep(1);
        }
        else
        {
            led_ctrl[1] = 9; //D9
            led_ctrl[0] = 0; //off
            
            ret = write(fd1,led_ctrl,sizeof(led_ctrl));
            
            if( ret != 2)
            {
            
                perror("write");
            }
            sleep(1);
    }
        display_word(black, 170, 100, guan, 16, 16);
        display_word(black, 170, 116, qian, 16, 16);
        display_word(black, 170, 132, maohao, 16, 16);
        display_bg(170, 148, 186, 164, white);
        display_digit(blue, 170, 148, Lux, 8, 16);
        display_word(blue, 170, 169, L, 8, 16);
        display_word(blue, 170, 177, U, 8, 16);
        display_word(blue, 170, 185, X, 8, 16);

        display_word(black, 196, 100, wen, 16, 16);
        display_word(black, 196, 116, du, 16, 16);
        display_word(black, 196, 132, maohao, 16, 16);
        display_bg(196, 148, 218, 172, white);
        display_digit(blue, 196, 148, T, 8, 16);
        display_word(blue, 196, 169, C, 16, 16);

        display_word(black, 222, 100, shi, 16, 16);
        display_word(black, 222, 116, du, 16, 16);
        display_word(black, 222, 132, maohao, 16, 16);
        display_bg(222, 148, 238, 182 + 100, white);
        display_digit(blue, 222, 148, Hum, 8, 16);
        display_word(blue, 222, 174, baifenhao, 8, 16);

        display_word(black, 248, 100, qi, 16, 16);
        display_word(black, 248, 116, ya, 16, 16);
        display_word(black, 248, 132, maohao, 16, 16);
        display_bg(248, 148, 264, 209 + 50, white);
        display_digit(blue, 248, 148, P, 8, 16);
        display_word(blue, 248, 193, _P, 8, 16);
        display_word(blue, 248, 201, A, 8, 16);

        display_word(black, 272, 100, hai, 16, 16);
        display_word(black, 272, 116, ba, 16, 16);
        display_word(black, 272, 132, maohao, 16, 16);
        display_bg(272, 148, 288, 177 + 100, white);
        display_digit(blue, 272, 148, H, 8, 16);
        display_word(blue, 272, 169, M, 8, 16);
    }
    
    close(fd);
    //return 0;
}

3.2 解析

这段代码是一个线程函数gy_39,该函数与一个光照、温湿度、气压和海拔高度传感器GY-39进行通信。以下是对该函数的详细解析:

  1. 函数开头的注释:提供了与传感器通信的指令格式。

  2. 初始化

    • 打开了一个名为/dev/led_drv的设备文件来控制LED。
    • 使用serial_init函数初始化了一个串行端口连接传感器。
  3. 通信部分

    • 代码定义了三种不同的指令,每个指令对应于从传感器请求不同的数据(光照、温湿度、气压和海拔高度)。
    • 使用write函数将这些指令写入串行端口,并尝试从传感器读取数据。
  4. 数据解析

    • 从传感器读取的数据被解析并存储在不同的变量(如Lux, T, P, Hum, H)中。
    • 这些数据被打印到控制台。
  5. LED控制

    • 根据读取的光照值(Lux),代码控制LED的状态。如果光照值小于6,LED会被打开;否则,LED会关闭。
  6. 显示函数

    • 使用了多个display_worddisplay_bg函数来在屏幕上显示不同的文本和背景。
  7. 循环

    • 整个代码位于一个无限循环中,使得传感器持续地发送数据并更新LED状态和屏幕显示。
  8. 函数结束

    • 关闭了串行端口并返回。

总体来说,这个线程函数gy_39负责与GY-39传感器通信,读取其数据,根据读取的数据控制LED的状态,并在屏幕上显示这些数据。

四、 RFID

4.1 RFID线程代码


void * rfid(void *arg)
{
    pthread_detach(pthread_self());
    //初始化串口
 int fd = serial_init(COM4,9600);
 printf("fd = %d\n",fd);
 //给我们的rfid发送使能命令 打开你的rfid这个设备
 //自己写一个函数 来实现命令的发送
 
 
 int r = SendEnableCmd(fd);
 if(r != 0)//失败了
 {
        printf("SendEnableCmd error\n");
 }
 
 while(1)
 {
  //发送请求
  r = RequestRfidCmd(fd);
  if(r == 0)//请求成功
  {
   //防碰撞
   CascAnticollRfidCmd(fd);
   printf("你好我是小草神\n");
            show_bmp("green.bmp", 450, 10,0);
            sleep(1);
            InitSensor();
        }
 }
}

4.2 解析

这段代码定义了一个名为rfid的线程函数,该函数用于与RFID设备进行通信并执行一系列操作。以下是对该函数的详细解析:

  1. 线程初始化

    • 使用pthread_detach函数使得线程在结束时能够自动释放其资源。
  2. 串口初始化

    • 使用serial_init函数初始化一个串行端口连接RFID设备,并返回一个文件描述符fd
    • 打印文件描述符fd的值。
  3. RFID设备使能

    • 调用SendEnableCmd(fd)函数发送使能命令给RFID设备。
    • 检查命令发送的结果,如果返回值不为0,表示命令发送失败,并打印错误信息。
  4. 主循环

    • 在一个无限循环中,不断地向RFID设备发送请求命令。
    • 如果请求成功(即返回值为0),则执行以下操作:
      • 调用CascAnticollRfidCmd(fd)函数进行防碰撞处理。
      • 在控制台打印消息"你好我是小草神"。
      • 使用show_bmp函数显示一个名为"green.bmp"的位图文件在指定位置。
      • 调用sleep(1)函数使线程休眠1秒。
      • 调用InitSensor函数进行传感器的初始化。
  5. 函数结束

    • 由于这是一个无限循环的线程函数,因此在正常情况下,函数不会自然结束。需要外部干预(例如通过其他线程或信号)才能结束该函数。

总的来说,该线程函数rfid负责与RFID设备通信,执行一系列初始化和操作,并在控制台上显示相关的消息和位图。

五、 完整代码


#include "sensor.h"    

extern int touch_fd;

// 存储点阵数据
char digits[10][16] = {
/*--  文字:  0  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00},

/*--  文字:  1  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00},

/*--  文字:  2  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00},

/*--  文字:  3  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x04,0x02,0x42,0x42,0x3C,0x00,0x00},

/*--  文字:  4  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x04,0x0C,0x0C,0x14,0x24,0x24,0x44,0x7F,0x04,0x04,0x1F,0x00,0x00},

/*--  文字:  5  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x78,0x44,0x02,0x02,0x42,0x44,0x38,0x00,0x00},

/*--  文字:  6  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x18,0x24,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x22,0x1C,0x00,0x00},

/*--  文字:  7  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x7E,0x42,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x00,0x00},

/*--  文字:  8  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00},

/*--  文字:  9  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
{0x00,0x00,0x00,0x38,0x44,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x24,0x18,0x00,0x00}
};
 char guan[] = {
 /*--  文字:  光  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x01,0x00,0x21,0x08,0x11,0x08,0x09,0x10,0x09,0x20,0x01,0x00,0xFF,0xFE,0x04,0x40,
0x04,0x40,0x04,0x40,0x04,0x40,0x08,0x42,0x08,0x42,0x10,0x42,0x20,0x3E,0xC0,0x00
};
char qian[] = {
/*--  文字:  强  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0xF9,0xFC,0x09,0x04,0x09,0x04,0x09,0xFC,0x78,0x20,0x40,0x20,0x43,0xFE,
0x42,0x22,0x7A,0x22,0x0B,0xFE,0x08,0x20,0x08,0x24,0x08,0x22,0x57,0xFE,0x20,0x02
};
char wen[] = {
/*--  文字:  温  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x23,0xF8,0x12,0x08,0x12,0x08,0x83,0xF8,0x42,0x08,0x42,0x08,0x13,0xF8,
0x10,0x00,0x27,0xFC,0xE4,0xA4,0x24,0xA4,0x24,0xA4,0x24,0xA4,0x2F,0xFE,0x00,0x00
};
char du[] = {
/*--  文字:  度  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
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
};
char shi[] = {
/*--  文字:  湿  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x27,0xF8,0x14,0x08,0x14,0x08,0x87,0xF8,0x44,0x08,0x44,0x08,0x17,0xF8,
0x11,0x20,0x21,0x20,0xE9,0x24,0x25,0x28,0x23,0x30,0x21,0x20,0x2F,0xFE,0x00,0x00
};
char qi[] = {
/*--  文字:  气  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x10,0x00,0x10,0x00,0x3F,0xFC,0x20,0x00,0x4F,0xF0,0x80,0x00,0x3F,0xF0,0x00,0x10,
0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x0A,0x00,0x0A,0x00,0x06,0x00,0x02
};
char ya[] = {
/*--  文字:  压  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x3F,0xFE,0x20,0x00,0x20,0x80,0x20,0x80,0x20,0x80,0x20,0x80,0x2F,0xFC,
0x20,0x80,0x20,0x80,0x20,0x90,0x20,0x88,0x20,0x88,0x40,0x80,0x5F,0xFE,0x80,0x00
};
char hai[] = {
/*--  文字:  海  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x01,0x00,0x21,0x00,0x11,0xFC,0x12,0x00,0x85,0xF8,0x41,0x08,0x49,0x48,0x09,0x28,
0x17,0xFE,0x11,0x08,0xE2,0x48,0x22,0x28,0x23,0xFC,0x20,0x08,0x20,0x50,0x00,0x20
};
char ba[] = {
/*--  文字:  拔  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x10,0x50,0x10,0x48,0x10,0x48,0x10,0x40,0xFB,0xFE,0x10,0x80,0x14,0x80,0x18,0xFC,
0x31,0x44,0xD1,0x44,0x11,0x28,0x11,0x28,0x12,0x10,0x12,0x28,0x54,0x44,0x21,0x82
};
char maohao[] = {
/*--  文字:  :  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x00,0x00,0x00,0x00
};
char C[] = {
/*--  文字:  ℃  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=16x16   --*/
0x60,0x00,0x91,0xF4,0x96,0x0C,0x6C,0x04,0x08,0x04,0x18,0x00,0x18,0x00,0x18,0x00,
0x18,0x00,0x18,0x00,0x18,0x00,0x08,0x00,0x0C,0x04,0x06,0x08,0x01,0xF0,0x00,0x00
};
char L[] = {
/*--  文字:  l  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00
};
char U[] = {
/*--  文字:  u  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x42,0x42,0x42,0x42,0x46,0x3B,0x00,0x00
};
char X[] = {
/*--  文字:  x  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x24,0x18,0x18,0x18,0x24,0x6E,0x00,0x00
};
char baifenhao[] = {
/*--  文字:  %  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x00,0x44,0xA4,0xA8,0xA8,0xB0,0x54,0x1A,0x2A,0x2A,0x4A,0x44,0x00,0x00
};
char _P[] = {
/*--  文字:  P  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x00,0xFC,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x40,0xE0,0x00,0x00
};
char A[] = {
/*--  文字:  a  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x0C,0x34,0x44,0x4C,0x36,0x00,0x00
};
char M[] = {
/*--  文字:  m  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x49,0x49,0x49,0x49,0x49,0xED,0x00,0x00
};

//6818串口所对应的文件名
#define COM2 "/dev/ttySAC1"
#define COM3 "/dev/ttySAC2"
#define COM4 "/dev/ttySAC3"
int * p, blue = 0xff0000, black = 0xff0000, white = 0x00FFFFFF;

void display_bg(int x0, int y0,int x1, int y1 , int color)
{
    int i, j;
    for(i = x0; i < x1; i++)
    {
        for(j = y0; j < y1; j++)
        {
            point(j, i, color);
        }
    }    
}
void display_word(int color,int x0, int y0, char word[], int w, int h)
{
    int i, j, x, y;
    
    for(i = 0; i < w*h/8; i++)
    {
        for(j = 0; j < 8; j++)
        {
            if(word[i]>>(7-j) & 1 ==1)
            {
                x = i/(w/8) + x0;
                y = (i%(w/8))*8 + j + y0;
                point(y, x, color);
            }
        }
    }
}

void display_digit(int color, int x0, int y0, int number, int w, int h)
{
    int i, j, m = 0, a[100] = {0};
    if(number == 0)
    {
        display_word(blue, x0, y0, digits[0], w, h);
    }
    else
    {
        for(i = 0; number != 0; i++)
        {
            a[i] = number%10;
            number /= 10;
        }
        for(j = i - 1; j >= 0; j--)
        {
           // printf("%d\n", a[j]);    
            display_word(blue, x0, y0+m*8, digits[a[j]], w, h);
            m++;
        } 
    }
}


void display_picture(int x0, int y0, char file[])
{
    printf("%s\n", file);
    short int m;
    int bmp_fd, w, h;
    bmp_fd = open(file, O_RDONLY);
    
    if(bmp_fd == -1)
    {
        perror("open picture file error!");
        return;
    }
    
    lseek(bmp_fd, 0x12, SEEK_SET);
    read(bmp_fd, &w, 4);
    lseek(bmp_fd, 0x16, SEEK_SET);
    read(bmp_fd, &h, 4);    
    lseek(bmp_fd, 0x1C, SEEK_SET);
    read(bmp_fd, &m, 2);
   // printf("w = %d\n", w);
   // printf("h = %d\n", h);
   // printf("m = %d\n", m);
    char color_buf[w*h*m/8];
    lseek(bmp_fd, 54, SEEK_SET);
    read(bmp_fd, color_buf, w*h*m/8);
    
    int i, j, n = 0;
    for(i = h-1+x0; i >= x0; i--)
    {
        for(j = y0; j < w + y0; j++)
        {
            int color = color_buf[2+3*n] << 16 | color_buf[1+3*n] << 8 | color_buf[0+3*n];
            point(j, i, color);
            n++;
        }
    }
    
    close(bmp_fd);
}


int serial_init(char *file,int speed)
{
 /*
  打开串口文件
 */
    int fd = open(file,O_RDWR);
    if(fd == -1)
    {
        perror("open serial error");
        return -1;
    }
 
    /*定义串口属性结构体*/
    struct termios myserial;
    memset(&myserial,0,sizeof(myserial));//清零
 
 /*设置控制模式 本地连接  使能接收*/
    myserial.c_cflag |= (CLOCAL | CREAD); 
    myserial.c_cflag &=  ~CSIZE; //清空数据位
    myserial.c_cflag &= ~CRTSCTS; //无硬件控制流
    myserial.c_cflag |= CS8; //数据位 8
    myserial.c_cflag &= ~CSTOPB; //停止位 1
    myserial.c_cflag &= ~PARENB; //不要校验

    /*设置波特率*/
 switch(speed)
 {
  case 9600:
   cfsetospeed(&myserial,B9600);
   cfsetispeed(&myserial,B9600);
   break;
  case 57600:
   cfsetospeed(&myserial,B57600);
   cfsetispeed(&myserial,B57600);
   break;
  case 115200:
   cfsetospeed(&myserial,B115200);
   cfsetispeed(&myserial,B115200);
   break;
 }
 
    /*刷新输出队列,清除正接收的数据*/
    tcflush(fd,TCIFLUSH);

    /*更改配置*/
    tcsetattr(fd,TCSANOW,&myserial);
 
    return fd;
}

//获取校验和
char get_BCC(char *cmd)
{
 char BCC = 0;
 int i;
 for(i = 0;i < cmd[0] - 2;i++)
 {
  //BCC = BCC ^ cmd[i];
  BCC ^= cmd[i];
 }
 
 return ~BCC;
}

/*
 防碰撞
 
*/

void CascAnticollRfidCmd(int fd)
{
 char cmd[8] = {0};
 cmd[0] = 0x08;
 cmd[1] = 0x02;
 cmd[2] = 0x42;
 cmd[3] = 0x02;
 cmd[4] = 0x93;//使用ALL模式
 cmd[5] = 0x00;
 cmd[6] = get_BCC(cmd);
 cmd[7] = 0x03;
 //将这个命令发送给rfid 
 write(fd,cmd,cmd[0]);
 
 //稍微延时一会 0.1s
 usleep(100000);
 
 //收rfid的回应
 unsigned char buf[10] = {0};
 int r = read(fd,buf,10);
 if(r == 10)
 {  
  if(buf[2] == 0)
  {
   int getUID  = buf[4] | buf[5] << 8 | buf[6] << 16 | buf[7] << 24;
   printf("getUID = %x\n",getUID);
  }
 }
 else
 {
  perror("read CascAnticollRfidCmd error");
 }
 
 
}

/*
 这个函数是对rfid进行请求的
 成功返回0  失败返回-1
*/
int RequestRfidCmd(int fd)
{
 unsigned char cmd[7] = {0};
 cmd[0] = 0x07;
 cmd[1] = 0x02;
 cmd[2] = 0x41;
 cmd[3] = 0x01;
 cmd[4] = 0x52;//使用ALL模式
 cmd[5] = get_BCC(cmd);
 cmd[6] = 0x03;
 //将这个命令发送给rfid 
 write(fd,cmd,cmd[0]);
 
 //稍微延时一会 0.1s
 usleep(1000000);
 
 //等待rfid的回应
 char buf[8] = {0};
 int r = read(fd,buf,8);
 if(r == 8)
 {
  if(buf[2] == 0)//请求成功
  { 
   switch(buf[4])
   {
    case 0x04:
     printf("S50\n");
     break;
    case 0x02:
     printf("S70\n");
     break;
   }
   
   return 0;
  }
  return -1;
  
 }
 else
 {
  perror("请求失败\n");
  //将蜂鸣器弄的不响
  
  return -1;
 }
}


/*
 这个函数的功能是为了给rfid发送使能命令 
 并且专注这个rfid的返回信息
 fd:是你的初始化好了的串口
 成功返回0 失败返回-1
*/
int SendEnableCmd(int fd)
{
 unsigned char cmd[6] = {0};
 cmd[0] = 0x06;
 cmd[1] = 0x01;
 cmd[2] = 0x41;
 cmd[3] = 0x00;
 cmd[4] = get_BCC(cmd);
 cmd[5] = 0x03;
 
 //将这个命令发送给rfid 
 write(fd,cmd,cmd[0]);
 
 //稍微延时一会 0.1s
 usleep(100000);
 
 
 //等你的rfid回你的信息
 char buf[18] = {0};
 int r = read(fd,buf,18);
 //printf("%d %d\n",r,buf[2]);
 if(18 == r)//这样你才叫得到了完整信息
 {
  if(buf[2] == 0)//这样才叫准备好了
  {
   printf("yes\n");
   return 0;
  }  
  return -1;
 } 
 else
 {
        printf("SendEnableCmd read r = %d\n",r);
  perror("read error");
  return -1;
 }
}

void InitSensor()
{
    show_bmp("beauty.bmp", 0, 0,0);
    show_bmp("draw4.bmp", 750, 400,0);
    Displaysql(200, 150, 90, 160, 0xffffff);
}


/* 进程部分 */

void * yanwu(void *arg)
{
    pthread_detach(pthread_self());

    int fd = serial_init(COM2, 9600);
    int fd1 = open("/dev/pwm", O_RDWR);
    int ret;
    char beep_ctrl[1];

    if(fd == -1)
    {
        perror("serial_init error!\n");
        return (void *)-1;
    }
    if(fd1 == -1)
    {
        perror("open /dev/pwm error!\n");
        return (void *)-1;
    }
    
    while(1)
    {
        char w_buf[9] = {0xFF, 0X01, 0x86, 0, 0, 0, 0, 0, 0x79};
        write(fd, w_buf, 9);
        usleep(1000);
        char r_buf[9];
        int r = read(fd, r_buf, 9);
        if(r == 9 && r_buf[0] == 0xff && r_buf[1] == 0x86)
        {
            int n = r_buf[2]<<8 | r_buf[3];
            printf("n = %d\n", n);
            if(n > 138)
            {
                printf("蜂鸣器\n");
                beep_ctrl[0] = 1;  //不响
                ret = write(fd1,beep_ctrl,sizeof(beep_ctrl));
                if( ret == -1)
                {
                    perror("write");
                }
                sleep(1);
                
                beep_ctrl[0] = 0;  //响
                ret = write(fd1,beep_ctrl,sizeof(beep_ctrl));
                if( ret == -1)
                {
                    perror("write");
                }
                sleep(1);
            }
            else
            {
                beep_ctrl[0] = 0;  //响
                ret = write(fd1,beep_ctrl,sizeof(beep_ctrl));
                if( ret == -1)
                {
                    perror("write");
                }
            }
        }
        
        sleep(1);
    }
    
    //close(fd1);
    close(fd);
    return 0;
}



void * rfid(void *arg)
{
    pthread_detach(pthread_self());
    //初始化串口
 int fd = serial_init(COM4,9600);
 printf("fd = %d\n",fd);
 //给我们的rfid发送使能命令 打开你的rfid这个设备
 //自己写一个函数 来实现命令的发送
 
 
 int r = SendEnableCmd(fd);
 if(r != 0)//失败了
 {
        printf("SendEnableCmd error\n");
 }
 
 while(1)
 {
  //发送请求
  r = RequestRfidCmd(fd);
  if(r == 0)//请求成功
  {
   //防碰撞
   CascAnticollRfidCmd(fd);
   printf("你好我是小草神\n");
            show_bmp("green.bmp", 450, 10,0);
            sleep(1);
            InitSensor();
        }
 }
}

void * gy_39(void *arg)
{
/*    
 发送的信息:
  开发板发送给传感器的指令格式:帧头+指令+校验和(8bit)
  帧头和校验和是用来“验证身份”的
  指令才是用来表达此次通信的目的
  各占一个字节,共三个字节
  帧头:0xa5
  指令:
    只请求光照: 10000001 -> 0x81
    只请求温湿度气压海拔:10000010 -> 0x82
    两种都请求:10000011 -> 0x83
  检验和:
    等于帧头加上指令,只保存低8位
   0xa5 + 0x81  -> 0x26
*/

    pthread_detach(pthread_self());

    char led_ctrl[2];
    int fd1 = open("/dev/led_drv",O_RDWR);
    if(fd1 < 0)
 {
  printf("open led_drv failed\n");
  return (void*)-1;
 }
    int fd = serial_init(COM3, 9600);
    int m = 2;
    char w_buf[][3] ={{0xa5, 0x81, 0x26}, {0xa5, 0x82, 0x27}, {0xa5, 0x83, 0x28}};
    int Lux = 0, T = 0, P = 0, Hum = 0, H = 0;
    int t,r,ret;
    char r_buf[24];
    while (1)
    {

        t = write(fd, w_buf[m], 3);
        // printf("%d\n", t);
        usleep(1000);
        r = read(fd, r_buf, 24);

        if (r == 9 && r_buf[2] == 0x15)
        {
            Lux = (r_buf[4] << 24 | r_buf[5] << 16 | r_buf[6] << 8 | r_buf[7]) / 100;
        }
        else if (r == 15 && r_buf[2] == 0x45)
        {
            T = (r_buf[4] << 8 | r_buf[5]) / 100;
            P = (r_buf[6] << 24 | r_buf[7] << 16 | r_buf[8] << 8 | r_buf[9]) / 100;
            Hum = (r_buf[10] << 8 | r_buf[11]) / 100;
            H = (r_buf[12] << 8 | r_buf[13]) / 100;
        }
        else if (r == 24)
        {
            Lux = (r_buf[4] << 24 | r_buf[5] << 16 | r_buf[6] << 8 | r_buf[7]) / 100;
            T = (r_buf[13] << 8 | r_buf[14]) / 100;
            P = (r_buf[15] << 24 | r_buf[16] << 16 | r_buf[8] << 8 | r_buf[9]) / 100;
            Hum = (r_buf[10] << 8 | r_buf[11]) / 100;
            H = (r_buf[12] << 8 | r_buf[13]) / 100;
        }
        printf("Lux = %d, T = %d, P = %d, Hum = %d, H = %d\n", Lux, T, P, Hum, H);
        sleep(1);

        if (Lux < 6)
        {
            led_ctrl[1] = 9;  //D9
            led_ctrl[0] = 1; //on
            ret = write(fd1,led_ctrl,sizeof(led_ctrl));
            
            if( ret != 2)
            {
                perror("write");
            }
            sleep(1);
        }
        else
        {
            led_ctrl[1] = 9; //D9
            led_ctrl[0] = 0; //off
            
            ret = write(fd1,led_ctrl,sizeof(led_ctrl));
            
            if( ret != 2)
            {
            
                perror("write");
            }
            sleep(1);
    }
        display_word(black, 170, 100, guan, 16, 16);
        display_word(black, 170, 116, qian, 16, 16);
        display_word(black, 170, 132, maohao, 16, 16);
        display_bg(170, 148, 186, 164, white);
        display_digit(blue, 170, 148, Lux, 8, 16);
        display_word(blue, 170, 169, L, 8, 16);
        display_word(blue, 170, 177, U, 8, 16);
        display_word(blue, 170, 185, X, 8, 16);

        display_word(black, 196, 100, wen, 16, 16);
        display_word(black, 196, 116, du, 16, 16);
        display_word(black, 196, 132, maohao, 16, 16);
        display_bg(196, 148, 218, 172, white);
        display_digit(blue, 196, 148, T, 8, 16);
        display_word(blue, 196, 169, C, 16, 16);

        display_word(black, 222, 100, shi, 16, 16);
        display_word(black, 222, 116, du, 16, 16);
        display_word(black, 222, 132, maohao, 16, 16);
        display_bg(222, 148, 238, 182 + 100, white);
        display_digit(blue, 222, 148, Hum, 8, 16);
        display_word(blue, 222, 174, baifenhao, 8, 16);

        display_word(black, 248, 100, qi, 16, 16);
        display_word(black, 248, 116, ya, 16, 16);
        display_word(black, 248, 132, maohao, 16, 16);
        display_bg(248, 148, 264, 209 + 50, white);
        display_digit(blue, 248, 148, P, 8, 16);
        display_word(blue, 248, 193, _P, 8, 16);
        display_word(blue, 248, 201, A, 8, 16);

        display_word(black, 272, 100, hai, 16, 16);
        display_word(black, 272, 116, ba, 16, 16);
        display_word(black, 272, 132, maohao, 16, 16);
        display_bg(272, 148, 288, 177 + 100, white);
        display_digit(blue, 272, 148, H, 8, 16);
        display_word(blue, 272, 169, M, 8, 16);
    }
    
    close(fd);
    //return 0;
}

int main()
{
    struct input_event ev;//
    int flag = 0;//超时的flag
    int ev_x0,ev_y0,ev_x,ev_y,move_x,move_y;


    pthread_t task_yanwu,task_rfid,task_gy39;
    if(pthread_create(&task_yanwu, NULL, (void *)yanwu, NULL) == -1)
    {
        perror("fail to create pthread task_yanwu\n");
        return -1;
    }
    if(pthread_create(&task_rfid, NULL, (void *)rfid, NULL) == -1)
    {
        perror("fail to create pthread task_rfid\n");
        return -1;
    }
    if(pthread_create(&task_gy39, NULL, (void *)gy_39, NULL) == -1)
    {
        perror("fail to create pthread task_rfid\n");
        return -1;
    }
    while (1)
    {
        //我们想获取坐标值  那么就是从这个文件里面读取内容
        int r = read(touch_fd,&ev,sizeof(ev));
        if(sizeof(ev) != r)//读出问题出来了
        {
            usleep(10);
            flag++;
            if(10 <= flag)
            {
                //超时太多了  不行了
                perror("read ev error");
                return 0;//返回一个错误的方向
            }
            continue;
        }
        flag = 0;
        //将数据打印出来看看
        //printf("type:%d code:%d value:%d\n",ev.type,ev.code,ev.value);
        //获取坐标
        if(EV_ABS == ev.type)//接下来的数据就是坐标
        {
            if(REL_X == ev.code)//x轴
            {
                ev_x = ev.value;
            }
            else if(REL_Y == ev.code)//y轴
            {
                ev_y = ev.value;
            }
        }
        if(0x01 == ev.type && BTN_TOUCH == ev.code && 0x01 == ev.value)//手按下去的时候
        {
            ev_x0 = ev_x * 800 / 1200;
            ev_y0 = ev_y * 480 / 600;
        }
        
        else if(0x01 == ev.type && BTN_TOUCH == ev.code && 0x00 == ev.value)//手抬起来
        {
            //printf("ev_x0:%d ev_y0:%d\n",ev_x0,ev_y0);
            //实现点击和方向判断
            if(ev_x0 == (ev_x * 800 / 1200) && ev_y0 == (ev_y * 480 / 600))//你的手没有动
            {
                printf("点击\n");
                //return;
            }
            if ((ev_x0 > 600 && ev_x0 < 680) && (ev_y0 > 400 && ev_y0 < 470))
            {

                printf("退出\n");
                pthread_cancel(task_yanwu);
                pthread_cancel(task_rfid);
                pthread_cancel(task_gy39);
                break;
                //exit(1);
            }
        }
    }
    
    return 0;
}


完整的工程大家可以在我的gitee上进行下载
下载地址:GEC6818智能语音家居系统

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/301844.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于YOLOv5全系列参数模型【n/s/m/l/x】开发构建道路交通场景下CCTSDB2021交通标识检测识别系统

交通标志检测是交通标志识别系统中的一项重要任务。与其他国家的交通标志相比&#xff0c;中国的交通标志有其独特的特点。卷积神经网络&#xff08;CNN&#xff09;在计算机视觉任务中取得了突破性进展&#xff0c;在交通标志分类方面取得了巨大的成功。CCTSDB 数据集是由长沙…

LXD容器中通过Qemu安装Win7虚拟机(呕心制作-诸多细节)

前言 为了抵御网络攻击&#xff0c;实验复现某些计算机漏洞&#xff0c;需要安装Win7操作系统。 真是呕心制作&#xff0c;反复尝试好多次&#xff0c;搜索很多相关资料&#xff0c;终于总结出这篇文章&#xff0c;其目的是通过虚拟化技术&#xff0c;完成Win7的安装配置。其中…

imgaug库指南(九):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

计算机网络(超级详细笔记)

使用教材计算机网络&#xff08;第8版&#xff09;&#xff08;谢希仁&#xff09; 第一章&#xff1a;概述 第二章&#xff1a;物理层 第三章&#xff1a;数据链路层 第四章&#xff1a;网络层 第五章&#xff1a;运输层 第六章&#xff1a;应用层 目…

王中阳Go赠书活动第一期:《TVM编译器原理与实践》

文章目录 前言TVM编译器的实现过程关于《TVM编译器原理与实践》编辑推荐内容简介作者简介图书目录书中前言/序言《TVM编译器原理与实践》全书速览入手《TVM编译器原理与实践》传送门&#xff1a;结束语参加抽奖 前言 随着人工智能的发展&#xff0c;计算机视觉、自然语言处理和…

RapidSSL和Geotrust的通配符证书区别

RapidSSL颁发的数字证书产品方便快捷&#xff0c;只有一款DV基础型通配符SSL证书&#xff0c;只需要验证域名所有权就可以签发证书。Geotrust旗下的通配符SSL证书产品不止一款&#xff0c;既有DV基础型通配符SSL证书&#xff0c;也有OV企业型通配符SSL证书。今天就随SSL盾小编了…

【每日论文阅读】Do Perceptually Aligned Gradients Imply Robustness?

近似人眼梯度 https://icml.cc/virtual/2023/oral/25482 对抗性鲁棒分类器具有非鲁棒模型所没有的特征——感知对齐梯度&#xff08;PAG&#xff09;。它们相对于输入的梯度与人类的感知非常一致。一些研究已将 PAG 确定为稳健训练的副产品&#xff0c;但没有一篇研究将其视为…

性能分析与调优: Linux 实现 CPU剖析与火焰图

目录 一、实验 1.环境 2.CPU 剖析 3.CPU火焰图 一、实验 1.环境 &#xff08;1&#xff09;主机 表1-1 主机 主机架构组件IP备注prometheus 监测 系统 prometheus、node_exporter 192.168.204.18grafana监测GUIgrafana192.168.204.19agent 监测 主机 node_exporter192…

产教融合 | 湖南科技大学近千名学子走进云畅科技,深度研学低代码技术与应用

近日&#xff0c;湖南科技大学计算机学院和潇湘学院的2022级共918名同学齐聚湖南云畅网络科技有限公司&#xff08;简称“云畅科技”&#xff09;&#xff0c;展开了一场深入了解低代码行业前沿技术的研学之旅。此次活动旨在拓展学生视野&#xff0c;提升对数字化转型的认知&am…

Jmeter扩展函数?年薪50W+的测试大佬教你怎么玩

我的 jmeter 里面&#xff0c;怎么没有 MD5 函数&#xff0c;base64 函数也没有&#xff0c;我是不是用了假的 jmeter&#xff1f; 哈哈哈&#xff0c;不是的。jmeter 的函数&#xff0c;有自带函数和扩展函数两大块&#xff0c;自带函数&#xff0c;就是 jmeter 官方自带的&a…

React.Children.map 和 js 的 map 有什么区别?

JavaScript 中的 map 不会对为 null 或者 undefined 的数据进行处理&#xff0c;而 React.Children.map 中的 map 可以处理 React.Children 为 null 或者 undefined 的情况。 React 空节点&#xff1a;可以由null、undefined、false、true创建 import React from reactexport …

CompletableFuture超详解与实践

0.背景 一个接口可能需要调用 N 个其他服务的接口&#xff0c;这在项目开发中还是挺常见的。举个例子&#xff1a;用户请求获取订单信息&#xff0c;可能需要调用用户信息、商品详情、物流信息、商品推荐等接口&#xff0c;最后再汇总数据统一返回。 如果是串行&#xff08;按…

ME11/ME12拷贝采购信息记录

注意点&#xff1a; ECC没有好用的修改/创建采购信息记录BAPI所以使用BDC处理&#xff0c; 因为BDC执行过程如果遇到黄色提示消息就会暂停&#xff0c;所以如果遇到黄色提示需要增强处理 还有就是价格的小数位数问题&#xff0c;如JPY不能使用小数位数问题处理 增强调整 如下…

C语言—数据类型

变量和基本数据类型 变量类型的概念 变量是在程序中可以发生变化的量&#xff0c;变量是有类型的&#xff0c;变量的类型决定了变量存储空间的大小以及如何解释存储的位模式。 1字节&#xff08;Byte&#xff09;8位&#xff08;bit&#xff09; 定义格式 存储类型 数据…

基于Java+Springboot+Mybatis+Vue+微信小程序的轿车改装设计方案

微信小程序的轿车改装设计方案,用户可以自行在小程序中查看某型号轿车的零件&#xff0c;可以查看相关的汽车资源。 一、API1.1 SpringBoot框架搭建1.2 数据库设计1.3 实体映射创建Mapper1.4 接口封装1.5 常用字段类型 二、小程序2.1 项目创建2.2 首页2.3 产品中心页 三、管理端…

[C#]winform利用seetaface6实现C#人脸检测活体检测口罩检测年龄预测性别判断眼睛状态检测

【官方框架地址】 https://github.com/ViewFaceCore/ViewFaceCore 【算法介绍】 SeetaFace6是由中国科技公司自主研发的一款人脸识别技术&#xff0c;它基于深度学习算法&#xff0c;能够快速、准确地识别出人脸&#xff0c;并且支持多种应用场景&#xff0c;如门禁系统、移动…

通过Kuboard部署Nginx服务并映射挂载NFS服务器

这里写目录标题 一、项目概述二、环境三、样式nginx运行页面nginx挂载存储页面nginx服务service页面index代理网页 四、部署流程集群导入NFS服务器搭建新建nginx工作负载配置拷贝配置信息到NFS 五、总结 一、项目概述 使用Kuboard图形化页面部署Nginx工作负载&#xff0c;代理…

FineBI实战项目一(8):每天每小时订单笔数

1 明确数据分析目标 统计每个小时产生的订单个数 2 创建用于保存数据分析结果的表 create table app_hour_orders(id int primary key auto_increment,daystr varchar(20),hourstr varchar(20),cnt int ); 3 编写SQL语句进行数据分析 selectsubstring(createTime,1,10) as …

SpringBoot pom.xml文件标签含义

Pom文件 基本构成 通过最简单的一个SpringBoot项目的 Pom文件来了解一下Pom文件的基本构成 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XML…

Failed to create CUDAExecutionProvider 使用onnxruntime-gpu未成功调用gpu

最近在使用GPU对onnx模型进行加速过程中&#xff08;仅针对N卡&#xff0c;毕竟也没有别的显卡了。。&#xff09;&#xff0c;遇到了点问题&#xff1a;就是明明在安装了合适版本的显卡驱动和CUDA后&#xff0c;onnx还是不能够成功调用GPU&#xff0c;并且还出现了先导入torch…