Atmega328 - Pulse-width modulation (PWM)
Autor: Victorio | Publicado: 2011-06-01T18:55:00-07:00

Processing – Controlando o Atmega328 com PWM no Standard Firmata
Este pequeno tutorial descreve os passos que fiz para construir a interface de controle do motor e um led pelo computador. O primeiro passo é fazer o upload do código “Standard Firmata” para o Atmega Arduino. Este código está na sessão da biblioteca Firmata da IDE Arduino, é uma versão do firmware específico para controle pelo Processing. Após o upload, nenhum comando funcionará direto no Arduino, os comandos deverão ser passados através da codificação no Processing pela porta serial.
O Arduino foi montado em uma Protoboard seguindo o esquema descrito a seguir, para acesso ao computador utilizei um conversor USB-TTL, este conversor possibilita o acesso pela porta USB com o Arduino e pode ser encontrado facilmente na Internet. Comprei o meu por R$ 26,00.



Pulse-width modulation (PWM) pode ser desenvolvido no Arduino de vários modos. O texto a seguir mostra de forma simples de como usar essa técnica para controlar a velocidade de um pequeno motor e um led através do computador. O código no Processing utiliza a mesma estrutura do exemplo proposto no exemplo “Fade” do Arduino.

/*&nbsp;Fade
&nbsp;This example shows how to fade an LED on pin 9&nbsp;using the analogWrite() function.
&nbsp;This example code is in the public domain.
&nbsp;*/int brightness = 0;&nbsp;&nbsp;&nbsp; // how bright the LED isint fadeAmount = 5;&nbsp;&nbsp;&nbsp; // how many points to fade the LED by
void setup()&nbsp; { &nbsp; // declare pin 9 to be an output:&nbsp; pinMode(9, OUTPUT);} 
void loop()&nbsp; { &nbsp; // set the brightness of pin 9:&nbsp; analogWrite(9, brightness);&nbsp;&nbsp;&nbsp; 
&nbsp; // change the brightness for next time through the loop:&nbsp; brightness = brightness + fadeAmount;
&nbsp; // reverse the direction of the fading at the ends of the fade: &nbsp; if (brightness == 0 || brightness == 255) {&nbsp;&nbsp;&nbsp; fadeAmount = -fadeAmount ; &nbsp; }&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; // wait for 30 milliseconds to see the dimming effect&nbsp;&nbsp;&nbsp; &nbsp; delay(30);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }

O que é PWM?
A Modulação por largura de pulso (MLP) - mais conhecida pela sigla em inglês "PWM" (Pulse-Width Modulation). Também é utilizada para variar o valor da transferência de potência entregue a uma carga sem as perdas ocorridas normalmente devido à queda de tensão por recursos resistivos. Em um sistema PWM, a chave de estado sólido (normalmente IGBT, MOSFET ou transistor bipolar) usada para controlar o fluxo de corrente: ora não conduzindo corrente, ora conduzindo, mas provocando uma queda de tensão muito baixa; como a potência instantânea dissipada pela chave é o produto da corrente pela tensão elétrica a um dado instante, isso significa que nenhuma potência é dissipada se a chave fosse uma chave "ideal". Com uma taxa de modulação suficientemente elevada, simples filtros RC são freqüentemente utilizados para suavizar o trem de pulsos em uma tensão analógica estável. Esse método é normalmente empregado no controle de velocidade de motores de corrente contínua.
Origem: Wikipédia, a enciclopédia livre.

Neste projeto, eu controlo um pequeno motor de corrente contínua de 6 Volts através de um MOSFET utilizando o PWM do arduino e também exibo o valor referente à velocidade na tela do computador. O controle da velocidade é feito por um programa no Processing, que se comunica com o arduino através da porta serial e envia valores para a mudança da velocidade. Esses valores variam de 0 a 255.
Referencia: http://processing.org/learning/
A seguir, veja o desenho na Protoboard de todos os componentes eletrônicos para o projeto.

=============================================================================

Na programação, criei dois módulos, o primeiro com os comandos para o controle no Arduino e o segundo com a classe de controle dos botões.
ArduinoControlPotMotors.pdeClassButtons.pde 
A codificação é auto descritiva para quem já conhece a linguagem, quem ainda não está familiarizado pode acessar os Sites para mais informações.
http://processing.org/learning/&nbsp; http://arduino.cc/en/Tutorial/HomePage
Abs, Marcelo Victorio A. Costa.
ArduinoControlPotMotors.pde
// By Marcelo Victorio A. Costa// 23/06/2011
import processing.serial.*;import cc.arduino.*;
Porta serial para a comunicação com o arduino;&nbsp;&nbsp;&nbsp; //[0] "COM1"&nbsp;&nbsp;&nbsp; //[1] "COM3"int pCOM = 1;int pino_led = 7;int pino_sensor_Pot = 3;int valor_capturado_Pot = 0;PFont arial;
int w = width;int h = height;
Cbutton CB1 = new Cbutton(600, 450, 80, 30,"Led1");Cbutton CB2 = new Cbutton(700, 450, 80, 30,"Exit");
void setup(){&nbsp;&nbsp;&nbsp; size(screen.width / 2, screen.height / 2);
&nbsp;&nbsp;&nbsp; background(0);&nbsp;&nbsp;&nbsp; ellipseMode(CENTER);&nbsp;&nbsp;&nbsp; println(Arduino.list());
&nbsp;&nbsp;&nbsp; arduino = new Arduino(this, Arduino.list()[pCOM], 57600);&nbsp;&nbsp;&nbsp; arduino.pinMode(pino_sensor_Pot, Arduino.INPUT);&nbsp;&nbsp;&nbsp; arduino.pinMode(pino_led, Arduino.OUTPUT);&nbsp;&nbsp;&nbsp; arial = createFont("Arial",50); 
&nbsp;&nbsp;&nbsp; println(width);&nbsp; }
void draw(){&nbsp;&nbsp; // captura o valor do potenciômetro&nbsp;&nbsp;&nbsp; valor_capturado_Pot = arduino.analogRead(pino_sensor_Pot);
&nbsp;&nbsp;&nbsp; background(200);&nbsp;&nbsp;&nbsp; // usa o valor capturado para alterar o diâmetro do círculo
&nbsp;&nbsp;&nbsp; fill(255,80,80);&nbsp;&nbsp;&nbsp; ellipse(width / 2, height / 2,&nbsp; valor_capturado_Pot/2,&nbsp; valor_capturado_Pot/2);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //println(valor_capturado_Pot);&nbsp;&nbsp;&nbsp; //println(height);
&nbsp;&nbsp;&nbsp; textFont(arial);&nbsp;&nbsp;&nbsp; fill(0,0,0);&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; text(valor_capturado_Pot/4,50,80);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delay(100);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; arduino.analogWrite(9,valor_capturado_Pot / 4);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; //Buttons Control&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (CB1.button()) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arduino.digitalWrite(pino_led, Arduino.HIGH);&nbsp;&nbsp; // set the LED on&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; else{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arduino.digitalWrite(pino_led, Arduino.LOW);&nbsp;&nbsp;&nbsp; // set the LED off&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; if (CB2.button()) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit();&nbsp;&nbsp;&nbsp; }
}
ClassButtons.pde// By Marcelo Victorio A. Costa// 23/06/2011
class Cbutton {&nbsp; int bx, by, bs, bt; &nbsp; String sNome; &nbsp; boolean locked = false;&nbsp; PFont arialButtons;
&nbsp; Cbutton (int pbx, int pby, int pbs, int pbt, String psNome) {&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bx = pbx;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by = pby;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bs = pbs;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bt = pbt;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sNome = psNome;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; boolean button() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; arialButtons = createFont("Arial",15);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textFont(arialButtons);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Test if the cursor is over the box &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mouseX &gt; bx &amp;&amp; mouseX &lt; bx+bs &amp;&amp; mouseY &gt; by &amp;&amp; mouseY &lt; by+bt) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drawbutton(255); &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mousePressed &amp;&amp; (mouseButton == LEFT)) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drawbutton(225);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; locked = true;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }else{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; locked = false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }else{&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drawbutton(150);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; locked = false;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp; return locked;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; void drawbutton(int pCollor) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stroke(100);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fill(pCollor);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rect(bx, by, bs, bt);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fill(0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; text(sNome,bx+25,by+20);&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }

}