lb8820265

个性签名:QQ:252669569

  • 2024-09-28
  • 加入了学习《Quartus Prime开发流程(英特尔官方教程)》,观看 Quartus_Prime与基于硬件描述语言的开发流程2

  • 加入了学习《Quartus Prime开发流程(英特尔官方教程)》,观看 Quartus_Prime与基于硬件描述语言的开发流程1

  • 2024-05-13
  • 发表了主题帖: 【2023 DigiKey大赛参与奖】开箱帖 Raspberry Pi 5 4G

    参与奖购买了Raspberry Pi 5 4G,之前一直玩的树莓派4,听说5升级很大,买一个来玩玩

  • 回复了主题帖: 51“万里”树莓派小车——树莓派图传遥控小车(视频展示)

    lkh747566933 发表于 2024-5-8 17:28 大佬厉害啊,图传用的什么方案,无人机能用吗? 哈哈,图传就是树莓派的WiFi呀,电脑和树莓派连在同一个WiFi上,通过视频推流就可以获取,无人机的话应该不太行,WiFi的距离有限。

  • 回复了主题帖: 16“万里”树莓派小车——光电编码器学习(转速的获取)

    nicklgw 发表于 2024-5-12 19:06 电机转速的正反,怎么获取了? 由于编码器是有AB相的,可以通过相位获取,Pico的PIO编码器接口可以自动的获取电机的正反转

  • 2024-03-09
  • 发表了主题帖: 52“万里”树莓派小车——小车速度与距离控制(视频展示)

    本帖最后由 lb8820265 于 2024-3-9 21:44 编辑 先上视频:     前面有使用树莓派4B采集编码器的值计算电机速度,进而进行速度控制,最后以失败告终,电机控制学习(4轮速度控制),我总结是树莓派操作系统为非实时的,这次换成嵌入式的PicoW加上500线的编码器,应该是不存在这个问题的。     速度控制的原理是在定时器中获取电机的速度,然后使用PD控制算法,通过控制PWM占空比对电机速度进行控制。前面有介绍PWM,定时器和PIO编码器外设的使用,可以参考。 定时器     在初始化中设置50ms定时器,代码如下:    add_repeating_timer_ms(-50, repeating_timer_callback, NULL, &timer);     在定时器回调函数中获取电机速度,首先获取两次定时器的时间差,这样是确保获取更加准确的时间差。然后用当前的编码器值减去上次获取的编码器值,然后乘以一个校准值就是当前的速度值。然后就是Car_Control()和Servo_Control()分别用来控制小车和舵机,代码如下: bool repeating_timer_callback(struct repeating_timer *t) {     static absolute_time_t t_from;     absolute_time_t t_to;     int64_t t_delta;     int Encoder_New_Value_1,Encoder_New_Value_2;     static int Encoder_Old_Value_1,Encoder_Old_Value_2;         t_to=get_absolute_time();         t_delta=absolute_time_diff_us(t_from,t_to);         t_from=t_to;         Encoder_New_Value_1 = -quadrature_encoder_get_count(pio, SM_Encoder_A);         Control_State.SPD_Real_A = (Encoder_New_Value_1 - Encoder_Old_Value_1)/(float)t_delta*1000;         Encoder_Old_Value_1 = Encoder_New_Value_1;         Encoder_New_Value_2 = quadrature_encoder_get_count(pio, SM_Encoder_B);         Control_State.SPD_Real_B = (Encoder_New_Value_2 - Encoder_Old_Value_2)/(float)t_delta*1000;         Encoder_Old_Value_2 = Encoder_New_Value_2;         Car_Control();         Servo_Control();         Trigger_LED_Flag=true; } Car_Control()函数     Car_Control()函数是小车控制的主要函数,函数中首先判断控制模式,分为及时控制以及距离控制,在这两个控制模式中又都分为PWM直接控制与速度控制。其中距离控制还需要在主函数中进行配合,代码如下: void Car_Control(void){     static int CMD_Dis_Mode_Pre=0;     int Motor_PWM_A_Set=0,Motor_PWM_B_Set=0;     if(Control_State.DIS_Dis_Mode!=0){//说明此时距离模式启用         switch(Control_State.DIS_Speed_Mode)             {             case 1://距离控制下使用PWM直接控制                 Motor_PWM_A_Set=(Control_State.DIS_Down_A==1)?0:(Control_State.DIS_Motor_PWM_A*10);                 if(Control_State.DIS_Set_A<0)Motor_PWM_A_Set=-Motor_PWM_A_Set;                 Motor_PWM_B_Set=(Control_State.DIS_Down_B==1)?0:(Control_State.DIS_Motor_PWM_B*10);                 if(Control_State.DIS_Set_B<0)Motor_PWM_B_Set=-Motor_PWM_B_Set;             break;             case 2://距离控制下使用速度控制                 Motor_PWM_A_Set=(Control_State.DIS_Down_A==1)?0:(Speed_PI(Control_State.DIS_Real_A,Control_State.DIS_Set_A,&Control_State.SPD_A_Encoder_Integral));                 if(Control_State.DIS_Set_A<0)Motor_PWM_A_Set=-Motor_PWM_A_Set;                 Motor_PWM_B_Set=(Control_State.DIS_Down_B==1)?0:(Speed_PI(Control_State.DIS_Real_B,Control_State.DIS_Set_B,&Control_State.SPD_B_Encoder_Integral));                 if(Control_State.DIS_Set_B<0)Motor_PWM_B_Set=-Motor_PWM_B_Set;             break;             }     }else if(Control_State.CMD_Speed_Mode!=0){//说明及时控制模式启用         switch(Control_State.CMD_Speed_Mode)         {         case 1://及时控制模式下PWM直接控制             Motor_PWM_A_Set=Control_State.Motor_PWM_A*10;             Motor_PWM_B_Set=Control_State.Motor_PWM_B*10;             break;         case 2://及时控制下使用速度控制 Motor_PWM_A_Set=Speed_PI(Control_State.SPD_Real_A,Control_State.SPD_Set_A,&Control_State.SPD_A_Encoder_Integral); Motor_PWM_B_Set=Speed_PI(Control_State.SPD_Real_B,Control_State.SPD_Set_B,&Control_State.SPD_B_Encoder_Integral);             break;         }     }else{//仅仅心跳     }     printf("A_PWM %6d,B_PWM %6d\n", Motor_PWM_A_Set,Motor_PWM_B_Set);     Motor_Control(1,Motor_PWM_A_Set);     Motor_Control(2,Motor_PWM_B_Set); } 距离控制判断函数     在距离控制中,需要在主函数中需要不断的判断是否达到设定的距离,然后需要马上停止,但是实际操作起来还是挺复杂的,需要有多个标志位配合来判断,且在接收到距离控制指令后需要保存编码器当时的值,且保存接收到的距离控制指令,因为距离指令通常不会一直发,代码代码如下: void Car_Distance_Stop_Check(void){     if(Control_State.DIS_Dis_Mode!=0){         switch(Control_State.DIS_Dis_Mode)             {             case 1:                     Control_State.DIS_Real_A= quadrature_encoder_get_count(pio, SM_Encoder_A)+Control_State.DIS_Zero_Point_A;                     Control_State.DIS_Real_B=-(quadrature_encoder_get_count(pio, SM_Encoder_B)-Control_State.DIS_Zero_Point_B);        if(abs(Control_State.DIS_Real_A)>=abs(Control_State.DIS_Set_A)&&Control_State.DIS_Down_A==0){                         Control_State.DIS_Down_A=1;                         Motor_Control(1,0);                   //      printf("DIS_Down_A");                     }         if(abs(Control_State.DIS_Real_B)>=abs(Control_State.DIS_Set_B)&&Control_State.DIS_Down_B==0){                         Control_State.DIS_Down_B=1;                         Motor_Control(2,0);                    //     printf("DIS_Down_B");                     }                     if(Control_State.DIS_Down_A==1&&Control_State.DIS_Down_B==1){                         Control_State.DIS_Dis_Mode=0;                     }                 break;             }     } } 速度PI控制函数     在Car_Control()函数中有对速度进行控制,将获取的速度与实际的速度进行PI控制,函数中有P、I和积分上限参数需要调整。代码如下: float Speed_PI(float Now_Speed,float Set_Speet,float * Encoder_Integral) {       float Speed_Kp=3,Speed_Ki=1;     float SPEED_INTEGRAL_MAX=1000;     float fP;     fP=Set_Speet-Now_Speed;     *Encoder_Integral+=fP;     if(*Encoder_Integral>SPEED_INTEGRAL_MAX){         *Encoder_Integral=SPEED_INTEGRAL_MAX;     }else if(*Encoder_Integral<-SPEED_INTEGRAL_MAX){         *Encoder_Integral=-SPEED_INTEGRAL_MAX;     }           return fP*Speed_Kp+*Encoder_Integral*Speed_Ki;   } 电机控制函数     无论什么控制模式,最后都要对电机进行控制,TB6612FNG电机驱动模块可以控制两个电机,一个PWM口用来控制电机,两个IO口控制正反转和急停,函数参数为电机位置和PWM占空比。代码如下: void Motor_Control(int M,int PWM){     if(PWM>1000){PWM=1000;}     else if(PWM<-1000){PWM=-1000;}     if(M==1){         if(PWM==0){             gpio_put(PIN_Motor_A_IN_1, 1);             gpio_put(PIN_Motor_A_IN_2, 1);         }else if(PWM>0){             gpio_put(PIN_Motor_A_IN_1, 1);             gpio_put(PIN_Motor_A_IN_2, 0);             pwm_set_gpio_level(PIN_Motor_A_PWM, PWM);         }else{             gpio_put(PIN_Motor_A_IN_1, 0);             gpio_put(PIN_Motor_A_IN_2, 1);             pwm_set_gpio_level(PIN_Motor_A_PWM, -PWM);         }     }     else if(M==2){         if(PWM==0){             gpio_put(PIN_Motor_B_IN_1, 1);             gpio_put(PIN_Motor_B_IN_2, 1);         }else if(PWM>0){             gpio_put(PIN_Motor_B_IN_1, 0);             gpio_put(PIN_Motor_B_IN_2, 1);             pwm_set_gpio_level(PIN_Motor_B_PWM, PWM);         }else{             gpio_put(PIN_Motor_B_IN_1, 1);             gpio_put(PIN_Motor_B_IN_2, 0);             pwm_set_gpio_level(PIN_Motor_B_PWM, -PWM);         }     } } UDP接收函数     PicoW接收手机发送过来的指令,对指令进行解析,然后对结构体进行赋值,同时将电机的速度和距离返回给手机端。这其中数据的位数和符号需要格外注意,要用memcpy而不是strcpy来复制数据。代码如下: void RcvFromUDP(void * arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t*addr,u16_t port) {     uint8_t *buffer=calloc(p->len+1,sizeof(uint8_t));       memcpy(buffer,(uint8_t *)p->payload,p->len);//注意这里复制数据不能用strcpy,否则0x00后面的数据就收不到了!!!     if(buffer[0]!=0x7F){         return;     }     Control_State.CMD_Speed_Mode= buffer[1]&0x0f;     Control_State.CMD_Dis_Mode= (buffer[1]&0xf0)>>4;     Control_State.Motor_PWM_A= (buffer[4]>126) ? buffer[4]-256 : buffer[4];     Control_State.Motor_PWM_B= (buffer[5]>126) ? buffer[5]-256 : buffer[5];     Control_State.SPD_Set_A= buffer[6]*256+buffer[7];     if(Control_State.SPD_Set_A>32768)Control_State.SPD_Set_A-=65536;     Control_State.SPD_Set_B= buffer[8]*256+buffer[9];     if(Control_State.SPD_Set_B>32768)Control_State.SPD_Set_B-=65536;     Control_State.DIS_Set_A= buffer[10]*256+buffer[11];     if(Control_State.DIS_Set_A>32768)Control_State.DIS_Set_A-=65536;     Control_State.DIS_Set_B= buffer[12]*256+buffer[13];     if(Control_State.DIS_Set_B>32768)Control_State.DIS_Set_B-=65536;     Control_State.Sover_PWM_A=(buffer[14]>126) ? buffer[14]-256 : buffer[14];     Control_State.Sover_PWM_B=(buffer[15]>126) ? buffer[15]-256 : buffer[15];     if(Control_State.CMD_Dis_Mode!=0){//位置指令,该指令在执行完之前,一般只执行一次         Control_State.DIS_Real_A=0;//复位位置         Control_State.DIS_Real_B=0;         Control_State.DIS_Motor_PWM_A=Control_State.Motor_PWM_A;//保存PWM直接控制值         Control_State.DIS_Motor_PWM_B=Control_State.Motor_PWM_B;         Control_State.DIS_SPD_A=Control_State.SPD_Set_A;//保存SPD控制值         Control_State.DIS_SPD_B=Control_State.SPD_Set_B;         Control_State.DIS_Down_A=0;         Control_State.DIS_Down_B=0;//是否完成标志位         Control_State.DIS_Dis_Mode=Control_State.CMD_Dis_Mode;//将位置指令保存,以防被下次数据覆盖         Control_State.DIS_Speed_Mode=Control_State.CMD_Speed_Mode;//将速度指令保存,以防被下次数据覆盖         Control_State.DIS_Zero_Point_A=-quadrature_encoder_get_count(pio, SM_Encoder_A);//将当前电机A的距离值保存         Control_State.DIS_Zero_Point_B=quadrature_encoder_get_count(pio, SM_Encoder_B);//将当前电机B的距离值保存     }         free(buffer);         pbuf_free(p);         Tx_buffer[0]=254;         Tx_buffer[1]=253;          memcpy(Tx_buffer+2, &Control_State.SPD_Real_A, 4);          memcpy(Tx_buffer+6, &Control_State.DIS_Real_A, 4);          memcpy(Tx_buffer+10, &Control_State.SPD_Real_B, 4);          memcpy(Tx_buffer+14, &Control_State.DIS_Real_B, 4);         SendUDP(addr,port,Tx_buffer,18);      //   printf("R1 %6d,R2 %6d\n", Control_State.Motor_PWM_A,Control_State.Motor_PWM_B); } 手机端     手机端主要是发送控制指令与接收小车发过来的数据,主要界面和功能如下图所示。代码太分散可以直接参考源码。 PicoW源码: Android源码:

  • 2024-03-06
  • 发表了主题帖: 51“万里”树莓派小车——树莓派图传遥控小车(视频展示)

    本帖最后由 lb8820265 于 2024-3-9 21:48 编辑 先上视频:     主要工作原理:树莓派获取摄像头数据然后通过RTSP推流,电脑接收视频数据,手机上位机连接PicoW控制小车运动和摄像头云台运动。     上位机的制作,和PicoW的相关外设的使用在前面的帖子中有介绍,树莓派摄像头的RTSP推流涉及到一系列的操作,会在以后进行介绍。        接下来的主要工作: 树莓派与PicoW通信; 树莓派图像视频; 树莓派雷达SLAM; 树莓派语音控制; 物联网控制。 PicoW程序源代码: Android上位机源代码:  

  • 发表了主题帖: 50“万里”树莓派小车——小车的构成与组装

    本帖最后由 lb8820265 于 2024-3-6 21:23 编辑     当前“万里”小车主要由购买的模块与小车底座构成,包括前面的“PicoW主控小车”和接下来的“PicoW+树莓派小车” PicoW主控小车    一个最简单的小车,由以下几个部分构成。 组成 型号参数 底盘 2电机,1万向轮的差速底盘 电机 12V,300rpm减速电机,带500线编码器 电机驱动 TB6612FNG(VM=15V,IOUT=1.2A) 电池 3S 11.1V 2200mAh锂电池 电源 Mini560(5~20V输入,3.3V 4A输出) 控制板 PicoW模块      使用洞洞板将PicoW、电源模块、电机驱动、电机和电池连接起来。使用嘉立创标准版绘制原理图如下。       由于是洞洞板,尽量保证连接最短,在PCU中进行布局如下。       在洞洞板上连接如下。       最后组装整个小车。   ​​​​​​ PicoW+树莓派小车     PicoW作为主控的小车,能够实现的功能有限,接下来可以将树莓派4B、摄像头和舵机加入进去,在前面的硬件的基础上,添加如下的硬件。 组成 型号参数 电源 MPS MEZS91202A模块X2 树莓派 树莓派4B 舵机+支架 数字舵机X2 摄像头 CSI接口树莓派摄像头     由于原来的小电源模块带不树莓派而且在舵机工作下电压波动剧烈,因此将电源模块更换成了MPS公司 MEZS91202A模块,这是一款 USB 充电器模块,具有 7-36V 输入、350kHz、2.5A 负载电流、5V 输出,效率高达 95%。这款电源模块堪称完美。       系统硬件连接框图如下图所示。     小车的硬件主要以树莓派4B和PicoW为中心。3S锂电池通过两个MPS电源模块分别给树莓派4B和PicoW供电,树莓派4B连接CSI树莓派摄像头,PicoW连接了包括包括舵机云台,编码器,电机驱动模块。电机驱动模块接受3S电池供电,MPS电源模块供电,和PicoW控制,然后连接直流电机。直流电机转速信息被编码器获取,然后反馈给PicoW,这样就可以进行稳定的速度控制,树莓派4B、PicoW、电脑、手机都连接在同一个无线路由器上。     各模块之间通过洞洞板连接,洞洞板如下图所示。       硬件连接原理图如下图所示。        这并不是最终的小车结构,以后还会有雷达、语音模块和屏幕等,底盘自行DIY,结构也会进一步完善。     嘉立创原理图源文件: 

  • 2024-02-04
  • 回复了主题帖: 【年终总结颁奖】2024,让我们保持热爱,奔赴下一场山海!

    地址已更新,感谢

  • 2024-01-31
  • 回复了主题帖: 【年终总结颁奖】2024,让我们保持热爱,奔赴下一场山海!

    已确认个人信息无误,感谢EE,祝EE越来越好!

  • 2024-01-29
  • 发表了主题帖: 【晒奖品】最开心的荣誉——论坛给的荣誉证书

    本帖最后由 lb8820265 于 2024-1-29 19:42 编辑     就在今天,收到了论坛给的荣誉证书,是个红色的很精致的封面,里面是个证书,感谢EE论坛,这个应该是今年收到的最让我开心的荣誉了,超开心!         还附赠了一个奖品,万用表。       今年我收到这个奖是有愧疚的,并没有太多的更新帖子,2024年我要加倍努力了,争取年年都能获得论坛的荣誉证书。  

  • 回复了主题帖: “年终总结”+2023,不负生活所爱,尽舞人生精彩

    真是太厉害了,祝越来越好! 楼主的很多感觉我也深有体会,我有空会滑滑板,感受到我在追风,自由的感觉。我也有一个大疆无人机,这东西真的很棒!

  • 2024-01-24
  • 回复了主题帖: 【年终总结】奔跑吧,少年!

    秦天qintian0303 发表于 2024-1-22 09:33 家里设计一个工作室,搞硬件的都想有一个这样的,丰富多彩的2023,期待精彩的2024 哈哈,谢谢,我也是一直有这样的一个想法,我买了个4房,被我砸墙改成了两房了

  • 回复了主题帖: 【年终总结】奔跑吧,少年!

    led2015 发表于 2024-1-21 22:55 早睡早起只适合那些开早市赚钱的,我们这样的,都忘记了啥叫生物钟 哈哈,有一定道理,但是目标还是要有的

  • 回复了主题帖: 【年终总结】奔跑吧,少年!

    se7ens 发表于 2024-1-20 23:15 加油,少年 第一个目标很好,我自己的感受就是精力比较好,而且身体也会比较健康,很少会生病 哈哈,是的,都知道要早起早睡,也知道好处,但是不知为何就是很难做到

  • 回复了主题帖: 45“万里”树莓派小车——PicoW学习(C语言环境搭建、新建工程、在线调试)

    LitchiCheng 发表于 2024-1-24 16:55 后面是打算用pico直接pwm控制直流电机做小车吗 应该会用pico做控制底盘,上面还是会用树莓派做图像处理

  • 2024-01-20
  • 发表了主题帖: 【年终总结】奔跑吧,少年!

    本帖最后由 lb8820265 于 2024-1-20 21:56 编辑     时光飞逝,感觉上次写总结还在不久前:【再见2021,你好2022】万里归来年愈少,【回顾2022展望2023】今年欢笑复明年,秋月春风等闲度。     今年最大的感觉就是很多时刻处于奔跑中,明显比去年忙碌,感觉人也更加年轻了些。         先给去年的计划对标吧。 1. 去年计划对标 序号 2023年目标 打分(百分制) 详情 1 早睡早起 50 今年坚持过一个月,后来放弃了 2 坚持锻炼 80 上半年有坚持跑步,下半年有坚持锻炼肌肉 3 完成工作上的项目 90 工作上事不多,完成 4 继续“万里”小车制作 60 进度实在是太慢 5 学会一项新技能 90 学会了装备宣传视频的拍摄和剪辑 6 读10本以上书 90 看的加听的够了 7 完成房屋装修,并在家里设计一个工作室 50 交房延期了一年,不过现在已经开始装修了     哈哈,对标总是这么残酷,早睡早起年年都有,但是实在是很做到,坚持锻炼还算做的不错,工作上也还行,“万里”小车进度实在很慢,我也是不太满意的,但是奈何这个只能用大片的时间做,碎片时间无法做。房屋装修由于交房延期,目前也才刚刚开始。 2. 论坛总结     2014年加入EE大家庭 , 23年总共发表了10篇帖子,上传了2个资源,参加了1个活动。     帖子数量不多,主要是围绕小车的制作分享。参加的活动是《DigiKey创意大赛》,大赛作品仍然是小车,哈哈哈! 3. 2023年是怎么度过的?     工作上,今年的评价是:平淡中包含小失落,工作内容和职务和去年一样没有什么变化,工作也不算特别忙,内容比较纯粹,不需要为工作焦虑与担心什么,但是今年的层级晋升没有成功,看着和我一起来的同事都升上去了,心里还是不免有些羡慕,我安慰自己,来日方长嘛,继续加油!     今年我揽了一个给中心产品拍宣传视频的活,使用了无人机,云台,摄像机;学会了拍摄技巧,镜头语言,视频剪辑,也得到了了同事的一致好评。     生活上,今年的评价是:幸运且忙碌!主要有三件大事,第一件捐献了造血干细胞,第二件读了个在职博士,第三件房子开始装修了。     今年我成功的捐献了造血干细胞,在13年前我加入了中华骨髓库,直到现在才进行了捐献,目前来看捐献这个并没有发现明显的坏处,也得到一点慰问金等好处,我想这是患者的幸运,也是我的幸运。     今年在同济读了个在职的博士,好像是别人都不太想读,所以就让我报名试试,然后就录取了,读的是控制科学与工程专业,这个是不是幸运还不好说,要是毕不了业一切就白搭了,总之,加油吧。     今年年底总算是交房了,房子延期了13个月,真是盼星星盼月亮,房子装修是找的装修公司,但是仍然有许多问题需要考虑,方案经过了多次的修改,而且为了对比材料和价格需要跑很多建材市场,做全屋智能需要多次去不同的全屋智能门店考察,总之,好多个周末都是在做装修相关的事了,不停的奔波,而且脑子里也都是装修的事,希望24年装修顺利吧。     家庭上,今年的评价是:革命尚未成功,同志仍需努力!今年爱人和我还是异地,我们也是聚少离多,但我们的感情还是很好,今年也在积极备孕中,希望明年能有好消息! 4. 2024年计划     我看了下23年的计划,这不也可以是24年的计划嘛,所以24年的计划和23年一样,完全不用修改。 早睡早起 坚持锻炼 完成工作上的项目 读10本以上书 继续“万里”小车制作 学会一项新技能 完成房屋装修,并在家里设计一个工作室     2024年,继续奔跑吧,少年!

  • 2024-01-19
  • 回复了主题帖: EEWorld 社区 2023年度人物颁奖

    个人信息确认无误,很惊喜,感谢EE,今年实在惭愧,没有太多更新,明年加大努力:)

  • 2024-01-15
  • 发表了主题帖: 【DigiKey创意大赛】树莓派图传遥控小车作品提交

    作品名称:树莓派图传遥控小车 作者:lb8820265      一、作品简介   DIY的树莓派图传遥控小车,主要用到的模块包括:树莓派4B、PicoW、树莓派CSI接口摄像头、MPS MEZS91202A电源模块、TB6612NFG电机驱动。树莓派获取摄像头数据然后通过RTSP推流,电脑接收视频数据,手机上位机连接PicoW控制小车运动和摄像头云台运动。该小车可作为高级玩具和视频监控机器人。 二、系统框图(图文结合) 系统硬件连接框图如下图所示。   各模块之间通过洞洞板连接,洞洞板如下图所示。     硬件连接原理图如下图所示。   小车的硬件主要以树莓派4B和PicoW为中心。3S锂电池通过两个MPS电源模块分别给树莓派4B和PicoW供电,树莓派4B连接CSI树莓派摄像头,PicoW连接了包括包括舵机云台,编码器,电机驱动模块。电机驱动模块接受3S电池供电,MPS电源模块供电,和PicoW控制,然后连接直流电机。直流电机转速信息被编码器获取,然后反馈给PicoW,这样就可以进行稳定的速度控制,树莓派4B、PicoW、电脑、手机都连接在同一个无线路由器上。 小车软件主要包括三个部分,PicoW软件,手机上位机软件,树莓派4B软件。PicoW软件主要包括:UDP网络通信,PWM电机控制,PWM舵机控制,电机驱动模块控制,GMR编码器数据获取,手机通信协议制定,速度控制算法等。手机上位机软件是在Android系统上编写,主要包括:UDP网络通信,摇杆控件,通信协议制定。树莓派4B内部运行Ubuntu Mate 20.04操作系统,主要是功能是获取CSI接口的摄像头数据,然后通过RTSP协议将视频数据推流到无线路由器,然后电脑端通过VLC软件获取推流并展现出来。 四、各部分功能说明(图文结合) (各部分实现的功能说明及讲解,以图文结合的展示) 对手机Android程序、PicoW程序和树莓派4B程序各功能进行详细说明。 3.1 PicoW UDP网络通信 UDP初始化程序如下图所示。   UDP通信程序回调如下图所示,在回调函数中接收手机端发送过来的数据进行解析,并将速度和距离数据发送回手机     3.2 PicoW PWM功能模块、电机与舵机控制 PWM使用电机和舵机两个地方,PWM初始化程序如下图所示。   舵机PWM控制程序如下图所示。   电机PWM控制程序如下图所示。   3.3 PicoW 编码器数据获取 编码器用来获取电机速度,编码器初始化代码如下。   数据获取代码如下。   3.4 PicoW 定时器 定时器用来定时的控制小车与舵机,控制闪烁LED灯,定时为50ms,定时器初始化代码如下。   定时器回调函数如下图所示。   3.5 PicoW控制LED PicoW的LED灯是通过无线通信芯片来控制的,要控制LED先要初始化通信芯片,在前面已经介绍了,LED的控制不能在中断函数中进行,只能在main主函数中进行,在定时器中将标志位至1,在while中不断的查询,然后翻转LED灯,代码如下。     3.6 手机Android定时器与控制逻辑 由于手机端Android程序过于庞大,这里介绍其核心代码,在手机定时器中不断的发送控制数据,定时器函数与代码如下。     3.7 树莓派4B摄像头视频推流 获取摄像头数据并RTSP推流的核心代码如下图所示。 raspivid -o - -t 0 |cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8090/}' :demux=h264  3.8 电脑端获取视频推流数据 电脑端主要通过VLC软件获取数据,在网络媒体中输入树莓派的IP地址,IP需要查询,不同用户不一样,让后再加上8090端口号,例如我的URL地址为:rtsp://192.168.31.159:8090/,然后点击播放即可。     四、作品源码 Android手机端源代码:https://download.eeworld.com.cn/detail/lb8820265/630787 PicoW端源代码:https://download.eeworld.com.cn/detail/lb8820265/630786 五、作品功能演示视频 演示视频链接:https://training.eeworld.com.cn/video/38973 六、项目总结 该项目主要使用了在DigiKey购买的PicoW和树莓派4B,项目复杂难度大,涉及到的需要编程的设备有4个,涉及到的硬件设备多达十余个。项目趣味性高,可以用于监控机器人,未来还可以进行自动行驶,可扩展性强。 七、其他 项目Android手机端部分界面照片如下。   小车多角度照如下。     全家福照片如下。       

  • 上传了资料: 树莓派图传遥控小车Android手机端源代码

最近访客

< 1/6 >

统计信息

已有862人来访过

  • 芯积分:2184
  • 好友:21
  • 主题:146
  • 回复:508

留言

你需要登录后才可以留言 登录 | 注册


安拉木 2018-12-30
网卡了,点了几下没反应,发了很多留言,不好意思了
查看全部