开发者学堂课程【HaaS 物联网应用开发课程:5_1_1_首页信息展示屏_整体介绍_技术点及获取电池电量】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/801/detail/13842
5_1_1_首页信息展示屏_整体介绍_技术点及获取电池电量
内容介绍:
一、实验整体及技术点介绍
二、ADC 操作与电量获取
一、实验整体及技术点介绍
1.整体介绍
上图是 HaaS EDU K1开发版的正面图片,右侧是上下左右四个按键,EDU demo 在程序中有许多子实验,所以子实验的切换是通过 K1和 K3两个按键控制,子实验中有贪吃蛇、飞机大战等游戏,也是通过这四个按键作为上下左右方向控制的;四个按键旁边黑色的按钮是复位按键,在复位时只需按这个按钮即可;最上面有四颗 LED,其中最左边的是电源指示灯,只要开发版有电,这颗就属于常亮状态,其余都是可编程的,在前面课程中见到的跑马灯就是利用这三颗带颜色的 LED 进行实验的。
左侧最显眼的是 OLED 屏幕,其左上角会显示系统时间,右上角会显示 Wi-Fi 连接状态及电池电量状态;中间的一行字表示的是 HaaS EDU K1当前烧录的软件版本号,最下面一行是 IP 地址;屏幕上方有一个圆圈,它是传感器,可以检测到环境光的亮度并且对物体接近程度进行检测。
要完整学习本节课内容,需要的硬件有:HaaS EDU K1开发板一块、USB2TypeC 数据线一条,开发用电脑一台
本实验中对应的软件是 HaaS EDU K1软件 V1.0.0版本
如果大家要动手进行编译和烧录,需要大家先在自己的电脑上安装 HaaS 的开发环境。
2.实验技术点
屏幕显示:通过 SPI 总线控制 OLED 显示功能
下图是 OLED 模子的外观,他和 HaaS EDU K1底板是通过排线进行连接的,在 OLED 排线是在如图所示的位置,但在 HaaS EDU K1主板上排线是在如图红框位置
上图是排线接口的定义,绿框里面的四根线是用来控制 OLED 屏幕输出的,其余几根是用来和 AP3216C 光照传感器以及接近传感器进行通信的。
3.网络相关
(1)WI-FI 状态
M-Fi 是一种网络传输标准,与蓝牙技术一样,同属于短距离无线技术。随着网络的应用普及它给人们带来极大的方便,也因此得到了广泛应用,Wi-Fi 让我们随时随地的上网成为可能。现在几乎所有的智能手机、平板电脑、电脑都支持 Wi-Fi 的功能,Wi-Fi 功能支持802.1x 协议定义的行为规范。
我们来看一下下面这张图:
最早的802.1x 协议是在1992年开始起草的,到现在已有近三十年历史。在前二十多年的时间里,人们日常对Wi-Fi功能的称呼是指设备所支持的802.1最高协议的版本,比如比较早的802.11a、802.11b、802.11g,最常用的是802.11n、802.11ac,以及近几年普及的802.11ax 等。
前两年,Wi-Fi 联盟对 Wi-Fi 的命名进行了重新定义,以 Wi-Fi 代次版本号表示,比如 Wi-Fi4对应的是802.11n,Wi-Fi5对应的是802.11ac,Wi-Fi6对应802.11ax。
HaaS EDU K1上面包含Wi-Fi 4.0版本的功能,通过 netmgr 对网络状态进行管理。
(2)IP 地址
Wi-Fi 连接上路由器之后会通过 DHCP 协议获取局域网内的 IP 地址。
说到 IP 地址就不得不提 DHCP 功能,DHCP 功能主要是对 IP 地址进行集中管理、分配,使网络环境中的主机动态的获取到 IP 地址、gateway 地址以及 DNS 服务器地址等信息。DHCP 功能中最常使用的过程是通过 DHCP 获取 IP 地址以及在 IP 地址过期之后进行 IP 地址续约,这两个过程的简单流程如下图:
HaaS EDU K1上也是通过 netmgr 模块提供的 API 获取网络地址的。
(3)网络对时
在界面左上角显示的就是当前的系统时间,HaaS EDU K1本身没有带 RTC 芯片,所以不能用本地时钟进行准确计时功能。
那么如何获取准确的时间呢,这里就需要用到 SNTP 协议进行网络对时。
SNTP 协议是基于 NTP 协议,在网络对时领域有着极为广泛的应用,手机也会使用 NTP 协议进行网络对时,除了NTP 之外,手机还会采用以运营商网络为媒介的 NATZ(网络标识与时区机制)以及基于 GPS 的对时功能。
4.电量检测
HaaS EDU K1是采用 ADC 对电池电压进行转换来对电池电量进行检测的。
ADC ( Analog-to-Digital Converter )模拟数字转换器
用于将模拟形式的连续信号转换为数字形式的离散信号的一类设备。一个模拟数字转换器可以提供信号用于测量。与之相对的设备成为数字模拟转换器(DAC )。
典型的模拟数字转换器是将模拟信号转换为表示一定比例电压值的数字信号。
为什么这里说是有一定比例:
因为 ADC 模块量测范围固定,比如 HaaS1000ADC 量程是从0到1.8伏,也就是超过1.8伏,HaaS1000是量测不出来的。
消费类电子产品的电池电压一般是3.7伏到4.2伏,这种一般是通过设计分压电路进行测量的。
二、ADC 操作与电量获取
1.电量信息-ADC
再次看这个原理图,大家可以看到在 VOLT 和 GND 之间有两个电阻,一个是1K,一个是2K,量测电压就~=VOLT的三分之一,也就是说通过GPADC1两侧的电压值乘以3和 VOLT 是差不多的。
2.ADC HAL API
在实际使用 ADC 功能时,需要使用 ADC HAL API,在使用它时需要包含 include/aos/hal/adc.h 头文件
hal_adc_init |
初始化指定ADC |
hal_adc_value_get |
获取ADC采样值 |
hal_adc_finalize |
关闭指定ADC |
typedef struct {
uint8_t port;/* adc port */
adc_config_t config; /adc config */
void *priv;/* priv data */
} adc_dev_t;
在 adc_dev_t 结构体里有三个变量非常重要,一个是 adc port,port 是指 adc 通道的 ID,HaaS1000上面 GPADC1引脚对应的 port=1,GPADC2=2,其他通道的id也是以此类推。
adc_config_t 这个结构体主要是用来设定 ADC 采样过程中的采样周期;priv 这个变量是为开发者预留的,用来保存和通道相关的 cio 数据结构指针。
3.获取电量值
获取电量的代码:
application/example/edu_demo/k1_apps/homepage/homepage.c
获取电池电量的函数名是 get_battery
(1)对 GADC1通道进行初始化
adc_dev_t adc = {1, 1000,0x12345678};
ret = hal_adc_init(&adc);
1代表的是 GADC1通道;1000代表采样周期是1000毫秒
(2)读取十次,循环调用 hal_adc_value_get 以获取 ADC 的两侧值。
每次两侧之间为10毫秒,过程中会记录十次中的最大值以及最小值。
hal_adc_value_get(&adc,&output,200);
test_sum += output;
/* the min sampling voltage */
if (test_min >= output)
{
test_min = output;
}
/* the max sampling voltage*/
if (test_max <= output)
{
test_max = output;
}
osDelay(10);
(3)计算平均电压,去掉最大最小值,然后取平均值
test_avrg 保存的是测量出的平均电压
(4)得到平均电压后,对 ADC value * 3.208得到实际电压
(5)根据读到的值和电池电量进行比较,返回不同的 level 值
test_avrg = (test_sum - test_min - test_max) >o> 3;
test_avrg *= 3.208;
if (test_avrg > 4100)
{
*level = 4;
}
else if ((test_avrg > 3980)&& (test_avrg < 4100)
{
*level = 3;
}
else if ((test_avrg > 3850&& (test_avrg < 3980))
{
*level = 2;
}
else if ( (test_avrg > 3700) 6& (test_avrg < 385e))
{
*level = 1;
}
else if (test_avrg - 3700)
{
*level = 0;
}
4.电量比例校准
接下来讲述为什么 test_avrg 乘的是3.208
在这张原理图可以看到,在 R13和 R15之外还有一些其他的电容电阻,这些电容电阻对测量点的电压是有影响的,所以要得到比较精确的电压判定,就要对输入电压和测量点电压的比例进行校准。校准的方法是在 VOLT 处输入不同电压,然后测量对应电压的实际测量值,下图是在5伏和3.65伏之间,每隔50毫伏做一个档位,输入对应档位的电压得到测量点电压,然后画出曲线。
可以看到曲线是近似比例的,所以比例(输入电压和测量点电压)的平均值是3.208。
这样单次测量电池电压的功能就讲完了,实际在系统开机之后,在主线程中会周期性的调用 get battery 这个函数获取电池电压,然后根据电池的电压级别动态的更新电池电量的图标。