【ATtiny202/402】メモリ不足を解消!超軽量UARTライブラリ「SimpleUART」公開

ATtiny 1604 / 202 / 402マイコンに対応した、超軽量UARTライブラリ「SimpleUART」の紹介。中央の14ピンATtiny1604チップから、PA6(TX)とPA7(RX)ピンを通じてパソコンとシリアル通信を行う様子を描いたイラスト。下部にはライブラリ名とGitHubのURL「asa-lab-bit/SimpleUART」が記載されておりますATtiny202/402 メモリ不足を解消!超軽量UARTライブラリ「SimpleUART」公開
スポンサーリンク

ATtiny202や402のような、安価で小さなマイコンを使っていて「シリアル通信(Serial)を入れたら、それだけでメモリがいっぱいになってプログラムが書けない!」と困ったことはありませんか?

ATtinyシリーズは非常に便利ですが、SRAMが128〜256バイトと極めて少ないのが悩みどころです。

そこで今回、機能を絞り込むことでメモリ消費を極限まで抑え、さらにバッファサイズを自由自在にカスタマイズできるライブラリ 「SimpleUART」 を作成しました!GitHubで公開しましたので、その特徴と使い方を紹介します。ATtiny1604 1616 404にも使うことができます。

スポンサーリンク

このライブラリを作ったきっかけ

安価で高性能なATtinyで電子工作をしていると「通信機能は欲しいけれど、他の処理にメモリを回したい」という場面に何度も遭遇しました。

標準のライブラリは多機能で素晴らしいのですが、小規模なプロジェクトには少し重すぎることがあります。「送信バッファはほんの数バイトでいいから、もっと身軽に動かしたい」という想いから、今回のライブラリ作りが始まりました。 また、AIにたくさん質問してわからないところは色々確認しました。

ハードウェアの準備

ATtiny1616/1604//202/404/402を使う際、プログラムの書き込みとシリアル通信には、それぞれ役割の違う「USBアダプタ」が必要になります。

1. 書き込みには「UPDI書き込み器」

プログラムをマイコンに流し込むために、UPDI対応の書き込み器(自作のSerialUPDIなど)を接続します。

2. シリアル確認には「USB-UART変換アダプタ」

今回の SimpleUART の出力をパソコンで見るためには、書き込み器とは別に「USB-UART変換アダプタ」が必要です。

  • 接続例: ATtinyのTX(PA6)ピン → アダプタのRXピン :ATtinyのRX(PA7)ピン → アダプタのTXピン
  • 注意: 書き込みが終わったら、シリアルモニタの接続先を「変換アダプタ」のポートに切り替えて確認してください。
  • Tera Term などターミナルソフトで接続すると書き込みと同時に使うことができます。

接続図

updi  UARTシリアル 回路

ライブラリ関数の詳細解説

/**
 * 1. 通信の準備(セットアップ)
 * 引数:baud (9600など) - 通信のスピードを指定します。
 * 内部でクロック設定や、文字が届いた時に「割り込み」を発生させる設定をまとめて行います。
 */
init(uint32_t baud);

/**
 * 2. 1文字だけ送信
 * 引数:c - 送りたい文字('A'や'\n'など)。
 * 送信レジスタが空くまで待ち、空いたら1文字を放り込みます。全ての送信の基本となる関数です。
 */
send_char(char c);

/**
 * 3. 文字列を一気に送信
 * 引数:str - "Hello" などの文字列。
 * 内部で「uart_send_char」を繰り返し呼び出し、文字の終わり(\0)が来るまで一文字ずつ送り続けます。
 */
send_string(const char* str);

/**
 * 4. メッセージが届いたかチェック
 * 戻り値:true(届いた) / false(まだ)
 * メインループの中で「今、1行分のコマンド(エンターまで)が届いているかな?」とポストを覗きに行く役割です。
 */
bool is_line_ready();

/**
 * 5. 届いたメッセージを取り出す
 * 戻り値:保存されている文字列へのポインタ。
 * 割り込みがバッファ(rx_buffer)に溜めてくれた文字列を、判定(strcmpなど)に使える形で返します。
 */
const char* get_line();

/**
 * 6. 受信状態をリセットする
 * 次の新しいメッセージを受け取れるように、バッファの書き込み位置を0に戻し、「準備完了」フラグを下ろします。
 * これを忘れると、同じコマンドが何度も実行されてしまいます。
 */
clear_line();

/**
  *---標準ライブラリ風 println 関数 ---
  */
println(const char* s)
println(int n)

/**
  *---標準ライブラリ風 print関数改行なし ---
  */
print(const char* s)
print(int n)

使い方とインストール方法

GitHubからZIPファイルをダウンロードして、すぐに使い始めることができます。

インストール手順:

  1. GitHubの [Code] ボタンから [Download ZIP] をクリック。
  2. Arduino IDEの [スケッチ] > [ライブラリをインクルード] > [.ZIP形式のライブラリをインストール…] からダウンロードしたファイルを選択。

最小限のコード例:

#include <SimpleUART.h>

// <16> は送信バッファのサイズ(バイト)です。
// 送る文字数に合わせて 8 や 32 など自由に調整してメモリを節約できます!
SimpleUART<16> myUART;

void setup() {
    // 115200bpsで初期化。
    // パソコン側のシリアルモニタも「115200」に設定してください。
    myUART.init(115200); 
    
    // 起動したことを知らせるメッセージ
     myUART.send_string("SimpleUART Ready!\r\n");
}

void loop() {
    // 1秒おきにメッセージを送信するテスト
     myUART.send_string("Hello ATtiny 202/402!\r\n");
     delay(50);
     myUART.println("next message.");
    delay(1000);
}

Attiny202でビルドしたとき

サンプルコード2:
パソコンから入力された文字を判定してPA1番につないだLEDをオンオフするプログラムで、Interrupt handlerを使っています。

#include <SimpleUART.h>
#include <string.h>

// Initialize with 16 bytes buffer
SimpleUART<16> myUART;

// Interrupt handler
ISR(USART0_RXC_vect) {
    myUART.handle_interrupt();
}

void setup() {
    PORTA.DIRSET = PIN1_bm; // PA1 as Output (LED)
    PORTA.OUTCLR = PIN1_bm; 

    myUART.init(115200);
    myUART.send_string("System Online. Send 'ON' or 'OFF'\r\n");
}

void loop() {
    if (myUART.is_line_ready()) {
        const char* cmd = myUART.get_line();

        if (strcmp(cmd, "ON") == 0) {
            PORTA.OUTSET = PIN1_bm;
            myUART.send_string("-> LED is now ON\r\n");
        } 
        else if (strcmp(cmd, "OFF") == 0) {
            PORTA.OUTCLR = PIN1_bm;
            myUART.send_string("-> LED is now OFF\r\n");
        }

        myUART.clear_line();
        myUART.println("Ready for next message.");
    }

}

なぜ「軽量」なのか?

このライブラリには、小さなマイコンで効率よく動くための工夫を詰め込みました。

SimpleUART<16> の「魔法の数字」

ライブラリを呼び出す時の <16> という数字。これはバッファ(データを一時的に貯める箱)のサイズを1バイト単位で指定できる仕組みです。 「短いメッセージしか送らないから <8> でいいや」といった具合に、自分のプロジェクトに合わせてメモリを最小限に節約できます。

コンパイル時の最適化

「テンプレート」という技術を使い、書き込みデータを作る段階でメモリサイズを確定させています。動的にメモリを確保しないため、実行中にメモリ不足で予期せず止まるリスクを減らし、処理スピードも高速に保っています。

通信速度 115200bps の採用

初期化時の 115200 は、現代のPCと通信するのに最もストレスが少なく、標準的な速度です。もちろん、接続する相手に合わせて 9600 などに変更することも可能です。

割り込みレスによる 「超軽量&高互換性」

SimpleUARTが選んだ「ポーリング方式」

SimpleUARTでは、あえてこの割り込みを使わず、プログラムが自らデータの有無を確認しに行く**「ポーリング方式」**を採用しました。

  • プログラムがシンプル: 割り込みの制御コードが不要なため、劇的にプログラムサイズが小さくなります。
  • 衝突を防げる: 他のライブラリ(タイマーやセンサー制御など)と割り込みの設定がぶつかって動かなくなる、というトラブルが起きません。

「とにかく軽さを追求し、他の機能との共存を最優先する」という、ATtinyのような極小マイコンに特化した設計思想で作られています。

まとめ

「メモリが足りないからできない」を「工夫して解決する」のが電子工作の醍醐味だと改めて感じました。

この SimpleUART が、皆さんのATtinyプロジェクトをより快適にする助けになれば嬉しいです。オープンソース(MITライセンス)ですので、自由に改造して使ってみてください!

タイトルとURLをコピーしました