基于 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 (*
  • 12
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值