- 2023-11-18
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
ninin2023 发表于 2023-11-18 09:49
树莓派不如esp8266好。还要贵些,能耗也比较高些。
嗯嗯,这个PicoW确实要比esp8266要贵些,而且这个也需要两个芯片来实现,相比esp8266只需要一个芯片成本确实更高,硬要说有什么优势,那可能就是这个具有PIO功能,可以在某些方面具有更快的速度。
-
回复了主题帖:
49“万里”树莓派小车——PicoW学习(C语言UDP通信)
lansebuluo 发表于 2023-11-15 08:49
这个模块能够完成的TCP测试,是通过UART转TCP实现的吗?
这个不是哦,这个PicoW是由一个主控芯片,加上一个双模Wifi+blue芯片,两者是通过SPI接口连接的,相比使用UART转的模块这个速度更快,更加底层,需要配置的也更多。
- 2023-11-12
-
发表了主题帖:
49“万里”树莓派小车——PicoW学习(C语言UDP通信)
UDP通信具有速度快的优点,TCP通信有例程可以参考,但是UDP通信却没有。
目标
新建一个PicoW模块基于UDP协议、STA模式的“echo”例程工程,可以通过手机与PicoW进行通信,并通过串口打印出相关信息。
新建工程
参考前面帖子的工程创建方法,使用“pico project generato”工具,工程名为“Test_IwIP_UDP”,勾选“Console over UART”和“Background IwIP”。
代码编写
前面的工作已经将工程框架搭建完成,下面贴出主要的代码。
添加头文件
#include "lwip/udp.h"
添加定义与全局变量
主要是WIFI用户名和密码,这里XX需要替换为自己的,通信端口号和pcb。
#define WIFI_SSID "XXXXXXXXXXX"
#define WIFI_PASSWORD "XXXXXXXXX"
#define RCV_FROM_PORT 1234
struct udp_pcb * rcv_udp_pcb;
main函数编写
主要是芯片的初始化,连接WiFi路由器,绑定UDP,注册接收回调函数,进行LED灯闪烁。UDP没有TCP那么多的功能,例如连接成功,发送成功等,都是没有回调函数的。
int main()
{
static bool LED_State=0;
stdio_init_all();
puts("Test IwIP UDP");
if (cyw43_arch_init()) {
printf("Wi-Fi init failed");
return -1;
}
cyw43_arch_enable_sta_mode();
printf("Connecting to Wi-Fi...\n");
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
printf("failed to connect.\n");
return 1;
} else {
printf("Connected.\n");
}
rcv_udp_pcb = udp_new();
err_t err = udp_bind(rcv_udp_pcb,IP_ADDR_ANY,RCV_FROM_PORT);
udp_recv(rcv_udp_pcb, RcvFromUDP,NULL);
while (true) {
sleep_ms(100);
if(LED_State){
LED_State=false;
}else{
LED_State=true;
}
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, LED_State);
}
return 0;
}
接收回调函数和发送函数的编写
在接收函数中将发送者的相关信息打印出来,并将收到的信息发送。UDP理论上是没法确实两者是否连接成功的,也不能像TCP一样,连接成功后可以发送一个“连接成功”的信息给Client。只有当收到信息后,才能通过收到信息,知道是谁发送了信息,进而发送回去。
void SendUDP(const ip_addr_t *dst_ip , int port, void * data, int data_size)
{
struct pbuf * p = pbuf_alloc(PBUF_TRANSPORT,data_size+1,PBUF_RAM);
char *pt = (char *) p->payload;
memcpy(pt,data,data_size);
pt[data_size]='\0';
cyw43_arch_lwip_begin();
udp_sendto(rcv_udp_pcb,p,dst_ip,port);
printf("send -> %s\n", pt);
cyw43_arch_lwip_end();
pbuf_free(p);
}
void RcvFromUDP(void * arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t*addr,u16_t port)
{
char *buffer=calloc(p->len+1,sizeof(char)); // use calloc to >
strncpy(buffer,(char *)p->payload,p->len);
printf("received from %d.%d.%d.%d port=%d\n",addr->addr&0xff,
(addr->addr>>8)&0xff,
(addr->addr>>16)&0xff,
addr->addr>>24,port);
printf("Length = %d , Total Length = %d\n",p->len,p->tot_len);
printf("payload -> %s\n", buffer);
free(buffer);
pbuf_free(p);
SendUDP(addr,port,buffer,p->len);
}
运行效果
在手机上运行“lb_socket_Android”APP,这是我自己编写的UDP通信软件,在前面有介绍,最后有下载。通过上一帖的方法知道PicoW的IP地址,然后输入端口号,点击连接。编辑发送数据,点击发送,就会看到接收到相同的数据。
连接串口调试助手,在串口调试助手上,会有WiFi连接整个过程的信息,例如,接收回调函数打印的相关信息。
APP源码与编写:socket学习(Android收发)
PicoW源码:
-
发表了主题帖:
48“万里”树莓派小车——PicoW学习(C语言TCP通信)
本帖最后由 lb8820265 于 2023-11-12 19:59 编辑
关于PicoW的WiFi功能程序的编写,官方有介绍文件《connecting-to-the-internet-with-pico-w》,帖子最后有下载,在官方例程中也有WiFi TCP通信的相关例程,路径为Pico_W/wifi/tcp_client和tcp_server,WiFi例程默认是不会编译的,需要提前进行配置,这个在PicoW学习(C语言环境搭建、新建工程、在线调试)有介绍。这两个例程需要一起使用,也就是两个PicoW中分别烧录tcp_client和tcp_server,然后连在同一个热点中,会完成一次数据的交互。但是例程需要两个PicoW太麻烦,而且不直观,而且都只有单一的首或者发的功能。通信例程通常是“echo”例程,也就是PicoW将收到的信息发送发送方。
目标
新建一个PicoW模块基于TCP协议、STA模式作为Server的“echo”例程工程,可以通过电脑创建TCP协议的Client与PicoW进行通信,并通过串口打印出相关信息。
工程创建
参考前面帖子的工程创建方法,使用“pico project generato”工具,工程名为“Test_IwIP_TCP”,勾选“Console over UART”和“Background IwIP”,该库表示中断模式接收,这里还有一个“Polled IwIP”可选,这个是轮寻方式接收。“PicoW onboard LED”库这个表示这个库仅仅只能控制LED灯,后面两个库是包含了LED灯的控制的。
代码编写
前面的工作已经将工程框架搭建完成,下面贴出主要的代码。
添加头文件
#include "lwip/tcp.h"
添加定义与全局变量
主要是WIFI用户名和密码,这里XX需要替换为自己的。然后是TCP相关的结构体。
#define WIFI_SSID "XXXXXXXXXXX"
#define WIFI_PASSWORD "XXXXXXXXX"
#define TCP_PORT 4242
#define DEBUG_printf printf
#define BUF_SIZE 2048
typedef struct TCP_SERVER_T_ {
struct tcp_pcb *server_pcb;
struct tcp_pcb *client_pcb;
bool complete;
uint8_t buffer_sent[BUF_SIZE];
uint8_t buffer_recv[BUF_SIZE];
int sent_len;
int recv_len;
int run_count;
} TCP_SERVER_T;
main函数编写
主要是芯片的初始化,连接WiFi路由器,运行TCP任务,进行LED灯闪烁。这里要注意如果长时间没有连上路由器,会报错。
int main()
{
static bool LED_State=0;
stdio_init_all();
puts("Test IwIP TCP");
if (cyw43_arch_init()) {
printf("Wi-Fi init failed");
return -1;
}
cyw43_arch_enable_sta_mode();
printf("Connecting to Wi-Fi...\n");
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
printf("failed to connect.\n");
return 1;
} else {
printf("Connected.\n");
}
run_tcp_server_test();
while (true) {
sleep_ms(100);
if(LED_State){
LED_State=false;
}else{
LED_State=true;
}
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, LED_State);
}
return 0;
}
TCP Server任务函数编写
主要是TCP Server初始化,连接回调函数的编写,在连接回调函数中注册接收、发送和错误等回调函数,并给Client发送连接成功字符。
static err_t tcp_server_accept(void *arg, struct tcp_pcb *client_pcb, err_t err) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
if (err != ERR_OK || client_pcb == NULL) {
DEBUG_printf("Failure in accept\n");
tcp_server_result(arg, err);
return ERR_VAL;
}
DEBUG_printf("Client connected\n");
state->client_pcb = client_pcb;
tcp_arg(client_pcb, state);
tcp_sent(client_pcb, tcp_server_sent);
tcp_recv(client_pcb, tcp_server_recv);
//tcp_poll(client_pcb, tcp_server_poll, POLL_TIME_S * 2);
tcp_err(client_pcb, tcp_server_err);
return tcp_server_send_data(arg, state->client_pcb);
}
static bool tcp_server_open(void *arg) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
DEBUG_printf("Starting server at %s on port %u\n", ip4addr_ntoa(netif_ip4_addr(netif_list)), TCP_PORT);
struct tcp_pcb *pcb = tcp_new_ip_type(IPADDR_TYPE_ANY);
if (!pcb) {
DEBUG_printf("failed to create pcb\n");
return false;
}
err_t err = tcp_bind(pcb, NULL, TCP_PORT);
if (err) {
DEBUG_printf("failed to bind to port %u\n", TCP_PORT);
return false;
}
state->server_pcb = tcp_listen_with_backlog(pcb, 1);
if (!state->server_pcb) {
DEBUG_printf("failed to listen\n");
if (pcb) {
tcp_close(pcb);
}
return false;
}
tcp_arg(state->server_pcb, state);
tcp_accept(state->server_pcb, tcp_server_accept);
return true;
}
void run_tcp_server_test(void) {
TCP_SERVER_T *state = tcp_server_init();
if (!state) {
return;
}
if (!tcp_server_open(state)) {
tcp_server_result(state, -1);
return;
}
}
接收发送回调函数编写
发送回调函数,在发送成功后进入,并通过串口发送发送字节数给PC。接收回调函数,在收到数据后,将数据发回给Client,并通过串口发送接收到的数据给PC。
static err_t tcp_server_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
DEBUG_printf("tcp_server_sent %u\n", len);
state->sent_len += len;
if (state->sent_len >= BUF_SIZE) {
// We should get the data back from the client
state->recv_len = 0;
DEBUG_printf("Waiting for buffer from client\n");
}
return ERR_OK;
}
err_t tcp_server_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
TCP_SERVER_T *state = (TCP_SERVER_T*)arg;
if (!p) {
return tcp_server_result(arg, -1);
}
cyw43_arch_lwip_check();
if (p->tot_len > 0) {
DEBUG_printf("tcp_server_recv %s", p->payload, err);
err_t err = tcp_write(tpcb,p->payload, p->tot_len, TCP_WRITE_FLAG_COPY);
if (err != ERR_OK) {
DEBUG_printf("Failed to write data %d\n", err);
return tcp_server_result(arg, -1);
}
}
pbuf_free(p);
return ERR_OK;
}
运行效果
将PicoW上电,会自动连接上路由器,在路由器上查看PicoW的IP地址,可以看到PicoW的IP地址为:192.168.31.136。
在PC打开网络调试助手,选择TCP Clinet,设置好IP地址,远端主机端口“4242”,点击连接,编辑发送数据,点击发送,就会看到接收到相同的数据。
连接串口调试助手,在串口调试助手上,会有WiFi连接整个过程的信息,例如,接收和发送回调函数打印的信息。
《connecting-to-the-internet-with-pico-w》:
源码:
-
发表了主题帖:
47“万里”树莓派小车——PicoW学习(PIO、编码器读取)
本帖最后由 lb8820265 于 2023-11-12 19:54 编辑
PIO简介
PIO是“Programmable I/O”的缩写,介绍在数据手册的309页,PIO和处理器一样是可编程的。RP2040有2组PIO,每个PIO里有4个状态机,所以Pico里共有8个状态机,可以独立的执行程序来操作gpio和传输数据,相比于传统处理器PIO更加关注与精确的定时和固定功能的硬件功能。单个PIO功能如下。
PIO通过9个汇编指令来实现各种功能,例如:I2C、 I2S、SDIO、SPI, DSPI, QSPI、UART、DVI 、VGA等等,这些功能芯片处理器很多都能实现,但是使用PIO会更加高效。
有人问,为什么不使用python语言进行程序编写,不能使用PIO进行编码器数据的读取这就是最大的理由。
目标
创建基于PIO的编码器读取工程,设置两组AB相编码器数据读取,在定时器中读取编码器的累计值和速度,并通过串口输出。
工程创建
参考上一篇帖子,使用“pico project generato”工具,增加勾选“PIO interface”,工程名为“Test_PIO_Encoder”。通常,PIO外设是需要进行编程的,编程需要用到汇编语言。好在例程编写好了,在“pio/quadrature_encoder”中。我们将“quadrature_encoder.pio”文件复制到创建好的工程根目录中,然后在“CMakeLists.txt”文件中进行修改,将原来的add_executable(Test_PIO_Encoder Test_PIO_Encoder.c )注释掉,改为如下:
add_executable(Test_PIO_Encoder)
pico_generate_pio_header(Test_PIO_Encoder ${CMAKE_CURRENT_LIST_DIR}/quadrature_encoder.pio)
target_sources(Test_PIO_Encoder PRIVATE Test_PIO_Encoder.c)
先编译工程,点击左边的CMake编译工具,再点击“Test_PIO_Encoder”工程后面的编译按钮,在就会出现“Test_PIO_Encoder_quadrature_encoder_pio_h”的可编译按钮,然后点击编译,如下图。
就会在根目录的“build”文件夹中"quadrature_encoder.pio.h"文件。这就是“pio”文件生成的头文件。
代码编写
前面的工作已经将工程框架搭建完成,下面贴出主要的代码。
PIO初始化
主要是PIO接口定义与功能初始化。
PIO pio = pio0;
const uint PIN_Encoder_1 = 16;//编码器1输入,16与17号引脚,只需要配置编码器的一个A输入口,相邻的下一个接口就是B
const uint SM_Encoder_1 = 0;//编码器1的SM编号,0
const uint PIN_Encoder_2 = 18;//编码器2输入,18与19号引脚,只需要配置编码器的一个A输入口,相邻的下一个接口就是B
const uint SM_Encoder_2 = 1;//编码器2的SM编号,1
void PIO_Encoder_Init(){
uint offset = pio_add_program(pio, &quadrature_encoder_program);
//初始化两个编码器输出PIO,只需要配置编码器的一个A输入口,相邻的下一个接口就是B
quadrature_encoder_program_init(pio, SM_Encoder_1, offset, PIN_Encoder_1, 0);
quadrature_encoder_program_init(pio, SM_Encoder_2, offset, PIN_Encoder_2, 0);
}
定时器初始化
初始化一个50ms的定时器。
void Timer_init(){
//配置定时器,-50表示50ms定时,负数表示从进入该函数开始计算,repeating_timer_callback是回调函数名
add_repeating_timer_ms(-50, repeating_timer_callback, NULL, &timer);
}
定时器回调函数
在回调函数中,获取两个电机编码器的值好定时器的精确值,算出速度,并通过串口输出。
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 = 0;
static int Encoder_Old_Value_1, Encoder_Old_Value_2 = 0;
int Encoder_Dalta_Value_1,Encoder_Dalta_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_1);
Encoder_Dalta_Value_1 = (Encoder_New_Value_1 - Encoder_Old_Value_1)/(float)t_delta*10000;
Encoder_Old_Value_1 = Encoder_New_Value_1;
Encoder_New_Value_2 = quadrature_encoder_get_count(pio, SM_Encoder_2);
Encoder_Dalta_Value_2 = (Encoder_New_Value_2 - Encoder_Old_Value_2)/(float)t_delta*10000;
Encoder_Old_Value_2 = Encoder_New_Value_2;
printf("time_diff_us: %8d\n", (int)t_delta);
printf("position_1 %8d, delta_1 %8d\n", Encoder_New_Value_1, Encoder_Dalta_Value_1);
printf("position_2 %8d, delta_2 %8d\n", Encoder_New_Value_2, Encoder_Dalta_Value_2);
}
编译烧录后,将一个编码器的AB线接入16和17引脚,另一个接入18和19引脚。转动电机,连接仿真器的串口,会打印定时器的时间差,电机1和电机2的累计计数和在该定时内的计数差。串口助手显示如下。
源码:
- 2023-11-01
-
发表了主题帖:
46“万里”树莓派小车——PicoW学习(PWM、定时器)
本帖最后由 lb8820265 于 2023-11-1 22:45 编辑
使用Pico W做底盘,需要至少有以下外设:GPIO,PWM,定时器,编码器读取和WiFi。GPIO,PWM,UART,定时器,这几个外设都有例程可以参考,移植起来也比较容易,这里一起介绍,顺便介绍一下工程移植过程。
目标
创建呼吸灯工程,设置两个个引脚为PWM输出连接LED,在定时器中断中改变PWM输出占空比,并通过UART输出定时器的间隔。
PWM简介
在写代码之前需要大致了解该芯片的PWM外设,PicoW主控芯片是RP2040,所以如果要详细的了解相关外设,可阅读芯片手册,在帖子最后有下载。PWM在数据手册的523页,所有的30个GPIO都可以用来输出PWM,一共16个PWM通道,由8个2通道的slices组成,也就是一个slices可以输出给两个引脚,可设置不同的占空比等。
PWM有一个不断增加计数器,通过TOP寄存器的值来周期,通过设置比较的值来控制占空比。普通模式(free-running模式)如下图。
PWM的频率公式如下。
fsys:PWM时钟,使用的CLK SYS,默认是等于PLL SYS=125Mhz
TOP:周期设置寄存器,默认65535
CSR_PH_CORRECT:相位校正模式,默认为0(普通模式)
DIV_INT:是时钟分配寄存器,1~255,默认为1
DIV_FRAC:FRAC是fractional的缩写,也就是小数,0~15,默认0
新建工程
使用前面介绍的方法打开工具“pico project generato”,勾选“HW TImer”,发现并没有PWM相关的模块可以勾选,这里我们尝试选择小车工程会需要的外设如下。
将例程中的“.viscode”文件夹复制到生成的工程中。生成的文件与大致的功能如下。
打开工程
打开“Pico - Visual Studio Code”软件,在软件中打开刚刚生成的工程文件夹。
会自动弹出选择编译工具,这两个任选一个都行,如果打开的时候错过了,可以点击最下方状态栏的“No Kit Selected”重新选择。
配置工程
重点关注“CMakeLists.txt”文件,这是CMake的配置文件。在“CMakeLists.txt”文件找到target_link_libraries,该指令的作用为将目标文件与库文件进行链接。
可以看到已有两个库文件,就是我们在工具中勾选的,从例程中得知,PWM的库文件名叫做“hardware_pwm”,因此添加该库文件如下。
还有一个add_executable指令,该指令的含义是使用“Test_Timer_PWM.c ”源文件生成“Test_Timer_PWM”可执行文件。
可以有多个该指令,生成多个可执行文件,可配合“target_link_libraries”指令链接不同的库,生成不同的可执行文件。
这里增加一个“peripherals.c”文件用来写外设的配置代码,如下。
新建“peripherals.c”与“peripherals.h”文件在根目录。
编写代码
PWM初始化如下:
void PWM_init(){
gpio_set_function(PIN_PWM_1, GPIO_FUNC_PWM);//设置引脚为PWM功能
gpio_set_function(PIN_PWM_2, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(PIN_PWM_1);//根据GPIO获取对应的slice号
pwm_config config = pwm_get_default_config();//获取默认的设置
pwm_config_set_clkdiv(&config, 4.f);//配置该slice的PWM的频率,4分频clk_sys
pwm_init(slice_num, &config, true);//配置并启动该PWM
}
定时器初始化如下:
void Timer_init(){
//配置定时器,-50表示50ms定时,负数表示从进入该函数开始计算,repeating_timer_callback是回调函数名
add_repeating_timer_ms(-50, repeating_timer_callback, NULL, &timer);
}
定时器回调函数如下:
bool repeating_timer_callback(struct repeating_timer *t) {
static absolute_time_t t_from;
absolute_time_t t_to;
int64_t t_delta;
static int fade = 0;
static bool going_up = true;
t_to=get_absolute_time();//获取上电开始的绝对时间
t_delta=absolute_time_diff_us(t_from,t_to);//获取时间差,转化为us
t_from=t_to;//保存上次的值
printf("time_diff_us: %8d\n", (int)t_delta);
if (going_up) {
++fade;
if (fade > 255) {
fade = 255;
going_up = false;
}
} else {
--fade;
if (fade < -255) {
fade = -255;
going_up = true;
}
}
pwm_set_gpio_level(PIN_PWM_1, fade * fade);//最大值65535,数值的平方更适合呼吸灯
pwm_set_gpio_level(PIN_PWM_2, 65535-fade * fade);
}
运行后,使用串口助手连接仿真器生成的串口,可以看到返回的数值都是50000,说明定时器非常的精准。
使用LED灯连接Pin14和Pin15另一端连接GND就可以看到灯交替闪烁了。使用示波器观察引脚频率,结合前面的PWM频率计算公式,理论上应该是125M/65536/4=476.84Hz,示波器实测的频率为476.9Hz,如下。
RP2040数据手册:
代码源文件:
- 2023-10-30
-
回复了主题帖:
来PK:最适合物联网开发的连接
lb8820265 发表于 2023-10-30 19:41
刚好最近在准备装修,计划全屋智能,智能家居算是物联网的一个典型的应用了,经过我的一番调研,我就从智能 ...
我说为啥以前我一直查不到华为使用的无线通信协议是啥,原来是自己的“闪星”,厉害,厉害,那我还是相信华为的技术,希望大力推广。
-
回复了主题帖:
来PK:最适合物联网开发的连接
刚好最近在准备装修,计划全屋智能,智能家居算是物联网的一个典型的应用了,经过我的一番调研,我就从智能家居这个切面来说说:目前主流的智能家居服务商包括:小米,绿米,易来,华为,摩根。
小米:主推WiFi,小米本身没有一个系统的智能家居服务,各个小厂的智能家居产品,可以连接在WiFi上进行控制,虽然本身也有蓝牙和多模网关,但是基本也没啥产品,所以主要还是以WiFi为主,因为简单,便宜,但是问题也非常多,延迟严重,稳定性差,不能连接太多个设备。
绿米:主推zigbee,绿米最开始是做智能门锁的,前期有小米的推广,现在基本和小米分家了,智能家居产品基本和小米不兼容,也就是如果选择绿米,除了路由器能用小米的,其他的设备全都用不了,需要用绿米的专用zigbee网关,因此,价格也是最贵的,但是效果也真的好,一个网关连接几十个设备不在话下,而且控制几乎没有延迟,比如灯的缓亮缓灭,这个竟然是通过不断的发送指令来控制的,几十个灯,还要不停发指令,竟然一点卡顿也没有,实在是牛。
易来:主推蓝牙mesh,易来的灯做的非常好,各项指标都很好,易来的营销是在网上用低价吸引客户去实体店,实体店的产品要比网上高级不少,实体店的产品都是使用蓝牙mesh协议的,但是我猜测这种mesh协议是不能自组网的,相当于星性结构,就只能和网关进行通信,整体和zigbee的效果差不多,也很厉害,而且价格要比绿米便宜不少。
华为,摩根:主推有线,华为也有无线通信,但是协议不明,但是主推的却是PLC,也就是有线,还有一家摩根智能,也是主推有线,说是有线要比无线稳定,但是,说有线要比无线稳定我是完全不同意的,没有过多了解,感觉有线就是主打一个高端,不是很推荐。
matter协议:我很奇怪,前段时间火热的协议,说是要终结智能家居的通信协议,以后一统天下,现在咋就没有哪个公司使用。现在智能家居各个公司都在各自为战,越来越封闭,选择一个品牌那么所有的产品都必须是这个品牌,这个完全不是物联网的初衷,希望有matter协议让物联网更加开放,更加兼容。
- 2023-10-29
-
发表了主题帖:
【DigiKey“智造万物,快乐不停”创意大赛】开箱——树莓派4B和PicoW
本帖最后由 lb8820265 于 2023-10-29 22:22 编辑
这次参加DigiKey的DIY大赛,计划做一个智能小车,主要用到树莓派4B和PicoW,开箱物料如下:
这次的作品会和“万里”树莓派小车同步制作,如有雷同,纯属巧合
-
回复了主题帖:
45“万里”树莓派小车——PicoW学习(C语言环境搭建、新建工程、在线调试)
plc2099 发表于 2023-10-28 09:02
步骤多了点!!!!
你说的对,我也感觉,这就是为啥很少有用C语言来编程控制Pico的,但是习惯了也还好,C语言还是有不少优势的。
- 2023-10-18
-
回复了主题帖:
45“万里”树莓派小车——PicoW学习(C语言环境搭建、新建工程、在线调试)
freebsder 发表于 2023-10-18 14:51
现在开发个单片机也要这么复杂的手续了哇?还是keil,iar好啊。并不是每个人都能折腾这么多乱七八糟的
哈哈,你说的真是我的心里话,我也是从keil、iar入门的单片机,那些编译、链接配置啥的都不要考虑,现在这些开源硬件都用免费的开发环境,配置就复杂了起来。
我这个分享的还是使用VSCode来开发还相对好一点,我见过一个大神,国外的一个很老的程序员,只需要一个代码编辑器比如vim,然后所有的操作都用指令来完成,整个写代码过程鼠标都不用,相当的优雅。
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
lugl4313820 发表于 2023-10-18 12:13
我上他家逛了一下,没找到大佬您的那一款呀。能方便给个链接吗?
好的,私信给你了,叫做R3差速底盘
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
lugl4313820 发表于 2023-10-18 07:32
价格不便宜呀,楼主花不少钱玩这小车子吧。
嗯嗯,确实是不便宜的,而且制作过程也是在摸索和试错,家里的各种零件都堆成山了
- 2023-10-17
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
lugl4313820 发表于 2023-10-17 18:08
楼主普及一下知识呀,这套件哪里有卖,弄个回来玩玩。
这个架子是淘宝上买的,一个叫做轮趣科技的店铺
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
lkh747566933 发表于 2023-10-17 17:22
我好奇前面的轮子是怎么样的,转弯时,会不会阻力特别大呀。
这个轮子很神奇,转弯很轻松
-
发表了主题帖:
45“万里”树莓派小车——PicoW学习(C语言环境搭建、新建工程、在线调试)
本帖最后由 lb8820265 于 2023-10-17 22:13 编辑
1. PicoW简介
PicoW就是Cortex-M0+内核的RP2040芯片加上一个CYW43439蓝牙WiFi双模芯片的核心板。主频最高可到133Mhz,内置264KB的 SRAM和2MB的板载内存,板子外形和相关外设如下图所示。
2. C语言环境搭建
网上大多是Pico W的python语言环境的搭建,但是据我了解在实时性和功能完整性上C/C++语言是要远远好于python语言环境的,所有我选择使用C/C++语言来开发Pico W,好在官方有教程。主要参考的文档为《getting-started-with-pico》和《connecting-to-the-internet-with-pico-w》。
Windows系统安装开发环境
Pico可以在多个操作系统中进行开发,但还是习惯在Windows下进行开发,在该GitHub仓库的介绍文档连接中下载安装包,直接双击安装,Pico的例程和VSCode开发环境也会一并进行安装。并且会生成一个专属Pico的VSCode环境的快捷方式,在开始菜单中“Pico - Visual Studio Code”。打开该VSCode会自动加载Pico的例程。
编译工程
首先确认编译工具选择“pico ARM GCC”或者“GCC 10.3.1 arm-nome-eabi”,VSCode软件最下面可以查看,函数库是默认使用的Pico硬件,WiFi和蓝牙相关例程是没有编译的,而且blink程序在PicoW上面也是不可以用的,可以在任意一个配置文件中添加使用PicoW设置和WiFi配置,例如在例程根目录的“CMakeLists.txt”文件中添加如下设置,SSID和Password需要根据实际的WiFi名和密码修改。
set(PICO_BOARD pico_w)
set(WIFI_SSID lb8820265)
set(WIFI_PASSWORD lb8820265)
在软件左边栏选择“CMake”,在最上方点击编译按钮可以编译所有工程,也可以在单个工程右边点击编译按钮,编译单个工程。
以blink程序为例,编译后的文件如下。
烧录工程
Pico可以像ST的NUCLEO开发板一样将生成的文件直接拖入到文件夹中就完成了烧录。不过Pico需要在插入USB的时候先按着板子上的“BOOTSEL”按钮。使用USB线连接板子和电脑,然后就出现一个新的盘符,像一个U盘一样,将编译生成的“*.uf2”文件复制到新的盘符里面就可以了,会自动运行,看到LED一闪一闪了。
3. 新建工程
Pico有两种方式新建工程,一种是通过命令行的方式,另一种通过自动工程工具“pico project generato”生成。工具网址,下载后该工具不能直接运行,需要使用命令启动,在系统搜索栏中搜索“Pico-Developer Command Prompt”运行。
转入进入到下载的软件目录中,例如:
cd pico-project-generator-master
输入如下指令运行软件:
py pico_project.py --gui
进入到软件界面,“Board Type”选择“Pico W”,其他的按需选择,最下面的“Create VSCode project”不需要勾选,因为软件自动生成的VSCode工程文件不好用,会导调试不成功。这里作为演示勾选如下配置。
从例程中将“.vscode”文件夹复制到刚刚新建的工程中,如下。
使用VSCode软件打开新建工程的文件夹,按照上面的方法进行编译,成功会生成“.elf”文件,如下。
4. 在线调试
Pico W支持SWD在线调试,需要完成OpenOCD的编译,在Windows环境下为了能编译OpenOCD又需要MSYS2软件。
MSYS2软件安装
在官网下载并安装该软件,然后打开MSYS软件,是一个类似终端的界面,然后进行输入如下指令进行环境的配置:
pacman -Syu
pacman -Su
pacman -S mingw-w64-x86_64-toolchain git make libtool pkg-config autoconf automake texinfo
mingw-w64-x86_64-libusb
下载编译OpenOCD
克隆树莓派仓库里的OpenOCD并且编译。这里要注意一定要通过指令克隆下来,不能在网页上直接下载下来。
git clone https://github.com/raspberrypi/openocd.git --branch rp2040 --depth=1
cd openocd
./bootstrap
./configure --disable-werror
make -j4
进入src文件夹,运行编译出来的文件,正确的结果如下。
制作Picoprobe
烧录工具可以使用Pico板子制作,也可以使用官方的Raspberry Pi Debug Probe工具,这里使用Pico通过烧录固件来制作一个Picoprobe,固件可以在官方GitHub
下载源码然后进行编译再烧录,但是我觉得没有必要,也可以直接在官网下载“picoprobe.uf2”文件,该文件在帖子最后也有下载。
给Pico烧录该固件后,将两个Pico连线如下。
使用杜邦线连接如下。
运行调试
选择“hello_serial”例程为例进行在线调试。点击左边栏的调试按钮,再点击绿色三角形,之后会在顶部弹出选择框,分别选择“Pico Debug”与“hello_serial”,就可以直接进入调试环境了,打开串口工具就可以看到输出的“Hello, world”字符串如下。
后续如果想要选择其他的例程进行调试,就点击最下面状态栏的[hello_serial]进行选择。最下面的状态栏指示栏如下。
- 2023-10-16
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
火辣西米秀 发表于 2023-10-16 07:29
有点小激动,很期待楼主后面的分享制作过程,,,
哈哈,谢谢啦!
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
极限零 发表于 2023-10-16 09:17
改用ESP32会不会过便宜一些,考虑到续航,还是用蓝牙连接更好一些
嗯嗯,ESP32也是一个很厉害的硬件产品,还没仔细了解过。不过WiFi有个优势就是可以连接路由器,以后家里全屋路由,小车连上WiFi,就可以在任何地方都能控制小车了
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
wangerxian 发表于 2023-10-16 17:53
楼主【万里】这个项目好久没更新了,最近不忙啦?
嗯嗯,前面一段时间比较懒惰,接下来要加油了
-
回复了主题帖:
44“万里”树莓派小车——PicoW遥控小车(视频展示)
damiaa 发表于 2023-10-16 09:08
楼主这个 优化后把成本降下来 可以销售了。
哈哈,销售这个倒是没啥意义,市面上太多这类东西,学习制作的过程比较有意思。