- 2024-12-29
-
发表了主题帖:
【Follow me第二季第4期】提交帖:全部任务
本帖最后由 lb8820265 于 2025-1-12 10:23 编辑
项目演示视频
物料展示
整个学习的过程只需要一个Arduino RP2040 开发板即可,开发板上自带有许多的传感器。
前期准备工作
Arduino® Nano RP2040 Connect这个开发板是Arduino公司生产的产品,用的是树莓派Pico中的RP2040,树莓派有针对该芯片有专门的专门的SDK,是用C语言写的,我之前有学习过,但这次Arduino公司有对其进行封装,让其上手变得特别简单,使用Arduino IDE可以非常简单的完成一些简单的任务,完全不需要关注底层的驱动和相关的配置。但是也有许多不便的地方,比如定时器需要另外的安装库,PIO的功能甚至连库也没找到,而且许多的库也没法看到源码。最后还是决定用Arduino IDE来完成本次的任务。
先在Arduino官网上将IDE软件下载下来然后安装,使用USB线连接好电脑与开发板,正常情况会默认识别出硬件与端口号,如下图所示。
而且提示安装对应的库文件,没安装也可以在后期搜索Arduino Mbed OS Nano Boards安装,如下图所示。
任务成果展示
任务一:
搭建环境并开启第一步Blink三色LED / 串口打印Hello DigiKey & EEWorld!;
三色LED灯的原理是通过三个引脚来控制的,引脚拉低,对应颜色的灯就发光。
但是,三个引脚是从Wifi芯片上引出的,这点和官方树莓派Pico的做法一样。
因此,需要安装WiFi芯片的库文件,在库文件搜索处,搜索WifiNINA,然后安装,如下图所示。
程序流程图如下:
程序全部源码如下:
#include "WiFiNINA.h"
void setup() {
Serial.begin(9600);
pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);
}
void loop() {
Serial.println("Hello DigiKey & EEWorld!");
// Red
digitalWrite(LEDR, LOW);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, HIGH);
delay(500);
// Green
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, LOW);
digitalWrite(LEDB, HIGH);
delay(500);
// Blue
digitalWrite(LEDR, HIGH);
digitalWrite(LEDG, HIGH);
digitalWrite(LEDB, LOW);
delay(500);
}
代码是然后LED三色闪烁,同时串口发送"Hello DigiKey & EEWorld!"。
可以先点击IDE的“√”按钮,看看语法有没有错误,然后点击“->”按钮进行程序烧录。
看到提示”Done uploading”就说明烧录成功了,如下图。
串口可以使用IDE软件自带的串口工具,在Tools->Serial Monitor中,设置好波特率后,就可以看到打印的字符。
任务二:
学习IMU基础知识,调试IMU传感器,通过串口打印六轴原始数据;
板子上有ST公司的陀螺仪加速度计芯片,叫做LSM6DSOX,Arduino IDE有IMU的库函数,但是需要额外安装,在库中搜索安装如下。
可以去Arduino官网中查看该库的详细介绍:Arduino_LSM6DSOX | Arduino Documentation,这个库函数写的非常的简单,而且限制了数据的跟新频率为104Hz,详细的源码可以去官方Github库中查看:arduino-libraries/Arduino_LSM6DSOX。
程序流程图如下:
程序全部源码如下:
#include <Arduino_LSM6DSOX.h>
float Ax, Ay, Az;
float Gx, Gy, Gz;
float data[6];
char tail[] = {0x00, 0x00, 0x80, 0x7f};
void setup() {
Serial.begin(115200);
while(!Serial);
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
}
void loop() {
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(Ax, Ay, Az);
data[0]=Ax;
data[1]=Ay;
data[2]=Az;
}
if (IMU.gyroscopeAvailable()) {
IMU.readGyroscope(Gx, Gy, Gz);
data[3]=Gx;
data[4]=Gy;
data[5]=Gz;
}
Serial.write((char *)data, sizeof(float) * 6);
Serial.write(tail, 4);
}
程序是在loop中不断的查询数据是否准备好,然后获取数据并发送出来。烧录程序后数据的展示使用的是一个叫做VOFA+的软件,这是一个免费的数据波形展示软件,设定两个波形显示控件,左边是加速度计的值,右边是陀螺仪的值,配置好数据引擎为JustFloat,配置好串口参数,打开DTR,如下图所示。
然后转动开发板,显示的结果如下图所示。
任务三:
学习PDM麦克风技术知识,调试PDM麦克风,通过串口打印收音数据和音频波形。
该任务在库例程中有一个直接可用的例程,在File->Examples->PDM,这个例子可以直接烧录运行,然后在IDE自带的数据显示工具中显示波形数据,但是波形显示的数据量太少,不太直观,这里仍然用VOFA+软件进行波形的展示,稍微修改一下例程中的代码,将波特率改为115200,数据按照通信协议进行发送。
程序流程图如下:
程序全部源码如下:
#include <PDM.h>
float data[2];
char tail[] = {0x00, 0x00, 0x80, 0x7f};
// default number of output channels
static const char channels = 1;
// default PCM output frequency
static const int frequency = 16000;
// Buffer to read samples into, each sample is 16-bits
short sampleBuffer[512];
// Number of audio samples read
volatile int samplesRead;
void setup() {
Serial.begin(115200);
while (!Serial);
// Configure the data receive callback
PDM.onReceive(onPDMdata);
// Optionally set the gain
// Defaults to 20 on the BLE Sense and 24 on the Portenta Vision Shield
// PDM.setGain(30);
// Initialize PDM with:
// - one channel (mono mode)
// - a 16 kHz sample rate for the Arduino Nano 33 BLE Sense
// - a 32 kHz or 64 kHz sample rate for the Arduino Portenta Vision Shield
if (!PDM.begin(channels, frequency)) {
Serial.println("Failed to start PDM!");
while (1);
}
}
void loop() {
// Wait for samples to be read
if (samplesRead) {
for (int i = 0; i < samplesRead; i++) {
data[0] = sampleBuffer[i];
Serial.write((char *)data, sizeof(float) * 1);
Serial.write(tail, 4);
}
samplesRead = 0;
}
}
/**
* Callback function to process the data from the PDM microphone.
* NOTE: This callback is executed as part of an ISR.
* Therefore using `Serial` to print messages inside this function isn't supported.
* */
void onPDMdata() {
// Query the number of available bytes
int bytesAvailable = PDM.available();
// Read into the sample buffer
PDM.read(sampleBuffer, bytesAvailable);
// 16-bit, 2 bytes per sample
samplesRead = bytesAvailable / 2;
}
烧录后对着板子说话,就可以在波形上位机中看到变化的声音波形数据了,如下图所示。
项目总结
这次使用Arduino® Nano RP2040 Connect开发板结合Arduino IDE确实体验到了开发的便利性,但是如果想要更好的发挥出这个板子的全部性能,做出有意思的东西,则还需要进行探索,期望后期能用这块板子做更多有意思的东西。
程序源码
Follow me 第二季第4期任务一-嵌入式开发相关资料下载-EEWORLD下载中心
Follow me 第二季第4期任务二-嵌入式开发相关资料下载-EEWORLD下载中心
Follow me 第二季第4期任务三-嵌入式开发相关资料下载-EEWORLD下载中心
-
加入了学习《Arduino? Nano RP2040任务讲解视频》,观看 Arduino Nano RP2040任务讲解视频
- 2024-12-28
-
上传了资料:
Follow me 第二季第4期任务三
-
上传了资料:
Follow me 第二季第4期任务二
-
上传了资料:
Follow me 第二季第4期任务一
- 2024-12-27
-
加入了学习《直播回放: DigiKey FollowMe 第二季 第4期 Arduino Nano RP2040 Connect 任务讲解》,观看 Arduino Nano RP2040 Connect 任务讲解
-
加入了学习《 【Follow me第二季第4期】任务汇总》,观看 FM4
-
加入了学习《【Follow me第二季第1期】全部任务演示》,观看 全部任务演示2.0
- 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,不负生活所爱,尽舞人生精彩
真是太厉害了,祝越来越好!
楼主的很多感觉我也深有体会,我有空会滑滑板,感受到我在追风,自由的感觉。我也有一个大疆无人机,这东西真的很棒!