基于STM32的智能电能表设计

news2024/11/24 16:56:48

引言

本项目设计了一个基于STM32的智能电能表,能够实时测量电压、电流、功率以及累计的电能消耗。通过ADC模块采集电压和电流信号,结合功率计算算法,系统可以精准地监控家庭或工业设备的电能消耗。该智能电能表还支持远程数据传输和本地数据显示功能,适用于能源监控和智能电网领域。

环境准备

1. 硬件设备
  • STM32F103C8T6 开发板(或其他 STM32 系列)
  • 电压互感器(用于电压采样,如 ZMPT101B)
  • 电流互感器(如 SCT013,用于电流采样)
  • ADC 模块(STM32 自带,用于读取电压和电流信号)
  • OLED 显示屏(用于显示电压、电流、功率和电能信息)
  • NRF24L01 无线通信模块(用于远程数据传输,选用)
  • USB-TTL 串口调试工具
2. 软件工具
  • STM32CubeMX:用于初始化 STM32 外设。
  • Keil uVision 或 STM32CubeIDE:用于编写和下载代码。
  • ST-Link 驱动程序:用于下载程序到 STM32。

项目实现

1. 硬件连接
  • 电压互感器连接:将电压互感器(如 ZMPT101B)的输出引脚连接到 STM32 的 ADC 输入引脚(如 PA0),用于采集电网电压。
  • 电流互感器连接:将电流互感器(如 SCT013)的输出引脚连接到 STM32 的 ADC 输入引脚(如 PA1),用于采集电流信号。
  • OLED 显示屏连接:将 OLED 的 SDA 和 SCL 引脚连接到 STM32 的 I2C 接口(如 PB6 和 PB7),用于显示电能信息。
  • NRF24L01 无线模块连接:将 NRF24L01 的 CE、CSN、MISO、MOSI 和 SCK 引脚连接到 STM32 的 SPI 接口(如 PB6、PB7、PB8、PB9、PB10),用于无线通信(选用)。
  • 按键连接:将按键连接到 STM32 的 GPIO(如 PA2),用于手动切换显示模式或重置累计电能。
2. STM32CubeMX 配置
  • 打开 STM32CubeMX,选择你的开发板型号。
  • 配置系统时钟为 HSI,确保系统稳定运行。
  • 配置 GPIO 引脚用于按键和 OLED 显示屏。
  • 配置 I2C 用于与 OLED 显示屏通信。
  • 配置 SPI 用于 NRF24L01 无线通信模块(如果使用)。
  • 配置 ADC 用于采集电压和电流信号。
  • 生成代码,选择 Keil 或 STM32CubeIDE 作为工具链。
3. 编写主程序

在生成的项目基础上,编写电压、电流采集、功率计算、累计电能计算以及数据展示的代码。以下是智能电能表的基本代码示例:

#include "stm32f1xx_hal.h"
#include "adc.h"
#include "oled.h"
#include "nrf24l01.h"  // 可选模块

// 定义电能计量参数
#define VOLTAGE_CONVERSION_RATIO 0.03  // 电压转换比
#define CURRENT_CONVERSION_RATIO 0.05  // 电流转换比
#define POWER_FACTOR 0.85  // 假设功率因数为0.85
#define SAMPLING_RATE 1000  // 采样频率

// 全局变量
float voltage = 0;
float current = 0;
float power = 0;
float energy = 0;
uint32_t sample_count = 0;

// 函数声明
void System_Init(void);
float Read_Voltage(void);
float Read_Current(void);
void Calculate_Power_Energy(void);
void Display_Status(void);

void System_Init(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_I2C1_Init();
    MX_ADC1_Init();
    
    OLED_Init();
    OLED_ShowString(0, 0, "Smart Energy Meter");
}

// 读取电压信号并转换为实际电压值
float Read_Voltage(void)
{
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
    uint16_t raw_value = HAL_ADC_GetValue(&hadc1);
    HAL_ADC_Stop(&hadc1);
    
    return raw_value * VOLTAGE_CONVERSION_RATIO;  // 将ADC值转换为实际电压
}

// 读取电流信号并转换为实际电流值
float Read_Current(void)
{
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
    uint16_t raw_value = HAL_ADC_GetValue(&hadc1);
    HAL_ADC_Stop(&hadc1);
    
    return raw_value * CURRENT_CONVERSION_RATIO;  // 将ADC值转换为实际电流
}

// 计算功率和累计电能
void Calculate_Power_Energy(void)
{
    voltage = Read_Voltage();
    current = Read_Current();
    power = voltage * current * POWER_FACTOR;  // 有功功率 P = U * I * cos(Φ)
    energy += power / SAMPLING_RATE;  // 电能 E = P * t,假设采样间隔为 1 秒
}

// 显示当前电压、电流、功率和电能信息
void Display_Status(void)
{
    OLED_Clear();
    OLED_ShowString(0, 0, "V: ");
    OLED_ShowFloat(32, 0, voltage, 2);
    
    OLED_ShowString(0, 1, "I: ");
    OLED_ShowFloat(32, 1, current, 2);
    
    OLED_ShowString(0, 2, "P: ");
    OLED_ShowFloat(32, 2, power, 2);
    
    OLED_ShowString(0, 3, "E: ");
    OLED_ShowFloat(32, 3, energy, 2);
}

int main(void)
{
    System_Init();
    
    while (1)
    {
        Calculate_Power_Energy();  // 计算功率和电能
        Display_Status();          // 显示实时数据
        HAL_Delay(1000);           // 每秒刷新一次数据
    }
}
4. 各模块代码
电压与电流读取

通过 STM32 自带的 ADC 模块读取电压和电流信号,并将 ADC 数值转换为实际的电压和电流值:

#include "adc.h"

// 读取电压信号并转换为实际电压值
float Read_Voltage(void)
{
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
    uint16_t raw_value = HAL_ADC_GetValue(&hadc1);
    HAL_ADC_Stop(&hadc1);
    
    return raw_value * VOLTAGE_CONVERSION_RATIO;  // 将ADC值转换为实际电压
}

// 读取电流信号并转换为实际电流值
float Read_Current(void)
{
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
    uint16_t raw_value = HAL_ADC_GetValue(&hadc1);
    HAL_ADC_Stop(&hadc1);
    
    return raw_value * CURRENT_CONVERSION_RATIO;  // 将ADC值转换为实际电流
}
OLED 显示

OLED 显示屏用于实时显示电压、电流、功率和累计电能:

#include "oled.h"

// 初始化 OLED 显示屏
void OLED_Init(void)
{
    // OLED 初始化代码
}

// 显示字符串
void OLED_ShowString(uint8_t x, uint8_t y, const char *str)
{
    // 在 OLED 指定位置显示字符串
}

// 显示浮点数
void OLED_ShowFloat(uint8_t x, uint8_t y, float num, uint8_t decimal_places)
{
    // 在 OLED 上显示浮点数
}

// 清屏
void OLED_Clear(void)
{
    // 清除 OLED 显示内容
}
NRF24L01 无线通信(可选)

用于远程传输电能数据到服务器或远程设备:

#include "nrf24l01.h"
#include "spi.h"

// 初始化 NRF24L01 模块
void NRF24L01_Init(void)
{
    // 配置 NRF24L01 工作模式、信道、地址等
}

// 发送数据
void NRF24L01_Send(float voltage, float current, float power, float energy)
{
    uint8_t data[16];
    memcpy(data, &voltage, 4);
    memcpy(data + 4, &current, 4);
    memcpy(data + 8, &power, 4);
    memcpy(data + 12, &energy, 4);
    
    NRF24L01_Transmit(data);  // 发送电能数据
}

⬇帮大家整理了单片机的资料

包括stm32的项目合集【源码+开发文档】

点击下方蓝字即可领取,感谢支持!⬇

点击领取更多嵌入式详细资料

问题讨论,stm32的资料领取可以私信!

 

5. 系统工作原理

  • 电压和电流采集:通过电压互感器和电流互感器采集电网中的电压和电流信号,并使用 STM32 的 ADC 将模拟信号转换为数字信号,进一步计算得到实际的电压和电流值。

  • 功率计算:根据公式 P=U×I×cos⁡(ϕ)P = U \times I \times \cos(\phi)P=U×I×cos(ϕ),计算出当前的有功功率。功率因数 cos⁡(ϕ)\cos(\phi)cos(ϕ) 是常数,可以根据实际使用环境调整。

  • 电能累计:通过积分法计算电能消耗,假设采样频率为 1 秒,则每次累积的电能 EEE 等于功率 PPP 乘以时间(1 秒)。

  • 数据展示与远程传输:OLED 显示屏实时显示当前的电压、电流、功率和累计电能。若使用 NRF24L01 模块,数据还可以通过无线方式传输到远程服务器,实现远程电能监控。

常见问题与解决方法

1. 测量不准确
  • 问题原因:电压、电流互感器校准不准确,或ADC分辨率不足。
  • 解决方法:对互感器进行校准,确保采样电压和电流信号与实际值一致,并提高ADC的分辨率,或使用外部高精度ADC模块。
2. OLED 显示不正常
  • 问题原因:I2C 通信错误,或显示屏初始化失败。
  • 解决方法:检查 I2C 连接是否牢固,确保 OLED 初始化代码正确无误。
3. 无线通信不稳定
  • 问题原因:NRF24L01 信号干扰或电源供电不足。
  • 解决方法:确保 NRF24L01 模块供电稳定,天线连接良好,调整通信信道避免干扰。

扩展功能

  • 远程控制与数据上传:通过 ESP8266 Wi-Fi 模块,扩展系统的联网功能,将电能数据上传到云服务器,实现远程监控和控制。

  • 智能电网接口:通过扩展协议(如 Modbus、CAN 总线等),可以将智能电能表集成到更大的智能电网系统中,监控家庭、工厂的整体能耗。

  • 历史数据存储:添加 SD 卡模块或外部 EEPROM,记录电能消耗的历史数据,便于后续的能耗分析。

结论

通过本项目,我们成功设计了一个基于 STM32 的智能电能表,能够实时测量电压、电流、功率,并计算累计电能。该系统不仅能够通过 OLED 显示屏本地展示数据,还可以通过无线模块实现远程传输,广泛适用于家庭、工厂和智能电网的能耗监控场景。项目具备很强的可扩展性,未来可以进一步添加联网功能、数据存储以及与智能电网的集成。

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

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

相关文章

Krea.ai正式发布AI视频集合站:Luma、Runway与可灵的深度整合

引言 在数字内容日益丰富的今天,视频制作的需求呈现爆发式增长。为了满足创作者对高效、创新视频工具的渴求,Krea.ai推出了全新的AI视频集合站。此平台整合了多款领先工具,如Luma、Runway、可灵和Minimax,为用户提供一站式的视频…

【等号绕过】

简介 一、大小于号绕过 上面的<>是不等于的意思 测试注入点&#xff1a; id1 正常输入id1 测试是否有注入id1 and 11%23 提示hacker~ 被过滤了id1 and 1%23 没有被过滤&#xff0c;说明是被过滤&#xff0c;但是没有输出id1 and 1%23 页面有输…

25四非网安保研回忆录(北航网安/东南网安/重大计科等)

目录 0 个人情况 1 夏令营 西南大学计科 西南交通大学计科 重庆大学计科 2 预推免 东南大学网安 北京航空航天大学网安 3 写在最后 0 个人情况 计算机类比较强的四非&#xff0c;信安专业rank1&#xff0c;六级540&#xff0c;竞赛十几个&#xff0c;无论文&#xff…

【Linux网络编程】网络基础 | Socket 编程基础

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

2.13寸电子墨水屏HINK-E0213+esp8266

记录好数字 2.13寸电子墨水屏HINK-E0213esp8266 声明:大部分资料来源于微雪电子http://微雪电子-官网 https://www.waveshare.net/ 前言 很久以前买的一块电子墨水屏,运气很好,这个型号HINK-E0213资料很全,而且微雪官网也有相关电路资料http://2.13inch e-Paper HAT - Waves…

java邮件发送

文章目录 前言一、开启SMTP邮箱配置二、spring-mail1.引入依赖2.yml配置3.使用二、hutool-mail1.引入hutool2.在resource下新增mail.setting3.使用总结前言 发送邮件: 目前比较简单的有两种方式实现: spring-mailhuool-mail现在看下两种方式 一、开启SMTP邮箱配置 两种方式…

mysql查询2张表连接列名一样的情况

people表&#xff1a; person表&#xff1a; SELECT * FROM person LEFT JOIN people on people.idperson.id 查询的结果id(1)和name(1)说明列名重复 SELECT person.id,person.name,people.id as pid,people.name as pname FROM person LEFT JOIN people on people.idperso…

Linux shellcheck工具

安装工具 通过linux yum源下载&#xff0c;可能因为yum源的问题找不到软件包&#xff0c;或者下载的软件包版本太旧。 ShellCheck的源代码托管在GitHub上(推荐下载方式)&#xff1a; GitHub - koalaman/shellcheck: ShellCheck, a static analysis tool for shell scripts 对下…

10.高级存储过程技巧(10/10)

高级存储过程技巧博客大纲 引言 在现代数据库管理系统中&#xff0c;存储过程作为提升数据操作效率和安全性的关键工具&#xff0c;已被广泛应用于各种数据库操作中。存储过程是一组为了完成特定功能的SQL语句集合&#xff0c;这些语句在数据库中被保存、编译和优化&#xff0…

Chromium 前端window对象c++实现定义

前端中window.document window.alert()等一些列方法和对象在c对应定义如下&#xff1a; 1、window对象接口定义文件window.idl third_party\blink\renderer\core\frame\window.idl // https://html.spec.whatwg.org/C/#the-window-object// FIXME: explain all uses of [Cros…

【原创】java+springboot+mysql在线课程学习网设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

陪诊小程序搭建:打造便利的陪诊环境

陪诊行业作为一个新兴行业&#xff0c;随着老龄化的严重&#xff0c;在近几年中需求量日益旺盛。陪诊师为大众的就医提供了极大的便利性&#xff0c;在看病难、医疗资源紧张方面发挥了积极作用。 在陪诊行业的快速发展下&#xff0c;陪诊小程序为行业带来了便捷的模式&#xf…

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器

使用 three.js和 shader 实现一个五星红旗 飘扬得着色器 源链接&#xff1a;https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idchinaFlag 国内站点预览&#xff1a;http://threehub.cn github地址: https://github.com/z2586300277/three-ce…

数学建模算法与应用 第6章 微分方程建模及其求解方法

目录 6.1 微分方程建模概述 6.2 发射卫星与三阶火箭建模 Matlab代码示例&#xff1a;火箭发射模拟 6.3 微分方程数值解法 Matlab代码示例&#xff1a;欧拉法与龙格-库塔法 6.4 放射性废料的处理 Matlab代码示例&#xff1a;放射性衰变 6.5 初值问题的Matlab数值求解 习…

Java项目:149 基于SSM的毕业设计管理系统

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 毕业设计管理系统 介绍 毕业设计是本科教育的最后一个环节&#xff0c;整个过程包括课题拟定与审核、师生双选、开题报告、文档审核、中期检查、毕业答…

C++ 比大小

//输入两个可能有前导 0 的大整数&#xff0c;a,b请输出他们谁大谁小#include <iostream> #include <string> #include <string.h> using namespace std; #define M 100005 int main() {char a[M], b[M];char *pa, *pb;pa a;pb b;cin >> a >> …

Linux的pinctrl和gpio子系统

上一章我们编写了基于设备树的 LED 驱动&#xff0c;但是驱动的本质还是没变&#xff0c;都是配置 LED 灯所使用的 GPIO 寄存器&#xff0c;驱动开发方式中硬件初始化这一部分和裸机基本没啥区别。Linux 是一个庞大而完善的系统&#xff0c;尤其是驱动框架&#xff0c;像 GPIO …

软考《信息系统运行管理员》- 4.1信息系统软件运维概述

4.1信息系统软件运维概述 文章目录 4.1信息系统软件运维概述信息系统软件运维的概念信息系统软件的可维护性及维护类型对软件可维护性的度量可以从以下几个方面进行&#xff1a;软件维护分类&#xff1a; 信息系统软件运维的体系1.**需求驱动**2.**运维流程**3.**运维过程**4.*…

ApiPost7一键压测

首先我们需要确认apipost已登录所需测试接口的后端 这边有个一键压测功能&#xff0c;可以帮助我们未下测试工具的同学直接进行接口测试 第一步&#xff1a;修改调试参数 首先我们需要在调试中把要传的参数设计成以下格式&#xff0c;确保后续压测功能成功执行 第二步&am…

MySQL-05.DDL-图形化界面工具

一.数据库图形化界面工具介绍 datagrip是Oracle公司所提供的一款专门用于操作数据库的图形化界面工具&#xff0c;目前已经被集成在了idea中&#xff0c;可以直接通过idea进行操作而不需要下载安装datagrip。 二.在idea中使用datagrip操作数据库 1.首先创建一个空项目 2.接着…