こんにちは、ゆうかりです。
さて今回は。
秋月電子のサイト見てたら、「ピックアップ」に、こんなのがあり。
つい気になって、衝動買い。
しかも何故かの八潮店で。
けっこうデカいのに、しれっと部品引き出しに納まってて、びっくり。
マトリクスLEDは、HUB75なコントローラー経由でしか触ったこと無いので、どうなることやらですが。
ま、遊んでみたいと思います。
素性
モノは、オプトサプライのやーつで。
蛍光管、VFDチックなお色でステキに輝くようです。
中身は、各LEDのアノードとカソードをマトリクス状に繋いでおり。
それぞれ16本、合計32本のI/Fという、なかなかにゴツーい感じ。
ま、やってみますか。
当初の作戦
マトリクスLEDは、そのまま使うと配線だらけになって使いづらいので、「ドライバIC」なるものがあります。
秋月電子も扱っていて、「HT16K33」てのをお勧めされております。
コイツは、I2Cドライバなので、大量の配線がSCLとSDAだけで制御可能になる夢のデバイスです。
えぇ、もちろん買いましたとも、何も考えず!。
しかも2セット。
でもねーこれねー、ソースは16chあるんだけど、シンクが8chしかなくて。
「複数使い用の同期」も取れなさそう。
2つ使えばいけんじゃね?、とごにょごにょ思考実験したんだが、同居は無理っぽくて。
「3ステートバッファ使ってソースシンクを切り替える」とかいう力業しか思いつかなくてね。
そもそもバッファ使うと「線少なくしたい」的なお話からは吹っ飛んでしまうし・・・。
つーわけで、やめやめ。
もうね、32本、GPIOに繋いでしまえと
しかも速度必要そうなので、CPU直結の。
流石にそんなステキCPU無いよねー、FPGAあたりでがんばりますかねー、とぐぐっていたら。
ありました、しかもArduino純正で。
「ATMEGA2560」、Arduino MEGA、ですね。
最大54本もGPIOがあり、各端子の定格は20mA、しかも5Vと、もうステキです。
早速純正品、、、ではなく、中華な互換品をAmazonでポチっと。
静電袋に入ってるのはいいんですが、オマケのピンヘッダを、ごろんと入れるの勘弁してほしい、なかなかに怖い!
とりあえず点けてみる
適当なピンをHIGHとLOWに設定し、適当なROW側にHIGHを、適当なCOL側にLOWを接続。
電流制限は20mAなので、 R = V / I 、250Ωですが、まあ半分の470Ωに設定。
特に事故もなく、光りましたとさ。
基板作成
適当な秋月B基板にハメてみると、ちょうどよさげなので。
ピンソケット経由にして、配線開始。
電流制限抵抗をちまちまと。
1/6Wタイプだけどまあ、50mWしか掛からんので、大丈夫でしょう
とりあえずランダム点灯
やりくちは簡単で。
ROW側がHIGH、COL側がLOWだと点灯しますよと
初期状態は、ROW側もCOL側もHIGHで。
非点灯にしたいとこをROW側をLOWにし。
最後に点灯したい列をLOWに落とす感じで。
UART経由流し込み点灯
まあ、こいつにセンサーとかつけてゴニョゴニョも楽し気ですが。
UART経由で描画することで、ラズパイだのから流し込みたいな、と。
ゆーわけで適当にプログラミング!。
mintmatrix_demo.ino
byte cols[16] = {54,56,58,60,62,64,66,68,32,34,36,38,40,42,44,46};
byte rows[16] = {55,57,59,61,63,65,67,69,33,35,37,39,41,43,45,47};
byte gmemory[256];
int x;
byte i = 0;
byte j,k;
byte rowswitch = 0;
unsigned long timenow,timedelta;
unsigned long timestart = 0;
unsigned long timethreshold = 1000;
int count;
byte mpointer = 0;
byte readdata = 0;
long randdata;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.setTimeout(100);
for (x=54; x <= 69; x++){
pinMode(x, OUTPUT);
digitalWrite(x, HIGH);
}
for (x=32; x <= 47; x++){
pinMode(x, OUTPUT);
digitalWrite(x, HIGH);
}
for (x=0; x <= 255; x++){
gmemory[x] = 0;
}
}
void loop() {
if (rowswitch != 0) {
if (timestart == 0){
digitalWrite(rows[i], LOW);
timestart = micros();
}
timenow = micros();
timedelta = timenow - timestart;
if (timedelta > timethreshold){
digitalWrite(rows[i], HIGH);
count++;
rowswitch = 0;
timestart = 0;
}
}
else {
i++;
if (i >= 16){
i = 0;
}
for (j=0; j <= 15; j++) {
k = i * 16 + j;
if (gmemory[k] == 0) {
digitalWrite(cols[j], LOW);
}
else {
digitalWrite(cols[j], HIGH);
}
}
rowswitch = 1;
}
}
void serialEvent() {
readdata = Serial.read();
if (readdata == 48) {
gmemory[mpointer] = 0;
mpointer++;
return;
}
if (readdata == 49) {
gmemory[mpointer] = 1;
mpointer++;
return;
}
if (readdata == 50) {
mpointer = 0;
return;
}
if (readdata == 51) {
timethreshold = 1000;
return;
}
if (readdata == 52) {
timethreshold = 100;
return;
}
if (readdata == 53) {
timethreshold = 50;
return;
}
if (readdata == 54) {
timethreshold = 10;
return;
}
if (readdata == 55) {
timethreshold = 2;
return;
}
}
UART、シリアルから数字を打ち込むことで描画します。
コマンドはこんな感じで。
コマンド | 内容 |
---|---|
0 | 非点灯 |
1 | 点灯 |
2 | 描画位置リセット |
3 | 一番明るい設定 |
7 | 一番暗い設定 |
コマンド送るたびに描画位置はひとつづつずれ、勝手に改行していく感じで。
明るさの設定は、各行に電圧加えた後の待機時間を調整することで実現してます。
コマンド例は、こんな感じ。
520000000000000000100000000110001011111110100110101000000001000110000000000000000010000000011111001111111010010010100000000110010000000000000000000111111011111110100010000100100001111110001110000000000000000000111111100000000000011100000000001111111000000000
コレをArduinoのシリアルモニタに、115200bpsで貼り付けると、無事に動作しますよ、うふふ。
工夫?のメモ
- ビット操作でメモリ圧縮しようとしたら、ビット操作自体時間かかってチラつく!
- ほんとは非点灯時COL側は、HIGHじゃなくてHi-Zがいいっぽいけど、まあいいや
- Duty弄ることで、2階調ではなく、8階調くらい作れそうだけど、リニアに変化しないので、めんどくさくなって無しに
- ドライバIC使ってないので、ちょっとでも処理がモタつくと即ちらつきが!、ホントは2コアCPUとかでマルチスレッドさせたい
- まあ、ちゃんと作るなら、FPGAのほうがよさそうね、、、
らずぱいにつなげてみました
まずはaptして
apt install python3-serial python3-pillow
pythonをざっくりと。
test.py
from PIL import Image, ImageFont, ImageDraw
import serial
import time
font = ImageFont.truetype("./misaki_gothic_2nd.ttf", size=8)
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1.0)
time.sleep(2)
count = 0
brcount = 0
brightness = 3
while (True):
count = count + 1
brcount = count % 10
if brcount == 0:
brightness = brightness + 1
if brightness > 7:
brightness = 3
image = Image.new("1", (16,16), color=0)
draw = ImageDraw.Draw(image)
draw.text((0, 0), 'TEST', fill=(1), font=font)
draw.text((0, 8), str(count).rjust(4), fill=(1), font=font)
image = image.rotate(90)
dataarray = image.tobytes()
output = str(brightness) + '2'
for i in range(32):
j = i + 1;
data = '{:08b}'.format(ord(dataarray[i:j]))
output = output + data
print (output)
ser.write(output.encode('utf-8'))
time.sleep(0.05)
ser.close()
無事に動作しましたとさ。
フォントは美咲フォントを使っているので、漢字とかもいけます、テストしてないけど!
動画だと、こんな感じ!。
ま、活用してみます
とりあえず作業場の消費電力を表示させてみたりして。
それなりに目を引く大きさですし、スキャンさせて点灯させてるので、消費電力を抑えられ気味。
なかなかステキなデバイスな気もします。
まあ、本来の用途は、スペアナとかっぽいけれども、気にしない!。
以上です。
投稿者の人気記事
-
eucaly
さんが
2023/09/02
に
編集
をしました。
(メッセージ: 初版)
-
eucaly
さんが
2023/09/02
に
編集
をしました。
-
eucaly
さんが
2023/09/02
に
編集
をしました。
Opening
Kazekaoru
2023/12/08
ログインしてコメントを投稿する突然のご連絡失礼いたします。
PCBGOGOマーケティング部門の葉と申します。
宣伝協力のことに関しまして、
一度ご相談させて頂けませんでしょうか。
ご興味がおありであれば、一度ご連絡をいただけますでしょうか。
ご多用の折恐れ入りますが、ぜひご検討くださいますよう
お願い申し上げます。
メール:service10@pcbgogo.jp