通过w(红色臂角度增大)s(红色臂角度减小)d(蓝色臂角度增大)a(蓝色臂角度减小)按键控制机械臂
注意:关闭计算机的杀毒软件,电脑管家,防火墙
1)基于TCP服务器的机械臂,端口号是8888, ip是Windows的ip;
查看Windows的IP:按住Windows+r 按键,输入cmd , 输入ipconfig
2)点击软件中的开启监听;
3)机械臂需要发送16进制数,共5个字节,协议如下
0xff 0x02 x y 0xff 0xff:起始结束协议,固定的; 0x02:控制机械手臂协议,固定的; x:指定要操作的机械臂 0x00 红色摆臂 0x01 蓝色摆臂 y:指定角度
#include <head.h>
#include <linux/input.h>
#define SER_PORT 8888 // 服务器端口号
#define SER_IP "192.168.118.58" // 服务器IP
#define CLI_PORT 9000 // 客户端端口号
#define CLI_IP "192.168.250.100" // 客户端IP
int main(int argc, const char *argv[])
{
// 1、创建用于连接的客户端套接字
int cfd = socket(AF_INET, SOCK_STREAM, 0);
if (cfd == -1)
{
perror("socket error");
return -1;
}
printf("socket success cfd = %d\n", cfd); // 3
// 设置端口号快速重用
int reuse = 1;
if (setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
{
perror("setsockopt error");
return -1;
}
printf("端口号快速重用成功\n");
// 2、绑定端口号和ip地址(非必须)
// 2.1 填充客户端地址信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(CLI_PORT);
cin.sin_addr.s_addr = inet_addr(CLI_IP);
/*2.2 绑定端口号和IP
if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
*/
// 3、连接服务器
// 3.1 填充要连接服务器的地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET; // 地址族
sin.sin_port = htons(SER_PORT); // 服务器端口号
sin.sin_addr.s_addr = inet_addr(SER_IP); // 服务器的IP地址
// 3.2 连接服务器
if (connect(cfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
{
perror("connect error");
return -1;
}
printf("连接成功!\n");
// 定义控制机械臂的容器
char buf_red[5] = {0xff, 0x02, 0x00, 0x00, 0xff}; // 红色臂容器
unsigned char buf_blue[5] = {0xff, 0x02, 0x01, 0x00, 0xff}; // 蓝色臂容器
// 将数据发送给服务器以初始化
send(cfd, buf_red, sizeof(buf_red), 0);
sleep(1);
send(cfd, buf_blue, sizeof(buf_blue), 0);
// 定义一个读取数据的结构体变量
struct input_event ie;
// 打开 /dev/input/event1文件
int fd = open("/dev/input/event1", O_RDONLY);
if (fd == -1)
{
perror("open error");
return -1;
}
// 4、收发数据
char ctrl = 0; // 用户输入的控制键
while (1)
{
// scanf("%c", &ctrl); //用户输入键
// getchar();
// 从文件中读取当前文件中的数据
// read(fd, &ie, sizeof(ie));
scanf("%c", &ctrl);
while (getchar() != '\n')
;
// 输出从键盘事件文件中读取的数据
// printf("ie.type = %d, ie.code = %d, ie.value = %d\n", ie.type, ie.code, ie.value);
// 对输入的字符进行多分支选择
switch (ctrl)
{
case 'w':
{
// 红色臂角度增大
buf_red[3] += 2;
if (buf_red[3] >= 90)
{
buf_red[3] = 90;
}
// 将数据发送给服务器
send(cfd, buf_red, sizeof(buf_red), 0);
}
break;
case 's':
{
// s键按下
buf_red[3] -= 2;
if (buf_red[3] <= -90)
buf_red[3] = -90;
// 将数据发送给服务器
send(cfd, buf_red, sizeof(buf_red), 0);
}
break;
case 'a':
{
// A键按下
buf_blue[3] += 2;
if (buf_blue[3] >= 180)
buf_blue[3] = 180;
// 将数据发送给服务器
send(cfd, buf_blue, sizeof(buf_blue), 0);
}
break;
case 'd':
{
// D键按下
buf_blue[3] -= 2;
if (buf_blue[3] <= 0)
buf_blue[3] = 0;
// 将数据发送给服务器
send(cfd, buf_blue, sizeof(buf_blue), 0);
}
break;
case 16:
goto END;
}
}
END:
// 5、关闭套接字
close(cfd);
return 0;
}
效果: