techemo(てけも)のブログ

30代リーマンの副業ブログ

【買ってよかった中国輸入品】ArduinoUno多機能拡張ボード 〜特徴は?使い道は?〜

📝 投稿: 🔄 更新:

316記事目(中国輸入品シリーズ)

 

こんばんは。いつも読んでいただきありがとうございます。

趣味で中国から面白そう・便利そうな商品を輸入して使ってみています。techemoです。

今日は最近購入したArduinoUno多機能拡張ボードの紹介です。

ArduinounoUno拡張ボード

Arduino UNOで色々試したいなぁと思っていたところ、

このボードを見つけました。300円でこの機能は驚きです!

…と思ったのですが、実際に使ってみるとちょっと注意点がありました。

 

特徴は

・とにかく安い(300円)

Arduino学習用のシールドとしては破格の安さです

個別にパーツを揃えるより圧倒的にコスパが良い

 

・4桁7セグメントディスプレイ付き

74HC595シフトレジスタで駆動

時計やカウンター、温度表示などに使えます

 

・独立ボタン3個+LED4個+ブザー

基本的な入出力の学習がすぐにできます

配線不要でプログラミングに集中できるのが嬉しい

 

・可変抵抗(ボリューム)付き

アナログ入力の学習に最適

明るさ調整やサーボ角度制御の実験に

 

・拡張インターフェースが豊富

温度センサー、赤外線、Bluetooth、サーボなど

ただし、モジュールは別売り!(ここ重要)

 

⚠️ 購入前に知っておきたいこと

商品説明を見ると「多機能!」と思いますが、実際にボード上に実装されているのは一部だけです。温度センサーや赤外線受信、Bluetoothなどは接続端子があるだけで、モジュール自体は別途購入が必要です。

 

実装済み機能と別売り機能

ここが一番重要なポイントです!

商品説明の機能が全部使えると思って買うと「あれ?」となります

 

📦 実装済み vs 別売り 機能一覧

✅ すぐ使える(実装済み)

  • 4桁7セグメントディスプレイ
  • LED × 4個
  • タクトボタン × 3個
  • ブザー × 1個
  • 可変抵抗(3296)
  • リセットボタン

❌ 要追加購入(端子のみ)

商品説明の機能は半分くらいが「端子があるだけ」です

 

実装済み部品の詳細:

・7セグメントディスプレイ

74HC595シフトレジスタ(595チップ)で駆動

IOピンを節約しながら4桁表示が可能

 

・ボタン(S1〜S3)

デジタル入力の基礎学習に

デバウンス処理や割り込みの練習に最適

 

・3296精密可変抵抗

アナログ入力(A0)に接続済み

回転角度を数値化する実験がすぐできます

 

🔌 主な接続インターフェース

温度センサー LM35 / DS18B20用端子
赤外線受信 IR受信モジュール用端子
Bluetooth HC-05/06用端子
サーボ/センサー 3ピンコネクタ × 複数

※すべて端子のみ。モジュールは別途購入が必要です

使い道は

実装済み部品だけでできること】

 

・デジタル時計

7セグメントで時刻表示、ボタンで時刻設定、ブザーでアラーム

Arduino入門の定番プロジェクトがすぐ作れます

 

・ストップウォッチ/カウンター

ボタンでスタート/ストップ/リセット

7セグメントに計測値を表示

 

・簡易ゲーム

LEDを使った反射神経ゲーム

スコア表示+効果音付きで本格的に

 

・PWM/アナログ入力の学習

可変抵抗でLEDの明るさを調整

アナログ値を7セグメントに表示

 

📚 段階的学習プラン

Step 1: LED点灯 → デジタル出力の基礎

Step 2: ボタン入力 → デジタル入力の基礎

Step 3: ブザー → tone()関数でメロディ

Step 4: 可変抵抗 → アナログ入力

Step 5: 7セグメント → シフトレジスタ制御

Step 6: センサー追加 → IoTへ発展!

 

【モジュールを追加すると…】

 

・温度センサー(DS18B20)追加

室温モニター、温度データロガー

設定温度でブザーアラート

 

・赤外線受信モジュール追加

リモコン信号の解析・学習

カスタムリモコンの製作

 

Bluetoothモジュール追加

スマホからの遠隔制御

センサーデータの無線送信

 

私は過去に購入したセンサー類を接続して遊んでいます

モジュールを既に持っている人には便利なボードです

 

プログラミング(3桁タイマー)

さっそく7セグメントディスプレイを使ってタイマーを作ろうとしたのですが…

 

💥 ハードウェア不良発覚!

私が購入した個体では、7セグメントの左から3桁目が点灯しない不良がありました。

300円なので返品するほどでもないし…動く3桁でなんとかしてみます!

 

こういうのも中国輸入品あるあるですね

安いので多少の不良は覚悟の上です

 

📺 表示イメージ

正常な4桁の場合:

[1][2][3][4]

私のボード(3桁目不良):

[1][2][][4] ← 3桁目は常に消灯

タイマー表示例(M.SS形式):

1.30 → 1分30秒(「1. 3 _ 0」のように見える)

0.05 → 5秒

 

作戦:桁1=分、桁2=秒10の位、桁4=秒1の位

3桁目をスキップして表示する方式で対応しました

最大9分59秒まで計測できます

 

🔧 HW-262 ピン対応表

機能 ピン 備考
7セグメントLED
LATCH D4 74HC595 ラッチ
CLK D7 74HC595 クロック
DATA D8 74HC595 データ
桁1(左端) 0xF1 ✅ 動作OK
桁2 0xF2 ✅ 動作OK
桁3 0xF4 ❌ 不良
桁4(右端) 0xF8 ✅ 動作OK
ボタン
ボタン1 A1 アクティブLOW
ボタン2 A2 アクティブLOW
ボタン3 A3 アクティブLOW
その他
ブザー D3 INPUT/OUTPUT切替方式
LED1〜4 D13〜D10  
ポテンショメータ A0  

 

サンプルコード(3桁カウントダウンタイマー)

 

/*
 * HW-262 カウントダウンタイマー
 * 3桁表示版(桁3不良対応)
 * 
 * 表示形式: M.SS(桁1=分、桁2=秒10の位、桁4=秒1の位)
 */

// === 7セグメントLED ピン定義 ===
#define LATCH_PIN 4
#define CLK_PIN 7
#define DATA_PIN 8

// === ボタン・ブザー ピン定義 ===
#define BUTTON_1 A1
#define BUTTON_2 A2  
#define BUTTON_3 A3
#define BUZZER_PIN 3

// === 桁選択パターン(アクティブHIGH) ===
const byte DIGIT_1 = 0xF1;  // 左端(分)
const byte DIGIT_2 = 0xF2;  // 秒10の位
// const byte DIGIT_3 = 0xF4;  // 不良のため使用しない
const byte DIGIT_4 = 0xF8;  // 右端(秒1の位)

// === コモンアノード用数字パターン ===
const byte SEGMENT_MAP[] = {
  0xC0, 0xF9, 0xA4, 0xB0, 0x99,  // 0-4
  0x92, 0x82, 0xF8, 0x80, 0x90   // 5-9
};

// 小数点付き(分と秒の区切り用)
const byte SEGMENT_MAP_DP[] = {
  0x40, 0x79, 0x24, 0x30, 0x19,  // 0.-4.
  0x12, 0x02, 0x78, 0x00, 0x10   // 5.-9.
};

// === タイマー変数 ===
unsigned long totalSeconds = 60;
unsigned long remainingSeconds = 60;
unsigned long lastUpdateTime = 0;
unsigned long lastDisplayTime = 0;
bool isRunning = false;
bool isFinished = false;

// === 表示用変数 ===
byte displayDigits[3];
int currentDigit = 0;

void setup() {
  Serial.begin(115200);
  
  pinMode(LATCH_PIN, OUTPUT);
  pinMode(CLK_PIN, OUTPUT);
  pinMode(DATA_PIN, OUTPUT);
  
  pinMode(BUTTON_1, INPUT_PULLUP);
  pinMode(BUTTON_2, INPUT_PULLUP);
  pinMode(BUTTON_3, INPUT_PULLUP);
  pinMode(BUZZER_PIN, INPUT);
  
  Serial.println(F("カウントダウンタイマー(3桁版)"));
  Serial.println(F("ボタン1: スタート/停止"));
  Serial.println(F("ボタン2: リセット"));
  Serial.println(F("ボタン3: +1分"));
  
  updateDisplayDigits();
}

void loop() {
  refreshDisplay();
  handleButtons();
  
  if (isRunning && !isFinished) {
    if (millis() - lastUpdateTime >= 1000) {
      lastUpdateTime = millis();
      
      if (remainingSeconds > 0) {
        remainingSeconds--;
        updateDisplayDigits();
        
        if (remainingSeconds <= 10 && remainingSeconds > 0) {
          beep(800, 50);  // 残り10秒で警告音
        }
      } else {
        isRunning = false;
        isFinished = true;
      }
    }
  }
  
  if (isFinished) {
    playAlarm();
  }
}

void sendToDisplay(byte digitSelect, byte segmentData) {
  digitalWrite(LATCH_PIN, LOW);
  shiftOut(DATA_PIN, CLK_PIN, MSBFIRST, segmentData);
  shiftOut(DATA_PIN, CLK_PIN, MSBFIRST, digitSelect);
  digitalWrite(LATCH_PIN, HIGH);
}

void refreshDisplay() {
  if (millis() - lastDisplayTime < 3) return;
  lastDisplayTime = millis();
  
  // 終了時は点滅
  if (isFinished && (millis() / 300) % 2 == 0) {
    sendToDisplay(0x00, 0xFF);
    return;
  }
  
  switch (currentDigit) {
    case 0: sendToDisplay(DIGIT_1, displayDigits[0]); break;
    case 1: sendToDisplay(DIGIT_2, displayDigits[1]); break;
    case 2: sendToDisplay(DIGIT_4, displayDigits[2]); break;
  }
  
  currentDigit = (currentDigit + 1) % 3;
}

void updateDisplayDigits() {
  int minutes = remainingSeconds / 60;
  int seconds = remainingSeconds % 60;
  
  if (minutes > 9) minutes = 9;
  
  displayDigits[0] = SEGMENT_MAP_DP[minutes];
  displayDigits[1] = SEGMENT_MAP[seconds / 10];
  displayDigits[2] = SEGMENT_MAP[seconds % 10];
}

void handleButtons() {
  // ボタン1: スタート/停止
  if (digitalRead(BUTTON_1) == LOW) {
    delay(50);
    if (digitalRead(BUTTON_1) == LOW) {
      while (digitalRead(BUTTON_1) == LOW) refreshDisplay();
      
      if (!isFinished) {
        isRunning = !isRunning;
        if (isRunning) lastUpdateTime = millis();
        beep(isRunning ? 1200 : 800, 80);
      }
    }
  }
  
  // ボタン2: リセット
  if (digitalRead(BUTTON_2) == LOW) {
    delay(50);
    if (digitalRead(BUTTON_2) == LOW) {
      while (digitalRead(BUTTON_2) == LOW) refreshDisplay();
      
      isRunning = false;
      isFinished = false;
      remainingSeconds = totalSeconds;
      beep(1000, 80);
      updateDisplayDigits();
    }
  }
  
  // ボタン3: +1分
  if (digitalRead(BUTTON_3) == LOW) {
    delay(50);
    if (digitalRead(BUTTON_3) == LOW) {
      while (digitalRead(BUTTON_3) == LOW) refreshDisplay();
      
      if (!isRunning && !isFinished) {
        totalSeconds += 60;
        if (totalSeconds > 599) totalSeconds = 60;
        remainingSeconds = totalSeconds;
        beep(1500, 80);
        updateDisplayDigits();
      }
    }
  }
}

void beep(int frequency, int duration) {
  pinMode(BUZZER_PIN, OUTPUT);
  tone(BUZZER_PIN, frequency);
  delay(duration);
  noTone(BUZZER_PIN);
  pinMode(BUZZER_PIN, INPUT);
}

void playAlarm() {
  static unsigned long lastAlarmTime = 0;
  if (millis() - lastAlarmTime > 500) {
    lastAlarmTime = millis();
    beep(2000, 150);
  }
}

 

⏱️ タイマーの操作方法

ボタン 機能
ボタン1 (A1) スタート / 一時停止
ボタン2 (A2) リセット
ボタン3 (A3) +1分(停止中のみ、最大9分)

特徴:残り10秒で警告音、終了時に点滅+アラーム音

ハードウェア不良があっても工夫次第で使えます

これも電子工作の醍醐味ですね

 

使い方は

Arduino UNOに装着

ピンヘッダがArduino UNOに合わせて設計されているので

そのまま差し込むだけでOK

Arduino Mega等には非対応)

 

②サンプルコードで動作確認

まずはLED点滅やボタン入力から試してみましょう

7セグメントの制御は74HC595シフトレジスタの理解が必要です

 

③必要に応じてモジュールを追加

端子の仕様を確認して、対応するモジュールを接続

温度センサーならDS18B20がおすすめです

 

まとめ

Arduino多機能拡張ボード、300円という価格を考えれば十分アリです

 

ただし、商品説明の機能が全部使えるわけではない点は注意

実際に実装されているのは7セグ、ボタン、LED、ブザー、可変抵抗くらい

温度センサーや赤外線、Bluetooth端子があるだけです

 

さらに私の個体は7セグの3桁目が不良でした…

でも残りの3桁でタイマーを作れたので結果オーライです

 

💡 このボードをおすすめできる人

Arduino入門で基礎を学びたい人

✅ 配線なしでプログラミングに集中したい人

✅ 既にセンサー類を持っていて活用したい人

✅ 多少の不良は工夫で乗り越える気概がある人

❌ 買ってすぐ全機能を使いたい人

❌ ESP32など他のマイコンで使いたい人

 

私の感想としては、安いので仕方ないけど期待しすぎは禁物

でも、モジュールを既に持っていれば色々遊べて楽しいです

 

Arduino学習の「段階的な演習場」として考えれば、

300円の投資は十分価値があると思います

 

今日も最後までお付き合いいただきありがとうございました。

私が買ってよかった商品はネットショップで販売できればと思っています。

似たようなものはAmazonでも購入できます。