【开源获奖案例】全工位氢氧根离子监测站

——来自4008云顶开发者论坛

本期为大家推送4008云顶开发者论坛获奖开源案例——全工位氢氧根离子监测站,工程师采用7英寸 串口屏 通过RS485和RS232双接口与外设通讯,实现水中 氢氧根 离子含量检测。 可应用于电厂污水、 纺织污水、池塘污水检测等场景,降低人工采集成本,测试精准度高。

【演示视频】


完整开发资料含 4008云顶屏DGUS工程资料与C51代码,获取方式:

1. 前往4008云顶开发者论坛获取:

http://inforum.fduoke.com:20080/forum.php?mod=viewthread&tid=9915&extra=page%3D1

2. 微信公众号中回复“全工位氢氧根离子”获取。

UI素材展示

UI素材展示1 UI素材展示2

【UI开发示例】

UI开发示例

C51工程设计

机械臂核心操作代码:

#ifndef __BASE_H__
#define __BASE_H__
#include "sys.h"

#define BASE_SHAKE_CNT_DEF                        12
#define BASE_CLEAN_TIME_DEF                        3

u8 base_shake(u16 cnt,u16 quit_code);
u8 base_clean(u16 clean_time, u16 quit_code);
u8 base_air_dry(u16 quit_code);
u8 base_select_sample(u8 pos,u8 is_clean,u16 quit_code);

#include "base.h"
#include "motor.h"
#include "test.h"
#include "params.h"

u8 base_shake_x_or_y(u8 is_x,u16 cnt,u16 quit_code)
{
#define SHAKE_STEP                        300
#define SHAKE_DELAY                        400
s16 cur_step = 0;
u8 res = 0;

if(cur_motor_pos==MOTOR_POS_CLEAN)
return 0;

while(cnt--)
{
if(cur_step==0)
cur_step = SHAKE_STEP;
else if(cur_step>0)
cur_step = SHAKE_STEP*-2;
else
cur_step = SHAKE_STEP*2;
if(is_x)
{
motor_set_dir((cur_step<0?MOTOR_DIR_FORWARD:MOTOR_DIR_BACKWARD),MOTOR_DIR_SKIP,MOTOR_DIR_SKIP);
motor_move((cur_step<0?-cur_step:cur_step),0,0);
}else
{
motor_set_dir(MOTOR_DIR_SKIP,(cur_step<0?MOTOR_DIR_FORWARD:MOTOR_DIR_BACKWARD),MOTOR_DIR_SKIP);
motor_move(0,(cur_step<0?-cur_step:cur_step),0);
}
sys_delay_ms(SHAKE_DELAY);
if(func_code_scan()==quit_code)
{
res = 1;
break;
}
}

if(cur_step!=0)
{
if(is_x)
{
motor_set_dir((cur_step<0?MOTOR_DIR_BACKWARD:MOTOR_DIR_FORWARD),MOTOR_DIR_SKIP,MOTOR_DIR_SKIP);
motor_move(SHAKE_STEP,0,0);
}else
{
motor_set_dir(MOTOR_DIR_SKIP,(cur_step<0?MOTOR_DIR_BACKWARD:MOTOR_DIR_FORWARD),MOTOR_DIR_SKIP);
motor_move(0,SHAKE_STEP,0);
}
sys_delay_ms(SHAKE_DELAY);
}

return res;
}

u8 base_shake(u16 cnt,u16 quit_code)
{
if(base_shake_x_or_y(1,cnt,quit_code))
return 1;
if(base_shake_x_or_y(0,cnt,quit_code))
return 2;
return 0;
}

u8 base_clean(u16 clean_time, u16 quit_code)
{
#define FULL_TIME                        (sys_params.full_time)
#define EMPTY_TIME                (FULL_TIME+25)
#define BASE_UNIT                        200
u8 res = 0;
u8 time;
motor_select_sample(MOTOR_POS_CLEAN);

WASTE_PUMP_OFF();
WATER_PUMP_ON();
time = FULL_TIME;
while(time--)
{
sys_delay_ms(BASE_UNIT);
if(func_code_scan()==quit_code)
{
res = 1;
break;
}
}



if(clean_time)
{
WASTE_PUMP_ON();
while(clean_time--)
{
sys_delay_ms(1000);
if(func_code_scan()==quit_code)
{
res = 1;
break;
}
}
}

WASTE_PUMP_ON();
WATER_PUMP_OFF();
time = EMPTY_TIME;
while(time--)
{
sys_delay_ms(BASE_UNIT);
if(func_code_scan()==quit_code)
res = 3;
}
WASTE_PUMP_OFF();
if(res==0)
{
test_update_sta(WORK_STA_AIR_DRY);
res = base_air_dry(quit_code);
}

return res;
}

u8 base_air_dry(u16 quit_code)
{
#define AIR_DRY_TIME        (sys_params.air_dry_time)
u8 res = 0;
u8 sec;

AIR_PUMP_ON();
sec = AIR_DRY_TIME;
while(sec--)
{
sys_delay_ms(1000);
if(func_code_scan()==quit_code)
{
res = 1;
break;
}
}
AIR_PUMP_OFF();
return res;
}

u8 base_select_sample(u8 pos,u8 is_clean,u16 quit_code)
{
if(is_clean)
{
test_update_sta(WORK_STA_CLEAN);
if(is_testing)
{
work_sta = WORK_STA_TEST_STEP_1;
if(test_upload_data())
return 1;
}
if(base_clean(BASE_CLEAN_TIME_DEF, quit_code))
return 1;
}
if(is_testing)
{
work_sta = WORK_STA_TEST_STEP_2;
if(test_upload_data())
return 1;
}

test_update_sta(WORK_STA_MOVE);
motor_select_sample(pos);
if(func_code_scan()==quit_code)
return 2;


test_update_sta(WORK_STA_SHAKE);
if(base_shake(BASE_SHAKE_CNT_DEF,quit_code))
return 3;
if(func_code_scan()==quit_code)
return 4;

return 0;
}

测试相关的代码
bit is_complete_tip = 0;
u16 complete_tip_time = 0;
u8 cur_bottle_no = 0;
u8 cur_completed_num = 0;
u8 total_sample_num = NUM_OF_GROUP_DEF;
u8 cur_work_sta = WORK_STA_IDLE;
u8 last_result[LAST_RESULT_MAX_LEN] = {"--------\0\0"};
u8 is_testing = 0;
u8 is_normal_completed = 0;

u8 test_make(u16 quit_code);

//开始测试
void test_start(u16 quit_code)
{
u16 val;

is_testing = 1;
is_complete_tip = 0;
cur_work_sta = WORK_STA_CLEAN;
cur_completed_num = 0;
cur_bottle_no = start_bottle_no;
score = SCORE_UNKNOW;
val = 1;
sys_write_vp(MAIN_WIN_START_BTN_VP,(u8*)&val,1);
main_win_update();
is_normal_completed = !test_make(quit_code);
if(is_normal_completed)
{
test_update_sta(WORK_STA_CLEAN);
base_clean(BASE_CLEAN_TIME_DEF, quit_code);
}
motor_select_sample(MOTOR_POS_PROTECT);


cur_work_sta = (is_normal_completed?WORK_STA_ALL_COMPLETED:WORK_STA_IDLE);
cur_bottle_no = 0;
val = 0;
sys_write_vp(MAIN_WIN_START_BTN_VP,(u8*)&val,1);
main_win_update();
if(is_normal_completed)
{
is_complete_tip = 1;
complete_tip_time = COMPLETE_TIP_MAX_TIME;
sys_goto_win(WIN_ID_MAIN);
sys_delay_ms(100);
sys_click_pos(2,13);
}
is_testing = 0;
is_stable = 0;
check_stable_tick = 0;
val = 0;
sys_write_vp(BTN_VAL_ADDR,(u8*)&val,1);
work_sta = WORK_STA_TEST_STEP_COMPLETED;
test_upload_data();
}

//测试流程
u8 test_make(u16 quit_code)
{
u8 pos;
u8 offset;
float sum = 0;
float max = -999999;
float min = 999999;
u8 index = 0;
u8 end_pos;

end_pos = total_sample_num+start_bottle_no-1;
for(pos=(start_bottle_no-1);pos<end_pos;pos++)
{
if(base_select_sample(pos,!(is_group&&(index%num_of_group)),quit_code))
return 1;
cur_work_sta = WORK_STA_ANALYSIS;
main_win_update();
if(is_testing)
{
work_sta = WORK_STA_TEST_STEP_3;
if(test_upload_data())
return 1;
}
check_stable_tick = 1;
is_stable = 0;
stable_val = 999999;
while(1)
{
if(is_stable)
break;
if(func_code_scan()==quit_code)
return 2;
}
score = SCORE_UNKNOW;
memset(last_result,0,LAST_RESULT_MAX_LEN);
sprintf(last_result,"%.3f",cur_ph);
if(is_group&&(invalid_num_of_group<num_of_group))
{
offset = index%num_of_group;
if(offset>=invalid_num_of_group)
{
sum += cur_val;//对有效点累加求和
if(cur_val>max)
max = cur_val;
if(cur_val<min)
min = cur_val;
}
if((offset+1)==num_of_group)
{
sum /= (num_of_group-invalid_num_of_group);
score = ((max-min)<valid_range_of_group?SCORE_YES:SCORE_NO);
sum = 0;
max = -999999;
min = 999999;
}
}
cur_completed_num++;
if(is_testing)
{
work_sta = WORK_STA_TEST_STEP_4;
if(test_upload_data())
return 1;
}
cur_bottle_no++;
if(cur_bottle_no>end_pos)
cur_bottle_no = 0;
main_win_update();
index++;
}
return 0;
}