本帖最后由 tom_green 于 2023-9-2 20:39 编辑
主要参考资料如下: [ [野火]瑞萨RA系列FSP库开发实战指南——基于野火启明开发板
本人新手小白,借鉴和学习了参加本次试用活动的大佬的代码和开发流程, 本项目用于监测高压三相电流数据,并对故障进行判断的设备,使用了串口,硬件I2C,ADC,OLED等硬件, 使用瑞萨的FSP3.5版本,整体工程见附件
启明6M5开发板硬件资源如图所示:
项目框架
三路ADC获取三相瞬时正弦波电流信息 正弦波转化为三相电流有效值 判断三相电是否发生故障 本地OLED显示,并上传云平台
开发流程 本人使用j-link的SWD 接口用于RA MCU的调试和程序下载,使用keil较为方便使用,需要如下配置: - /* TODO: add your own code here */
- Debug_UART2_Init(); // SCI4 UART 调试串口初始化
- ESP8266_UART9_Init(); // ESP8266 (SCI9 UART) 串口初始化
-
- printf("欢迎使用野火启明6M5开发板\n\n");
复制代码
硬件I2C的OLED 使用EBF Module 接口的P505,P506配置硬件I2C,驱动OLED屏幕
使用相关驱动初始化后,OLED打印信息 - OLED_ShowString(0, 16, (const uint8_t*)"AIrms", 16, 1);
- OLED_ShowString(43, 16,(const uint8_t*)"BIrms", 16, 1);
- OLED_ShowString(87, 16,(const uint8_t*)"CIrms", 16, 1);
-
- OLED_ShowString(0, 32, AIrms_str, 16,1);
- OLED_ShowString(43, 32, BIrms_str, 16,1);
- OLED_ShowString(87, 32, CIrms_str, 16,1);
- OLED_ShowString(0, 0, (const uint8_t*)"state:", 16, 1);
- OLED_ShowNum(87, 0, state,1,16, 1);
- OLED_Refresh_Gram();
复制代码
数据采集 使用开口式电流互感器,可选一次侧与二次侧的变比100:1,200:1,500:1,将开口式电流互感器二次侧接入采样电阻,可转化为电压值进行ADC采样
ADC配置 配置ADC扫描参数,赋能ADC通道。在此函数中设置通道特定设置。 - /* Enable scan triggering from ELC events. */
- (void) R_ADC_ScanStart(&g_adc0_ctrl);
复制代码 回调函数adc_callback ()- void adc_callback(adc_callback_args_t * p_args)
- {
- FSP_PARAMETER_NOT_USED(p_args);
- scan_complete_flag = true;
- }
复制代码
读取ADC值 - err =R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_0, &adc_data1);
- assert(FSP_SUCCESS == err);
- a1=(double)(adc_data1/4095.0)*3.3;
复制代码读取三通道ADC值
- //ADC转换完成标志位
- volatile bool scan_complete_flag = false;
- void adc_callback(adc_callback_args_t * p_args)
- {
- FSP_PARAMETER_NOT_USED(p_args);
- scan_complete_flag = true;
- }
- void ADC_Init(void)
- {
- fsp_err_t err;
- err = R_ADC_Open(&g_adc0_ctrl, &g_adc0_cfg);
- err = R_ADC_ScanCfg(&g_adc0_ctrl, &g_adc0_channel_cfg);
- assert(FSP_SUCCESS == err);
- }
- /* 进行ADC采集,读取ADC数据并转换结果 */
- void Read_ADC_Voltage_Value(double *adcdata)
- {
-
- uint16_t adc[3];
- (void) R_ADC_ScanStart(&g_adc0_ctrl);
- while (!scan_complete_flag) //等待转换完成标志
- {
- ;
- }
- scan_complete_flag = false; //重新清除标志位
-
- /* 读取通道0数据 */
- R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_1, &adc[0]);
- /* ADC原始数据转换为电压值(ADC参考电压为3.3V) */
- adcdata[0] = (double)(adc[0]*3.3/4095);
-
- /* 读取通道0数据 */
- R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_2, &adc[1]);
- /* ADC原始数据转换为电压值(ADC参考电压为3.3V) */
- adcdata[1] = (double)(adc[1]*3.3/4095);
-
- /* 读取通道0数据 */
- R_ADC_Read(&g_adc0_ctrl, ADC_CHANNEL_3, &adc[2]);
- /* ADC原始数据转换为电压值(ADC参考电压为3.3V) */
- adcdata[2] = (double)(adc[2]*3.3/4095);
-
- }
复制代码 计算出电流有效值- /******************************************************
- 函数名称: getrms
- 描述: 遍历查找电流样本点,得到极致点序列,计算出电流有效值
- 输入: iphase:电流样本数组
- SAMPLE_N:电流样本数据点数
-
- 输出:
- 返回: 电流有效值
- ******************************************************/
- float getrms(float *phase,int SAMPLE_N)
- {
- int changeSignCount=0;
- int changeSignIndex[changeSignCount];
- // 遍历查找电流样本点
- for (int i = 1; i < SAMPLE_N; i++)
- {
- //极大值,
- if((phase[i-1] <= phase[i] && phase[i] >=phase[i+1]) )
- {
- changeSignIndex[changeSignCount] = i;
- changeSignCount++;
- }
- }
- // 创建新数组,放置查找结果
- float changeSignSeq[changeSignCount];
- float max = 0;
- float min = 0;
- for(int i = 0; i < changeSignCount; i++)
- {
- changeSignSeq[i] = phase[changeSignIndex[i]];
- if (max<changeSignSeq[i]) {
- max=changeSignSeq[i];
- }
- if (min>changeSignSeq[i]) {
- min=changeSignSeq[i];
- }
-
- }
- //得出电流有效值
- if(fabs(max)>fabs(min)) {
- return (float)(fabs(max) * 0.707);
- }
- else {
- return (float)(fabs(min) * 0.707);
- }
- }
复制代码 电流故障类型判断- /******************************************************
- 函数名称: changesign
- 描述: 电流故障类型判断
- 输入: Aphase,Bphase,Cphase三相电有效值
- maxphase理论最大电流
-
- 输出:
- 返回: 错误类型
- ******************************************************/
- int GetCableFaulttype(float Aphase,float Bphase,float Cphase,float maxphase)
- {
- int Fault;
-
- if(Aphase<maxphase&&Bphase<maxphase&&Cphase<maxphase)
- {
- if(Aphase<2||Bphase<2||Cphase<2)
- {
-
- Fault = 5;//接地网脱落,或三相电未全部接地
- }
-
-
- Fault =6;//接地正常
- }
-
- else{
- if(Aphase>100||Bphase>100||Cphase>100)
- {
- Fault = 3;//隔板击穿
-
- }
- //排序得到最大最小值
- float max=Aphase;
- float min=Bphase;
- if(max<=Bphase)
- {
- max=Bphase;
- min=Aphase;
- }
- if(max<=Cphase)
- {
- max=Cphase;
- }
- if(min>=Cphase)
- {
- min=Cphase;
- }
-
- if(max>6*min)
- {
- Fault = 0;////接地错误
-
- }
- if(max>6+min)
- {
- Fault = 2;//外护套破损
-
- }
-
-
- }
- return Fault;
- }
复制代码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表示正常。
以上内容如有侵权,请联系删减,谢谢
|