目录
1.关于6个人机交互功能按钮逻辑图设计
2.错误处理机制
1.关于6个人机交互功能按钮逻辑图设计
初次的设计想法是按钮亮表示大家能按,但要是想在按一次,发送有效数据,就得先按亮,在按灭。这里以上料区为例,其它区域同理。
2.错误处理机制
代码部分逻辑如下,得到过大师的指点,这部分的逻辑写的杠杆滴~
//线程1的入口函数,处理数据的线程函数,负责将解析json的数组写入寄存器
#define MAX_CONNECT_ATTEMPTS 6
void* processDataWrapper(void* arg) {
#if HMI_INFO //HMI_INFO控制是否打印日志信息到当前目录
// 设置日志文件名
hlog_set_file("hmi_info.log");
// 设置日志格式
hlog_set_format("[hmi_info] %y-%m-%d %H:%M:%S.%z %L %s");
// 启用日志颜色(如果支持)
logger_enable_color(hlog, 1);
#endif
hmi_info_log_init();
modbus_t* ctx = NULL;
static int connect_attempt = 0;
static int conn_succ_flag = 0;
while (1) {
if (ctx == NULL) {
// 新建libmodbus context
ctx = modbus_new_rtu("/dev/ttyS0", 115200, 'N', 8, 1);
if (ctx == NULL) {
fprintf(stderr, "Unable to allocate libmodbus context\n");
#if HMI_INFO
fprintf(stderr, "Unable to allocate libmodbus context\n");
#endif
//goto cleanup;
}
// 设置从机地址
int slave_id_set = modbus_set_slave(ctx, SERVER_ID);
// 设置从机地址
if (slave_id_set == -1) {
fprintf(stderr, "Unable to set slave ID: %s\n", modbus_strerror(errno));
#if HMI_INFO
fprintf(stderr, "Unable to allocate libmodbus context\n");
#endif
modbus_close(ctx);
modbus_free(ctx);
ctx = NULL;
}
if(ctx != NULL)
{
// 设置485模式
modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
}
}
// 连接设备
if (ctx != NULL) {
if ((conn_succ_flag==0)&&(modbus_connect(ctx) == -1))
{
conn_succ_flag =0;
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
#if HMI_INFO
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
#endif
connect_attempt++;
if (connect_attempt >= MAX_CONNECT_ATTEMPTS) {
fprintf(stderr, "Exceeded maximum connect attempts. Exiting.\n");
#if HMI_INFO
fprintf(stderr, "Exceeded maximum connect attempts. Exiting.\n");
#endif
goto cleanup;
}
// Retry after a delay
usleep(500000);
continue;
}
else
{
connect_attempt = 0; // Reset connect attempt count on successful connection
conn_succ_flag = 1;
}
}
// 写多个寄存器
convertMachineInfoToArray(machineInfo, infoArray);
//pthread_mutex_lock(&mutex);
writeModbusRegisters(ctx, 0, infoArray, 29);
//pthread_mutex_unlock(&mutex);
//先使能按钮 enablebutton_present readCoilValues_before[1 1 0 0 0 0]
pthread_mutex_lock(&mutex);
convert_Enable_ButtonInfo_ToArray(buttoninfo, enablebutton_present); // 将接收的使能按钮json值转换为数组
handleEnableButton(ctx, enablebutton_present, readCoilValues_before);
memcpy(readCoilValues_before, enablebutton_present, sizeof(enablebutton_present));
pthread_mutex_unlock(&mutex);
//读取6个开关量的状态
int rc = modbus_read_bits(ctx, coiladdr, 6, readCoilValues_after);//复制一份才能做对比
if (rc == -1) {
//fprintf(stderr, "Failed to read coil values: %s\n", modbus_strerror(errno));
// 解锁
usleep(500000); // 等待一段时间再重试
continue;
#if HMI_INFO
hlogi("Failed to read coil values: %s", modbus_strerror(errno));
#endif
if(hmi_log)
{
hlogi("Failed to read coil values: %s", modbus_strerror(errno));
}
}
memcpy(enablebutton_person_save, readCoilValues_after, sizeof(readCoilValues_after));
usleep(1000);
}
goto cleanup;
cleanup:
// 清理资源
if (ctx) {
modbus_close(ctx);
modbus_free(ctx);
}
return NULL;
}