基于 Modbus 的工业数据采集、控制(part 3)

Modbus 设备(利用 slave 模拟)

在这里插入图片描述

在这里插入图片描述

Modbus 采集程序

client.c

#include "client.h"

modbus_t *ctx;
key_t key_shm, key_msg;
int shmid, msgid;
struct shm *shm0;
struct msgbuf msg0;

void *collector(void *arg) {
   

    struct shm *p = (struct shm *)arg;
    while (1){
   
        sleep(1);
        if (modbus_read_registers(ctx, 0, 4, p->buf) < 0) {
   
            perror("Failed to modbus_read_registers");
            return NULL;
        }

        printf("LIGHT SENSOR: %d\n", p->buf[0]);
        printf("ACCELERATION SENSOR-X: %d\n", p->buf[1]);
        printf("ACCELERATION SENSOR-Y: %d\n", p->buf[2]);
        printf("ACCELERATION SENSOR-Z: %d\n\n", p->buf[3]);
    }
    pthread_exit(0);
}

void *control(void *arg) {
   

    while (1){
   
        msgrcv(msgid, &msg0, sizeof(msg0)-sizeof(long), 250, 0);
        printf("LED: %c\n", msg0.ctl[0]);
        printf("BUZZER: %c\n\n", msg0.ctl[1]);
        modbus_write_bit(ctx, msg0.ctl[0]-48, msg0.ctl[1]-48);
    }
    pthread_exit(0);
}

int main(int argc, char const *argv[])
{
      
    if (argc != 3) {
   
        printf("Please input %s <ip> <port>. \n", argv[0]);
        return -1;
    }

    init_modbus(&ctx, argv[1], atoi(argv[2]));

    shm0 = init_shared_memory(&key_shm, &shmid);
    printf("The key(shm): %#x\n", key_shm);
    printf("The shmid: %d\n", shmid);

    init_msg_queue(&key_msg, &msgid);
    msg0.mtype = 250;
    printf("The key(msg): %#x\n", key_msg);
    printf("The msgid: %d\n", msgid);

    pthread_t tid1, tid2;

    if (pthread_create(&tid1, NULL, collector, shm0)) {
   
        perror("Failed to create a thread named collector");
        return -1;
    }

    if (pthread_create(&tid2, NULL, control, msg0.ctl)) {
   
        perror("Failed to create a thread named input");
        return -1;
    }

    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    // shmdt(p);
    // shmctl(shmid, IPC_RMID, NULL);
    // msgctl(msgid, IPC_RMID, NULL);
    modbus_close(ctx);
    modbus_free(ctx);
    return 0;
}

client.h

#ifndef __CLIENT_H_
#define __CLIENT_H_

#include <stdio.h>
#include <modbus.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/msg.h>

#define SHM_SIZE 64

struct shm {
   
    uint16_t buf[4];
    // int flag;
};

struct msgbuf {
   
    long mtype;    		/* message type, must be > 0 */
    uint8_t ctl[2]; 	/* message data */
};

int init_modbus(modbus_t **, const char *, int);
struct shm *init_shared_memory(key_t *, int *);
int init_msg_queue(key_t *, int *);

#endif

func.c

#include "client.h"

int init_modbus(modbus_t **ctx, const char *ip, int port) {
   

    *ctx = modbus_new_tcp(ip, port);
    if (*ctx == NULL) {
   
        perror("Failed to modbus_new_tcp");
        return -1;
    }

    if (modbus_set_slave(*ctx, 1) < 0) {
   
        perror("Failed to modbus_set_slave");
        return -2;
    }

    if (modbus_connect(*ctx) < 0) {
   
        perror("Failed to modbus_connect");
        return -3;
    }

    return 0;
}

struct shm *init_shared_memory(key_t *key, int *shmid) {
   
    
    *key = ftok("./client.c", 'v');        // ftok(任意文件名/路径名, 任意字符);
    if (key < 0) {
   
        perror("Failed to ftok");
        return NULL;
    }

    *shmid = shmget(*key, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666);
    if (*shmid < 0) {
   
        if (errno == EEXIST)
            *shmid = shmget(*key, SHM_SIZE, 0666);
        else {
   
            perror("Failed to shmget");
            return NULL;
        }
    }

    struct shm *p = shmat(*shmid, NULL, 0);     // 0 表示可读可写, 若只读则 SHM_RDONLY
    if (p == (void *)-1) {
   				   		// if (*p == -1) 也可以
        perror("Failed to shmat");
        return NULL;
    }

    return p;
}

int init_msg_queue(key_t *key, int *msgid) {
   

    *key = ftok("./client.h", 'v');
    if (*key < 0){
   
        perror("Failed to ftok");
        return -4;
    }

    *msgid = msgget(*key, IPC_CREAT | IPC_EXCL | 0666);
    if (

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/179883.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

目前比较好用的护眼台灯?央视公认好用的五款护眼台灯推荐

据国家卫健委最新数据&#xff0c;2020年我国儿童青少年总体近视率是52.7&#xff05;&#xff0c;幼儿园&#xff08;数据仅覆盖大班&#xff09;近视率达14.3&#xff05;&#xff0c;小学阶段35.6&#xff05;&#xff0c;初中阶段71.1&#xff05;&#xff0c;而高中阶段达…

运维 在Windows上搭建小型Git服务

文章目录 1、Git选型1.1、主要特性1.2、代码管理1.3、工单管理1.4、Pull/Merge requests1.5、第三方集成1.6、选型结论 2、环境搭建2.1、Gitea下载2.2、Gitea安装2.3、配置服务信息2.4、运行服务2.5、注册Gitea为服务2.6、正常使用 1、Git选型 1.1、主要特性 1.2、代码管理 1.…

创建vue项目体验

文章目录 使用vue-cli创建vue项目创建出的项目目录结构配置router 运行问题router未找到eslint报错 首页显示单页面内容替换 使用vue-cli创建vue项目 安装vue-cli&#xff0c;创建基本项目 选择步骤 一般创建成功后&#xff0c;提示使用下面的指令运行demo npm run serve创建…

发挥云计算潜力:Amazon Lightsail 与 Amazon EC2 的综述

文章作者&#xff1a;Libai 欢迎来到云计算世界&#xff0c;这里有无数的机会和无限的应用程序增长。 在当今的数字时代&#xff0c;企业可能会发现管理基础架构和扩展应用程序具有挑战性。 传统的本地解决方案需要大量的硬件、软件和维护前期投资。 要满足不断增长的需求&…

Vatee万腾数字引领未来:vatee科技力量的独特路径

在当今数字化浪潮的推动下&#xff0c;Vatee万腾以其卓越的科技力量&#xff0c;正引领着未来的数字化时代&#xff0c;描绘着一条独特的发展路径。通过持续创新、前瞻思维和对技术的深度理解&#xff0c;Vatee万腾正在为未来的科技发展创造新的可能性&#xff0c;塑造着数字引…

节能灯和led灯哪个更护眼?精选高品质的LED护眼台灯

节能灯和LED灯相比&#xff0c;我认为LED灯会更加护眼一些&#xff0c;不过想要更护眼建议选择LED的护眼台灯会更好&#xff01; 大家都知道光亮对于我们来说是非常重要的&#xff0c;尤其是夜晚的时候&#xff0c;往往要借助一些灯具来提供充足的照明。对于孩子而言&#xff0…

小型洗衣机哪个牌子好用又耐用?最好用的迷你洗衣机

随着大家工作的压力越来越大&#xff0c;下了班之后只能想躺平&#xff0c;在洗完澡之后看着还需要手洗的内衣裤真的很头疼。有些小伙伴还有会攒几天再丢进去洗衣机里面一起&#xff0c;而且这样子是非常不好的&#xff0c;用过的内衣裤长时间不清洗容易滋生细菌&#xff0c;而…

qq录屏怎么只录电脑声音?我来告诉你答案

录制屏幕已成为人们日常生活中经常需要使用的功能&#xff0c;尤其是录制电脑声音。qq作为国内最受欢迎的社交软件之一&#xff0c;其内置的录屏功能十分便捷&#xff0c;可以满足用户的基本需求。可是您知道qq录屏怎么只录电脑声音吗&#xff1f;在本文中&#xff0c;我们将详…

深入理解JMM以及并发三大特性(1)

文章目录 1. 并发与并行2. JMM3. 并发三大特性4.总结 1. 并发与并行 并行&#xff1a;指在同一时刻&#xff0c;有多条指令在多个处理器上同时执行。所以无论从微观还是宏观来看&#xff0c;二者都是一起执行的。 并发&#xff1a;指在同一时刻只能有一个指令执行&#xff0c;…

2023年【道路运输企业安全生产管理人员】模拟试题及道路运输企业安全生产管理人员作业考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年道路运输企业安全生产管理人员模拟试题为正在备考道路运输企业安全生产管理人员操作证的学员准备的理论考试专题&#xff0c;每个月更新的道路运输企业安全生产管理人员作业考试题库祝您顺利通过道路运输企业安…

FreeRTOS源码阅读笔记5--mutex

互斥量是一种特殊的二值信号量&#xff0c;拥有优先级继承的机制&#xff0c;所以适合用在临界资源互斥访问。 5.1创建互斥量xSemaphoreCreateMutex() 5.1.1函数原型 5.1.2函数框架 5.2创建递归互斥量xSemaphoreCreateRecursiveMutex() 5.2.1函数原型 5.2.2函数框架 xSemaph…

金融众筹模式系统源码 适合创业孵化机构+天使投资机构+投资基金会等 附带完整的搭建教程

随着互联网技术的发展和金融市场的开放&#xff0c;金融众筹模式逐渐成为一种新型的融资方式。这种模式通过互联网平台聚集大量投资者&#xff0c;共同参与到一个项目中&#xff0c;为项目提供资金支持&#xff0c;最终获得投资回报。今天罗峰给大家分享一款金融众筹模式系统源…

app小程序开发的重点在哪里?|企业软件定制网站建设

app小程序开发的重点在哪里&#xff1f;|企业软件定制网站建设 App小程序定制开发是近年来快速发展的一项技术服务&#xff0c;随着移动互联网的普及和用户需求的不断升级&#xff0c;越来越多的企业和个人开始关注和需求定制化的小程序开发。那么&#xff0c;对于app小程序定制…

OAuth2认证请求头中的authorization从哪里来的

Oauth2的登录接口oauth/token, 在请求头里有个 authorization: Basic dGVzdENsaWVudElkOnRlc3RDbGllbnRTZWNyZXQ 其中 dGVzdENsaWVudElkOnRlc3RDbGllbnRTZWNyZXQ 是 client-id:client-secret 的base64的编码 例如项目中的配置是(这个东西一般在网关里配置的): security:oau…

搜维尔科技:Faceware面部捕捉最佳实践!

视频源和分辨率&#xff1a; 我们的软件针对 RGB 彩色素材进行了优化&#xff0c;不支持使用红外摄像机。 我们建议视频分辨率为 720p 和 1080p。低于 720p 的分辨率可能会对跟踪质量产生负面影响&#xff0c;而高于 1080p 的分辨率会导致存储要求和传输时间增加&#xff0c;而…

程序员最奔溃的瞬间

身为程序员哪一个瞬间让你最奔溃&#xff1f; *程序员最奔溃的瞬间&#xff0c; 勇士&#xff1f; or 无知&#xff1f;

经典百搭女童加绒卫衣,看的见的时尚

经典版型套头卫衣 宽松百搭不挑人穿 单穿内搭都可以 胸口处有精美的小熊印花 面料是复合柔软奥利绒 暖和又不显臃肿哦&#xff01;&#xff01;

提升编程效率:软件工程师必备的10个Git命令

本文翻译自 10 Must-Know Git Commands for Software Engineers&#xff0c;作者&#xff1a; Rabi Siddique&#xff0c; 略有删改。 Git和GitHub是每个软件工程师必须知道的最基本的东西。这些工具是开发人员日常工作的组成部分&#xff0c;因为我们每天都与它们互动。熟练掌…

【excel技巧】excel表格如何转换为word

Excel表格想要转换到word文档中&#xff0c;直接粘贴复制的话&#xff0c;可能会导致表格格式错乱&#xff0c;那么如何转换才能够保证表格不错乱&#xff1f;今天分享两个方法&#xff0c;excel表格转换到word文件。 方法一&#xff1a; 首先打开excel表格&#xff0c;将表格…

Leetcode—1410.HTML实体解析器【中等】

2023每日刷题&#xff08;三十八&#xff09; Leetcode—1410.HTML实体解析器 算法思想 实现代码 typedef struct entityChar {char* entity;char rechar; }entity;entity matches[] {{"&quot;", "},{"&apos;", \},{"&amp;"…