quinta-feira, novembro 17, 2011

Passo a Passo: Usando o Arduino UNO para Gravar o Bootloader do Arduino em um ATMega328

Como já mostrei sucintamente, um Arduino pode ser usado como gravador de microcontroladores AVR. Neste post, vamos ver passo a passo como usa uma Arduino UNO para gravar o bootloader do Arduino em um microcontrolador ATMega328 (em uma espécie de reprodução assexuada).



Pré-Requisitos

Você vai precisar de:
  • Um Arduino UNO. Outros modelos podem ser usados com pequenas adaptações.
  • A IDE do Arduino instalada no micro. No caso usei o Arduino 022 rodando sob Windows XP. Outras versões e outros sistemas operacionais podem exigir pequenas adaptações.
  • Comunicação entre o Arduino e o micro funcionando. Se você consegue carregar um sketch no Arduino, está tudo certo.
  • Uma breadboard (também chamada de protoboard ou matriz de contatos) e alguns fios de interconexão. Você pode fazer a montagem de outras formas, mas esta é a mais simples.
  • Um ATMega328. Com pequenas adaptações você pode usar um ATMega168 ou ATMega8.
  • Um cristal de 16MHz e dois capacitores de 22pF. O cristal pode ser de qualquer frequência entre 4 e 20MHz, 16MHz é o valor usado no Arduino. Os capacitores podem ser entre 12 e 27pF. Você pode ainda substituir estes três componentes por um ressonador.
  • Dois resistores de 1K 1/8 ou 1/4W.
  • Um LED (qualquer cor).
  • Um capacitor de 10uF, 16V ou mais.
 Além disso você precisa:

  • Saber qual a serial corresponde à conexão do Arduino. Com a IDE rodando e o Arduino conectado, você pode observar isto no menu Tools / Serial Port.
  • Saber em qual diretório está instalado o software do Arduino. No meu caso, está em "C:\Program Files\arduino-0022", mas provavelmente está em algum outro diretório do seu micro.

Passo 1: Programação do Arduino

Na IDE do Arduino, selecione File | Examples | ArduinoISP e faça o upload para o Arduino. Se tudo estiver certo, você verá a mensagem "Done uploading.".



Se isto não acontecer, você está com algum problema na conexão do Arduino ao IDE. Certifique-se que o modelo do Arduino e a porta serial estão selecionadas corretamente na IDE.

Passo 2: Teste Preliminar

Como primeiro teste, vamos colocar o LED de heartbeat. O LED tem um terminal positivo (normalmente mais comprido) e um negativo (normalmente indicado por uma parte reta no encapsulamento plástico). O terminal positivo será ligado ao pino Digital 9 do Arduino, através de um resistor de 1K. O terminal negativo será ligado ao terra (pino GND do Arduino):

O LED deverá piscar gradualmente, como se fosse um coração batendo:



Passo 3: Montagem

Desconecte o cabo USB e complete a montagem na protoboard, conforme a figura abaixo.

Atenção para a polaridade do eletrolítico, o terminal '-' deve estar ligado ao terra e o terminal '+' ao pino de Reset do Arduino.


Passo 4: Teste da Montagem

Abra uma janela de comando e vá para o subdiretório hardware\tools\avr\bin do diretório onde a IDE do Arduino está instalada. Digite o comando

avrdude -p atmega328P -c avrisp -P com4 -b 19200

substituindo COM4 pela porta que corresponde ao Arduino .

Você deve receber mensagens como as abaixo, indicando que o AVRDUDE conseguiu comunicar corretamente com o Arduino e reconheceu o ATmega328. Se o AVTDUDE der alguma mensagem de erro, verifique os passos anteriores.


Passo 5: Programação

Copie o arquivo optiboot_atmega328.hex do subdiretório hardware\arduino\bootloaders\optiboot para o subdiretório hardware\tools\avr\bin:

COPY ..\..\..\arduino\bootloaders\optiboot\optiboot_atmega328.hex

Para gravar o bootloader na Flash, usamos o comando

avrdude -p atmega328P -c avrisp -P com4 -b 19200 -U flash:w:optiboot_atmega328.hex

A gravação é bem rápida mas a verficação demora um pouco; ao final você deve ter algo como:


Agora falta somente acertar os flags:

avrdude -p atmega328P -c avrisp -P com4 -b 19200 -u -U efuse:w:0x05:m -U hfuse:w:0xDA:m -U lfuse:w:0xFF:m -U lock:w:0x0F:m

E pronto, você tem um ATmega328 pronto para ser colocado em um Arduino!

Um comentário sobre os valores dos fuses: na documentação da Atmel, os bits não usados dos fuses são indicados com o valor "1" porém o AVRDUDE usa o valor "0". Se você tentar programar o extended fuse com 0xFD, o AVRDUDE vai dizer que deu erro pois leu 0x05. Portanto é necessário colocar "0" nos bits não usados nos fuses.

Atualização em 28/4/12:  corrigido o esquema de montagem - o resistor no pino 1 (Reset) do ATmega que está sendo gravado deve ir para +5 e não para terra!

55 comentários:

Anônimo disse...

Realmente muito interessante essa tua postagem!Parabéns.
Uma pergunta. Você já tentou usar o Arduino como gravador para microcontroladores de outros fabricantes?

Daniel Quadros disse...

Não tentei usar como gravador para outros microcontroladores. Uma busca rápida mostrou alguns poucos projetos do tipo.

Anônimo disse...

Olá Daniel,
Não sei se recebeste meu e-mail. No site do Arduino.cc diz que não é possivel fazer isso no Arduino UNO. Tentei de diversas formas e não consegui gravar. Alguma dica?
Um abraço e parabéns pelo Blog.

Daniel Quadros disse...

O problema com o UNO é o auto-reset, o capacitor no reset deveria resolver isto. Veja o meu post
http://dqsoft.blogspot.com/2011/09/o-auto-reset-do-arduino.html

Anônimo disse...

Olá!
Parabéns pelo blog!
Estou seguindo esse tutorial mas me deparei com o seguinte erro:

avrdude: Expected signature for ATMEGA8 is 1E 93 07
Double check chip, or use -F to override this check.

Você pode me ajudar?
Abraços
Antonio

Daniel Quadros disse...

Antonio,

Para poder ajudar preciso de algumas informações adicionais.

Em que passo este erro aparece? Você está usando um Arduino UNO ou outro modelo? O chip que você quer gravar é um ATMega8 ou ATMega328?

Merchanda disse...

não estou conseguindo passar do passo 4 acontece da um erro, e não consigo, so consigo acessar o avrdude depois dai não da
\avrdude e quando coloco >avrdude não vai

Daniel Quadros disse...

Merchanda: você está no diretório onde o avrdude foi instalado? Qual a mensagem de erro que aparece?

Ribeiro disse...

Ao realizar o Passo 4 acontece um erro:
avrdude: can´t open config file "": No such file or directory
avrdude: erro reading system wide configuration file""

Ja refiz todo o processo e nao consigo realizar esse teste.

Atsuki disse...

É possível fazer o mesmo com o duemilanove?
Grato.

Daniel Quadros disse...

Sr Ribeiro: Veja se o arquivo de configuração está em hardware\tools\avr\etc. Se estiver, o mais simples é copiar para o mesmo diretório que o executável (hardware\tools\avr\bin). Outra opção é usar a opção -C na linha de comando para fornecer o caminho do arquivo de configuração (-C ..\etc\avrdude.conf).

Daniel Quadros disse...

Atduki: sim, é possível usar o Duemilanove. Neste caso, ao invés de ligar um eletrolítico entre o reset e o terra você precisa ligar um resistor de 120R entre o reset e o +5.

Anônimo disse...
Este comentário foi removido por um administrador do blog.
Anônimo disse...
Este comentário foi removido por um administrador do blog.
Anônimo disse...
Este comentário foi removido por um administrador do blog.
Anônimo disse...

Boa noite, gostei muito do tutorial, tava tentando de tudo e nada gravava o bootloader até que percebi que meu CI era atmega328 -PU e não o atmega328p-PU, achei uma meneira de resolver esse problema nesse link: http://arduino.cc/forum/index.php/topic,68889.0.html

Daniel Quadros disse...

Eu também já apanhei do atmega328-pu. A solução é acrescentar a definição deste chip no arquivo de configuração do avrdude, como indicado no link que você passou.

Unknown disse...

Olá, muitos parabéns pelo blog.
Eu estou com um erro, eu tenho uma arduino uno r2 e quero fazer o burn do bootloader do chip atmega328-pu, já alterei o ficheiro de configuração, mas quando estou no passo 5, tenho o seguinte erro:

C:\Arduino\arduino-1.0-windows\arduino-1.0\hardware\tools\avr\bin>avrdude -p atm
ega328P -c avrisp -P com13 -b 19200 -U flash:w:optiboot_atmega328.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.13s

avrdude: Device signature = 0x1e9514
avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed

To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "optiboot_atmega328.hex"
avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
avrdude: writing flash (32768 bytes):

Writing | ################################################# | 98% 1.06s
avrdude: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64
avrdude: stk500_cmd(): protocol error

O que posso fazer???
Cumprimentos
Diogo Inácio

Daniel Quadros disse...

Diogo,

Uma sugestão que encontrei na internet é acrescentar -vvv no comando. Com esta opção o avrdude vai apresentar várias mensagens de acompanhamento, aparentemente isto contorna um problema de temporização.

Outra sugestão que encontrei é baixar a velocidade de comunicação para 9600. Isto requer alterar o Serial.begin no sketch ISP e a opção -b na linha de comando do avrdude.

Nos conte depois se uma destas sugestões funcionou.

Unknown disse...

Muito obrigado pela resposta...
Tentei fazer as alterações que recomendou-me e tinha sempre o mesmo resultado...
Portanto como última alternativa fiz download do arduino 1.0.2 (tinha o arduino 1).
Com a alteração do Arduino e com mais umas trocas dos componentes, alterações na breadboard, consegui gravar o "optiboot_atmega328.hex" na memória do chip.

Conclui portanto que o erro deve-se ao equipamento, pois penso que o novo arduino não tem nenhuma alteração a respeito do optiboot_atmega328,...

Mais uma vez obrigado pelo atenção.

Anônimo disse...
Este comentário foi removido pelo autor.
Anônimo disse...
Este comentário foi removido pelo autor.
Anônimo disse...

Oi Daniel, primeiramente parabéns pelo blog, e especificamente por esse post. Fui seguindo seus passos e infelizmente obtive problemas no passo 4. Estou utilizando a versão 1.0.3 da IDE do arduino, arduíno uno R3 como gravador, e gravando um atmega328p. Acesso o diretório desejado e digito o comando requerido, e ele me retorna os seguintes erros:
avrdude: can´t open config file "":Invalid argument
avrdude: error reading system wide configuration file "".
Por acaso você teria alguma idéia do que poderia estar havendo? (Me desculpe se for algum erro bobo, sou "meio" iniciante). Obrigado desde já.

Daniel Quadros disse...

Vitor,

Vou instalar a versão 1.03 e fazer um teste, mas deveria ter no diretório o arquivo avrdude.conf. Se não tiver, procure nos outros diretórios e copie para junto do avrdude.exe.

Anônimo disse...

Oi Daniel, realmente, a versão 1.0.3 não tem o arquivo avrdude.config, então resolvi testar com a versão 0022, a mesma que você utilizou. Infelizmente o mesmo erro voltou a acontecer... Até tomei a precaução de executar em modo de administrador, mas mesmo assim, aconteceu do mesmo jeito. Caso já não seja pedir de mais, segue uma screenshot da tentativa, para uma possível análise: http://upload.crazzy.com.br/show-image.php?id=c81968a34dfa8242963a0359ca77c3e4

Daniel Quadros disse...

Vitor,

Veja se o avrdude.com não está em hardware\tools\avr\etc. Se estiver, copie para hardware\tools\avr\bin que deve funcionar.

Anônimo disse...

Daniel, muito obrigado pela paciência e atenção, parte dos problemas que estavam ocorrendo comigo foram resolvidos quando botei todos os arquivos necessários na pasta bin, alguns persistiram, mas ai troquei o atmega e tudo funcionou corretamente. Apesar de ter conseguido, ainda fiquei com umas dúvidas, e se não for pedir de mais, você poderia me dizer pra que servem as flags?
OBS: existe uma biblioteca chamada opitiloader, que deixa o processo um pouco mais simples. Ele dribla o auto-reset, sem necessidade do capacitor, e no caso de um atmega virgem, ele dispensa até os 2 capacitores de 22 e o cristal.

Anônimo disse...

da um Help ai:
da uma olhda o q esta acontecendo:

C:\arduino-1.0\hardware\tools\avr\bin>avrdude -p atmega328P -c avrisp -P com15 -
b 19200

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.09s

avrdude: Device signature = 0x000000
avrdude: Yikes! Invalid device signature.
Double check connections and try again, or use -F to override
this check.


avrdude done. Thank you.

Daniel Quadros disse...

Anônimo confira as ligações do Arduino com o ATmega, pois não estão conseguindo conversar.

Lovaglio disse...

Olá Daniel parabéns pelo Blog e este passo a passo que e util e funcional.

Realizei o teste com um arduino do modelo 2009 funcionou ok!

Tenho um arduino 2009 fabricado pela xinda que so funciona na versão da IDE 0023 você tem alguma ideia do que seja?

Alirio disse...

Parabéns pelo tutorial. Fiz todo o procedimento e não deu nenhuma mensagem de erro. Porém, quando coloco o atmega na placa e não comunica. erro: avrdude: stk500_getsync(): not in sync: resp=0x00. Se puder me ajudar, obrigado.

Daniel Quadros disse...

Alirio, apareceram todas as mensagens confirmando que o bootloader e os fuses foram gravados corretamente? A placa funciona com outro ATmega?

MARCOS COTONA disse...

Olá
Estou com mesmo erro da maioria no passo 4
fiz todas as dicas que falou, e foi melhorando, mas nao cheguei ao sucesso, ainda da erro:
avrdude: Device signature = 0x1e9514
avrdude: Expected signature for ATMEGA328P is 1E 95 0F
Double check chip, or use -F iverride this check

avrdude done. Thank you

ja colocoquei a opçao -vvv, apresentou outras janelas, ja troquei 3x o chip, chequei todas ligaçoes varias vezes, o led esta pulsando, enfim nao sei mais o que fazer
Pode ajudar.
Quais arquivos sao necessarios estar no ......\bin, pois no etc so tinha o avrdude.config, seria só este?
grato.

MARCOS COTONA disse...

Olá
Estou usando o Arduino UNO R2, mas nao consigo passar do passo 4.
POr favor me AJUDE.
como posso contata-lo por email ou telefone se for possivel.

grato

Daniel Quadros disse...

Marcos, os seus chips são o modelo atmega328-pu e não atmega328p-pu. A boa notícia é que você pode usar os seus chips. O mais simples é acrescenta r-F na linha de comando, para o avrdude não conferir a assinatura. A solução mais correta, mas mais trabalhosa, é incluir o atmega328 no avrdude.conf e trocar na linha de comando atmega328p por atmega328. Para incluir no conf, copie as linhas da definição do atmega328p e mude o nome a assinatura.

Anônimo disse...

Olá Daniel, estou com uma pequena dúvida. Após retirar o uC do arduino e colocar o novo microcontrolador no lugar, a mesma não deveria ser alimentada por uma fonte externa de 12V? As gravações neste nível requer tensões maiores?

Daniel Quadros disse...

Anônimo, acho que você misturou as coisas: (1) o microcontrolador novo vai na protoboard (2) se você alimentar o Arduino com 12V ele continua a operar a 5V (3) este tipo de programação é feita a 5V mesmo, não precisa de tensão maior.

Anônimo disse...

Olá Daniel, realmente confundi tudo mesmo. Muito obrigado pela explicação. acho que vou comprar um garagino e gravá-lo.

Esthevan disse...

Daniel ótimo post

Talvez oque eu estava realmente precisando.

Sou iniciante no mundo da eletronica então desculpe qualquer besteira que falar.

Estou fazendo um projeto que ira usar um Arduino Standalone Atmega328p só que gostaria de ligar-lo em um cristal de 20mhz.

O chip que comprei ja veio com o bootloader do arduino gravado (16mhz), as informações que encontrei na net dizem que tem que regravar o bootloader, e editar alguns arquivos (.txt) dentro da pasta da IDE do arduino.

Seria isso mesmo? Tenho que regravar o bootloader usando seu tutorial.
Modificar o documento boards.txt na IDE

Em seguida, dando certo, eu posso usar placa do arduino uno, com um cristal de 16mhz para gravar o codigo, depois passar o chip para a placa a placa final com o cristal de 20mhz?

Daniel Quadros disse...

Esthevan, basicamente é isto, só que tem um passo importante faltando: é preciso recompilar o bootloader para ele funcionar a 20MHz.

Unknown disse...

Tenho um arduino mega 1258, é possível utiliza-lo para gravar o bootloader num atmega328p-pu ?
quais as alterações que devem ser feitas?

Vlw

Daniel Quadros disse...

William,sim você pode usar um Arduino Mega, porém os pinos da interface SPI são diferentes:
10->53
11->51
12->50
13->52

Unknown disse...

Prezados, estou tentando gravar o bootload no arduino chip atmega 328p -pu porem esta me dando a seguinte menssagem

avrdude: Expected signature for ATMEGA328P is 1E 95 0F
Double check chip, or use -F to override this check.
já fiz de tudo já verifiquei todas as conexões já troquei o arduino e nada. Alguem pode me ajudar

Daniel Quadros disse...

Franklin, verifique se o ATmega é o ATmega328P-PU. O avrdude deve ter informado a assinatura que ele leu. Se for 00 00 00 tem algo errado na montagem, se for algo diferente pode ser que você esteja com outro modelo do ATmega (por exemplo um ATmega328-PU, sem o P).

Anônimo disse...

Fiz todos os passos descritos no tutorial utilizando o ATmega328p-PU e não ocorreu nenhum problema. Para quem está tendo dificuldades em encontrar o arquivo "avrdude.conf", na versão 1.0.5 fica localizado no diretório ...\arduino-1.0.5-r2\hardware\tools\avr\etc, esse deve ser copiado para ...\arduino-1.0.5-r2\hardware\tools\avr\bin. Contudo, gostaria de saber se há uma maneira de testar o funcionamento do bootloader após a gravação. Obrigado.

Anônimo disse...

Eu estou tentando reproduzir o projeto do protuino, o qual necessita do bootloader, que consegui gravar utilizando o tutorial acima. A minha pergunta é se existe um processo análogo para gravar o firmware USB em um ATmega8A-PU (ou ATmega8)?

Unknown disse...

Daniel tenho um atmega328-pu, toda vez que tento gravar a aparece a seguinte informacao
avrdude: Device signature = "0xfbdf7"
avrdude: Expectede signature for atmega328P is 1E 95 14

ai toda vez q eu rodo o comando ele gera uma "Device signature" diferente.

o outro ci q tenho da o comando ate
"avrdure stk500_disable (): protocolo erro, expect=0x14, resp 0x51
avrdude: initialization faled, rc=-1

Patricio disse...

Parabéns pela iniciativa!
Gostaria desaber se tem como gravar o bootloader no ATmega8 com a nano?Pode me ajudar?

Daniel Quadros disse...

Patricio, sim é possível. As conexões de hardware são as mesmas, porém os valores para os fuses e o bootloader são outros.

Cristian disse...

Bom tutorial, mas tive um erro ao executar o cmd acusando que está faltando o libusb0.dll

Daniel Quadros disse...

Cristian, o libusb0.dll deveria estar no mesmo diretório que o avrdude.exe (hardware\tools\avr\bin). Obs: Neste post eu estou usando uma versão antiga da IDE, pode ser que tenha mudado nas versões mais recentes.

Miguel disse...

Muito bom, eu sempre tive duvidas de gravar bootloader mas vi este site e consigui gravar, nao ocorreu nenhum erro. Boa Sorte dou nota 10

Miguel disse...

Funcionou tudo corretamente:


C:\Program Files (x86)\Arduino\hardware\arduino\avr\bootloaders\optiboot>avrdude -p atmega328P -c arduino -P com6 -b 115200 -u -U efuse:w:0x00:m -U hfuse:w:0x00:m -U lfuse:w:0x00:m -U lock:w:0x00:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e950f
avrdude: reading input file "0x00"
avrdude: writing efuse (1 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0x00:
avrdude: load data efuse data from input file 0x00:
avrdude: input file 0x00 contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0x00"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0x00:
avrdude: load data hfuse data from input file 0x00:
avrdude: input file 0x00 contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0x00"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0x00:
avrdude: load data lfuse data from input file 0x00:
avrdude: input file 0x00 contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.02s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude: reading input file "0x00"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.02s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x00:
avrdude: load data lock data from input file 0x00:
avrdude: input file 0x00 contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of lock verified

avrdude done. Thank you.

Miguel disse...

Meu tipo de arduino é Arduino Uno CH340G

Miguel disse...

Por isso troquei os fuses