quarta-feira, 26 de junho de 2013

Ambiente de Desenvolvimento para PIC: SDCC+GPUtils

À medida que ficamos mais exigentes com os microcontroladores as complexidades começam a aparecer. Programar em Assembly começa a deixar espaços para algo mais produtivos... então vamos para um compilador.

Naturalmente pensa-se em C. Mas de qual fabricante? Bom o objetivo desse post não é tecer um comparativo entre uns e outros. Cada um tem uma visão de como tratar o código. Eu escolhi o SDCC por ser o mais disponível de todos. (É gratuito).

O SDCC


O SDCC surgiu como um projeto para a criação de um compilador que pelo menos facilitasse a vida de portar código entre diferentes microcontroladores (retargettable compiler). Vamos deixar de utopias, mas isso é praticamente impossível a menos que tenha uma camada que abstraia o processador. O SDCC suporta muitos dos microcontroladores comuns: PIC(8bits, 16bits), 8051, HC08, Z80. Com uma ou outra alteração que atenda às características intrínsecas do microcontrolador, podemos ter um código até razoavelmente portável...

Bom, mais informações sobre o projeto do sdcc: http://sdcc.sourceforge.net/

O problema do SDCC é que o manual é escasso e confuso. O projeto é bem intencionado. Tenho acompanhado as listas de developers por longa data e muito daquelas pessoas têm dado uma constante dedicação para criar e manter um produto com grande qualidade (Parabéns/Congrats/KUDO's). Para quem está iniciando programar com vistas ao SDCC, configurar o ambient e se achar nele é uma novela.

GPUtils


Não vou falar muito do projeto GPUtils pois pouco tenho interagido com o grupo que o desenvolve. Mas é uma alternativa para o MPASM (da microchip) e têm tido muito sucesso. Eu chamo o GPUtils de backend de PIC do SDCC.

O SDCC não gera código HEX. Mas gera o código assembly necessário para que o GPUtils/gpasm possa tratar e gerar o .HEX.

SDCC+GPUTILS: Instalação


Não vou ser purista em ambiente de desenvolvimento. Esse post é para instalações baseadas em WINDOWS. Fora a instalação que é específica para esse ambiente, o restante se aplica a qualquer sistema operacional.

Baixe e Instale o SDCC do site http://sourceforge.net/projects/sdcc/files/
Durante a instalação NÃO DEIXE QUE O INSTALADOR ADICIONE O SDCC AO PATH; e anote onde ele instalou!


Baixe e Instale o GPUtils do site http://sourceforge.net/projects/gputils/files/
Durate a instalação NÃO DEIXE QUE O INSTALADOR ADICIONE O SDCC AO PATH; e anote onde ele instalou!

Por que não deixar adicionar? Simples. No Windows ele irá colocar os caminhos como "C:\Program Files..." isto é com espaço em branco e isso dá dor de cabeça depois! :) Além do que, os utilitários do SDCC e GPUtils poderão gerar conflitos com os utilitários do Windows/DOS. Ok?

Nota: Estou assumindo que GPUtils e SDCC serão instalado no diretório padrão (C:\Program Files\...).

Configuração do Ambiente

Eu recomendo criar um arquivinho .CMD dentro do diretório bin do SDCC. Por exemplo, no meu sistema, o SDCC está instalado em c:\Program Files\SDCC; então eu tenho um arquivo C:\Program Files\SDCC\bin\setEnv.cmd com o seguinte conteúdo:

@echo OFF

echo SDCC Development Environment Setup
echo.

SET PATH=C:\WINDOWS;C:\WINDOWS\SYSTEM32
SET PATH=C:\PROGRA~1\SDCC\bin;%PATH%
SET PATH=C:\PROGRA~2\GPUTILS\bin;%PATH%


No Desktop, um atalho para o prompt do DOS (c:\Windows\System32\cmd.exe) com os parâmetros setados conforme  abaixo:



Nome/Name: SDCC Command Prompt
Destino/Target: C:\Windows\System32\cmd.exe /K ""c:\Program files\SDCC\bin\setenv.cmd""
Iniciar em/Start In: C:\Development\SDCC

Explicando...


O arquivo setenv.cmd é o acionador do nosso shell de desenvolvimento. Ele possui as principais entradas para configurar o ambiente tendo acesso ao básico do DOS, mais o SDCC e o GPUTILS. Se for necessário adicionar um outro caminho para algum utilitário que queira usar no desenvolvimento de seus códigos, em vez de poluir o PATH global do sistema, aqui é um bom lugar!

PROGRA~1, PROGRA~2? é... lembra que eu falei sobre nao deixar o windows adicionar o path? Pois bem, existe uma condição (digamos assim) que faz com que o sdcc tenha problemas durante a compilação/linkedição por causa dos espaços em branco. No meu sistema, "C:\Program Files" é registrado (convenção DOS 8.3) como c:\PROGRA~1, e é onde está o SDCC. "C:\Program Files (x86)" é c:\PROGRA~2. É onde encontra-se o GPUtils.

C:\Development\SDCC? Você não me falou disso! É o meu diretório de desenvolvimento. Crie um e coloque o startup do atalho apontanto para ele.


Para ver os nomes do seu sistema assim, abra o prompt do DOS e digite DIR /X :)

Testando...


Se fez como eu disse, você vai ter ter:
- No desktop: O atalho do Prompt do DOS - Agora SDCC Command Prompt;
- Dentro do \bin o arquivo setenv.cmd apontando para os locais corretos

Duplo clique no SDCC Command Prompt e...




Bingo!

Crie um pequeno programa: blink.c

#define __18F252
#include "pic18fregs.h"

#pragma config OSC=HS, OSCS=OFF, PWRT=OFF, BOR=OFF, WDT=OFF, CCP2MUX=OFF, LVP=ON, CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF

int main()
{
TRISB=0xFD;
while(1) {
PORTB=(PORTB^0x02);
}

}

Salve e compile

c:\Development\SDCC>sdcc --use-non-free -mpic16 -p18f252 blink.c
message: using default linker script "C:\Program Files (x86)\gputils\lkr\18f252_g.lkr"

c:\Development\SDCC>

Ignore a mensage do linker script - NÃO É ERRO! Inspecione o diretório (dir)

c:\Development\SDCC> dir
 Volume in drive C has no label.
 Volume Serial Number is 88EE-897E

 Directory of c:\Development\SDCC

06/26/2013  04:29 PM             .

06/26/2013  04:29 PM             ..

06/26/2013  04:29 PM             4,198 blink.asm
06/26/2013  03:03 PM               238 blink.c
06/26/2013  04:29 PM             8,192 blink.cod
06/26/2013  04:29 PM               630 blink.hex
06/26/2013  04:29 PM            13,111 blink.lst
06/26/2013  04:29 PM             4,833 blink.o
               6 File(s)         31,202 bytes
               2 Dir(s)  165,685,358,592 bytes free


All done! Você já tem um .HEX para queimar no PIC (não faça isso ainda, os fuses estão "a la loca"!):)

--//--

Próximos posts: Picolino (minhas placas chegaram!!!), Programação para PIC usando SDCC

sexta-feira, 7 de junho de 2013

PIColino - Development Board para PIC

Mais um projeto que estou encabeçando, apresento-lhes em primeira mão o Picolino! Dá até para ter idéia né?!

Muitos já procuraram por aí uma placa de desenvolvimento com a versatilidade do Arduino, mas, para a família de microcontroladores PIC essa busca nunca é satisfatória por diversos fatores, dentre eles cito o custo e design. Talvez o que mais chegue perto é o ChipKit. Mas não vou entrar nesses assuntos agora.

A minha proposta é apresentar para vocês um projeto novo e acredito que vai ajudar bastante muita gente nos trabalhos de conclusão de curso. É o Picolino, uma placa QUASE  compatível com o conhecido Arduino... Mas o core dele é um PIC da famila 18F de 28 pinos.

O Picolino

O hardware do Picolino deverá possuir as seguintes características:
  • Alguma Compatibilidade (pin/pin) com shields Arduino;
  • Clock de 20MHz ou mais (isso garantirá no máximo 5MIPS para as famílias PIC18F ou 1MIPS/MHz em PIC24 e PIC32)
  • Porta Serial RS232 nativo (ainda insisto no RS232, apesar do USB estar começando a aparecer com mais frequencia);
  • Simples de usar, simples de implementar;
  • Compacto: "best fit" na categoria.(aproveita o mesmo layoute do Arduino, só que espelhado)

Por design do microcontrolador, aparecerão as restrições:
  • Ausencia de PWM pins. Terá que ser feito via software!
  • I2C pins e RXTX em localização diferente do arduino
  • Programação via conector próprio (Sem bootloader ainda)
  • 5 portos AD (em vez de 6 no arduino) (mesmo trazendo 6 pinos no conector RA)
  • SPI (MISO/MOSI/SCLK/SS) via software apenas!

Mesmo com algumas restrições que o afastam ainda mais do Arduino, o projeto parece ser promissor. Haja visto que existe uma base de conhecimento imensa usando PIC tais como compiladores, livros didáticos e muitos outros recursos de software.

Ser "best fit" na categoria significa que ele provê o máximo de funcionalidade possível e que pelo menos, num projeto de tamanho razoável (controle de iluminação, temperatura, controles pequenos), pelo menos 50% da sua capacidade seja usada. Isto é, o seu integrado e suas funcionalidades não tenham pinos desperdiçados!

Escolhi a família de microcontroladores PIC18F sendo a placa base, compatível com os seguintes microcontroladores:

PIC18F2520
PIC18F2550
PIC18F2580
PIC18F26K20
CPU clk (max)
40
48
40
64
CPU clk (MIPS)
10
12
10
16
MEM (CODE)
32K
32K
32K
64
MEM (RAM)
1.5K
2K
1.5K
3.5K
MEM (EEPROM)
256
256
256
1K
IO PINS
25
24
25
25
AD converters
10
10
8
10
Timers
4
4
4
4
PWM
2
2
1
1
RS232
Y
Y
Y
Y
I2C
Y
Y
Y
Y
SPI
Y
Y
Y
Y
USB

Y


CAN


Y

LIN
Y
Y
Y
Y


 Ainda tem o PIC18F252 que ficou de fora da comparação. Mas é tirar um e colocar outro no lugar. 

Especial atenção para quem utilizar PIC18F2550: O pino RC3 é perdido pois nesse chip ele é usado para ser referencia de VUSB!

Protótipo

Não costumo perder tempo nos meus projetos. Sempre que começo a pensar, já tenho que implementar algo que possa ser facilmente realizável e entender as suas dificuldades. Então temos abaixo o esquema inicial do protótipo. Parece promissor.

Surpresa!!! Saiba que o picolino tem quase a mesma configuração de pinos de um AVR, só que espelhado...  Isso cria uma nova e interessante solução. conector do Arduino tem que ser colocado no lado da solda. Sendo assim fica pro lado dos componentes o conector dos shields Picolino

Mandei hoje (06/06/2013) a requisição para cotação da manufatura de 6 protótipos... quer ver como ele vai ficar?


Os componentes nessa fase são through hole. Futuras versões virão mais compactos. Usarei SMD.

Agora a surpresa... Saiba que o Picolino tem quase a mesma configuração de pinos de um Arduino, só que espelhado...  Isso cria uma nova e interessante solução: - conector do Arduino tem que ser colocado no lado da solda. Sendo assim fica pro lado dos componentes o conector dos shields Picolino, veja o esquema abaixo:

   .Picolino. Arduino Shield
   .    |   .  
=|-.   =|=  . -|=-|=
[| .   [|   .  |] |
<| .   [|   .  || | 
=|-.   =|=  . -|=-|=
   .    |   .
O desenho não ficou bom..

Ambiente de Programação

Esse é um assunto delicado. Pois desenvolver hardware e software ao mesmo tempo é algo complexo e demanda muito tempo... não tenho equipe comigo nisso. Então vamos fazer assim.

Fica o leitor liberado para usar o que quiser, mas desde que tenha possibilidade de escrever o firmware através do porto ICSP da placa. 

Em paralelo, vou estar trabalhando com uma frente: SDCC. Onde criarei wrappers que facilitem a programação. Em seguida o bootloader. Fica o leitor liberado para usar com toda liberdade. 

--//--

Quando chegar as placas do Picolino, eu atualizo este post...  :)

quinta-feira, 23 de maio de 2013

Driver de Motor: L298 + Arduino (Parte 3 - Final)

Não adianta em nada fazer um hardware, passar horas a fio roteando cada trilha do circuito para não ter com que usar. Os microcontroladores trouxeram para o mundo uma flexibilidade enorme para o projeto de hardware... então mãos na massa

Especificações

O firmware deverá ser capaz de fazer o controle total do hardware:
- acionar as respectivas saídas: direção, acionamento e velocidade
- ler as entradas de controle (Rsensing)

Não colocarei portabilidade no rol de requisitos. É para Arduino, pronto e acabou. Se quiser portar para PIC, 8051 ou outra plataforma... é um outro projeto.

Para facilitar o instanciamento, já que o compilador core do Arduino suporta suporta, é uma classe (isso mesmo C++!!!) chamado L298Driver. Junto dele vai um exemplo do sketch para ser feito no Arduino.

Implementação

Para reduzir a complexidade desse post, o código fonte está disponível no site do Google Code, sob o projeto l298-arduino-driver: https://code.google.com/p/l298-arduino-driver

Instalação e Teste

É necessário que se tenha o Arduino. Procure identificar onde o Arduino está instalado. Vamos chamar esse diretório de ; dentro dele existem diversos diretórios. O importante é o libraries.

Baixe o projeto do GoogleCode, https://code.google.com/p/l298-arduino-driver/source/browse/ o arquivo L298Driver.zip

""Unzipe"" o arquivo para dentro da pasta libraries dentro do diretório de instalação do Arduino IDE , como na figura abaixo: 


Uma vez feito. Abra o Arduino IDE (ele irá reconfigurar os diretórios para reconhecer a nova biblioteca).

Antes de codificar, indique para utilizar a biblioteca: Menu>Sketch>Import Library>L298Driver, a IDE irá adicionar o cabeçalho #include .. veja abaixo

E por fim um programa funcional!


É compilar, gravar no Arduino, empilhar o Shield e se divertir!

Até breve!

quarta-feira, 22 de maio de 2013

Driver de Motor: L298 + Arduino (Parte 2)


Continuação do artigo anterior (parte 1)
Esta é a parte do artigo que explicará as funcionalidades e modo de operação do nosso driver. O artigo anterior, lidados com as bases do hardware. Na 3a e última parte, descreveremos a biblioteca para Arduino.

Funcionamento

O funcionamento é extremamente simples. Aplicando as tensões nas entradas de controle conforme o diagrama abaixo, temos a ativação, ou não, da saída.

Entrada
Saída
A(C)
EN1(2)
B(D)
OUT
X
0
X
0
0
1
0
0
0
1
1
RUN +
1
1
0
RUN -
1
1
1
0

X - não importa o valor da entrada.
0, 1: sinal low (0V) e high (Vcc) respectivamente
RUN: saída ativada (+ em uma polaridade, - com polaridade invertida)

No diagrama abaixo, temos um exemplo de conexão com a utilização do Arduino. A conexão SENS1,SENS2 é opcional.



A alimentação do motor não deverá ultrapassar 46V. Nem o consumo total dos motores, excederem 2A cada um – Não há fusível de proteção.
Quando a alimentação do motor estiver ativada, o LED7 ficará aceso. Os demais LEDs estão ligados às linhas de sinal do L298.

PWM

Até o presente momento não se falou em controle de velocidade. Do jeito que está, o motor irá girar na sua velocidade nominal, proporcional à corrente que passa, claro! E se quisermos dotar os motores de um controle de velocidade? Como não temos potenciômetros para controlar corrente, então lançamos mão do PWM.

O PWM significa Pulse Width Modulation, ou modulação por largura de pulso. Quando se trabalha com PWM, o leitor tem que ter em mente o conceito de ciclo de trabalho (duty cycle). Um sinal de PWM tem freqüência fixa, e valores de amplitudes bem definidos – 0 ou 1 (0 ou VCC, como quiser) – mudando somente quanto tempo no ciclo o sinal vai estar em 0 ou 1. Isto é, eu altero somente a largura do pulso... Veja  no diagrama abaixo 5 sinais  de mesma freqüência, porém com largura de pulso diferentes.



Na prática, dado as características elétricas da carga mediante um sinal variável, a largura de pulso irá influenciar dramaticamente no comportamento do dispositivo:
  1.   A tensão efetiva (eficaz ou RMS) será proporcional à largura do pulso. Apesar da corrente agora, ser também pulsada, esse conceito não se aplica. Se o motor consome 2A, ele receberá os 2A, só que por um período de tempo determinado pelo PWM. Isso faz com que se tenha melhor controle de consumo e por sua vez a potência consumida J
  2. Sinais PWM costumam gerar harmônicos: Prepare-se para instabilidades com ruídos e ajustes nos capacitores que vão aos motores L
  3. O corte abrupto (1 --> 0) nos sinais PWM faz com que as cargas indutivas criem correntes parasitas (fly back). Os diodos de proteção irão trabalhar mais intensamente! Fica de olho, costumam esquentar!!! K  

Plugue os pinos EN1 e EN2 nas portas do Arduino que suportem PWM. Quando ativar o pino, em vez de usar a função digitalWrite, use analogWrite passando o numero do pino e o valor de PWM desejado (0 a 255, para 0 e 100% respectivamente)
No diagrama de conexão acima, os pinos EN estão ligados aos pinos 6 e 9 que são PWM! :) 


Current Sensing

Por fim, e não menos importante, current sensing, isto é os pinos SENS1 e SENS2. É dele que virá o controle de feedback do driver.

Se estiver utilizando o current sensing propriamente, isto é com o resistor de 0.5Ohm/1W. Teremos ali a leitura de tensão proporcional à corrente que passa por cada canal do L298. Conforme especificado, se essa tensão ultrapassar 1V, teremos uma corrente circulante &gt; 2A, o que pode queimar o integrado...

Os pinos SENS1 e SENS2 deverão ser ligados a um conversor AD, o arduino possui esses pinos (A0..A5). Para ler, utilize analogRead(). Faça as conversões necessárias. O AD do arduino tem resolução de 10bits... com fundo de escala de 5V... então fazendo os cálculos, qualquer leitura acima de 204 (~=1V) já podemos tomar algumas ações como, diminuir o ciclo de PWM; ou desabilitar o canal respectivo momentaneamente; ou parar tudo para proteger o L298.

No diagrama acima, eles estão ligados aos pinos A0 e A1 respectivamente.

--//--

No proximo e último artigo, trataremos da biblioteca de controle para o Arduino.

terça-feira, 21 de maio de 2013

Driver de Motor: L298 + Arduino (Parte 1)


Vamos fazer o Arduino andar? É comum o Arduino ser utilizado em projetos de robótica, ora lendo sensores e dando um feedback e/ou movimentando algum chassis com motores.

Fazer estas coisas não é um mistério, mas em muitos casos conseguir no mercado nacional aquele shield que faça essa interface é uma aventura e muitas vezes o preço não é convidativo.

O driver aqui descrito é baseado num manjadíssimo circuito integrado dedicado para motores o L298; Vários fabricantes produzem esse integrado, mas é mais comum vê-lo sob a sigla da ST (SGS-Thompson). Esse integrado é conhecido como "Ponte H" - H-Bridge - Dual. Isto é, ele tem 2 bridges, o que pode fazê-lo controlar 2 motores com um componente só! O que é muito bom!

Quer saber um pouco mais sobre pontes-H? Visite o artigo neste blog: http://mmc-zaap.blogspot.com/2013/05/ponte-h.html

O L298

O L298 implementa a ponte-H conforme o diagrama abaixo:

Não se assuste com as portas AND fazendo o driver dos transistores. A função dele é criar a lógica necessária de forma que NUNCA coloque os transistores de saída em curto e fazer a interface entre o setor de baixa tensão e alta tensão.  Já que o L298 trabalha com 2 alimentações.

São 2 canais(A, B); Eis a Pinagem e função:
Pino
Função
Descrição
IN1
E
Entrada de comando canal A
IN2
E
Entrada de comando Canal A
OUT1
S
Saída de carga canal A
OUT2
S
Saída de carga canal A
EN1
E
Habilita canal A
SENS1
S
Saída para o sensor de corrente do canal A(R)
IN3
E
Entrada de comando canal B
IN4
E
Entrada de comando Canal B
OUT3
S
Saída de carga canal B
OUT4
S
Saída de carga canal B
EN2
E
Habilita canal B
SENS2
S
Saída para o sensor de corrente do canal B(R)
VS
PWR
Alimentação do conjunto de potencia dos canais
VCC/+Vss
PWR
Alimentação da lógica
GND
PWR
Ground

Não vou entrar nos detalhes das características elétricas, mas resumirei o que for importante para a implementação desse projeto:
- Alimentação da lógica: 4,5V a 7V.
- Alimentação do conjunto de poténcia: 7 a 46V - com limitação de corrente circulante de até 2A por canal!!! (não se iluda com os 4A que diz no datasheet, isso é corrente TOTAL=A+B)
- Frequencia de comutação máxima aplicada nos pinos IN e EN : 40Khz (caso use alguma entrada com PWM)

O Sensor de corrente nada mais é que um resistor cuja derivação serve para monitorar a tensão gerada. Um microcontrolador ou algum outro circuito dedicado tem que ler essa saída e fazer o corte do fornecimento de tensão para a carga de forma que o circuito se mantenha estável e dentro dos parâmetros de funcionamento.

O datasheet não é claro, mas há o entendimento que deverá ser um resistor cuja finalidade é gerar uma tensão proporcional à corrente circulante em cada um dos canais. O corte será feito se a corrente atingir 2A.

Segundo o datasheet, a tensão gerada em SENS1, SENS2 não deverá exceder 2V. Se fixarmos em 1V, teremos que para 2A, a resistencia deverá ser de 0.5Ohm. Portanto um Resistor de 0.5Ohmx1W tá de bom tamanho. Pede-se que seja um resistor puro, não de fio. Pois num processo de comutação, esses resistores (de fio) podem dar problemas devido indutância intrínseca do componente. 


O circuito

Com base no datasheet do L298, o circuito final é bastante simples:

Para auxiliar a depuração e funcionamento do motor, foi colocado uma bateria de LED's na parte de controle do circuito, justamente para visualizar o sinal de cada estágio.

Os diodos D1 a D8 são diodos para proteção. Se o circuito não for crítico, pode usar o 1N4007. Mas recomendo algum tipo de diodo schottky para potência: 1N5819, UF4007 por exemplo. Não utilize o circuito sem os diodos de proteção. D9 é só uma proteção adicional contra inversão de polaridade.

C1,C2 são capacitores de desacoplamento de fonte. Valores não críticos: 10uF para o Eletrolítico, 100nF para o despolarizado (Cerâmica ou poliéster - tanto faz). C3,C4 são de poliéster - 10nF ou 47nF. para desacoplamento/ruído do motor.

Especial atenção para RS1 e RS2. Estes resistores deverão ser de 0.5Ohm/1Watt. De preferência que não seja de fio! Caso o driver trabalhe com motores de pequena potência (desses de brinquedos) O resistor pode ser substituído por um jumper. Os demais resistores (R1 a R6) 1k2; R9 é calculado em função da tensão de alimentação 4k7 tá de bom tamanho)

O conector J1 é do tipo KK. Ele não é conectado diretamente a algum pino do Arduino por uma questão de projeto. No futuro pretendo liberar mais outros 2 artigos, usando um controlador dedicado para este driver de potência: Usando o SN74HC14 ou SN74HC00 (ou qualquer porta inversora) e outro dedicado ao seu controlador original, o L297. Esses 2 últimos projetos, sim, conectados diretamente à porta do Arduino. X1,X2,X3 são conectores tipo MTA de 0.156” (distância entre pinos) com trava.

Realização

Abaixo temos o layout do circuito impresso. Em breve disponibilizarei o projeto na em um repositório público e o leitor poderá baixar e reproduzir a placa.


Veja como ficou...


Veja o vídeo do carro robótico em funcionamento, logo abaixo:



É isso aí! Até a próxima!