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

news2024/11/27 16:46:04

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智能语音家居系统

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NPS 内网穿透安装

NPS 内网穿透安装 NPS分为服务端和客户端&#xff0c;对应的不同操作系统软件可以在GitHub RELEASES自行选择下载。 服务端搭建 由于个人非企业级使用&#xff0c;为了方便直接使用docker安装 1.docker运行 (注意需要提前下载conf文件&#xff0c;或者将镜像中文件copy出来…

多线程模板应用实现(实践学习笔记)

出处&#xff1a;B站码出名企路 个人笔记&#xff1a;因为是跟着b站的教学视频以及文档初步学习&#xff0c;可能存在诸多的理解有误&#xff0c;对大家仅供借鉴&#xff0c;参考&#xff0c;然后是B站up阳哥的视频&#xff0c;我是跟着他学。大家有兴趣的可以到b站搜索。加油…

C/C++ 联合体

目录 联合体概述 联合体的内存分配 联合体大小计算 联合体概述 联合与结构非常的相似&#xff0c;主要区别就在于联合这两个字。 联合的特征&#xff1a;联合体所包含的成员变量使用的是同一块空间。 联合体定义 //联合类型的声明 union Un {char c;int i; }; //联合变量…

isaacgym(legged_gym)学习 (二)—— 设置环境地形

isaacgym(legged_gym)学习 &#xff08;二&#xff09;—— 设置环境地形 文章目录 isaacgym(legged_gym)学习 &#xff08;二&#xff09;—— 设置环境地形前言一、了解isaacgym中地形如何构成的二、自定义修改1.代码2.查看script/play.py 总结 前言 如何设置isaacgym中的环…

【操作系统篇】正在持续写入的日志如何清理?

正在持续写入的日志如何清理? ✔️典型解析✔️ 推荐的日志管理工具✔️如何设置日志轮转工具✔️如何选择适合我的Logrote-NG日志轮转工具✔️如何测试Logrote-NG工具的稳定性✔️分析一个简单的ELK报警✔️这个报警的作用是什么✔️报警机制的优缺点✔️如何减少报警机制的误…

蓝牙运动耳机哪款好用?运动用什么耳机比较好?2024运动耳机推荐

​在众多的耳机类型中&#xff0c;运动耳机因其独特的设计和功能而备受青睐。它们不仅要具备出色的音质&#xff0c;还需要能够适应激烈的运动环境&#xff0c;如防水、防汗、牢固耐用等。今天&#xff0c;我想向大家推荐一些在这些方面表现出色的运动耳机&#xff0c;这些耳机…

Unity 圆角 线段 绘制 LineRender

需求 绘制圆角 核心函数 /// <summary>/// 点ABC 形成的角度必须为90 点c为中间的点/// </summary>/// <param name"a"></param>/// <param name"b"></param>/// <param name"c"></param>/// &…

C++学习笔记——友元及重载运算符

目录 一、友元 1.1声明友元函数 1.2声明友元类 二、运算符重载 2.1重载加号运算符 2.2重载流插入运算符 三、一个简单的银行管理系统 四、 详细的介绍 一、友元 在 C 中&#xff0c;友元是一个函数或类&#xff0c;它可以访问另一个类的私有成员或保护成员。通常情况下…

微服务实战系列之Filter

前言 Filter&#xff0c;又名过滤器&#xff0c;当然不是我们日常中见到的&#xff0c;诸如此类构件&#xff1a; 而应该是微服务中常使用的&#xff0c;诸如此类&#xff08;图片来自官网&#xff0c;点击可查看原图&#xff09;&#xff1a; 一般用于字符编码转换&#xf…

Unity DOTS中的baking(二)Baker的触发

Unity DOTS中的baking&#xff08;二&#xff09;Baker的触发 我们知道&#xff0c;当传入Baker的authoring component的值发生变化时&#xff0c;就会触发baking。不过在有些情况下&#xff0c;component所引用的对象没有变化&#xff0c;而是对象自身内部的一些属性发生了变化…

DNS--windows sever 2012 r2

1 安装dns服务 得到 2 配置正向解析文件 设置正向解析文件的别名 配置(1)主机名 (2)别名&#xff08;3)邮件交换器 最终得到 3 配置反向文件 建立指针 得到 4 验证

【百科物理】-1.弹力和压力

导入 问题&#xff1a; 为什么在蹦床上弹得更高&#xff1f; 现象背后的原理&#xff0c;因为有力。 力&#xff1a;物体(物质)与物体(物质)之间推、拉、挤压的相互作用。力可以改变物体的运动状态&#xff08;比如踢足球&#xff09;&#xff0c;力可以改变物体的形状&#xf…

ProtoBuf一些踩坑记录

一、Protobuf学习基础 学习的资料很多也很全&#xff0c;这里添加几个链接进行Protobuf的基础学习的链接&#xff0c;链接中的案例使用C编辑&#xff1a; 链接&#xff1a;Protobuf介绍及简单使用(上&#xff09;_google_protobuf_version-CSDN博客 Protobuf介绍及简单使用(下&…

行云部署成长之路 -- 慢 SQL 优化之旅 | 京东云技术团队

当项目的SQL查询慢得像蜗牛爬行时&#xff0c;用户的耐心也在一点点被消耗&#xff0c;作为研发&#xff0c;我们可不想看到这样的事。这篇文章将结合行云部署项目的实践经验&#xff0c;带你走进SQL优化的奇妙世界&#xff0c;一起探索如何让那些龟速的查询飞起来&#xff01;…

three.js 学习笔记(学习中1.7更新) |

文章目录 three.js 学习笔记入门基础概念透视相机 第一个three.js应用threejs画布尺寸和布局canvas画布宽高度动态变化 坐标辅助器 THREE.AxesHelper实现动画效果requestAnimationFrame时间相关属性和方法 THREE.Clock类 相机控件 轨道控制器OrbitControls 灯光点光源点光源辅助…

【ArcGIS微课1000例】0087:经纬度格式转换(度分秒转度、度转度分秒)

ArcGIS软件可以很方便的直接实现度分秒转度、度转度分秒。 文章目录 一、转换预览二、工具介绍三、案例解析一、转换预览 借助ArcGIS快速实现度分秒与度及其他格式的坐标转换。例如:度分秒→度 度分秒: 度: 二、工具介绍 转换坐标记法:将一个或两个字段包含的坐标记法从一…

PAT 乙级 1049 数列的片段和

分数 20 作者 CAO, Peng 单位 Google 给定一个正数数列&#xff0c;我们可以从中截取任意的连续的几个数&#xff0c;称为片段。例如&#xff0c;给定数列 { 0.1, 0.2, 0.3, 0.4 }&#xff0c;我们有 (0.1) (0.1, 0.2) (0.1, 0.2, 0.3) (0.1, 0.2, 0.3, 0.4) (0.2) (0.2, 0.3) …

【JAVA】Iterator 和 ListIterator 有什么区别?

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 在Java中&#xff0c;遍历集合是日常编程中常见的任务&#xff0c;而Iterator和ListIterator作为遍历集合的两个主要接口&#xff0…

【MySQL】索引基础

文章目录 1. 索引介绍2. 创建索引 create index…on…2.1 explain2.2 创建索引create index … on…2.3 删除索引 drop index … on 表名 3. 查看索引 show indexes in …4. 前缀索引4.1 确定最佳前缀长度&#xff1a;索引的选择性 5. 全文索引5.1 创建全文索引 create fulltex…

Angular学习第二天--问题记录

一、问题 1.用脚手架搭建完项目之后&#xff0c;缺少app.modules.ts文件&#xff0c; 2.解决办法&#xff1a; 在终端继续输入命令 ng new 项目名称 --no-standalone --routing --ssrfalse 3.完整目录&#xff1a; 二、问题 1.问题来源&#xff0c;源代码&#xff1a; <fo…