linux-安防监控实现之传感器真实数据上传到网页

首先将fsadc、fsbeeper、fsled、fsmpu6050驱动移植安装到a9,保证a9可以正常采集数据,

传感器数据交互用到的两个线程文件如下:

pthread_refresh.c


#include "data_global.h"
#include "common.h"
#include "mpu6050.h"
#include 

//接收ZigBee的数据和采集的A9平台的传感器数据
int adc_fd;
int mpu_fd;

extern pthread_cond_t cond_transfer;
extern pthread_mutex_t mutex_transfer;
extern struct env_info_client_addr  sm_all_env_info;

int file_env_info_a9_zigbee_debug(struct env_info_client_addr* rt_status, int home_id);
int file_env_info_a9_zigbee_stm32(struct env_info_client_addr* rt_status, int home_id);

int printf_sensor_info_debug(struct env_info_client_addr* sm_all_env_info, int home_id);
//读取adc、mpu数据
void* pthread_transfer(void* arg)
{
	int home_id = 1;
	adc_fd = open(ADC_DEV, O_RDWR);//打开adc驱动设备
	mpu_fd = open(MPU6050_DEV, O_RDWR);//打开mpu驱动设备
	if ((adc_fd == -1) || (mpu_fd == -1))
	{
		printf("open adc or mpu device failed.\n");
	}
	while (1)
	{
		pthread_mutex_lock(&mutex_transfer);//增加线程锁
		pthread_cond_wait(&cond_transfer, &mutex_transfer);//等待条件变量变化,结束休眠,条件变量在书信数据线程
		printf("pthread_analysis and tranfer.\n");
#if 1
		file_env_info_a9_zigbee_stm32(&sm_all_env_info, home_id);//发生数据变化会对数据进行填充刷新,
#else	
		file_env_info_a9_zigbee_debug(&sm_all_env_info, home_id);
#endif
		pthread_mutex_unlock(&mutex_transfer);//解锁
		sleep(1);
	}
	close(adc_fd);
	close(mpu_fd);
}




int file_env_info_a9_zigbee_debug(struct env_info_client_addr* rt_status, int home_id)
{
	static int temp = 0;
	int  env_info_size = sizeof(struct env_info_client_addr);
	//	printf("env_info_size = %d.\n",env_info_size);

	rt_status->monitor_no[home_id].zigbee_info.temperature = 10.0;
	rt_status->monitor_no[home_id].zigbee_info.tempMIN = 2.0;
	rt_status->monitor_no[home_id].zigbee_info.tempMAX = 20.0;
	rt_status->monitor_no[home_id].zigbee_info.humidity = 20.0;
	rt_status->monitor_no[home_id].zigbee_info.humidityMIN = 10.0;
	rt_status->monitor_no[home_id].zigbee_info.humidityMAX = 30.0;
	rt_status->monitor_no[home_id].zigbee_info.reserved[0] = 0.01;
	rt_status->monitor_no[home_id].zigbee_info.reserved[1] = -0.01;

	temp++;
	rt_status->monitor_no[home_id].a9_info.adc = temp;
	rt_status->monitor_no[home_id].a9_info.gyrox = -14.0;
	rt_status->monitor_no[home_id].a9_info.gyroy = 20.0;
	rt_status->monitor_no[home_id].a9_info.gyroz = 40.0;
	rt_status->monitor_no[home_id].a9_info.aacx = 642.0;
	rt_status->monitor_no[home_id].a9_info.aacy = -34.0;
	rt_status->monitor_no[home_id].a9_info.aacz = 5002.0;
	rt_status->monitor_no[home_id].a9_info.reserved[0] = 0.01;
	rt_status->monitor_no[home_id].a9_info.reserved[1] = -0.01;

	printf_sensor_info_debug(rt_status, home_id);

	//添加stm32部分的数据、arduino数据,

	return 0;
}


#if 0
int	get_sensor_data_from_a9(struct makeru_a9_info* a9_sensor_data)
{
	int adc_sensor_data;
	struct mpu6050_data data;

	/*get adc sensor data*/
	read(adc_fd, &adc_sensor_data, 4);
	printf("adc value :%0.2fV.\n", (1.8 * adc_sensor_data) / 4096);

	/* get mpu6050 sensor data*/
	ioctl(mpu_fd, MPU6050_GYRO, &data);
	printf("gyro data: x = %05d, y = %05d, z = %05d\n", data.gyro.x, data.gyro.y, data.gyro.z);
	ioctl(mpu_fd, MPU6050_ACCEL, &data);
	printf("accel data: x = %05d, y = %05d, z = %05d\n", data.accel.x, data.accel.y, data.accel.z);

	/*预填充,有点浪费空间,大家可以优化一下*/
	a9_sensor_data->adc = (1.8 * adc_sensor_data) / 4096 * 100; //定义未int32,应该是float,放大100倍,保护小数位
	a9_sensor_data->gyrox = data.gyro.x;
	a9_sensor_data->gyroy = data.gyro.y;
	a9_sensor_data->gyroz = data.gyro.z;
	a9_sensor_data->aacx = data.accel.x;
	a9_sensor_data->aacy = data.accel.y;
	a9_sensor_data->aacz = data.accel.z;

	return 0;
}
#endif 

//读adc、mpu数据,将数据存到rt_status结构体中
int file_env_info_a9_zigbee_stm32(struct env_info_client_addr* rt_status, int home_id)
{
	int  env_info_size = sizeof(struct env_info_client_addr);
	printf("env_info_size = %d.\n", env_info_size);

	rt_status->monitor_no[home_id].zigbee_info.head[0] = 'm';
	rt_status->monitor_no[home_id].zigbee_info.head[1] = 's';
	rt_status->monitor_no[home_id].zigbee_info.head[2] = 'm';
	rt_status->monitor_no[home_id].zigbee_info.head[3] = 'z';
	rt_status->monitor_no[home_id].zigbee_info.temperature = 10.0;
	rt_status->monitor_no[home_id].zigbee_info.tempMIN = 2.0;
	rt_status->monitor_no[home_id].zigbee_info.tempMAX = 20.0;
	rt_status->monitor_no[home_id].zigbee_info.humidity = 20.0;
	rt_status->monitor_no[home_id].zigbee_info.humidityMIN = 10.0;
	rt_status->monitor_no[home_id].zigbee_info.humidityMAX = 30.0;
	rt_status->monitor_no[home_id].zigbee_info.reserved[0] = 0.01;
	rt_status->monitor_no[home_id].zigbee_info.reserved[1] = -0.01;

	//获取数据     
	int adc_sensor_data;
	struct mpu6050_data data;
	/*get adc sensor data*/
	read(adc_fd, &adc_sensor_data, 4); /*遗留问题解决:忘记加载驱动了,同志们要注意了......*/
	printf("adc value :%0.2fV.\n", (1.8 * adc_sensor_data) / 4096);
	rt_status->monitor_no[home_id].a9_info.adc = (float)((1.8 * adc_sensor_data) / 4096);

	/* get mpu6050 sensor data*/
	ioctl(mpu_fd, MPU6050_GYRO, &data);
	printf("gyro data: x = %d, y = %d, z = %d\n", data.gyro.x, data.gyro.y, data.gyro.z);
	ioctl(mpu_fd, MPU6050_ACCEL, &data);
	printf("accel data: x = %d, y = %d, z = %d\n", data.accel.x, data.accel.y, data.accel.z);

	rt_status->monitor_no[home_id].a9_info.head[0] = 'm';
	rt_status->monitor_no[home_id].a9_info.head[1] = 's';
	rt_status->monitor_no[home_id].a9_info.head[2] = 'm';
	rt_status->monitor_no[home_id].a9_info.head[3] = 'a';

	rt_status->monitor_no[home_id].a9_info.gyrox = (short)data.gyro.x;
	rt_status->monitor_no[home_id].a9_info.gyroy = (short)data.gyro.y;
	rt_status->monitor_no[home_id].a9_info.gyroz = (short)data.gyro.z;

	rt_status->monitor_no[home_id].a9_info.aacx = (short)data.accel.x;
	rt_status->monitor_no[home_id].a9_info.aacy = (short)data.accel.y;
	rt_status->monitor_no[home_id].a9_info.aacz = (short)data.accel.z;
	rt_status->monitor_no[home_id].a9_info.reserved[0] = 0.01;
	rt_status->monitor_no[home_id].a9_info.reserved[1] = -0.01;

	printf_sensor_info_debug(rt_status, home_id);

	//添加stm32部分的数据、arduino数据,

	return 0;
}


int printf_sensor_info_debug(struct env_info_client_addr* sm_all_env_info, int home_id)
{
	printf("a9_info.adc  : %f.\n", sm_all_env_info->monitor_no[home_id].a9_info.adc);
	printf("a9_info.gyrox: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.gyrox);
	printf("a9_info.gyroy: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.gyroy);
	printf("a9_info.gyroz: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.gyroz);
	printf("a9_info.aacx : %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.aacx);
	printf("a9_info.aacy : %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.aacy);
	printf("a9_info.aacz : %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.aacz);
	printf("a9_info.reserved[0]: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.reserved[0]);
	printf("a9_info.reserved[1]: %d.\n", sm_all_env_info->monitor_no[home_id].a9_info.reserved[1]);

	return 0;
}

pthread_refresh.c

#include "data_global.h"
#include "sem.h"

#define N 1024  //for share memory

extern int shmid;
extern int msgid;
extern int semid;

extern key_t shm_key;
extern key_t sem_key;
extern key_t key; //msg_key

extern pthread_mutex_t mutex_client_request,
mutex_refresh,
mutex_sqlite,
mutex_transfer,
mutex_analysis,
mutex_sms,
mutex_buzzer,
mutex_led,
mutex_camera;

extern pthread_cond_t  cond_client_request,
cond_refresh,
cond_sqlite,
cond_transfer,
cond_analysis,
cond_sms,
cond_buzzer,
cond_led,
cond_camera;


extern struct env_info_client_addr  sm_all_env_info;

struct shm_addr
{
	char shm_status;   //shm_status可以等于home_id,用来区分共享内存数据
	struct env_info_client_addr  sm_all_env_info;
};
struct shm_addr* shm_buf;

int file_env_info_struct(struct env_info_client_addr* rt_status, int home_id);//模拟数据刷新的函数

void* pthread_refresh(void* arg)
{
	//semaphore for access to resource limitsftok 访问资源限制的信号量sftok 函数用于将给定的文件路径名和一个整数标识符转换为一个唯一的 key 值,用于标识 System V IPC(进程间通信)的资源,如消息队列、信号量和共享内存等
	if ((sem_key = ftok("/tmp", 'i')) < 0)
	{
		perror("ftok failed .\n");
		exit(-1);
	}
	//semget 函数用于创建或访问一个 System V 信号量集。信号量是一种用于多进程(或多线程)之间进行同步和互斥的机制,用于控制对共享资源的访问。
	semid = semget(sem_key, 1, IPC_CREAT | IPC_EXCL | 0666);
	if (semid == -1)
	{
		if (errno == EEXIST)
		{
			semid = semget(sem_key, 1, 0777);
		}
		else
		{
			perror("fail to semget");
			exit(1);
		}
	}
	else
	{
		init_sem(semid, 0, 1);
	}

	//share memory for env_info refresh config env_info刷新配置的共享内存
	if ((shm_key = ftok("/tmp", 'i')) < 0)
	{
		perror("ftok failed .\n");
		exit(-1);
	}

	shmid = shmget(shm_key, N, IPC_CREAT | IPC_EXCL | 0666);
	if (shmid == -1)
	{
		if (errno == EEXIST)
		{
			shmid = shmget(key, N, 0777);
		}
		else
		{
			perror("fail to shmget");
			exit(1);
		}
	}

	//share memap shmat 函数用于将共享内存段附加到调用进程的地址空间,使进程可以访问和操作共享内存中的数据
	if ((shm_buf = (struct shm_addr*)shmat(shmid, NULL, 0)) == (void*)-1)
	{
		perror("fail to shmat");
		exit(1);
	}
	printf("pthread_refresh ......>>>>>>>\n");
	bzero(shm_buf, sizeof(struct shm_addr));
	while (1)
	{
		sem_p(semid, 0); //P操作sem_p 函数一般用于实现信号量的 P(wait)操作,用于对信号量进行减操作。它用于控制对共享资源的访问以实现进程间的同步与互斥。
		shm_buf->shm_status = 1;
		int home_id = 1;
#if 1
		shm_buf->sm_all_env_info.monitor_no[home_id] = sm_all_env_info.monitor_no[home_id];  //真实数据上传
#else
		file_env_info_struct(&shm_buf->sm_all_env_info, shm_buf->shm_status); //模拟数据上传
#endif 
		sleep(1);
		sem_v(semid, 0); //v操作sem_v函数是POSIX标准中用于信号量操作的函数之一。该函数的作用是对指定的信号量进行V操作。具体而言,sem_v函数会将信号量的值加1,并且如果有进程或线程正在等待该信号量,则唤醒其中的一个。V操作是一种原子操作,也就是说,它是以原子方式进行的,不会被中断。通过调用sem_v函数,可以实现对信号量进行加锁或解锁的操作,用于保护共享资源的访问。
		pthread_cond_signal(&cond_transfer);//唤醒pthread_transfer线程,继续刷新数据
	}


}



int file_env_info_struct(struct env_info_client_addr* rt_status, int home_id)
{
	int  env_info_size = sizeof(struct env_info_client_addr);
	//	printf("env_info_size = %d.\n",env_info_size);

	rt_status->monitor_no[home_id].zigbee_info.temperature = 10.0;
	rt_status->monitor_no[home_id].zigbee_info.tempMIN = 2.0;
	rt_status->monitor_no[home_id].zigbee_info.tempMAX = 20.0;
	rt_status->monitor_no[home_id].zigbee_info.humidity = 20.0;
	rt_status->monitor_no[home_id].zigbee_info.humidityMIN = 10.0;
	rt_status->monitor_no[home_id].zigbee_info.humidityMAX = 30.0;
	rt_status->monitor_no[home_id].zigbee_info.reserved[0] = 0.01;
	rt_status->monitor_no[home_id].zigbee_info.reserved[1] = -0.01;


	rt_status->monitor_no[home_id].a9_info.adc = 9.0;
	rt_status->monitor_no[home_id].a9_info.gyrox = -14.0;
	rt_status->monitor_no[home_id].a9_info.gyroy = 20.0;
	rt_status->monitor_no[home_id].a9_info.gyroz = 40.0;
	rt_status->monitor_no[home_id].a9_info.aacx = 642.0;
	rt_status->monitor_no[home_id].a9_info.aacy = -34.0;
	rt_status->monitor_no[home_id].a9_info.aacz = 5002.0;
	rt_status->monitor_no[home_id].a9_info.reserved[0] = 0.01;
	rt_status->monitor_no[home_id].a9_info.reserved[1] = -0.01;

	//添加stm32部分的数据、arduino数据,

	return 0;
}







你可能感兴趣的:(linux,安防监控,linux,运维,安防监控项目)