DVD Player LED
2021.01.30
YouTube でも紹介しています。画像をクリックすると再生できます。
DVDプレーヤーからパーツ取りしたLEDを時計と温度表示に利用してみました。
Arduino でいかにスイッチのオン・オフをするのかがポイントです。
■ワイドFM対応の7インチポータブルDVDプレーヤー

パーツ取りしたのは、ダイニチ電子株式会社の DV-PF701X です。
赤枠で囲んであるパーツが今回使用する、DVD Player LED です。

12ピンのLEDです。
■参考サイトおよび動画
記事を作成するうえで、下記の情報を活用させていただきました。
・TECHZONE - Arduino Clock with DVD Player LED Display
LEDの動作解析に関しては以下の動画を参考にしました。
・DVD Player LED Display Recycling
動画の中にもピンの対応表がありますが、製品によって微妙にLEDのレイアウトが違います。
■動作解析

12本のピンから2本を選んで、総当たりでショートさせ、LEDが光る部分を確認していきます。
画像では、アノード(+)側に1KΩの抵抗を挟んでいます。
解析結果を表に纏めると、下図のようになります。
■開発環境

パソコンから、TeraTeamでラズパイにSSH接続、PlatformIOを用いてビルドします。
→ Arduino開発環境構築 PlatformIO
■配線 Arduino - DVD Player LED
Arduino Nano | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 13 |
| ↓ | ↓ | ↓ | ↓ | ↓ | ↓ | ↓ | ↓ | ↓ | ↓ | ↓ | ↓ |
DVD Player LED | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| ー | ー | ー | ー | ー | + | + | + | + | + | + | + |

■コーディング解説
定数定義
int characterdata[10][7] = {
{1,1,1,1,1,1,0},
{0,1,1,0,0,0,0},
{1,1,0,1,1,0,1},
{1,1,1,1,0,0,1},
{0,1,1,0,0,1,1},
{1,0,1,1,0,1,1},
{1,0,1,1,1,1,1},
{1,1,1,0,0,0,0},
{1,1,1,1,1,1,1},
{1,1,1,1,0,1,1} };
int anode[7] = {4,5,6,13,2,3,7};
int cathode[5] = {12,11,10,9,8};
7セグメントLEDを使う際の定石的な定義です。
配列中の'1'は、該当するセグメントの点灯を指示します。
このパターンの組み合わせで、0~9を表示させます。
| a | b | c | d | e | f | g | | |
{ | 1, | 1, | 1, | 1, | 1, | 1, | 0 | }, | 0 |
{ | 0, | 1, | 1, | 0, | 0, | 0, | 0 | }, | 1 |
{ | 1, | 1, | 0, | 1, | 1, | 0, | 1 | }, | 2 |
{ | 1, | 1, | 1, | 1, | 0, | 0, | 1 | }, | 3 |
{ | 0, | 1, | 1, | 0, | 0, | 1, | 1 | }, | 4 |
{ | 1, | 0, | 1, | 1, | 0, | 1, | 1 | }, | 5 |
{ | 1, | 0, | 1, | 1, | 1, | 1, | 1 | }, | 6 |
{ | 1, | 1, | 1, | 0, | 0, | 0, | 0 | }, | 7 |
{ | 1, | 1, | 1, | 1, | 1, | 1, | 1 | }, | 8 |
{ | 1, | 1, | 1, | 1, | 0, | 1, | 1 | }}; | 9 |
anode[7]={ | 4, | 5, | 6, | 13, | 2, | 3, | 7 | }; | |
セグメントのa,b,c・・・の並びに対応するように、Arduino側のピン配列を変更しています。
初期処理
void setup () {
for (int i=0;i<7;++i) {
pinMode(anode[i], OUTPUT);
digitalWrite(anode[i], LOW);
}
for (int i=0;i<5;++i) {
pinMode(cathode[i], INPUT);
}
}
アノード(+)用ピンのモードをOUTPUTに設定し、LOWで初期化します。
カソード(-)用ピンのモードをINPUTに設定します。
ループ処理
void loop () {
drawDigit(0,5);
drawDigit(1,4);
drawColon();
drawDigit(2,3);
drawDigit(3,2);
}
ここでは、テスト的に上位の桁から5→4→:→3→2の順に表示を繰り返しています。
LED表示処理
void drawDigit(int pos, int num) {
for (int i=0;i<5;++i) pinMode(cathode[i], INPUT);
pinMode(cathode[pos+1], OUTPUT);
digitalWrite(cathode[pos+1], 0);
for (int i=0;i<7;++i) digitalWrite(anode[i], characterdata[num][i]);
delay(500);
}
この赤線の箇所が肝になるところです。
カソード(-)のピンモードをOUTPUTにして、0(LOW)に設定します。
その後に点灯させたいセグメントのアノード(+)を1(HIGH)にします。
これにより、実際にはGND状態にあるカソードに電流が流れこみ、指定したセグメントが点灯します。
※危険:2つのI/OピンがともにOUTPUTモードで、片方がLOW、もう片方がHIGHでこの2つを直接繋ぐと、過電流が流れてArduinoを破損させてしまいます。
上記の回路ではアノード側の出力は1KΩの抵抗を介してLEDに接続されています。これにより、間違えてカソードに繋いだときの損傷も回避しています。
$ pio run -t upload

1桁ずつ表示されていますが、これを高速で切り替えることで、全桁が点灯してみえます。
void drawDigit(int pos, int num) {
・・・・
delay(2);
}
■リアルアイムクロックDS1302/AHT10デジタル温湿度センサー
表示を確認できたところで、時刻と温度表示を行います。
ここでは、配線のみを記載しています。詳細な設定は、リンク先を参照してください。
Ref.DS1302 → 画像処理 第3回リアルタイムクロック
Arduino | - | DS1302 |
5V | - | [1]Vcc2 Power-Supply |
GND | - | [4]GND |
A2(16) | - | [5]CE |
A1(15) | - | [6]I/O |
A0(14) | - | [7]SCLK |
Ref.AHT10 → Seeeduino XIAO
Arduino | - | AHT10 |
A4/SDA | - | SDA |
A5/SCK | - | SCL |
GND | - | GND |
5V | - | Vin |
■コテライザー 70Aセット20~80W相当 N70A
今年になって新調したガス式はんだゴテです。とても快適です。
コテライザー70
・ライター着火タイプ
・連続使用時間:120分
・付属コテ先:70-01-01
・全長(mm):243
・最高温度(℃):約500(はんだこて)/約630(ホットブロー)
・ガス充填量(ml):28
・電気はんだこて20~80W相当
お買い物はこちらです♡→コテライザー 70 (amazon)
■時計/温度表示装置完成

背面からみた様子です。上段が表示用基板、中段がArduino Nano と温湿度センサーになっています。
Arduino Nanoから,LED12ピン分の配線が延びています。

中段から下段のリアルタイムクロックへは5本の線でつながっています。

時刻と温度を自動的に切り替えて表示するようにしてあります。
右側に写っているのは、5V昇圧回路の基板です。乾電池に繋がっています。
割と電力を消費しますので、実際にはUSB給電がよいと思います。
■ソースコード
雑なコードですので、使用する際には好きなように編集してください。
#include <Adafruit_AHTX0.h>
Adafruit_AHTX0 aht;
//---- DS1302 definition ---------------------
#define PIN_CE 16
#define PIN_IO 15
#define PIN_SCLK 14
const uint8_t Sun = 1;
const uint8_t Mon = 2;
const uint8_t Tue = 3;
const uint8_t Wed = 4;
const uint8_t Thr = 5;
const uint8_t Fri = 6;
const uint8_t Sat = 7;
static char clockTime[13];
static char editTime[20];
static char shortTime[7];
static String recv = "";
//----------------------------------------
int characterdata[10][7] = {
{1,1,1,1,1,1,0},
{0,1,1,0,0,0,0},
{1,1,0,1,1,0,1},
{1,1,1,1,0,0,1},
{0,1,1,0,0,1,1},
{1,0,1,1,0,1,1},
{1,0,1,1,1,1,1},
{1,1,1,0,0,0,0},
{1,1,1,1,1,1,1},
{1,1,1,1,0,1,1} };
int anode[7] = {4,5,6,13,2,3,7};
int cathode[5] = {12,11,10,9,8};
int digits[4];
// 整数値をBCDに変換
byte dec2bcd(int x) {
return ((x/10)<<4)+(x%10);
}
uint8_t bcd2dec(const uint8_t bcd) {
return (10*((bcd&0xF0)>>4)+(bcd&0x0F));
}
uint8_t shiftInEx() {
uint8_t input_value=0;
uint8_t bit=0;
pinMode(PIN_IO,INPUT);
for (int i=0; i<8; ++i) {
digitalWrite(PIN_SCLK,HIGH);
delayMicroseconds(1);
digitalWrite(PIN_SCLK,LOW);
delayMicroseconds(1);
bit = digitalRead(PIN_IO);
input_value |= (bit<<i); // Bits are read LSB first.
}
return input_value;
}
void shiftOutEx(const uint8_t value) {
bool pinModeFlag = false;
pinMode(PIN_IO, OUTPUT);
for (int i=0;i<8;++i) {
digitalWrite(PIN_IO, (value>>i)&1);
delayMicroseconds(1);
digitalWrite(PIN_SCLK,HIGH);
delayMicroseconds(1);
if (i==7) {
if (value==0xBF) pinModeFlag=true; // clock Burst Read
if ((value>=0x80)&&(value<=0x8D)&&(value%2)) pinModeFlag=true;
}
if (pinModeFlag) {
pinMode(PIN_IO,INPUT);
} else {
digitalWrite(PIN_SCLK,LOW);
delayMicroseconds(1);
}
}
}
uint8_t readReg(const uint8_t reg) {
digitalWrite(PIN_SCLK,LOW);
digitalWrite(PIN_CE,HIGH);
delayMicroseconds(4);
shiftOutEx(reg);
uint8_t dec = bcd2dec(shiftInEx());
digitalWrite(PIN_CE, LOW);
delayMicroseconds(4);
return dec;
}
void writeReg(const uint8_t reg, uint8_t value) {
digitalWrite(PIN_SCLK,LOW);
digitalWrite(PIN_CE,HIGH);
delayMicroseconds(4);
shiftOutEx(reg);
shiftOutEx(value);
digitalWrite(PIN_CE, LOW);
delayMicroseconds(4);
}
void writeProtect() {
writeReg(0x8E,0x00);
}
// トリクルチャージ設定(1ダイオード,2kΩ)
void trickleCharge() {
writeReg(0x90,0xA5);
}
void getDateBurst() {
digitalWrite(PIN_SCLK,LOW);
digitalWrite(PIN_CE,HIGH);
delayMicroseconds(4);
shiftOutEx(0xBF); //clock Burst Read
uint8_t ss = bcd2dec(shiftInEx() & 0x7F);
uint8_t ii = bcd2dec(shiftInEx());
uint8_t hh = bcd2dec(shiftInEx());
uint8_t dd = bcd2dec(shiftInEx());
uint8_t mm = bcd2dec(shiftInEx());
uint8_t day = bcd2dec(shiftInEx());
uint8_t yy = bcd2dec(shiftInEx());
digitalWrite(PIN_CE, LOW);
delayMicroseconds(4);
sprintf(clockTime,"%02d%02d%02d%02d%02d%02d",yy,mm,dd,hh,ii,ss);
sprintf(editTime, "20%02d-%02d-%02d %02d:%02d:%02d",yy,mm,dd,hh,ii,ss);
sprintf(shortTime,"%02d%02d%02d",yy,mm,dd);
}
// 時刻を設定する
void adjustClock() {
char updateTime[13];
int yy=21,mm=01,dd=18,hh=19,ii=31,ss=00,day=Mon;
sprintf(updateTime,"%02d%02d%02d%02d%02d%02d",yy,mm,dd,hh,ii,ss);
getDateBurst();
// シリアル通信開始時の、Arduinoオートリセット機能対応
if (strcmp(updateTime,clockTime)>0) {
writeProtect();
digitalWrite(PIN_SCLK,LOW);
digitalWrite(PIN_CE,HIGH);
delayMicroseconds(4);
shiftOutEx(0xBE); //clock Burst Write
shiftOutEx(dec2bcd(ss));
shiftOutEx(dec2bcd(ii));
shiftOutEx(dec2bcd(hh));
shiftOutEx(dec2bcd(dd));
shiftOutEx(dec2bcd(mm));
shiftOutEx(dec2bcd(day));
shiftOutEx(dec2bcd(yy));
//shiftOutEx(0x00); // Write protecton register
digitalWrite(PIN_CE, LOW);
delayMicroseconds(4);
trickleCharge();
}
}
void updateTime() {
Serial.println("updateTime=" + recv);
uint8_t yy = (recv[0]-0x30)*10 + (recv[1]-0x30);
uint8_t mm = (recv[2]-0x30)*10 + (recv[3]-0x30);
uint8_t dd = (recv[4]-0x30)*10 + (recv[5]-0x30);
uint8_t hh = (recv[6]-0x30)*10 + (recv[7]-0x30);
uint8_t ii = (recv[8]-0x30)*10 + (recv[9]-0x30);
// writeReg(0x80,dec2bcd(ss)); // 秒
writeReg(0x82,dec2bcd(ii)); // 分
writeReg(0x84,dec2bcd(hh)); // 時
writeReg(0x86,dec2bcd(dd)); // 日
writeReg(0x88,dec2bcd(mm)); // 月
writeReg(0x8C,dec2bcd(yy)); // 年
}
void getTime() {
getDateBurst();
digits[0] = clockTime[6]-0x30;
digits[1] = clockTime[7]-0x30;
digits[2] = clockTime[8]-0x30;
digits[3] = clockTime[9]-0x30;
}
void setTime() {
while (Serial.available()) {
char data = Serial.read();
Serial.print(data);
if ((data=='\n')||(data=='\r')) {
if (recv.length()==10) {
updateTime();
getDateBurst();
Serial.println(clockTime);
}
recv = "";
} else {
recv += data;
}
}
}
void setup_DS1302() {
digitalWrite(PIN_CE, LOW);
pinMode(PIN_CE, OUTPUT);
pinMode(PIN_IO, INPUT);
digitalWrite(PIN_SCLK, LOW);
pinMode(PIN_SCLK,OUTPUT);
}
void getTemperature() {
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);
int intTemp = (int)(temp.temperature * 100);
digits[0] = (int)(intTemp/1000); intTemp -= (digits[0]*1000);
digits[1] = (int)(intTemp/100); intTemp -= (digits[1]*100);
digits[2] = (int)(intTemp/10); intTemp -= (digits[2]*10);
digits[3] = intTemp;
}
void setup_AHT10() {
if (! aht.begin()) {
Serial.println("Could not find AHT? Check wiring");
while (1) delay(10);
}
}
void drawDigit(int pos, int num) {
for (int i=0;i<5;++i) pinMode(cathode[i], INPUT);
pinMode(cathode[pos+1], OUTPUT);
digitalWrite(cathode[pos+1], 0);
for (int i=0;i<7;++i) digitalWrite(anode[i], characterdata[num][i]);
delay(2);
}
void drawColon() {
for (int i=0;i<5;++i) pinMode(cathode[i], INPUT);
pinMode(cathode[0], OUTPUT);
digitalWrite(cathode[0], 0);
for (int i=0;i<7;++i) digitalWrite(anode[i], 0);
digitalWrite(anode[1], 1);
delay(2);
}
void setup () {
Serial.begin(115200);
setup_DS1302();
setup_AHT10();
for (int i=0;i<7;++i) {
pinMode(anode[i], OUTPUT);
digitalWrite(anode[i], LOW);
}
for (int i=0;i<5;++i) {
pinMode(cathode[i], INPUT);
}
}
void showLED() {
for(int i=0;i<250;i++) {
drawDigit(0,digits[0]);
drawDigit(1,digits[1]);
drawColon();
drawDigit(2,digits[2]);
drawDigit(3,digits[3]);
}
}
void loop () {
setTime();
getTime();
for(int i=0;i<3;i++) showLED();
getTemperature();
showLED();
}
サンプルプログラムでは、デバイスモニターを起動して、西月日時分を各々2桁で入力すると、時刻を更新できます。
例えば、西暦2021年1月30日21時5分の場合
$ platformio device monitor -p /dev/ttyUSB0 -b 115200
2101302105
|

【深層学習関連】
【画像処理関連】

【音楽関連】

【WEBサイト構築関連】

【開発環境関連】

【SNS関連】

【周辺機器関連】

【その他】

Interface 2021年4月号
リアルタイムOS新時代に突入! クラウド接続もスタンドアロンも! ~
☆特集「 Amazon×マイコン FreeRTOS入門 」
☆新連載: 逆引きMicroPythonプログラム集
ラズパイマガジン2021年春号
モーターやLED、小型ディスプレイ、スイッチなど、多様な電子パーツ450種を一挙に紹介します。
特性や価格の一覧表を用意したので、用途に合った適切な製品を選べます。
トランジスタ技術 2021年3月号
☆特集~ 周辺素子,シリアル通信,アナログ入出力, CPUの活用~「FPGAを全方位に使いこなす」
日経Linux 2021年3月号
【特集 1】まる分かり50ステップ Linux 超入門
【特集 2】あなたのワガママかなえます! WindowsのアプリをLinuxで使いたい
【特集 3】公衆Wi-Fiは危険がいっぱい!? パスワードの盗聴を実験してみた
【特集 4】キーボード一体型の新モデル Raspberry Pi 400を検証
【特集 5】ラズパイで楽しむLinuxライフ オンラインのドキュメント編集をNextcloudとCollabora Onlineで実現
15Stepで踏破 自然言語処理アプリケーション開発入門
エンジニアの実務に役立つ知識に絞り、独自に15の学習ステップを体系化しました。
数値計算にNumPy、形態素解析にMeCab、機械学習にscikit-learn、ディープラーニングに
Keras等を使い、Pythonのコードを記述し動かしていきます。
プログラミング・ビットコイン ―ゼロからビットコインをプログラムする方法
Linuxサーバーがゼロから作れる本
このLinuxを使いこなす上で一番手っ取り早いのが自分でLinuxサーバーを構築してみることです。
WindowsやMacのパソコンしか使ったことが無い人でも理解できるよう、
しくみや手順の解説を丁寧にまとめ上げた、ゼロからのサーバー入門ガイドです。
Raspberry Pi 3 Model B V1.2 (日本製) 国内正規代理店品
【仕様概要】CPU:ARM 1.2GHz 4コア、GPU:2コア 3D・動画支援、RAM:1GB、ネットワーク:LAN/Wi-Fi/Bluetooth、インターフェース:USB/HDMI/オーディオ/GPIO(UART/I2C/I2S/SPI...)。
Arduino Nano
ATmega328搭載/
動作電圧: 5V/
入力電源電圧(推奨):7~12V/
デジタル入出力ピン: 14本/
PWMチャンネル: 6本/
アナログ入力チャンネル: 8本/
直流電流(1ピン当り最大): 40 mA/
直流電流(3.3Vピン、1ピン当り最大): 50 mA/
Flashメモリ: 32 KB (ATmega328) 内2KBはブートローダーで使用/
SRAM: 2 KB (ATmega328)/
EEPROM: 1 KB (ATmega328)/
Clock Speed: 16 MHz
逆引き PIC電子工作 やりたいこと事典
機能が豊富で、速度・アナログ制御・省電力性・コストの面でもアドバンテージをもつPICマイコン。そんなPICマイコンの使い方を、目的別にやりたいことから引ける、逆引きタイプのガイドブックです。
C言語による PICプログラミング大全
2002年に初版、2009年に第2版を発売した名著『C言語によるPICプログラミング入門』
が大幅リニューアルし「大全」として生まれ変わりました。
本書では、機能豊富なPIC16F1シリーズを使いこなすために、統合開発環境を
MPLAB X IDEに、CコンパイラはMicrochip Technology社純正のXC8に、それぞれ変更しました。
C言語でPICマイコンのプログラミングを始めたい方から、最新のPICマイコンの機能をとことん使い倒したい方まで、必ず役に立つ1冊です。
PICと楽しむRaspberry Pi活用ガイドブック
「PICマイコン+Raspberry Pi3B」という組み合わせで、高機能な電子工作を簡単に実現し、電子工作を各段に高度化する方法について解説していきます。
ESP32&Arduino 電子工作 プログラミング入門
電子工作ファンに人気のマイコンArduino、そしてWiFiとBluetooth内蔵でネットワーク接続しやすいESP32。それらのマイコンでプログラムを組む際に使うのが「Arduino言語」です。
超特急Web接続!ESPマイコン・プログラム全集
IoT技術の回路とプログラムを解説しました.
トランジスタ技術2016年9月号と2017年3月号の特集に
最新の情報を加筆して一冊に仕上げました.
回路とプログラムのサンプル資料として最適です.
ラズベリー・パイやIchigoJamを連動させた例も紹介しています
M5Stack用カード型キーボードユニット
M5Stackにフル機能のQWERTY配列キーボードを実装できるユニットです。複数のボタンの組み合わせ(Sym + Key、Shift + Key、Fn + Key)や豊富なキーの値を出力することが可能です。
Ubuntu サーバー徹底構築
サーバー用UbuntuでLinuxサーバーを構築しよう!
導入からLinuxやコマンドの基本、各種サーバー構築、バックアップやストレージ管理まで!
サーバー用Linuxディストリビューションとして定評のあるUbuntu Serverの中でも、
10年長期サポート版であるUbuntu Server 18.04 LTSに対応!
[改訂第3版]Linuxコマンドポケットリファレンス
本書はLinux操作に必要なコマンドを収録したポケットリファレンスです。機能別にコマンドを分類し、各コマンドページでは書式/使用例などをコンパクトにまとめています。またアルファベット順索引も用意しており、名前しかわからなくてもすぐに目的のコマンドを探すことができます。今回の改訂では仮想化、データベース、クラウド時代に対応したネットワークコマンドなどを追加しています。おもなLinuxディストリビューションのCentOS、Fedora、Debian GNU/Linux、Ubuntuに対応し、初心者から上級者まで必携の1冊です。
できるPRO Apache Webサーバー 改訂版 Version 2.4/2.2/2.0対応
番のApache独学書を改訂しました!
CentOS、Ubuntu、Windows、Mac OS Xに対応しています。できるPROシリーズは、実際の画面や詳細なイラスト、概念図などで構成。
はじめての方でも理解しやすくなっています。
インストール、アクセス制限、CGI、モジュール拡張、ログ管理など、基本的なことから実践的なことまでていねいに解説しています。
[改訂第3版]PHPポケットリファレンス
PHPを利用したいすべての方必携の「PHPポケットリファレンス」最新版がついに登場! PHP 5/4による開発の際によく利用される機能を集約し、必要な知識を目的別、逆引きでまとめました。PHP5.3以降を対象とし、PHP4からある機能はPHP4でも利用できることがわかるようになっています。またオブジェクト指向型のAPI解説を大幅に強化。開発の現場には1冊置いておきたい書籍です。
MySQL ポケットリファレンス
MySQLはさまざまなWebサービスの中核を担うデータベースです。本書はMySQLの基礎的な内容を中心に、日常的によく使うちょっとしたコマンドや、外部管理ツールとの連携など、MySQLの管理/運用にあたって便利な情報を素早く探し出すことができます。MySQL自体の操作、MySQL特有のコマンド、MySQL専用管理ツール、PHPからの操作など、MySQLを実際に使っているユーザーに役立つ内容となっています。
Postfix詳解―MTAの理解とメールサーバの構築・運用
電子メールの配送システムの中核を担うプログラム「MTA」(Message Transfer Agent)のひとつが、「Postfix」です。 この全容を記した本です。
すところなく解説していきます。
DNSがよくわかる教科書
本書では、DNSの仕組みから、ドメイン名のルール、主なリソースレコードの内容、コマンドによる動作確認、DNSの運用ノウハウ、DNSSECの基礎知識まで、順を追ってやさしく解説します。
|