关于modbus与HMI车载侧屏通信的错误机制处理

目录

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值