servos matriz
FUNCIONAMIENTO DE SERVOMOTORES Y MOTOR PASO A PASO CON INDICADOR EN MATRIZ 8X8 CON COMUNICACION SERIAL
MATERIALES
- Tarjeta nucleo STM32F446RE
- Servomotores
- Motor paso a paso
- Tarjeta controladora de motor paso a paso ULN2003APG
- Matriz 8X8 con controlador MAX7219
- Jumpers
- Protoboard
Materiales
PROCEDIMIENTO
Se procede a conectar los servomotores a las salidas PWM de la tarjeta. El PINOUT esta definido en el código. Para el motor paso a paso se declaran 4 salidas digitales cualesquiera. La matriz se conecta a los pines de CLOCK, SSEL y MOSI.
Advertencia: Para alimentar los servo motores y el motor paso a paso se utilizo un fuente externa de 5V con tierra común a la tarjeta. La matriz si esta alimentada por la tarjeta.
El código muestra en la matriz la dirección y el número del motor el cual esta funcionando. Los datos de entrada van por serial utilizando el programa Advanced Serial Port Terminal para Windows.
El código es autoria de los desarrolladores del proyecto tomando como referencia el proyecto anteriormente publicado de funcionamiento de una matriz 8X8 con SPI, además del código de protocolo de comunicación serial y el funcionamiento de los servomotores extraidos del siguiente desarrollador. https://developer.mbed.org/users/fabeltranm/
Anotaciones y explicaciones en el código mismo
<</codigo>>
- include "mbed.h"
PC_12: DIN, PC_10: CLK, PA_15: LOAD/CS SPI max72_spi(PC_12, NC, PC_10); DigitalOut load1(PA_15); DigitalOut load2(PC_3);
DigitalOut A(PB_8); DigitalOut B(PB_9); DigitalOut C(PA_5); DigitalOut D(PA_6); DigitalIn dir(PC_13);
PwmOut mypwm(PA_0); PwmOut mypwm1(PA_1); PwmOut mypwm2(PB_0);
Serial command(USBTX, USBRX);
define registros de matriz MAX7219
- define max7219_reg_noop 0x00
- define max7219_reg_digit0 0x01
- define max7219_reg_digit1 0x02
- define max7219_reg_digit2 0x03
- define max7219_reg_digit3 0x04
- define max7219_reg_digit4 0x05
- define max7219_reg_digit5 0x06
- define max7219_reg_digit6 0x07
- define max7219_reg_digit7 0x08
- define max7219_reg_decodeMode 0x09
- define max7219_reg_intensity 0x0a
- define max7219_reg_scanLimit 0x0b
- define max7219_reg_shutdown 0x0c
- define max7219_reg_displayTest 0x0f
- define LOW 0
- define HIGH 1
- define DEBUG 1
*************** COMANDO MOVER MOTOR |POS 1|POS 2|POS 3|POS 4| POS 5| | < | #M | , | #°G | > | #M -> indica el motor que se va a mover #°G -> indica los grados a mover del servomotor <,> -> inicio, separdor y fin de comando el inicio de comando no se almacena en el buffer *****************
VARIABLES PARA DEFINIR EL COMMANDO
- define BUFF_SIZE 8
- define COMM_NUM_MOTOR 0
- define COMM_SEPARADOR 1
- define COMM_GRADOS_MOTOR 2
- define COMM_NUM_MOTOR1 3
- define COMM_GRADOS_MOTOR1 4
- define COMM_NUM_MOTOR2 5
- define COMM_GRADOS_MOTOR2 6
uint8_t buffer_command[BUFF_SIZE]={0,0,0,0,0,0};
void print_num(uint8_t val)
{ if (val <10) command.putc(val+0x30); else command.putc(val-9+0x40);
} void print_bin2hex (uint8_t val) { command.printf(" 0x"); print_num(val>>4); print_num(val&0x0f);
}
TODO : TIMEOUT UART SERIAL void Read_command() { for (uint8_t i=0; i<BUFF_SIZE;i++) buffer_command[i]=command.getc();
}
void echo_command() { for (uint8_t i=0; i<BUFF_SIZE;i++) print_bin2hex(buffer_command[i]);
}
uint8_t check_command() { if (buffer_command[BUFF_SIZE-1]== '>' && buffer_command[COMM_SEPARADOR]==','){
- if DEBUG command.printf("\nMover Motor:"); print_bin2hex(buffer_command[COMM_NUM_MOTOR]); command.printf(" -> "); print_bin2hex(buffer_command[COMM_GRADOS_MOTOR]); command.printf("N grados \n");
- endif return 1; }
- if DEBUG command.printf("\n ERROR COMANDO -> "); echo_command();
- endif return 0;
}
void maxOne( int reg, int col) { maxSingle es la funcion facil para usar una sola matriz max7219 load1 = LOW; comienza max72_spi.write(reg); especifica registro max72_spi.write(col); coloca datos load1 = HIGH; acegura que los datos estan cargados(en el cambio en alto de LOAD/CS) }
void setup () { iniciacion de la matriz MAX7219 configuracion SPI : 8 bits, modo 0 max72_spi.format(8, 0); maxOne(max7219_reg_scanLimit, 0x07); maxOne(max7219_reg_decodeMode, 0x00); usando una matriz led (sin digitos) maxOne(max7219_reg_shutdown, 0x01); no para modo apagado
for (int e=1; e<=8; e++) { registros vacios, apaga todos los LEDs maxOne(e,0);
}
maxOne(max7219_reg_intensity, 0x03 & 0x0f); con el primer registro se cambia intensidad luminica de la matriz. rango: 0x00 a 0x0f }
//////
void AN() {
maxOne(1,158); maxOne(2,69); maxOne(3,37); maxOne(4,30); maxOne(5,248); maxOne(6,36); maxOne(7,66); maxOne(8,241);
}
void CUg(){
maxOne(1,0); maxOne(2,240); maxOne(3,144); maxOne(4,240); maxOne(5,130); maxOne(6,242); maxOne(7,135); maxOne(8,2);
}
void NUg(){
maxOne(1,2); maxOne(2,247); maxOne(3,146); maxOne(4,242); maxOne(5,130); maxOne(6,242); maxOne(7,135); maxOne(8,2);
}
void COUg(){
maxOne(1,2); maxOne(2,247); maxOne(3,146); maxOne(4,242); maxOne(5,128); maxOne(6,240); maxOne(7,128); maxOne(8,0);
}
void CDg(){
maxOne(1,0); maxOne(2,240); maxOne(3,144); maxOne(4,240); maxOne(5,146); maxOne(6,210); maxOne(7,183); maxOne(8,2);
}
void NDg(){
maxOne(1,2); maxOne(2,247); maxOne(3,146); maxOne(4,242); maxOne(5,146); maxOne(6,210); maxOne(7,183); maxOne(8,2);
}
void CODg(){
maxOne(1,2); maxOne(2,247); maxOne(3,146); maxOne(4,242); maxOne(5,144); maxOne(6,208); maxOne(7,176); maxOne(8,0);
}
void CRg(){
maxOne(1,0); maxOne(2,248); maxOne(3,136); maxOne(4,248); maxOne(5,138); maxOne(6,170); maxOne(7,223); maxOne(8,2);
}
void NRg(){
maxOne(1,2); maxOne(2,255); maxOne(3,138); maxOne(4,250); maxOne(5,138); maxOne(6,170); maxOne(7,223); maxOne(8,2);
}
void CORg(){
maxOne(1,2); maxOne(2,255); maxOne(3,138); maxOne(4,250); maxOne(5,136); maxOne(6,168); maxOne(7,216); maxOne(8,0);
}
void PASOD(){
maxOne(1,0); maxOne(2,240); maxOne(3,144); maxOne(4,240); maxOne(5,114); maxOne(6,66); maxOne(7,247); maxOne(8,2);
}
void PASOI(){
maxOne(1,2); maxOne(2,247); maxOne(3,146); maxOne(4,242); maxOne(5,112); maxOne(6,64); maxOne(7,240); maxOne(8,0);
}
void command_motor(uint8_t nm,uint8_t grado) {
unsigned int g = grado*10+640;
if (nm==0x01){
if (grado==0x5a){
mypwm.pulsewidth_us(g);
NUg();
}
else if (grado<0x5a){
mypwm.pulsewidth_us(g);
CUg();
}
else{
mypwm.pulsewidth_us(g);
COUg(); }
}
else if (nm==0x02){
if (grado==0x5a){
mypwm1.pulsewidth_us(g);
NDg();
}
else if (grado<0x5a){
mypwm1.pulsewidth_us(g);
CDg();
}
else{
mypwm1.pulsewidth_us(g);
CODg(); }
}
else if (nm==0x03){
if (grado==0x5a){
mypwm2.pulsewidth_us(g);
NRg();
}
else if (grado<0x5a){
mypwm2.pulsewidth_us(g);
CRg();
}
else{
mypwm2.pulsewidth_us(g);
CORg(); }
}
else if(nm==0x04){
unsigned int p = grado*10;
if(dir==0x01){
PASOD();
for(int i=0; i<p; i++){
A=1; B=0; C=0; D=0; wait_us(950); A=1; B=1; C=0; D=0; wait_us(950); A=0; B=1; C=0; D=0; wait_us(950); A=0; B=1; C=1; D=0; wait_us(950); A=0; B=0; C=1; D=0; wait_us(950); A=0; B=0; C=1; D=1; wait_us(950); A=0; B=0; C=0; D=1; wait_us(950); A=1; B=0; C=0; D=1; wait_us(950); } }
else{
PASOI();
for(int i=0; i<p; i++){
A=0; B=0; C=0; D=1; wait_us(950); A=0; B=0; C=1; D=1; wait_us(950); A=0; B=0; C=1; D=0; wait_us(950); A=0; B=1; C=1; D=0; wait_us(950); A=0; B=1; C=0; D=0; wait_us(950); A=1; B=1; C=0; D=0; wait_us(950); A=1; B=0; C=0; D=0; wait_us(950); A=1; B=0; C=0; D=1; wait_us(950); } }
}
}
int main() {
- if DEBUG command.printf("Brandon\n");
- else command.printf("inicio sin debug\n");
- endif uint8_t val;
mypwm.period_ms(20); mypwm1.period_ms(20); mypwm2.period_ms(20); setup (); while (1){
val=command.getc(); if (val== '<'){ Read_command(); if (check_command()){ command_motor(buffer_command[COMM_NUM_MOTOR],buffer_command[COMM_GRADOS_MOTOR]); command_motor(buffer_command[COMM_NUM_MOTOR1],buffer_command[COMM_GRADOS_MOTOR1]); command_motor(buffer_command[COMM_NUM_MOTOR2],buffer_command[COMM_GRADOS_MOTOR2]);
} }
} }
Changes
Revision | Date | Who | Commit message |
---|---|---|---|
1:101a20f9eed2 | 2017-05-05 | miguelmstein | piccolo; |
0:84edf6b90d7e | 2017-04-27 | miguelmstein | servos matriz |