ATmega328Pに、FT232RLでスケッチを書き込んで、シリアルモニタも使う（Windows）

# FT232RLって、Amazonで安く売ってるんですよね
FT232RLを使ったUSBシリアル変換アダプタって、Amazonで1個500円前後で売られてたりします。
こんな形のやつ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34966/f543c59e-aa91-2042-8eba-861ec3fcee0e.png)

AVR-ISPのライターは3～4千円くらいするし、ArduinoUNOをISPにもできるけどそっちも3千円を超えるし。
なので、FT232RLを搭載した、汎用のUSBシリアル変換アダプタで、ATmega328PやATTiny85に書き込めるようにします。

# 必要なもの
- ATmega328PとかATtiny85とか、とにかくAVR系のマイコン
- FT232RLを使ったUSBシリアル変換アダプタ（CP2102でもいけるかも。）
- USB miniBケーブル（変換アダプタの口に合わせてご用意ください）
- ブレッドボード
- ジャンパ線6本
- ICソケット。なくてもいいけどブレッドボードが痛むらしい。安いブレッドボードをAVR書き込み専用にしてしまえば、なくてもいいような…
- Arduinoの開発環境（今回はVSCodeとPlatformIOを例にしています。）
- FT232-AVR Writer http://jsdiy.webcrow.jp/ft232_ftavrw/ 『昼夜逆転』工作室様
    - うちの環境ではavrdudeが「libftdiかlibusbが無い」って言って動かなかったので、ピン配置さえ変えればavrdudeでも動くんじゃないかと思います。

# 配線
ブレッドボードなどを使って、USBシリアル変換アダプタとATmega328Pなどを、このように配線します。
重要なのは「SCK」「RESET」「MISO」「MOSI」の4つのピンです。これらのピンの位置を、お使いのマイコンのピン位置に合わせてください。
この図ではATTiny85を例にしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34966/bc768bda-572f-47a8-12d2-894c75005d12.png)

FT232RLをArduinoのISPにする記事ではRTSピンを接続しているものが多いようですが、たいていの安い変換アダプタには、RTSが無くて、CTSのピンが生えているようです。なので、この記事ではCTSピンを接続しています。後述のFT232-AVR Writerの引数にピンを指定しているのでCTSピンできちんと動きます。
VCCとGNDは変換アダプタから取らなくても大丈夫です。

# マイコンの情報を読んでみる
動作確認として、fuseの設定を読んでみます。
http://jsdiy.webcrow.jp/ft232_ftavrw/ から、FT232-AVR Writerをダウンロードして解凍してください。
コマンドプロンプトを起動したら、下記のコマンドを実行します。

```
ftavrw.exe -pa3410 -br9600 -r -rf
```

こんな風に表示されれば、適切に接続できています。

```
FT232 open
Target device = ATtiny85

Signature byte = 1E 93 0B
Flash memory size = 8192byte (64byte x 128page)
EEPROM size = 512byte (4byte x 128page)

Read fuse byte.
Low  =  01100010  62
High =  11011111  DF
Ext  =  -------1  FF

OSC Calibration byte : 0x00 0x01 = 136 60 (decimal)

FT232 close
Press any key.
```

# fuseを設定する
ATTiny85とかATmega328とか、どれもこれも、ブートローダーすら書き込まれていない出荷状態のものは、内蔵RCクロックで1MHzで動作するように設定されています。
これを、内蔵RCクロックで8MHzで動作するように変更します。
もちろん、外部クロックで動作するように設定してもかまいません。

内蔵RCクロックの8MHzで動作させる場合、fuseのLowに 11100010（0xE2）を書き込みます。

```
ftavrw.exe -pa3410 -br9600 -fl11100010
```

```
FT232 open
Target device = ATtiny85

Write fuse byte : Low = 11100010 (-FL11100010 0xE2)
->Verify NG : Read =    00000000

FT232 close
Press any key.
```

Verifyに失敗していますが、うちではよくあることです。ノイズが多いのでしょうか…
確認のために読み取っておきましょう。

```
ftavrw.exe -pa3410 -br9600 -rf
```

```
FT232 open
Target device = ATtiny85

Read fuse byte.
Low  =  11100010  E2
High =  11011111  DF
Ext  =  -------1  FF

OSC Calibration byte : 0x00 0x01 = 136 60 (decimal)

FT232 close
Press any key.
```

大丈夫なようです。
MISOとMOSIをプルアップしたりすれば、もっと高速に通信できると思います。わたしの回路は手抜きです。
`-br9600` の部分がbaudrateなので、変えて試してみてください。

# スケッチを書く
なんでもいいんですが、今回はLチカとソフトウェアシリアルのスケッチを書きました。
ソフトウェアシリアルの容量が大きいので、Flashが2KBしかないマイコンには書き込めません。そういう場合はシリアルモニタを諦めましょう…

```c++
#include <Arduino.h>
#include <SoftwareSerial.h>

#ifdef PIN_RX
    SoftwareSerial SSerial(PIN_RX, PIN_TX);
    #define LOG(str) SSerial.println(str)
#else
    #define LOG(str)
#endif

void setup() {
    #ifdef PIN_RX
    SSerial.begin(9600);
    #endif
    LOG("init");
    pinMode(PIN_LED, OUTPUT);
}

bool on = false;
void loop (){
    char msg[] = "loop:       ms";
    ultoa(millis(), msg + 7, 10);
    LOG(msg);
    on = !on;
    digitalWrite(PIN_LED, on ? HIGH : LOW);
    delay(1000);
}
```

# PlatformIOの準備をする
## platformio.ini に設定を書く
後述するPythonスクリプトも必要なのですが、まずはiniの、envに下記のように記入します。
envの名前とbuild_flagsの部分は適宜変更してください。

```ini
[env:ATTiny85-20PU]
board = attiny85
platform = atmelavr
extra_scripts = extra_script.py
framework = arduino
upload_protocol = custom
upload_flags = 
	-pa3410
	-w2
	-v-
	-br9600
monitor_speed = 9600
build_flags = 
	-DPIN_LED=4
	-DPIN_RX=0
	-DPIN_TX=1
```

## extra_script.py を設置する
platformio.ini と同じディレクトリに、 extra_script.py を設置します。
`UPLOADER`の部分は環境に合わせていじってください。この例ではplatformio.iniと同じディレクトリに `ftavrw` フォルダがあることになっています。

```python:extra_script.py
Import("env")

platform = env.PioPlatform()

env.Prepend(
    UPLOADERFLAGS=[]
)
env.Append(
    UPLOADERFLAGS=[]
)
env.Replace(
    UPLOADER="$PROJECT_DIR/ftavrw/ftavrw.exe",
    UPLOADCMD="$UPLOADER $PLATFORMIO_UPLOAD_FLAGS $UPLOADERFLAGS $BUILD_DIR/firmware.hex"
)
```

## アップロードする
こんな風に、platformioからftavrwが呼び出されます。
![Desktop-2020.07.06---15.03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34966/aff2477e-3b48-8bc0-3ea9-380c228f3ea4.gif)

# シリアルモニタについて
シリアルモニタに触れてませんが、スケッチでSoftwareSerialを初期化してるので、アップロード出来てればシリアルモニタも使えるはずです。
大切なことは、ATtiny（またはATmega）のMISOとFT232のRXを、MOSIとTXを接続することです。
それで、Flashライターとシリアルモニタの機能を両立できます。

# FT232RLって、Amazon以外でも安く売ってるんですよね
AliExpressなんて、ものによっては$2未満です。
JTAGとかが使える上位のチップがあるので、古くて下位なチップは投げ売りされてるんでしょうかね。
とにかく安くて、ブレイクアウトボードから生えてる6ピンをブレッドボードに挿してminiUSBを挿せば、書き込みが出来てシリアルモニタも出来るようになるので、個人的にはArduinoUNOをISPにするよりお手軽かなと思っています。
それではみなさん、世界をLチカで幸せにしましょう～