Voir la traduction automatique
Ceci est une traduction automatique. Pour voir le texte original en anglais cliquez ici
#Tendances produits
{{{sourceTextContent.title}}}
Machine à snacks basée sur l'écran intelligent T5L
{{{sourceTextContent.subTitle}}}
[Open Source Award Case]
{{{sourceTextContent.description}}}
Bonjour à tous ! Aujourd'hui, nous sommes ravis de vous présenter un cas primé de logiciel libre issu du forum des développeurs DWIN : Snack Machine Based on T5L Smart Screen (Machine à snacks basée sur un écran intelligent T5L). Cette solution exploite la puce T5L pour contrôler en temps réel la force et la vitesse de préhension des griffes via l'interface PWM. Elle prend en charge des fonctions telles que la lecture des durées d'appui prolongé sur les boutons d'arrière-plan, l'autocontrôle de chaque module, les alertes en cas d'erreur et l'affichage synchrone du nombre de pièces insérées, des comptes à rebours des jeux, etc. Il permet également de paramétrer les ratios pièces/crédits, les modes de jeu, les interfaces multilingues et les seuils de force de préhension.
(1) Code de communication entre l'écran intelligent T5L et le contrôleur principal
void uart2_master_isr() interrupt 4 {
u8 res ;
if(RI0) {
RI0 = 0 ;
res = SBUF0 ;
uart2_rx_timeout = UART2_RX_TIMEOUT ;
if((uart2_rx_sta&UART2_PACKET_OK)==0) {
if(step==0) {
recv_len = 0 ;
si(res==0x15) step = 1 ;
} else if(step==1) {
date_len = res ;
pas = 2 ;
si(date_len>UART2_PACKET_MAX_LEN) step = 0 ;
} else if(step==2) {
if(recv_len==date_len) {
step = 0 ;
if(res==0x16) {
uart2_rx_sta = date_len ;
uart2_rx_sta |= UART2_PACKET_OK ;
}
} else {
uart2_buf[recv_len++] = res ;
}
}
}
}
}
(2) Code du pilote de moteur
void motor_move(MOTOR motor, MOTOR_DIR dir) {
if (motor == MOTOR_Z) { // Moteur à griffes de l'axe Z
if (dir == MOTOR_DIR_NONE) { // Stop
MOTOR_Z_DISABLE() ;
} else {
if ((IS_MOTOR_Z_BACKWARD_POS() && dir == MOTOR_DIR_BACKWARD) ||
(IS_MOTOR_Z_FORWARD_POS() && dir == MOTOR_DIR_FORWARD))) {
MOTOR_Z_DISABLE() ;
dir = MOTOR_DIR_NONE ;
} else {
MOTOR_Z_ENABLE() ;
MOTOR_Z_DIR_PIN = (dir == MOTOR_DIR_BACKWARD) ;
}
}
} else if (motor == MOTOR_X) { // Mouvement du moteur sur l'axe X
// Logique similaire pour l'axe X avec contrôle de la position
else if (motor == MOTOR_Y) { // Moteur de déplacement sur l'axe Y
// Logique similaire pour l'axe Y avec contrôle de la position
else if (motor == MOTOR_CLAW) { // Moteur de griffe
if (dir == MOTOR_DIR_NONE) {
MOTOR_CLAW_RELEASE() ; // Libération de la griffe
} else {
MOTOR_CLAW_HOLD() ; // Maintien des objets
}
}
}
(3) Ajustement de la force et de la vitesse de rotation des griffes par PWM
const u16 MOTOR_DUTY[MOTOR_TOTAL][MOTOR_SPEED_MAX+1] = {
{45+DUTY_OFFSET, ...}, // Vitesses de l'axe X
{45+DUTY_OFFSET, ...}, // Vitesses sur l'axe Y
{45, 60, ...}, // Vitesses de l'axe Z (sans décalage)
{200, 220, ...}, // Niveaux de force des griffes
} ;
void motor_set_speed(MOTOR motor, u8 speed) {
if(speed>MOTOR_SPEED_MAX) return ;
pwm_set_duty((PWM_CH)motor, MOTOR_DUTY[motor][speed]) ;
}
void motor_set_claw_strength_by_vol(float vol) {
#define CLAW_DUTY_MIN 200
#define CLAW_DUTY_MAX TIM_ARR
u16 duty ;
vol = (vol - QZLDY_MIN) / (QZLDY_MAX - QZLDY_MIN) ; // Normalisation de la tension
if(vol<0)
vol = 0 ;
else if(vol>1)
vol = 1
duty = (u16)(vol * (CLAW_DUTY_MAX - CLAW_DUTY_MIN) + 0.5f) + CLAW_DUTY_MIN ;
pwm_set_duty(PWM_CH_MOTOR_CLAW, duty) ;
}
(4) Détection d'un appui long sur les boutons de l'arrière-plan du fabricant
u8 key_check_long_press(KEY key, u32 time) {
while(1) {
if( !(KEY_Scan(1) & key)) return 1 ; // Touche relâchée : échec
if(time) {
sys_delay_ms(1) ;
temps-- ;
if(time==0) return 0 ; // Délai d'attente : succès
}
}
}