アナログマルチプレクサ(CD74HC4067)でロータリースイッチを作る
誤って届いたアナログマルチプレクサ CD74HC4067 ブレイクアウトボードを使って、ロータリースイッチを作ってみます。
アナログマルチプレクサの使い方としてはなんだか贅沢な使い方の様な気がしないでもないですが
ひとまずデータシートを見て、制限事項を確認します。
TexasInstruments CD74HC4067 5V、16:1、1 チャネル・アナログ・マルチプレクサ
https://www.tij.co.jp/product/jp/CD74HC4067
・Vcc以上の電圧を通してはナラヌ
・20mAくらい以上の電流を通してはナラヌ
・コントロールのHIレベルは2Vで75%、4.5Vで70%なので3.3Vだと大体73%の2.4Vくらい
・コントロールのON抵抗は60~300ohmくらい
・通す経路の抵抗は8.5~20ohmくらい
これらを念頭において、自動ロータリースイッチ的なものを組んでみます。
LEDを適当に並べて、マイコンから操作できるロータリースイッチみたいにできればと。
ロータリースイッチに見立てるのですから、ESP32から出る3.3Vを振り分けても面白くありません。
どうせなら違う電圧の回路を切り替えてやろうって事で別電源から5Vを持ってきます。
早速Vcc以上を通してはナラヌ制約とかどうでもいい感じに
こんな感じでいきましょうかね。
とりあえず大体で多分大丈夫です。(ぇ
5VラインのLEDをガチャガチャっと切り替えて順番に点灯させます。
実際に回路の開閉を行うのは3.3V回路に並べたトランジスタスイッチです。
ここをリレーやフォトカプラにすればもっとロータリースイッチ的になるんじゃないかと。
・・・IOエキスパンダやシフトレジスタでもいいんですが・・・
とりあえず使い方をチェックって事で大目に見て下さい( ノД`)
気にせずブレッドボードにするとこんな感じに。
キモいですな
線材をケチってワニ口クリップ使ったりオスメスを継いだりしてますが。。。
一応回路図の通りになっている筈( ノД`)
さてプログラムの方はこんな感じに。
#include <Arduino.h>
/*
// Analog MUX ロータリースイッチテスト
*/
// ----------------------------------------------------------------
// トグルスイッチピン
uint8_t gpio_mux_sig = 32; // To Base 3.3V
uint8_t gpio_mux_en = 14; // To MUX EN
uint8_t gpio_mux_s3 = 33; // To MUX s3
uint8_t gpio_mux_s2 = 25; // To MUX s2
uint8_t gpio_mux_s1 = 26; // To MUX s1
uint8_t gpio_mux_s0 = 27; // To MUX s0
uint8_t mux_channel[16][4] = {
{0, 0, 0, 0}, // 0
{1, 0, 0, 0}, // 1
{0, 1, 0, 0}, // 2
{1, 1, 0, 0}, // 3
{0, 0, 1, 0}, // 4
{1, 0, 1, 0}, // 5
{0, 1, 1, 0}, // 6
{1, 1, 1, 0}, // 7
{0, 0, 0, 1}, // 8
{1, 0, 0, 1}, // 9
{0, 1, 0, 1}, // 10
{1, 1, 0, 1}, // 11
{0, 0, 1, 1}, // 12
{1, 0, 1, 1}, // 13
{0, 1, 1, 1}, // 14
{1, 1, 1, 1} // 15
};
// 点灯秒数設定
uint16_t pw_short = 500; // ms
uint16_t pw_long = 8000; // ms
// ----------------------------------------------------------------
//------------------------------------------------------------------------------------------
// 対象MUX channel設定
bool muxSetChannel(uint8_t _target_ch)
{
uint8_t _control_pin[] = {gpio_mux_s0, gpio_mux_s1, gpio_mux_s2, gpio_mux_s3};
for (uint8_t i = 0; i < 4; i++)
{
digitalWrite(_control_pin[i], mux_channel[_target_ch][i]);
}
Serial.print("MUX Channel Set:");
Serial.println(_target_ch);
return true;
}
//------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
// ボタンプッシュ
bool muxButtonPush(uint8_t _target_ch, String _push_method)
{
Serial.print("MUX Button Push:");
Serial.print(_target_ch);
Serial.print(" method:");
Serial.println(_push_method);
// 対象MUX channel設定
muxSetChannel(_target_ch);
// EN解除
digitalWrite(gpio_mux_en, LOW);
// ボタンプッシュ
if (_push_method == "long")
{
digitalWrite(gpio_mux_sig, HIGH);
delay(pw_long);
digitalWrite(gpio_mux_sig, LOW);
}
else
{
digitalWrite(gpio_mux_sig, HIGH);
delay(pw_short);
digitalWrite(gpio_mux_sig, LOW);
}
// EN設定
digitalWrite(gpio_mux_en, HIGH);
// 対象MUX COM設定リセット
// uint8_t _reset_ch = 0;
// muxSetChannel(_reset_ch);
muxSetChannel(0);
return true;
}
//------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
// setup
void setup()
{
// シリアル開始
Serial.begin(115200);
delay(50);
// GPIOピンモードを設定 初期設定
// MUX Base 3.3V
pinMode(gpio_mux_sig, OUTPUT);
digitalWrite(gpio_mux_sig, LOW);
// MUX EN
pinMode(gpio_mux_en, OUTPUT);
digitalWrite(gpio_mux_en, HIGH);
// MUX channel gpio
pinMode(gpio_mux_s3, OUTPUT);
pinMode(gpio_mux_s2, OUTPUT);
pinMode(gpio_mux_s1, OUTPUT);
pinMode(gpio_mux_s0, OUTPUT);
digitalWrite(gpio_mux_s3, LOW);
digitalWrite(gpio_mux_s2, LOW);
digitalWrite(gpio_mux_s1, LOW);
digitalWrite(gpio_mux_s0, LOW);
delay(100);
}
//------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------
// main loop
void loop()
{
// シリアルコンソールからトグルスイッチ操作
if (Serial.available())
{
int inputchar = Serial.read();
if (char(inputchar) == '1')
{
muxButtonPush(0, "long");
}
else if (char(inputchar) == '2')
{
muxButtonPush(1, "long");
}
else if (char(inputchar) == '3')
{
muxButtonPush(2, "long");
}
else if (char(inputchar) == '4')
{
muxButtonPush(3, "long");
}
else if (char(inputchar) == 'q')
{
muxButtonPush(0, "short");
}
else if (char(inputchar) == 'w')
{
muxButtonPush(1, "short");
}
else if (char(inputchar) == 'e')
{
muxButtonPush(2, "short");
}
else if (char(inputchar) == 'r')
{
muxButtonPush(3, "short");
}
}
delay(200);
}
//------------------------------------------------------------------------------------------
ざっくりとシリアルコンソールで 1,2,3,4 を押すと該当するLEDが8秒点灯します。
q,w,e,r を押すと該当するLEDが0.5秒点灯します。
s0~s3の4つのピンのどれをHIGHにするかLOWにするかで16チャンネルの経路を選択し、基盤ではSIGと書いてあるピンとC0~C15までの経路が導通する仕組みみたいです。
ENに印加すると、すべての経路を遮断する模様。
通電中にs0~s3の印加を変えるとほぼリアルタイムに経路が変化してしまう様で、ここではいちいちENで落として切り替えたりしていますが、LEDの点灯くらいであればENに落とさなくてもいいでしょう。
センサー類からの入力を綺麗に受け取ったり、想定外の電気が流れる可能性がある場合にはちゃんとENを使った方がいいと思います。
ではちょっと動かしてみます
うん、ちゃんと想定どおりの動きをしてくれました。
簡単に使えてわりと便利なICなんですね。
VCC以上の電圧を扱えたらもっと最高なんですが、、、
それこそアナログ/デジタルロータリースイッチ的な。
相手回路は5Vですので、例えばVCCに5Vを入れてやれば良い気がしてきますが、5Vだと経路を制御するs0~s3をHIGHにするのにおよそ3.5V必要になります。
ざっくりと4Vは印加しなくてはいけませんので、3.3V出力のGPIOではこれらのピンをHIGHに出来ないんですね。
このマルチプレクサとマイコンの間にレベルシフターなるものを挟めば多分出来るんでしょうけれど、今回の様に4ch程度しか切り替えないのであればトランジスタと抵抗を使った方が安いと思います。
わりと簡単な制御で高速にスイッチできるアナログマルチプレクサでした。
ついでに高速で切り替えられるという事でしたので、高速に切り替えてみた動画を撮ったのですが、、、
gif化する時にフレームを抜かれてしまうので高速かどうかよく判らないモノに。。。
ですので、YouTubeに置いておく事にしました。
これなら速度が判りますね。
さて今回は、アナログマルチプレクサをLチカに使うなどという暴挙に出ましたが
ADCはわりと高価ですから、やはり複数のセンサーを使ってアナログ信号を受け取る様な用途に使うべきだと思うます。
まぁこっちですよね・・・
これを使う時、電圧と電流、気を付けてくださいませ。
電圧はVccまで、電流は20mAまで。
各種環境センサー的なものは大体10mAくらいまでしか出て来ない様ですのでそのままお使いになれると思います。
ESP32のGPIOは3.3V、20mAまでとなっている様ですし、3.3VマイコンのGPIOに関してはそのまま通しても大丈夫かもしれません。
オーディオや電波辺りはヤバイかもですね
楽器は、、モノによるのかな
そういえばESP32のGPIO制御にマルチプレクサが組み込まれてましたね。
理解を深める意味ではとても参考になったかもしれません。
ディスカッション
コメント一覧
まだ、コメントがありません