ESP8266 WiFi物联网智能插座—电能计量
目录
1、芯片功能
2、性能指标
3、寄存器说明
4、UART通信协议
4.1、写操作帧格式和时序
4.2、读操作帧格式和时序
4.3、读取全电参数数据包
4.4、配置波特率
4.5、UART保护机制
5、功能说明
5.1、电流电压瞬态波形计量
5.2、有功功率
5.3、有功功率防潜动
5.4、电能计量
5.5、电流电压有效值
5.6、过流检测
5.7、过零检测
5.8、线电压频率检测
6、应用电路
7、驱动程序
8、替代方案
WiFi物联网智能插座硬件设计的重点就是电能计量,为此单独写一篇博文讲解电量计量的设计方案和实现原理。
电量计量选用上海贝岭的BL0942芯片,最主要有原因是:硬件方案设计简单、计量精度不错且免校准、价格便宜以及软件驱动方法简单。
1、芯片功能
BL0942 能够测量电流、电压有效值、有功功率、有功电能量等参数,可输出快速电流有效值(用于过流保护),以及波形输出等功能,外围元件满足一定条件下可以免校准,当然BL0942 也是支持校准的。
芯片特性如下:
- 两路独立的 Sigma-Delta ADC,一路电流和一路电压。
- 电流有效值范围(10mA~30A)@1mohm。
- 有功电能(1w~6600w)@1mohm@220V 。
- 可输出电流、电压有效值,快速电流有效值,有功功率。
- 批次出厂增益误差小于 1%,外围元件满足一定条件下可以免校准。
- 电流通道具备过流监控功能,监控阈值及响应时间可设置。
- 电压/电流过零信号输出。
- 内置波形寄存器,可输出波形数据用于负载类型分析。
- SPI(最快速率支持 900KHz)/UART(4800-38400bps)通信方式(TSSOP14L 封装支持最多 4 片级联 UART通信)。
- 电源掉电监测,低于 2.7V 时,芯片进入复位状态。
- 内置 1.218V 参考电压源 。
- 内置振荡电路,时钟约 4MHz 。
- 芯片单工作电源 3.3V,低功耗 10mW(典型值) 。
- SSOP10L/TSSOP14L 封装。
本项目选用SSOP10L封装,UART驱动。
2、性能指标
3、寄存器说明
本项目通过UART总线读取或设置BL0942芯片寄存器,寄存器说明如下图所示:
4、UART通信协议
BL0942芯片UART通信特性如下:
- 通过管脚 SEL 选择,与SPI 复用,UART模式SEL=0。
- 芯片工作在从模式。
- 半双工通讯,波特率可软硬件配置为 4800bps,9600bps,19200bps,38400bps。
- 8-bit 数据传输,无校验位,停止位 1 。
- 支持数据包读取。
TSSOP14L 封装可支持器件片选功能,硬件片选地址管脚为[A2_NCS,A1],可选器件 0~3。可支持 4 片 BL0942 挂在 UART 总线上进行数据通信,只占用 MCU 的一个 UART 接口。
在UART通信模式下,先发送 8bit 识别字节(0x58) 或(0xA8),(0x58)是读操作识别字节,(0xA8)是写操作识别字节,然后再发送寄存器地址字节,决定访问寄存器的地址(请参见 BL0942 寄存器列表),一帧数据传送完成,BL0942 重新进入通信模式。
4.1、写操作帧格式和时序
帧结构有两种,写操作帧和读操作帧。
写操作帧格式如下所示:
主机UART 写数据时序如下图所示,主机先发送命令字节{1,0,1,0,1,0,A2,A1},然后发送需要写入数据的寄存器字节(ADDR),接下来依次发送数据字节(低字节在前,高字节在后,数据有效字节不足 3 字节的,无效位补 0),最后校验和字节。
{1,0,1,0,1,0,A2,A1}为写操作的帧识别字节。假设{A2,A1}=10,器件地址 2,帧识别字节为0xAA。
ADDR 为写操作对应的 BL0942 的内部寄存器地址。
CHECKSUM 字节为({1,0,1,0,1,0,A2,A1}+ADDR+DATA[7:0]+DATA[15:8]+DATA[23:16])&0xFF 取反。
4.2、读操作帧格式和时序
读操作帧格式如下所示:
主机UART 读数据时序如下图所示,主机先发送命令字节{0,1,0,1,1,0,A2,A1},然后发送需要读取的寄存器地址字节(ADDR),接下来 BL0942 依次发送数据字节(低字节在前,高字节在后,数据有效字节不足 3 字节的,无效位补 0),最后校验和字节。
{0,1,0,1,1,0,A2,A1}为读操作的帧识别字节,假设{A2,A1}=10,器件地址 2,帧识别字节为0x5A。
ADDR 为读操作对应的 BL0942 的内部寄存器地址。
CHECKSUM 字节为({0,1,0,1,1,0,A2,A1}+ADDR+DATA[7:0]+DATA[15:8]+DATA[23:16])&0xFF 取反。
注意:SSOP10L 封装的器件地址是 0,即{A2,A1}=00。
时序要求如下图所示:
4.3、读取全电参数数据包
本项目读取BL0942电能计量参数,就是读取全电参数数据包。
通过命令“{0,1,0,1,1,0,A2,A1}+ 0xAA”,BL0942 会返回一个全电参数数据包。返回的数据包共 22 个字节,当使用 4800bps 时,用时约 48ms。
全电参数包格式如下:
checksum=(({0,1,0,1,1,0,A2,A1} + 0x55 + data1_l + data1_m + data1_h +…….)& 0xff)再按位取反。
4.4、配置波特率
使用模式寄存器 UART_RATE_SEL(MODE[9:8])和管脚 SCLK_BPS 可以配置波特率。 芯片每次上电时 RATE_SEL 复位值为 0x0,此时根据管脚 SCLK_BPS 确定波特率。
4.5、UART保护机制
BL0942芯片内置了一些保护机制,如下所示:
- 帧超时复位,如果字节与字节之间的间隔时间超过 20ms,UART 接口复位。
- 手动复位,UART 连续收到超过 32 个“0”,UART 接口复位。
- 帧识别字节或者 checksum 字节错误,则该帧数据放弃。
- UART 模式多片通信时,每发送一帧等待一个帧超时时间后或者发送一个手动复位后才能发送下一帧。
5、功能说明
BL0942 主要分为模拟信号处理和数字信号处理两块,模拟部分主要包括两通道 PGA、两通道Sigma-Delta ADC、内置时钟(internal clock)、上下电监测(Power on/reset)、LDO 等相关模拟模块,数字部分为数字信号处理模块(DSP)。
5.1、电流电压瞬态波形计量
电流和电压分别通过模拟模块放大器(PGA)和高精度的模数转换(ADC)得到两路1bit PDM 给数字模块,数字模块经过降采样滤波器(SINC3)、高通滤波器(HPF)、通道偏置校正等模块,得到需要的电流波形数据和电压波形数据(I_WAVE,V_WAVE)。
采集到的负载电流和电压波形数据以 7.8k 的速率更新,每个采样数据为 20bit 有符号数,并分别存入波形寄存器(I_WAVE,V_WAVE),SPI 速率配置大于 375Kbps,可连续读取一个通道的波形值。
注:寄存器为 24bit,不足位数,高位补零。
5.2、有功功率
有功功率计算公式:
其中,𝐼(𝐴),𝑉(𝑉)为通道管脚输入信号的有效值(mV),φ为 I(A)、V(V)交流信号的相位夹角,Vref 为内置基准电压,典型值为 1.218V。
该寄存器表示当前有功功率是正功还是负功,Bit[23]为符号位,Bit[23]=0,当前功率为正功,Bit[23]=1,当前功率为负功,补码形式。
5.3、有功功率防潜动
BL0942 具有专利功率防潜功能,保证无电流输入的时候板级噪声功率不会累积电量。
有功防潜动阈值寄存器(WA_CREEP),为 8bit 无符号数,缺省为 0BH。该值与有功功率寄存器值对应关系见下面公式,当输入有功功率信号绝对值小于这个值时,输出有功功率设为 0。这可以使在无负载情况下,即使有小的噪声信号,输出到有功功率寄存器中的值为 0,电能不累积。
可以根据功率寄存器 WATT 的值设置 WA_CREEP,它们的对应关系如下:
注:当前通道处于防潜状态时,该通道的电流有效值不测量,也切除到 0。
5.4、电能计量
BL0942 提供电能脉冲计量,有功瞬时功率按时间进行积分,可获得有功能量,并可进一步输出校验脉冲 CF。CF_CNT 寄存器保存输出电能脉冲 CF 的个数,具体如下图所示:
可直接从有功电能脉冲计数寄存器 CF_CNT 读取用电量,也可通过配置 OT_FUNX 寄存器后,由 I/O 中断从 CF1/CF2/ZX 引脚直接对脉冲个数进行计数,CF 的周期小于 160ms 时,为 50%占空比的脉冲,大于等于 160ms 时,高电平固定脉宽 80ms。
CF_EN 为能量脉冲输出总开关,关闭后,CF_CNT 停止计数,CF1/CF2/ZX 引脚停止输出电能脉冲计数。
可通过 CF_CNT_CLR_SEL 寄存器,选择 CF 计数寄存器(CF_CNT)读后是否清零。可通过CF_CNT_ADD_SEL 对脉冲能量累加模式进行选择。
注:CF_CNT 寄存器默认电能脉冲绝对值累积方式。
每个 CF 脉冲的累积时间如下所示:
其中WATT 为对应的有功功率寄存器值(WATT)。
5.5、电流电压有效值
电流和电压通道的有效值如下图所示,经过平方电路(X 2)、低通滤波器(LPF_RMS)、开根电路(ROOT),得到有效值的瞬时值 RMS_t,再经过平均得到两个通道的平均值(I_RMS 和 V_RMS)。
设置 MODE[3].RMS_UPDAT_SEL,可选择有效值平均刷新时间是 400ms 或 800ms,默认 400ms。
当通道处于防潜状态时,该电流通道的有效值为零。
电流有效值转换公式:
电压有效值转换公式:
𝑉𝑟𝑒𝑓是参考电压,典型值是 1.218V。
注:I(A)是 IP,IN 管脚间的输入信号(mV),V(V)是 VP 管脚的输入信号(mV)。
5.6、过流检测
BL0942 可快速采集电流有效值实现过流检测功能。I_WAVE_F 取绝对值后进行半周波或周波时间累加,存于 I_FAST_RMS 寄存器,与电流快速有效值阈值寄存器 I_FAST_RMS_TH 进行比较后通过引脚输出过流中断。
通过 I_FAST_RMS_TH 快速有效值阈值寄存器,设定快速有效值阈值(即过流阈值)。
取 I_FAST_RMS 寄存器的 Bit[23:8]与过流阀值 I_FAST_RMS_TH [15:0]比较,若大于等于设置的阀值,则过流报警输出指示管脚 CF1/CF2/ZX 输出高电平。CF1/CF2/ZX 由 OT_FUNX 输出配置寄存器进行设置。
通过 I_FAST_RMS_CYC 快速有效值刷新周期寄存器,设定快速有效值刷新周期。其中周波根据MODE[5]的设置值可选 50H 或者 60Hz。如选择 50hz,默认 1 周波即 20ms 刷新一次。如选择最快的 0.5周波累加时,I_FAST_RMS 寄存器的误差会相对较大。
需要注意,快速有效值和有效值的算法不一样。快速有效值仅用于大信号时的测量判断。在小信号时快速有效值的测量会由于包含直流偏置成分不准确。如果需要去除直流偏置成分,设置FAST_RMS_SEL(MODE[4])=1,I_WAVE_F 选择 HPF 后的波形。
通过 MODE[5]设置交流电频率。
5.7、过零检测
BL0942 提供电压和电流过零检测,可由引脚 CF1/CF2/ZX 输出过零信号,管脚输出零表示波形正半周,管脚输出 1 表示波形负半周。与实际输入信号的时延 570us 。
通过 OT_ FUNX 对输出管脚进行配置(SSOP10L 封装只有 CF1)。
若电压或电流有效值过低,过零检测输出信号不稳定。
当电压有效值V_RMS高5bit等于0时,V_ZX_LTH_F为1,表示电压有效值过低,小于满量程的1/32,电压过零指示关闭,保持为 0。
当电流有效值 I_RMS 高 6bit 等于 0 时,I_ZX_LTH_F 为 1,表示电流有效值过低,小于满量程的 1/64,电流过零指示关闭,保持为 0。
5.8、线电压频率检测
BL0942 具有线电压频率检测功能,每个若干设定的周期(FREQ_CYC)刷新一次,所检测的是全波电压波形。
线电压测量的分辨率为 2us/LSB(500KHz 时钟),相当于 50Hz 线路频率时的 0.01%或 60Hz 线路频率时的 0.012%。线电压寄存器(FREQ)与实际线电压频率的折算关系:
其中默认模式下 fs=500KHz;对于 50Hz 的市电网络,测得 FREQ 的值为 20000(十进制),对于 60Hz 的市电网络,测得 FREQ 的值为 16667(十进制)。
另外,电压有效值低于过零判断阈值时,线电压频率检测关闭。
6、应用电路
7、驱动程序
使用Arduino IDE驱动ESP8266周期读取全电参数数据包,源文件如下所示:
/******************************************************************************** File Name : bl0942.cpp** Functional Description:* bl0942驱动库文件** Change Logs:* Date Author Notes explain* 2022-12-6 yangjunjie V1.0 *
*******************************************************************************//******************************************************************************* Include files******************************************************************************/
#include "bl0942.h"/******************************************************************************* Global variable definitions******************************************************************************/
static char serial_data[SERIAL_RX_MAXLEN];// 串口接收数据队列句柄
extern struct tk_queue serial_receive_dataqueue;// 此参数尚未使用,可用作二次校准设备
static float adjust_volrate = 1;
static float adjust_currentrate = 1;
static float adjust_powerrate = 1;/******************************************************************************* Local type definitions ('typedef')******************************************************************************/
static void sendCommand(void);
static status_t receiveData(void);/******************************************************************************* function realize******************************************************************************//********************************************************************************** \brief 初始化BL0942芯片**** \param 无**** \retval 无********************************************************************************/
void Init_BL0942(void)
{Serial.begin(4800, SERIAL_8N1); // 4800bps 无校验Serial.setTimeout(30); // 设置串口超时时间为30msmemset(serial_data, 0, SERIAL_RX_MAXLEN);
}/********************************************************************************** \brief 每秒钟刷新一次,依次读(电压或者电流,和功率)**** \param 无**** \retval 无********************************************************************************/
void Updata_BL0942(void)
{sendCommand(); // 发送指令receiveData(); // 处理串口接收数据
}/********************************************************************************** \brief 串口发送指令获取电参数据**** \param 无**** \retval 无********************************************************************************/
static void sendCommand(void)
{Serial.write((byte)0X58);Serial.write((byte)0XAA);
}/********************************************************************************** \brief 接收并解析串口接收到的电参指令**** \param 无**** \retval STATUS_SUCCESS:数据校验成功 STATUS_ERROR:数据校验失败********************************************************************************/
static status_t receiveData(void)
{status_t ret = STATUS_SUCCESS;bool temp_flag = false, receive_flag = false;char temp_data = 0X00;uint8_t data_index = 0X00;uint8_t checksum = 0X58;char temp_serial_data[SERIAL_RX_MAXLEN];while(Serial.available()) {temp_data = (char)Serial.read();if(temp_data == 0X55) // 判断帧头{temp_flag = true;}if(temp_flag == true){temp_serial_data[data_index++] = temp_data;}if (data_index >= SERIAL_RX_MAXLEN){// tk_queue_push_multi(&serial_receive_dataqueue, temp_serial_data, SERIAL_RX_MAXLEN); // 装数据长度到缓存data_index = 0;temp_flag = false;receive_flag = true;// memset(temp_serial_data, 0, SERIAL_RX_MAXLEN); }else{receive_flag = false;}}// 未用到中断接收,缓存模式暂时用不到,此功能保留// if(tk_queue_empty(&serial_receive_dataqueue) == false) // 缓存有数据// {// tk_queue_pop_multi(&serial_receive_dataqueue, temp_serial_data, SERIAL_RX_MAXLEN); // 从缓存区获取数据if(receive_flag == true){for(uint8_t i = 0; i < SERIAL_RX_MAXLEN - 1; i++) // 校验数据{checksum += temp_serial_data[i];}checksum = ~(checksum & 0XFF);if(checksum == temp_serial_data[SERIAL_RX_MAXLEN - 1]){memcpy(serial_data, temp_serial_data, SERIAL_RX_MAXLEN);Log.verboseln("serial receive OK");}else{Log.errorln("serial receive ERROR");ret = STATUS_ERROR;}}return ret;
}/********************************************************************************** \brief 获取电流**** \param 无**** \retval 电流数据********************************************************************************/
float getCurrent(void)
{uint32_t parm = 0;float current = 0.0;parm = ((uint32_t)serial_data[3] << 16) + ((uint32_t)serial_data[2] << 8) + serial_data[1];current = (float)parm * V_REF * adjust_currentrate * 1000 / (305978 * RL_CURRENT); // mAreturn current;
}/********************************************************************************** \brief 获取电压**** \param 无**** \retval 电压数据********************************************************************************/
float getVoltage(void)
{uint32_t parm = 0;float voltage = 0.0;parm = ((uint32_t)serial_data[6] << 16) + ((uint32_t)serial_data[5] << 8) + serial_data[4];voltage = (float)parm * V_REF * (R2_VOLTAGE + R1_VOLTAGE) * adjust_volrate / (73989 * R1_VOLTAGE * 1000);return voltage;
}/********************************************************************************** \brief 过流检测,快速采集电流有效值实现过流检测功能**** \param 无**** \retval 电流快速有效值数据********************************************************************************/
float getFastCurrent(void)
{uint32_t parm = 0;parm = ((uint32_t)serial_data[9] << 16) + ((uint32_t)serial_data[8] << 8) + serial_data[7];float fcurrent = (float)parm * V_REF * adjust_currentrate * 1000 / (305978 * RL_CURRENT); // mAreturn fcurrent;
}/********************************************************************************** \brief 获取有功功率**** \param 无**** \retval 有功功率数据********************************************************************************/
float getActivePower(void)
{uint32_t parm = 0;float power = 0.0;parm = ((uint32_t)serial_data[12] << 16) + ((uint32_t)serial_data[11] << 8) + serial_data[10];if (1 == bitRead(serial_data[12], 7)){parm = 0xFFFFFF - parm + 1; // 取补码}power = (float)parm * adjust_powerrate * V_REF * V_REF * (R2_VOLTAGE + R1_VOLTAGE) / (3537 * RL_CURRENT * R1_VOLTAGE * 1000);return power;
}/********************************************************************************** \brief 获取用电量**** \param 无**** \retval 用电量数据********************************************************************************/
float getEnergy(void)
{uint32_t parm = 0;float energy = 0.0;parm = ((uint32_t)serial_data[15] << 16) + ((uint32_t)serial_data[14] << 8) + serial_data[13];energy = (float)parm * 1638.4 * 256 * V_REF * V_REF * (R2_VOLTAGE + R1_VOLTAGE) / (3600000.0 * 3537 * RL_CURRENT * R1_VOLTAGE * 1000);return energy;
}/********************************************************************************** \brief 线电压频率检测功能**** \param 无**** \retval 线电压频率数据********************************************************************************/
float getFREQ(void)
{uint32_t parm = 0;float FREQ = 0.0;parm = ((uint32_t)serial_data[18] << 16) + ((uint32_t)serial_data[17] << 8) + serial_data[16];if (parm > 0){FREQ = 500 * 1000 * 2 / (float)parm;}return FREQ;
}/********************************************************************************** \brief 工作状态**** \param 无**** \retval 工作状态数据********************************************************************************/
uint8_t getSTATUS(void)
{return (uint8_t)serial_data[19];
}/******************************************************************************/
/* EOF (not truncated) */
/******************************************************************************/
头文件如下所示:
/******************************************************************************** File Name : bl0942.h** Functional Description:* bl0942驱动库文件** Change Logs:* Date Author Notes explain* 2022-12-6 yangjunjie V1.0 *
*******************************************************************************/#ifndef __BL0942_H__
#define __BL0942_H__/******************************************************************************/
/* Include files */
/******************************************************************************/
#include <Arduino.h>
#include "tk_queue.h"/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif//@{/******************************************************************************* Local pre-processor symbols/macros ('#define')******************************************************************************/
#define V_REF 1.218
#define RL_CURRENT 1 // 0.001欧,单位为毫欧
#define R2_VOLTAGE 1950 // 390K*5,单位为K欧
#define R1_VOLTAGE 0.51 // 0.51K,单位为K欧#define SERIAL_RX_MAXLEN 23/******************************************************************************** Local type definitions ('typedef')******************************************************************************//******************************************************************************* Global variable definitions ('extern')******************************************************************************/
// 判断队列是否为空
extern bool tk_queue_empty(struct tk_queue *queue);// 向队列压入(入队)多个元素数据
extern uint16_t tk_queue_push_multi(struct tk_queue *queue, char *pval, uint16_t len);// 从队列弹出(出队)多个元素数据
extern uint16_t tk_queue_pop_multi(struct tk_queue *queue, char *pval, uint16_t len);/****************************************************************************** Function definitions - global ('extern') and local ('static')******************************************************************************/
// 初始化BL0942芯片
void Init_BL0942(void);// 每秒钟刷新一次,依次读(电压或者电流,和功率)
void Updata_BL0942(void);// 获取电流
float getCurrent(void);// 获取电压
float getVoltage(void);// 过流检测,快速采集电流有效值实现过流检测功能
float getFastCurrent(void);// 获取有功功率
float getActivePower(void);// 获取用电量
float getEnergy(void);// 线电压频率检测功能
float getFREQ(void);// 工作状态
uint8_t getSTATUS(void);//@}
#ifdef __cplusplus
}
#endif#endif /* __BL0942_H__ *//******************************************************************************/
/* EOF (not truncated) */
/******************************************************************************/
8、替代方案
上海贝岭也提供了需要校准的电量计量芯片:BL0937。
BL0937 在定义产品时考虑到智能插座类产品厂家不是专业计量器具厂家,没有专业昂贵的校准设备,对电能计量精度要求也相对较低,只是提供用电参考信息,不作计费标准。智能插座只需要读取功率,电压,电流,并根据功率计量累积电量,所以BL0937 与 MCU 间不要复杂的通讯协议去实时的读取计量芯片寄存器,计量精度校准也相对简单,只需在额定功率负载时校准系数,也不需要复杂的校准设备。
BL0937方案的应用电路如下所示,经过实际测试稳定可靠:
感兴趣的朋友可以研究一下这个方案,由于不是本项目所使用的方案,不再赘述。
相关文章:
ESP8266 WiFi物联网智能插座—电能计量
目录 1、芯片功能 2、性能指标 3、寄存器说明 4、UART通信协议 4.1、写操作帧格式和时序 4.2、读操作帧格式和时序 4.3、读取全电参数数据包 4.4、配置波特率 4.5、UART保护机制 5、功能说明 5.1、电流电压瞬态波形计量 5.2、有功功率 5.3、有功功率防潜动 5.4、电能计量 5.5、…...
“智慧”北京,人工智能引领“新风尚”
原创 | 文 BFT机器人 北京时间,9月15日,北京人工智能产业峰会暨中关村科学城科创大赛颁奖典礼在北京中关村举行,同时惠阳还举行了“中关村人工智能大模型产业集聚区”启动建设的揭牌仪式。 此次大会围绕北京AI产业的建设与发展,各…...
狮子鱼社区团购小程序v18.1独立全开源版+小程序前端
狮子鱼社区团购商城系统小程序V18.1独立开源版,该系统本身就非常完善也没更新的必要,此系统拿来即用非常方便,同一版一样人类小徐特别优化很多细节首页美化了下,如小程序端授权窗口美化了下,该版本用户授权接口正常。功…...
深拷贝和浅拷贝的区别
本文内容 主要阐述下深拷贝和浅拷贝的区别 通俗理解 深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。 假设B复制了A,修改A的时候,看B是否发生变化: 如果B跟着也变了,说明是浅拷贝&…...
利用优化算法提高爬虫任务调度效率
目录 一、任务调度优化的重要性 二、选择合适的优化算法 三、建立任务调度模型 四、设计适应性函数 五、算法实施和调优 六、性能评估和优化结果分析 代码示例 总结 随着网络信息的爆炸式增长,网络爬虫在信息获取和数据挖掘等领域的应用越来越广泛。然而&am…...
Swiper的使用流程
1.官网查看演示 Swiper演示 - Swiper中文网 2.找到想使用的 比如想使用 卡片切换(255) 记住这个名字 3.去下载示例 下载Swiper - Swiper中文网 4.找到对应文件 5.根据里面引入的东西加到自己的页面 一定要引入swiper的 js 和 css html结构要按示例对应的三层结构 需要 …...
如何快速实现一个可视化看板?
一、用python实现一个可视化数据看板,最多支持多大体量的数据处理? Python可以通过多种可视化库来实现数据看板,例如Matplotlib、Seaborn、Plotly等。这些库可以处理各种规模的数据,从小型数据集到大型数据集都可以应用。 对于小型…...
基于PyTorch搭建FasterRCNN实现目标检测
基于PyTorch搭建FasterRCNN实现目标检测 1. 图像分类 vs. 目标检测 图像分类是一个我们为输入图像分配类标签的问题。例如,给定猫的输入图像,图像分类算法的输出是标签“猫”。 在目标检测中,我们不仅对输入图像中存在的对象感兴趣。我们还…...
线性表应用(非递减合并、分解链表、删除线性表)
将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其它的存储空间。表中允许有重复的数据。 #include<iostream> using namespace std; typedef struct list {int data;list* next; }list,*linklist;…...
【C++面向对象侯捷下】1.导读
文章目录 来源:我的百度网盘 百科全书 专家书籍 C标准库 C编译器...
Ubuntu22.04 vnc远程黑屏
一、原因 原因是Ubuntu22.04使用的gnome启用了Wayland。vnc、teamviewer、向日葵、todesk等均无法使用或者远程黑屏等。 简单的说vnc、teamviewer、向日葵、todesk等均基于xorg实现(xorg太流行),并不兼容Wayland,所以vnc无法正常…...
【1区TOP】Elsevier旗下CCF推荐,仅3个月左右录用!
01 期刊简介 CCF推荐人工智能类SCIE&EI 【期刊概况】IF:8.0-9.0,JCR1区,中科院2区TOP; 【版面类型】正刊; 【检索情况】SCIE&EI双检,CCF推荐; 【数据库收录年份】1992年ÿ…...
CentOS下安装Python3
一、电脑有网络: 1、直接使用yum包管理安装: yum是CentOS的默认包管理器,在安装软件时非常方便。要安装Python3,可以使用以下命令: sudo yum install python3等待安装完成后,查看python3是否安装完成 //不…...
微信小程序底部安全区域高度获取
CSS 属性 safe-area-inset-bottom safe-area-inset-bottom 就是安全区的高度 padding-bottom:env(safe-area-inset-bottom); wx.getSystemInfoSync() wx.getSystemInfoSync()可以获取系统信息 let system wx.getSystemInfoSync() let bottomSafe system.screenHeight -…...
虚拟机部署linux网络连接配置
1、虚拟机安装linux后,配置网络访问 虚拟机网络设置为NAT模式 linux网络配置好IP,主要是以下网络配置 2、linux没有ifconfig命令,ifconfig命令是在net-tools.x86_64包里 yum install net-tools.x86_64安装...
2591. 将钱分给最多的儿童(Java)
给你一个整数 money ,表示你总共有的钱数(单位为美元)和另一个整数 children ,表示你要将钱分配给多少个儿童。 你需要按照如下规则分配: 所有的钱都必须被分配。 每个儿童至少获得 1 美元。 没有人获得 4 美元。 请你…...
c++23中的新功能之十五类tuple类型的完全支持
一、std::tuple和std::pair 在传统的C里一直有一个问题让开发者不爽,就是无法返回多个值。一般来说,返回多个都建议采用封装的模式,比如弄一个结构体或者类啥的。这样做一定时没有问题的,但对于一些只返回一些简单值并且只在偶尔…...
iPhone15线下购买,苹果零售店前门店排长队
今年的苹果新品发布会于北京时间 9 月 13 日凌晨举行,并于 9 月 15 日(周五)开启订购,9 月 22 日(周五)起正式发售。 据多位网友反馈,首批苹果 iPhone15 系列手机、Apple Watch Ultra 2 / Seri…...
Vue3如何优雅的加载大量图片?
前端面试题库 (面试必备) 推荐:★★★★★ 地址:前端面试题库 表妹一键制作自己的五星红旗国庆头像,超好看 最近开发了一个功能,页面首页会加载大量的图片,初次进入页面时ÿ…...
Go语言开发环境搭建指南:快速上手构建高效的Go开发环境
Go 官网:https://go.dev/dl/ Go 语言中文网:https://studygolang.com/dl 下载 Go 的语言包 进入官方网站 Go 官网 或 Go 语言中文网: 选择下载对应操作系统的安装包: 等待下载完成: 安装 Go 的语言包 双击运行上…...
flex布局与float布局
float布局 俩栏 三栏 flex布局...
【C语言】字符函数和字符串函数(含模拟)
前言: 在做OJ题或阅读代码时或多或少会遇到一些字符函数和字符串函数, 如果不认识或不熟悉就会造成不便, 本篇文章主要是为了这方面而存在, 此篇介绍各个字符串的功能与使用方法, 下一篇会讲解如何模拟这些函数 重点&a…...
基于YOLOv8模型的条形码二维码检测系统(PyTorch+Pyside6+YOLOv8模型)
摘要:基于YOLOv8模型的条形码二维码检测系统可用于日常生活中检测与定位条形码与二维码目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测…...
2023/09/22 制作demo期间心得
A*的估价函数:例如A->C,会计算A到B的距离B到C的距离作为成本,雕刻不会导致全局路线的重新计算,凸多边形是一个内部为凸集的简单多边形。 简单多边形的下列性质与其凸性等价:1、所有内角小于等于180度。 2、任意两个…...
高阶数据结构——图
图 图的基本概念 图的基本概念 图是由顶点集合和边的集合组成的一种数据结构,记作 G ( V , E ) G(V, E)G(V,E) 。 有向图和无向图: 在有向图中,顶点对 < x , y >是有序的,顶点对 < x , y > 称为顶点 x 到顶点 y 的…...
高性能AC算法多关键词匹配文本功能Java实现
直接上测试结果: 1000000数据集。 1000000关键词(匹配词) 装载消耗时间:20869 毫秒 匹配消耗时间:6599 毫秒 代码和测试案例: package com.baian.tggroupmessagematchkeyword.ac;import lombok.Data;im…...
如何在没有第三方.NET库源码的情况,调试第三库代码?
大家好,我是沙漠尽头的狼。 本方首发于Dotnet9,介绍使用dnSpy调试第三方.NET库源码,行文目录: 安装dnSpy编写示例程序调试示例程序调试.NET库原生方法总结 1. 安装dnSpy dnSpy是一款功能强大的.NET程序反编译工具,…...
仿互站资源商城平台系统源码多款应用模版
首先安装好环境,推荐用Linux宝塔 请示:安装前请先别开防火墙,和跨站篡改 第1步上传程序到服务器, 第2步修改数据库文件,config/config.php 第3步,导入数据,根目录的数据库文件夹里面 数据.s…...
华为云云耀云服务器L实例评测 | L实例性能测试实践
🦖我是Sam9029,一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 **🐱🐉🐱🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求…...
VR赋能红色教育,让爱国主义精神永放光彩
昨天的918防空警报长鸣,人们默哀,可见爱国主义精神长存。为了贯彻落实“把红色资源利用好、红色传统发扬好、红色基因传承好”的指示精神,许多红色景点开始引入VR全景展示技术,为游客提供全方位720度无死角的景区展示体验。 VR全…...
wordpress站点路径/网站运营指标
1.设定文件系统配额,只能针对磁盘独自分区的文件系统 不能针对文件 目录 未分区磁盘 <1>.实现home家目录的迁移 迁移之前实行备份 --新建一分区sdc2 --创建文件系统 --创建目录并挂载 --拷贝 --切换单一模式 备份后删除以前家目录 并将挂载写入/etc/fstab --重…...
做旅游网站的毕业论文/网站外链出售
本节分别介绍Tmonitor web portal和后台进程的安装部署,web portal和后台最好能分别安装在不同的机器上。注意:所有操作均在root权限下执行。 安装需要3个包(以安装时最新的发布包为准): web_portal_2.2.18_05130ad9.tar.gz 主要…...
政府网站app/网络广告策划书范文
近日,一家VR(虚拟现实)创业公司Pico对外披露,该公司已被字节跳动收购。受这件事的催化,一个很多人都不认识的新名词——“元宇宙”,进入了大众的视野。 当我们还在试图理解消化这个新概念时,一…...
网站开发公司名单/最新消息今天的新闻
Windows》Customize Perspective》Command Groups Availability选项卡,左边的Available command groups 下的Android 开头的那几个都打上勾,然后ok就好了...
湖南seo网站策划/网络推广方案模板
vs2017有独立的python环境;所以想在vs2017开发python并使用第三方包,需要在vs2017中操作,完成第三方包的安装。 一,查看vs2017有哪些版本的python,当前使用的是哪个版本 工具--》Python--》Python环境 可以看到vs2017包…...
口腔医院网站优化服务商/国家高新技术企业认定
今天我们讲linux系统软件管理。我们电脑上有着各种各样的软件,今天我们就学习如何在Linux系统上进行软件管理。 软件安装首先要有安装包,windows安装包后缀是.exe,而linux不是。Linux有两种安装包。RPM包安装RPM Package Manager(原Red Hat Package Mana…...