基于DragonBoard 410c的遥控炮台四之远程交互(中)

一.背景

上篇博客,博主给大家阐述了如何基于socket实现android手机与linux系统(DragonBoard 410c)之间通讯的功能,本文继续在此基础上整合linux端对舵机的控制逻辑。

二.舵机控制

1.舵机控制原理:在《http://blog.csdn.net/ad3600/article/details/59491854》这篇博客我们介绍了如何实现DragonBoard 410c 对舵机的信号控制。在export出我们所选的PWM0通道(pca9685最高支持16路并发控制)后,我们对舵机的转角控制信号实质就是对PWM信号的脉宽进行调节,其调节的指令为:

sudo echo n > /sys/class/pwm/pwmchip0/pwm0/duty_cycle /*其中n的单位为ns(纳秒)*/

        我们可能通过改变n的值来实现对舵机的角度控制,而我们知道,舵机的转角y从0到180度之间的变化对应的PWM脉宽周期为0.5ms~2.5ms,即n的取值范围为[500000,2500000],如下:


图1 舵机转角与PWM脉宽的关系

三.linux服务器

1.核心的控制:

弄明白舵机的控制信号后,我们的控制函数编写就呼之欲出了:

#define DRIVER_PERIOD "/sys/class/pwm/pwmchip0/pwm0/period"
#define DRIVER_CYCLIE "/sys/class/pwm/pwmchip0/pwm0/duty_cycle"
void open_stree()/**舵机的周期设置**/
{
   char* driver_period="/sys/class/pwm/pwmchip0/pwm0/period";
   char BUFF[128]={0};
   int period=20000000;//set the freq to 20ms(50Hz)s
   sprintf(BUFF,"sudo echo %d > %s",period,driver_period);
   system(BUFF);
  
}
int set_dutycycle(int cycle)/**舵机的脉宽设置,即转角控制信号设置**/
{
   char BUFF[128]={0};
   char* driver_cycle="/sys/class/pwm/pwmchip0/pwm0/duty_cycle";
   sprintf(BUFF,"sudo echo %d > %s",cycle,driver_cycle);
   system(BUFF);
}


2.linux服务端总的控制代码:

#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          #include 
         
           #include 
          
            #include 
           
             #include 
            
              #include 
             
               #include 
              
                #define PORT 8888 //服务器端监听端口号 #define MAX_BUFFER 1024 //数据缓冲区最大值 #define left_flag "LEFT" #define right_flag "RIGHT" #define STEP 50000 #define DRIVER_PERIOD "/sys/class/pwm/pwmchip0/pwm0/period" #define DRIVER_CYCLIE "/sys/class/pwm/pwmchip0/pwm0/duty_cycle" void open_stree() { char* driver_period="/sys/class/pwm/pwmchip0/pwm0/period"; char BUFF[128]={0}; int period=20000000;//set the freq to 20ms(50Hz)s sprintf(BUFF,"sudo echo %d > %s",period,driver_period); system(BUFF); } int set_dutycycle(int cycle) { char BUFF[128]={0}; char* driver_cycle="/sys/class/pwm/pwmchip0/pwm0/duty_cycle"; sprintf(BUFF,"sudo echo %d > %s",cycle,driver_cycle); system(BUFF); } int main() { struct sockaddr_in server_addr, client_addr; int server_sockfd, client_sockfd; int size, write_size; char buffer[MAX_BUFFER]; char *buffer_report="Succee"; int cycle=1500000; open_stree(); set_dutycycle(cycle); //init mid station if ((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) //创建Socket { perror("Socket Created Failed!\n"); exit(1); } printf("Socket Create Success!\n"); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(PORT); bzero(&(server_addr.sin_zero), 8); int opt = 1; int res = setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //设置地址复用 if (res < 0) { perror("Server reuse address failed!\n"); exit(1); } if (bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) //绑定本地地址 { perror("Socket Bind Failed!\n"); exit(1); } printf("Socket Bind Success!\n"); if (listen(server_sockfd, 5) == -1) //监听 { perror("Listened Failed!\n"); exit(1); } printf("Listening ....\n"); socklen_t len = sizeof(client_addr); printf("waiting connection...\n"); if ((client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &len)) == -1) //等待客户端连接 { perror("Accepted Failed!\n"); exit(1); } printf("connection established!\n"); printf("waiting message...\n"); while (1) { memset(buffer, 0, sizeof(buffer)); //清空数据缓冲区 if ((size = read(client_sockfd, buffer, MAX_BUFFER)) == -1) //读取客户端的数据 { perror("Recv Failed!\n"); exit(1); } printf("1111 Recv msg from client: %s\n", buffer); if (size != 0) { // printf("Recv msg from client: %s\n", buffer); if((strcmp(buffer,left_flag))==0) { if(cycle>500000) { cycle=cycle-STEP; // printf("Recv msg is left turn\n"); set_dutycycle(cycle); } else { printf("it is left side\n"); } } else if((strcmp(buffer,right_flag))==0) { if(cycle<2500000) { cycle=cycle+STEP; // printf("Recv msg is right turn\n"); set_dutycycle(cycle); } else { printf("it is right side\n"); } } else { printf("Recv msg from client: %s,why not?\n", buffer); } // buffer[6] = '\0'; if ((write_size = write(client_sockfd, buffer_report,6)) > 0) //把收到的数据回发给客户端 { ("Sent msg to client successfully!\n"); } } } close(client_sockfd); //关闭Socket close(server_sockfd); return 0; } 
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

四.实测效果:


图2 手机控制舵机

  通过手机输入数值,我们就可以简单地通过远程控制我们的舵机转动,当然这样输入数值的方式不大方便,在下一节,我们会详细阐述如何解决这个问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值