c – Trying to control step motor with LCD and Raspberry Pi Pico 2
I have an LCD touchscreen connected to my Raspberry Pi Pico 2. My goal is to detect a touch on the screen and, when the user taps it, start spinning a stepper motor. The motor is controlled through GPIO pins.
The problem I am facing is that the stepper motor is spinning much slower than expected after the touch event. I am not sure if the issue is related to the way I am driving the motor, the delay between steps, or the way the touchscreen interaction is handled in the code.
I would like the motor to start spinning immediately and at a higher speed after the screen is touched. What might be causing the motor to run so slowly and how I could improve the performance?
#include
#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;
}
Read more here: Source link
