316記事目(中国輸入品シリーズ)
こんばんは。いつも読んでいただきありがとうございます。
趣味で中国から面白そう・便利そうな商品を輸入して使ってみています。techemoです。
今日は最近購入したArduinoUno多機能拡張ボードの紹介です。

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)に接続済み
回転角度を数値化する実験がすぐできます
🔌 主な接続インターフェース
※すべて端子のみ。モジュールは別途購入が必要です
使い道は
【実装済み部品だけでできること】
・デジタル時計
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学習の「段階的な演習場」として考えれば、
300円の投資は十分価値があると思います
今日も最後までお付き合いいただきありがとうございました。
私が買ってよかった商品はネットショップで販売できればと思っています。
似たようなものはAmazonでも購入できます。