嵌入式学习:开发模拟红外测距仪

疫情期间由于条件限制,故不做硬件的具体实现,选择用vs模拟出一个红外测距传感器。
选择编写两个程序:workstation和sensor,前者代替信息收集与处理模块,后者模拟传感器模块负责收集反馈信息。采用的是UDP通信,sensor作为服务端,workstation做client。workstation会向sensor发送一个UDP数据包,即request,sensor则是被动工作。目前还处于中期工作,并没有完善的GUI界面。暂时成效如下:
sensor部分:

// Sensor_UDP.cpp: 定义控制台应用程序的入口点。


#include <winsock2.h>
#pragma comment (lib, "ws2_32.lib")  	// 使用WinSock2.2实现网络通信所需文件
#define _WINSOCK_DEPRECATED_NO_WARNINGS 
#include <time.h>
#include <stdio.h>
#include <math.h>
#include<time.h>

#define BUFF_SIZE 64

double generate();
char response[BUFF_SIZE];

int main()
{
	//创建接收与发送缓冲区
	char recvbuff[BUFF_SIZE];
	char sendbuff[BUFF_SIZE];

	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		printf("dll初始化失败");
	}

	//创建套接字
	SOCKET hServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (hServer == INVALID_SOCKET) {
		printf("socket failed \n");
		return 0;
	}
	//创建服务器端地址并绑定端口号的IP地址
	sockaddr_in addrServer;
	addrServer.sin_family = AF_INET;
	addrServer.sin_port = htons(8889);
	addrServer.sin_addr.S_un.S_addr = INADDR_ANY;
	int nRet = bind(hServer, (sockaddr*)&addrServer, sizeof(addrServer));
	if (nRet == SOCKET_ERROR) {
		printf("socket bind failed\n");
		closesocket(hServer);
		WSACleanup();
		return 0;
	}
	//接收客户端请求
	SOCKADDR clntAddr;  //客户端地址信息
	int nSize = sizeof(SOCKADDR);

	//等待接收初始化命令
	while (1) {
		int strLen = recvfrom(hServer, recvbuff, BUFF_SIZE, 0, &clntAddr, &nSize);			//接收指令,并储存数据长度
		recvbuff[strLen] = '\0';								//防止出现乱码

		if (recvbuff != 0)
		{
			sendto(hServer, "1", strlen("1"), 0, &clntAddr, nSize);
			break;
		}
	}
	memset(recvbuff, 0, BUFF_SIZE); //重置缓冲区

	while (1) {
		int strLen = recvfrom(hServer, recvbuff, BUFF_SIZE, 0, &clntAddr, &nSize);			//接收指令,并储存数据长度
		recvbuff[strLen] = '\0';								//防止出现乱码

		if (strcmp(recvbuff, "read_mode") == 0)
		{
			//判断指令
			double timing = generate();							//产生模拟数据
			printf("单次距离读取指令\n");
			sprintf_s(response, sizeof(response), "%.6f", timing);				//double 转 字符串
			sendto(hServer, response, strlen(response), 0, &clntAddr, nSize);
		}
		else if (strcmp(recvbuff, "close") == 0)
		{
			printf("断开连接指令\n");
			sendto(hServer, "服务器已关闭\0", strlen("服务器已关闭\0"), 0, &clntAddr, nSize);
			break;
		}
		else
		{
			printf("指令输入有误\n");
			sendto(hServer, "指令输入有误\0", strlen("指令输入有误\0"), 0, &clntAddr, nSize);
			printf("错误指令:%s\n", recvbuff);
		}
		memset(recvbuff, 0, BUFF_SIZE); //重置缓冲区
		memset(sendbuff, 0, BUFF_SIZE); //重置缓冲区
	}

	//关闭套接字
	closesocket(hServer);
	WSACleanup();
	return 0;
}

double generate()
{				//产生模拟数据
	srand((unsigned)time(NULL));
	double timing = (rand() % 1000) ;//生成时间单位为微秒
	return timing;
}


workstation部分:

#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib") 	// 使用WinSock2.2实现网络通信所需文件
#include<stdlib.h>
#include<windows.h>
#include<iostream>
#include<stdio.h>
#include<string>
#include <Ws2tcpip.h>


#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define BUFF_SIZE 64		// 缓冲区大小
#define STORAGE_SIZE 10		//历史记录上限
#define Cspeed 3.0e8
#define ACCURACY 3

const int BUFFER_SIZE = 1024;
char buffer[BUFFER_SIZE];			//show函数中所用

char recvbuff[BUFF_SIZE] = { 0 };
char sendbuff[BUFF_SIZE] = { 0 };   	// 创建接收与发送缓冲
double timing = 0.0;
double storage[STORAGE_SIZE] = { 0,0,0,0,0,0,0,0,0,0 };	      //储存历史数据
int J = -1;				//指向最新数据
int K = 0;				//指向回查数据

//函数声明
int sensorInit(SOCKET ConnectSocket, sockaddr_in servAddr, int accuracy);	//初始化	
double trans(double timing);					//把时间转换成距离并存储
double read_storage();					//阅读历史数据
void read_mode(SOCKET ConnectSocket);			//读取距离
void show(double storage[STORAGE_SIZE]);			//把历史数据转换成曲线

sockaddr serSockAddr;					//不断获取输入并发送到服务器,接收服务器数据
int addrLen = sizeof(serSockAddr);

int main()
{
	// WSADATA结构体主要包含了系统所支持的winsock版本
	WSADATA wsaData;

	// 初始化winsock 2.2
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		printf("WSAStartup 无法初始化! ");
		return 0;
	}
	//创建连接到服务器的SOCKET对象
	SOCKET sClient;
	sClient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (SOCKET_ERROR == sClient) {
		printf("socket failed !\n");
		return 0;
	}

	//创建服务器端地址
	sockaddr_in serverAddr;
	//创建服务器端地址
	sockaddr_in clientAddr;
	//设置服务器端地址,端口号,协议族
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(8889);
	serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");


	// 传感器初始化
	int init_zet = sensorInit(sClient, serverAddr, ACCURACY);

	//char strC1[30] = "单次距离读取",strC2[30] = "读取历史数据",strC3[30] = "清除历史数据";
	printf("提示: \n read_mode:单次距离读取\n read_storage:读取历史数据\n clear_storage:清空历史数据\nclose:关闭服务端\n");

	while (1) {
		if (init_zet == 1)
		{
			printf("Input a command:");	//输入命令
			scanf_s("%s", sendbuff, BUFF_SIZE);
			if (strcmp(sendbuff, "read_storage") == 0)
			{
				printf("历史记录: %f\n", read_storage());	//读取历史记录
			}
			else if (strcmp(sendbuff, "clear_storage") == 0)
			{
				memset(storage, 0, STORAGE_SIZE);
			}
			else {
				sendto(sClient, sendbuff, strlen(sendbuff), 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));	//发送数据
			}
			if (strcmp(sendbuff, "read_mode") == 0)
			{
				read_mode(sClient);
			}
			if (strcmp(sendbuff, "close") == 0)
			{
				printf("服务端已关闭\n");
			}
			memset(recvbuff, 0, BUFF_SIZE);
			memset(sendbuff, 0, BUFF_SIZE);	//重置缓冲区
		}
		else
		{
			printf("传感器初始化失败\n");
			Sleep(10000);
			break;
		}
	}
	closesocket(sClient);
	WSACleanup();  	// 释放资源
	// 清除工作
	if (WSACleanup() == SOCKET_ERROR)
		printf("WSACleanup 出错! ");
	printf("\n\n");
	system("pause");
	return 0;
}

int sensorInit(SOCKET ConnectSocket, sockaddr_in servAddr, int accuracy)
//初始化:成功返回1,不成功返回0  
{
	int i = 0;
	sprintf_s(sendbuff, sizeof(sendbuff), "%d", accuracy);

	while (strcmp(recvbuff, "1") != 0)
	{
		sendto(ConnectSocket, sendbuff, strlen(sendbuff), 0, (struct sockaddr*)&servAddr, sizeof(servAddr));
		//发送初始化信息,并建立连接
		recvfrom(ConnectSocket, recvbuff, BUFF_SIZE, 0, &serSockAddr, &addrLen);													//接收初始化结果信息
		Sleep(1);			//延时1ms
		i++;
	}
	if (i > 10)           //等待10ms以上
	{
		return 0;      //初始化失败
	}
	else return 1;             //初始化成功
}

double read_storage()
{
	char recvdata[BUFF_SIZE];
	printf("回看记录数(范围:0-9):");
	scanf_s("%s", recvdata, sizeof(recvdata));
	K = (J - strtol(recvdata, NULL, 10) + STORAGE_SIZE) % STORAGE_SIZE;
	//求回看数
	return storage[K];
}


double trans(double timing)
{
	double distance = 0;
	distance = timing * Cspeed / 2;
	J = (J + 1) % STORAGE_SIZE;
	storage[J] = distance;
	printf("Message from server:%f\n", distance);
	return 0;
}

void read_mode(SOCKET ConnectSocket)
{
	recvfrom(ConnectSocket, recvbuff, BUFF_SIZE, 0, &serSockAddr, &addrLen);
	//接收数据
	timing = strtod(recvbuff, NULL)/1000000;
	//把字符型数据转换成整形
	trans(timing);	//转换并存储
}


测试如下
测试如下
还有show函数没有实现(展示函数图像)以及GUI未能做完,敬请期待。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值