El proposito de este ejemplo es mostrar el funcionamiento de 2 motores DC activandolos por PWM lo cual podemos hacer con cualquier microcontrolador. Para este ejemplo usaremos una Placa Romeo la cual utilizo por la comodidad de tener los perifericos mas utilizados en un robot para uso didáctico. Se podria combinar un puente H tipo L298 con una placa Arduino UNO, o utilizar cualquiera similar.
El proposito del ejemplo es el siguiente: El mismo programa de prueba realizado con el IDE standard de Arduino y con el Atmel Studio 6. Veremos que si programamos en ANSI C directamente el mismo programa ocupara la cuarta parte de memoria o menos.
El programa con el IDE de Arduino ocupa 1882 bytes
El mismo programa con Atmel Studio 6 ocupa 430 bytes
Como podemos ver la diferencia en memoria es considerable.
// Ejemplo utilizando el IDE Arduino. //================================================= //Standard PWM DC control int E1 = 5; // M1 Control de velocidad int E2 = 6; // M2 Control de velocidad int M1 = 4; // M1 Control de Dirección int M2 = 7; // M2 Control de Dirección int L1 = 13; // Led de la placa void setup(void){ int i; for(i=4; i<=7; i++) pinMode(i, OUTPUT); pinMode(L1,OUTPUT); } void loop(void){ if(digitalRead(L1)) digitalWrite(L1, LOW); else digitalWrite(L1, HIGH); advance (80,80); delay(5000); back_off (80,80); delay(5000); turn_L (60,60); delay(5000); turn_R (60,60); delay(5000); advance (70,70); delay(5000); back_off (70,70); delay(5000); stop(); delay(5000); } void stop(void){ //Stop digitalWrite(E1,LOW); digitalWrite(E2,LOW); } void advance(char a,char b){ // Movimientro hacia adelante analogWrite (E1,a); digitalWrite(M1,HIGH); analogWrite (E2,b); digitalWrite(M2,HIGH); } void back_off (char a,char b){ // Movimientro hacia atras analogWrite (E1,a); digitalWrite(M1,LOW); analogWrite (E2,b); digitalWrite(M2,LOW); } void turn_L (char a,char b){ // Giro CCW analogWrite (E1,a); digitalWrite(M1,LOW); analogWrite (E2,b); digitalWrite(M2,HIGH); } void turn_R (char a,char b){ // Giro CW analogWrite (E1,a); digitalWrite(M1,HIGH); analogWrite (E2,b); digitalWrite(M2,LOW); }
// El mismo ejemplo anterior con Atmel Studio 6 - ANSI C //================================================= /* * MotorCC.c * * Created: 09/01/2013 19:29:59 * Author: BairesRobotics */ #define F_CPU 16000000UL #include < util/delay.h > #include < avr/io.h > #define LED 0b00100000 void Move_Fwd(char, char); void Move_Bck(char, char); void Turn_L(char, char); void Turn_R(char, char); int main(void){ DDRD = 0b11110000; DDRB = LED; TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM21) | _BV(WGM20); TCCR0B = _BV(CS22); OCR0A = 180; OCR0B = 50; while(1){ PORTB ^= LED; Move_Bck(35,35); _delay_ms(3000); Move_Fwd(35,35); _delay_ms(3000); Turn_L(60,60); _delay_ms(3000); Turn_R(60,60); _delay_ms(3000); Move_Fwd(45,45); _delay_ms(3000); Move_Bck(45,45); _delay_ms(3000); Stop(); _delay_ms(3000); } } void Move_Fwd(char a, char b){ // Movimiento hacia adelante OCR0A = a; PORTD |= 0b10000000; OCR0B = b; PORTD &= ~0b00010000; } void Move_Bck(char a, char b){ // Movimiento hacia atras OCR0A = a; PORTD &= ~0b10000000; OCR0B = b; PORTD |= 0b00010000; } void Turn_L(char a, char b){ // Giro CCW OCR0A = a; PORTD &= ~0b00010000; OCR0B = b; PORTD |= 0b00010000; } void Turn_R(char a, char b){ // Giro CW OCR0A = a; PORTD &= ~0b10000000; OCR0B = b; PORTD |= 0b10000000; } void Stop(void){ // Stop OCR0A = OCR0B = 0; }
Buen ejemplo Jorge, te hago una consulta no te parece que configurar los PWM, tanto en ATMEL, ARDUINO, y PIC , son mas sencillos que en Freescale, me da esa impresion, me gustaria saber tu opinion al respecto teniendo en cuenta tu experiencia.
Saludos, gracias y que andes bien.
Cristian, creo que en cualquiera de los tres es sencilllo. solo que algunos te dan mas salidas PWM, o tiene mas opciones, no se si sera mi experiencia pero las formas de uso son muy similares.