尝试用LCD与树莓派Pico 2控制步进电机
我有一个LCD触控屏连接在我的Raspberry Pi Pico 2开发板上。我的目标是在屏幕上检测触摸,当用户点按屏幕时让步进电机开始旋转。电机通过GPIO引脚进行控制。
我遇到的问题是,在触摸事件发生后,步进电机的转速比预期慢得多。我不确定问题是否出在驱动电机的方式、每步之间的延时,还是代码中对触控交互的处理。
我希望在屏幕被触摸后,电机能立即启动并以更高的速度旋转。造成电机运行如此缓慢的原因可能是什么,我又怎样提升性能?
#include <stdio.h>
#include "pico/stdlib.h"
#include "tft_lcd_ili9341/gfx/gfx_ili9341.h"
#include "tft_lcd_ili9341/ili9341/ili9341.h"
#include "tft_lcd_ili9341/touch_resistive/touch_resistive.h"
#include "image_bitmap.h"
#define SCREEN_ROTATION 1
const int width = 320;
const int height = 240;
const int BOBINAS[4] = {5, 4, 3, 2};
const int rotImgPosX = (width - 32) / 2;
const int rotImgPosY = (height - 24) / 2;
int f_btn = 0;
volatile int motor_state = 0;
volatile int imagem_state = 0;
void ledButtonCallback(GFX_Button *btn) {
f_btn = 1;
}
int direcao = 1;
void drawImagem(int estado) {
gfx_fillRect(rotImgPosX, rotImgPosY, 32, 24, 0x0000);
if (direcao == 1){ //horario
if (estado == 0)
gfx_drawBitmap(rotImgPosX, rotImgPosY, horario_1, 24, 32, 0xFFFF);
else if(estado == 1)
gfx_drawBitmap(rotImgPosX, rotImgPosY, horario_2, 32, 24, 0xFFFF);
else if (estado == 2)
gfx_drawBitmap(rotImgPosX, rotImgPosY, horario_3, 24, 32, 0xFFFF);
else if (estado == 3)
gfx_drawBitmap(rotImgPosX, rotImgPosY, horario_4, 32, 24, 0xFFFF);
}
else if (direcao == -1){ //æntihorario
if (estado == 0)
gfx_drawBitmap(rotImgPosX, rotImgPosY, anti_horario_4, 32, 24, 0xFFFF);
else if(estado == 1)
gfx_drawBitmap(rotImgPosX, rotImgPosY, anti_horario_3, 24, 32, 0xFFFF);
else if (estado == 2)
gfx_drawBitmap(rotImgPosX, rotImgPosY, anti_horario_2, 32, 24, 0xFFFF);
else if (estado == 3)
gfx_drawBitmap(rotImgPosX, rotImgPosY, anti_horario_1, 24, 32, 0xFFFF);
}
}
bool timer_motor_callback(struct repeating_timer *t) {
motor_state = 1; // Alterna o estado do motor
return true; // Retorna true para continuar o timer
}
bool timer_imagem_callback(struct repeating_timer *t) {
imagem_state = 1;
return true;
}
int main() {
repeating_timer_t timer_motor;
repeating_timer_t timer_imagem;
stdio_init_all();
for (int i = 0; i < 4; i++) {
gpio_init(BOBINAS[i]);
gpio_set_dir(BOBINAS[i], GPIO_OUT);
}
LCD_initDisplay();
LCD_setRotation(SCREEN_ROTATION);
configure_touch();
gfx_init();
gfx_clear();
gfx_setTextSize(2);
gfx_setTextColor(0x07E0);
gfx_drawText(
width/6,
10,
"PicoDock LED Toggle"
);
GFX_Button ledButton = {
.x = rotImgPosX,
.y = rotImgPosY,
.w = 32,
.h = 32,
.callback = ledButtonCallback
};
gfx_registerButton(&ledButton);
int i = 0;
int motor_on = 0;
int img = 0;
drawImagem(img);
add_repeating_timer_us(1000, timer_motor_callback, NULL, &timer_motor);
add_repeating_timer_ms(500, timer_imagem_callback, NULL, &timer_imagem);
while (true) {
int touchRawX, touchRawY;
int screenTouchX, screenTouchY = 0;
int touchDetected = readPoint(&touchRawX, &touchRawY);
if (touchDetected) {
gfx_touchTransform(SCREEN_ROTATION,
touchRawX, touchRawY,
&screenTouchX, &screenTouchY);
gfx_updateButtons(screenTouchX, screenTouchY, touchDetected);
}
if (f_btn) {
direcao = -direcao;
motor_on = 1;
drawImagem(img);
f_btn = 0;
}
if (motor_state && motor_on) {
motor_state = 0;
for (int k = 0; k < 4; k++) {
gpio_put(BOBINAS[k], 0);
}
if (direcao == 1){
gpio_put(BOBINAS[i], 1);
}
else {
gpio_put(BOBINAS[3 - i], 1);
}
i = (i + 1) % 4;
}
if (imagem_state && motor_on) {
imagem_state = 0;
img = (img + 1) % 4;
drawImagem(img);
}
}
return 0;
}
解决方案
GPIO引脚可能无法提供足够的电流来驱动电机。你应该改用逻辑电平MOSFET/晶体管来进行开关,然后通过一个合适的电阻把GPIO引脚连接到栅极/基极。此外,电机是感性负载,在关断时会产生电压尖峰,可能会损坏你的Pico。你应该在电机两端并联一个反向偏置的二极管(接法为“反向连接”,阴极连正极,阳极连负极),例如1N4007。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。