野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 626|回复: 0

【野火】瑞萨RA MCU创意氛围赛+高压电网电流监测

[复制链接]
发表于 2023-8-22 01:21:23 | 显示全部楼层 |阅读模式
本帖最后由 tom_green 于 2023-9-2 20:39 编辑

主要参考资料如下:
[ [野火]瑞萨RA系列FSP库开发实战指南——基于野火启明开发板
本人新手小白,借鉴和学习了参加本次试用活动的大佬的代码和开发流程,
本项目用于监测高压三相电流数据,并对故障进行判断的设备,使用了串口,硬件I2C,ADC,OLED等硬件,
使用瑞萨的FSP3.5版本,整体工程见附件

启明6M5
开发板硬件资源如图所示:

项目框架

三路ADC获取三相瞬时正弦波电流信息
正弦波转化为三相电流有效值
判断三相电是否发生故障
本地OLED显示,并上传云平台

开发流程
本人使用j-link的SWD 接口用于RA MCU的调试和程序下载,使用keil较为方便使用,需要如下配置:
  • P300/TCK/SWCLK 可通过跳线帽可接到 P201/MD 引脚。用于控制 MD 引脚电平,使MCU上电时进入不同的启动模式。

  • P112/UART2_TXD 和 P113/UART2_RXD 两个引脚可配置为串口功能


  1.     /* TODO: add your own code here */
  2.     Debug_UART2_Init(); // SCI4 UART 调试串口初始化

  3.     ESP8266_UART9_Init();  // ESP8266 (SCI9 UART) 串口初始化
  4.    
  5.     printf("欢迎使用野火启明6M5开发板\n\n");
复制代码

硬件I2C的OLED
使用EBF Module 接口的P505,P506配置硬件I2C,驱动OLED屏幕



使用相关驱动初始化后,OLED打印信息
  1.   OLED_ShowString(0, 16, (const uint8_t*)"AIrms", 16, 1);
  2.                 OLED_ShowString(43, 16,(const uint8_t*)"BIrms", 16, 1);
  3.                 OLED_ShowString(87, 16,(const uint8_t*)"CIrms", 16, 1);
  4.                
  5.                 OLED_ShowString(0, 32, AIrms_str, 16,1);               
  6.                 OLED_ShowString(43, 32, BIrms_str, 16,1);        
  7.                 OLED_ShowString(87, 32, CIrms_str, 16,1);        
  8.                 OLED_ShowString(0, 0, (const uint8_t*)"state:", 16, 1);
  9.                 OLED_ShowNum(87, 0, state,1,16, 1);
  10.     OLED_Refresh_Gram();
复制代码


数据采集
使用开口式电流互感器,可选一次侧与二次侧的变比100:1,200:1,500:1,将开口式电流互感器二次侧接入采样电阻,可转化为电压值进行ADC采样

ADC配置
配置ADC扫描参数,赋能ADC通道。在此函数中设置通道特定设置。
  1. /* Enable scan triggering from ELC events. */
  2.         (void) R_ADC_ScanStart(&g_adc0_ctrl);
复制代码
回调函数adc_callback ()
  1. void adc_callback(adc_callback_args_t * p_args)
  2. {
  3.     FSP_PARAMETER_NOT_USED(p_args);
  4.     scan_complete_flag = true;
  5. }
复制代码

读取ADC值
  1. err =R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_0, &adc_data1);
  2.         assert(FSP_SUCCESS == err);

  3.         a1=(double)(adc_data1/4095.0)*3.3;

复制代码
读取三通道ADC值

  1. //ADC转换完成标志位
  2. volatile bool scan_complete_flag = false;

  3. void adc_callback(adc_callback_args_t * p_args)
  4. {
  5.     FSP_PARAMETER_NOT_USED(p_args);
  6.     scan_complete_flag = true;
  7. }

  8. void ADC_Init(void)
  9. {
  10.     fsp_err_t err;
  11.     err = R_ADC_Open(&g_adc0_ctrl, &g_adc0_cfg);
  12.     err = R_ADC_ScanCfg(&g_adc0_ctrl, &g_adc0_channel_cfg);
  13.     assert(FSP_SUCCESS == err);
  14. }

  15. /* 进行ADC采集,读取ADC数据并转换结果 */
  16. void Read_ADC_Voltage_Value(double *adcdata)
  17. {
  18.    
  19.                         uint16_t adc[3];

  20.     (void) R_ADC_ScanStart(&g_adc0_ctrl);
  21.     while (!scan_complete_flag) //等待转换完成标志
  22.     {
  23.         ;
  24.     }
  25.     scan_complete_flag = false; //重新清除标志位
  26.                
  27.     /* 读取通道0数据 */
  28.                 R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_1, &adc[0]);
  29.     /* ADC原始数据转换为电压值(ADC参考电压为3.3V) */
  30.     adcdata[0] = (double)(adc[0]*3.3/4095);
  31.                
  32.                     /* 读取通道0数据 */
  33.                 R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_2, &adc[1]);
  34.     /* ADC原始数据转换为电压值(ADC参考电压为3.3V) */
  35.     adcdata[1] = (double)(adc[1]*3.3/4095);
  36.                
  37.                     /* 读取通道0数据 */
  38.                 R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_3, &adc[2]);
  39.     /* ADC原始数据转换为电压值(ADC参考电压为3.3V) */
  40.     adcdata[2] = (double)(adc[2]*3.3/4095);
  41.                
  42. }
复制代码
计算出电流有效值
  1. /******************************************************
  2. 函数名称:        getrms
  3. 描述:                遍历查找电流样本点,得到极致点序列,计算出电流有效值
  4. 输入:                iphase:电流样本数组
  5.                                 SAMPLE_N:电流样本数据点数
  6.                                 
  7. 输出:        
  8. 返回:                电流有效值
  9. ******************************************************/
  10. float getrms(float *phase,int SAMPLE_N)
  11. {
  12.         int changeSignCount=0;
  13.         int changeSignIndex[changeSignCount];
  14. // 遍历查找电流样本点
  15. for (int i = 1; i < SAMPLE_N; i++)
  16. {      

  17.         //极大值,
  18. if((phase[i-1] <= phase[i] && phase[i] >=phase[i+1]) )
  19.         {
  20.             changeSignIndex[changeSignCount] = i;
  21.             changeSignCount++;  
  22.         }
  23. }
  24. // 创建新数组,放置查找结果
  25. float changeSignSeq[changeSignCount];
  26.          float max = 0;
  27.         float min = 0;
  28. for(int i = 0; i < changeSignCount; i++)
  29.                 {
  30.         changeSignSeq[i] = phase[changeSignIndex[i]];
  31.                         if (max<changeSignSeq[i])  {
  32.                         max=changeSignSeq[i];
  33.                         }
  34.                         if (min>changeSignSeq[i])  {
  35.                         min=changeSignSeq[i];
  36.                         }
  37.                         
  38.     }
  39.                 //得出电流有效值
  40.                 if(fabs(max)>fabs(min)) {
  41.                 return (float)(fabs(max) * 0.707);
  42.                 }
  43.                 else {
  44.                 return (float)(fabs(min) * 0.707);
  45.                 }
  46. }
复制代码
电流故障类型判断
  1. /******************************************************
  2. 函数名称:        changesign
  3. 描述:                电流故障类型判断
  4. 输入:                Aphase,Bphase,Cphase三相电有效值
  5.                                         maxphase理论最大电流
  6.                                                                         
  7. 输出:        
  8. 返回:                错误类型
  9. ******************************************************/

  10. int GetCableFaulttype(float Aphase,float Bphase,float Cphase,float maxphase)
  11. {
  12.         int Fault;
  13.                
  14.         if(Aphase<maxphase&&Bphase<maxphase&&Cphase<maxphase)
  15.         {
  16.                 if(Aphase<2||Bphase<2||Cphase<2)
  17.                 {
  18.                         
  19.                         Fault        = 5;//接地网脱落,或三相电未全部接地
  20.                 }
  21.                
  22.                
  23.                 Fault =6;//接地正常
  24.         }
  25.         
  26.         else{
  27.         if(Aphase>100||Bphase>100||Cphase>100)
  28.         {
  29.                 Fault = 3;//隔板击穿
  30.                
  31.         }
  32.         //排序得到最大最小值
  33.         float max=Aphase;
  34.         float min=Bphase;
  35.         if(max<=Bphase)
  36.                 {
  37.                         max=Bphase;
  38.                         min=Aphase;
  39.                 }
  40.         if(max<=Cphase)
  41.                 {
  42.                         max=Cphase;
  43.                 }               
  44.         if(min>=Cphase)
  45.                 {
  46.                         min=Cphase;
  47.                 }        
  48.                
  49.         if(max>6*min)
  50.         {
  51.                 Fault = 0;////接地错误
  52.                
  53.         }        
  54.         if(max>6+min)
  55.         {
  56.                 Fault = 2;//外护套破损
  57.                
  58.         }        
  59.         
  60.         
  61. }
  62.         return Fault;
  63. }
复制代码
GROUND_ERROR = 0,//接地错误
WATER_IN_BOX = 1,//接地箱进水
OUTER_SHEATH_DAMAGE = 2,//护套破损
PARTITION_BREAKDOWN = 3,//隔板击穿
PROTECTOR_BREAKDOWN = 4,//保护器击穿
GROUND_GRID_LOOSE = 5,//接地网脱落
GROUND_OK = 6//正常



一般使用4G模块,也可使用本开发板上板载的ESP8266

实现效果如下:
没有实际接入高压电,ADC通道1,直接接入函数发生器生成的50HZ正弦波3.3V波峰,有效值为3.3*0.7.7=2.3331V,故障状态6表示正常。
12345.png


野火论坛202308212236246754..png
以上内容如有侵权,请联系删减,谢谢



野火论坛202308220036514051..png
野火论坛202308220036405145..png
野火论坛202308220036071272..png

DWZLtest.zip

1.57 MB, 下载次数: 13

使用fsp3.5

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-2 07:47 , Processed in 0.038397 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表