ブートローダを書き込んでいない、生のATmega328Pに「optifix」と呼ばれるoptibootの改良版のブートローダを書き込む方法をメモしておきます。
概要
生のATmega328Pに「optifix」と呼ばれるoptibootの改良版のブートローダを書き込む手順を回路図つきで紹介しています。 この方法ではArduino UNOが必須です。
2017年12月22日追記 2017年12月現在、ArduinoのIDEから生のAVRマイコンへブートローダを書き込む機能があります。この方法は新しくありません。
手順
配線
http://arduino.cc/en/Tutorial/ArduinoToBreadboard ここに書いてある方法でArduino UNOと書き込み対象のマイコンを接続していきます。
必要な物は
・ブレッドボード ・Arduino UNO ・ATmega328P ・10kΩの抵抗 ・22pFのコンデンサ ・16MHzのクリスタル ・ジャンパ
です。
optifixのダウンロードと編集
http://arduino.cc/forum/index.php/topic,28733.0.html ここにあるoptifix.zipを用います。
そのままでは使用できないので、optifix.zipを展開して中のoptiloader.hを書き換えます。
#include <WProgram.h>
typedef struct image { char image_name[30]; /* Ie "optiboot_diecimila.hex" */これを
#include <Arduino.h>
typedef struct image { char image_name[30]; /* Ie "optiboot_diecimila.hex" */このように1行目を書き換えて保存します。
改行コードの関係でメモ帳は避けた方がよいです。
あとはArduinoIDEで先ほどのoptifix.pdeを開いて、シリアルモニターを開き、通信速度を19200baudに設定し、スケッチをアップロードして次のように表示されれば終わりです。
OptiFix Bootstrap programmer.2011 by Bill Westfield (WestfW)
Starting Program Mode [OK]
Reading signature:950FSearching for image... Found "optiboot_atmega328.hex" for atmega328 Start address at 7E00 Total bytes read: 508
Setting fuses for programming Lock: 3F FFE000 Low: FF FFA000 High: DE FFA800 Ext: 5 FFA400
Programming bootloader: 512 bytes at 0x3F00 Commit Page: 3F00:3F00 Commit Page: 3F40:3F40 Commit Page: 3F80:3F80 Commit Page: 3FC0:3FC0
Restoring normal fuses Lock: F FFE000
Type 'G' or hit RESET for next chipあとはもとのマイコンと入れ替えてBlinkなど適当なテストプログラムが動く事を確認できると思います。
元のマイコンをはずして書き込む事も可能です。
fuseがUno標準のoptibootとoptifixでは異なるようです。
簡単!ATmega328Pにブートローダを書きこむ | N.Yamazaki's blogでは以下のように書かれています。
フューズの違い フューズの設定はUnoとOptifixでは微妙に違います。EESAVEだけですので、EEPROM使う人はちょっと気をつけてください。
Uno: Low:FF HI:D6 Ext:FD Optifix: Low:FF HI:DE Ext:FD
EESAVEはFlash書き込み時にEEPROMを消すか、ということらしいです。
マイコン風聞録 - *: EESAVEでは以下のように書かれています。
で、Fuseビットをよくよく見ると「EESAVE」というのがあって これを設定することでFlash書き込み時にEEPROMの消去を阻止できることが ようやく分かった。
実際に、Arduino UNOに載ってたATmega328Pのfuseを読んでみるとhFusesは0xD6でした。
しかし、boards.txtを読んでみると、
uno.name=Arduino Unouno.upload.protocol=arduinouno.upload.maximum_size=32256uno.upload.speed=115200uno.bootloader.low_fuses=0xffuno.bootloader.high_fuses=0xdeuno.bootloader.extended_fuses=0x05uno.bootloader.path=optibootuno.bootloader.file=optiboot_atmega328.hexuno.bootloader.unlock_bits=0x3Funo.bootloader.lock_bits=0x0Funo.build.mcu=atmega328puno.build.f_cpu=16000000Luno.build.core=arduinouno.build.variant=standardoptibootだけどhFusesがDEになってますね。
0xDEなので1101 1110。 0xD6は1101 0110。
# ATMega328P fuse bits (fuse bits for other devices are different!):# Example for 8 MHz internal oscillator, default setting# Fuse high byte:# 0xd9 = 1 1 0 1 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000)# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0# | | | | | +-------- BOOTSZ1# | | | | +---------- EESAVE (0 : preserve EEPROM over chip erase)# | | | +-------------- WDTON (0 : Watchdog timer always on)# | | +---------------- SPIEN (1 : serial programming is disabled)# | +------------------ DWEN (0 : debugWIRE enabled)# +-------------------- RSTDISBL (0 : RESET pin is disabled)【備忘】ATmega328P fuse bit default setting : 湧雲日記
ということがわかります。
1 1 0 1 1 1 1 0 = 0xDE (optiboot) ^ ^ ^ ^ ^ ^ ^ ^------ BOOTRST (boot reset vector at 0x0000) | | | | | | +-------- BOOTSZ0 | | | | | +---------- BOOTSZ1 | | | | +------------ EESAVE (0 : preserve EEPROM over chip erase) | | | +-------------- WDTON (0 : Watchdog timer always on) | | +---------------- SPIEN (1 : serial programming is disabled) | +------------------ DWEN (0 : debugWIRE enabled) +-------------------- RSTDISBL (0 : RESET pin is disabled)
1 1 0 1 0 1 1 0 = 0xD6 (Arduino UNO) ^ ^ ^ ^ ^ ^ ^ ^------ BOOTRST (boot reset vector at 0x0000) | | | | | | +-------- BOOTSZ0 | | | | | +---------- BOOTSZ1 | | | | +------------ EESAVE (0 : preserve EEPROM over chip erase) | | | +-------------- WDTON (0 : Watchdog timer always on) | | +---------------- SPIEN (1 : serial programming is disabled) | +------------------ DWEN (0 : debugWIRE enabled) +-------------------- RSTDISBL (0 : RESET pin is disabled)つまり、boards.txtの通りだと、Flash書き込み時にEEPROMが消去されてしまう。 消して困る場合は、hFusesを0xD6に書き換えれば良いと思われます。(未検証)
fusesについてはこのページが便利です。 http://www.frank-zhao.com/fusecalc/fusecalc.php?chip=atmega328p
マイコンにはシール貼っておくとかなり便利です。
http://homepage1.nifty.com/ORBIT/etc/orbit-a01_arduino_sticker.pdf
このPDFとかいい感じです。
一応ミラー。
このブートローダだと16MHzのクリスタルを必ずつけないといけないので注意してください。
USBシリアル変換モジュールをブレッドボードに載せたりすると楽かもしれないです。
https://www.sparkfun.com/products/9716 ここにある回路図を参考にすればFT232RL(秋月で300円)と少しのパーツだけで作れるから安上がり…かな?
今度やってみます。
関連記事
- (Updated )Arduinoに書き込めない問題を修正する方法[not in sync]Arduinoのリセットピンの接続方法が問題で以下のようなエラーが出て、スケッチをアップロードできませんでした。その対処方法をメモしておきます。
- (Updated )秋月の通過型フォトインタラプタ、CNZ1023(ON1023)を使う秋月電子の通過型フォトインタラプタ、CNZ1023。
- (Updated )Arduinoに書き込めない問題を修正する方法[invalid device signature]ArduinoIDEからスケッチをアップロードしようとすると、以下のようなエラーが出てアップロードできませんでした。 boards.txtを修正して対処したのでその方法をメモしておきます。
- 2025年6月以降ROS環境でapt-get updateするときにGPG errorが発生する場合の対処方法2025年5月末にROS/ROS 2の署名鍵が期限切れになったことで発生するGPG errorの原因と、公開鍵を差し替えて解消する手順をまとめたメモ。
- Jetson Orin NanoをUSB接続のSSDから起動するmicroSDカードで動作確認済みのJetson Orin NanoをUSB接続SSDから起動する手順。SDK Managerが不要で、extlinux.confを書き換えるだけで移行できる方法を解説する。

