ワイヤレスレーザーデータ通信(Li-Fi) - 100bps性能概要
必要な部品と材料
| 部品 | 数量 | 備考 |
|---|---|---|
| Arduino Nano R3 | 2 | 送信側・受信側各1台 |
| ブレッドボード(フルサイズ) | 2 | |
| 英数字LCD 16×2 | 2 | 送信側・受信側各1台 |
| ジャンパーワイヤー | 30本 | |
| キーパッド 4×3 | 1 | 送信側用 |
| 9V電池 | 2 | |
| 9V電池スナップ | 2 | |
| レーザーダイオード(2ピン) | 1 | 送信側用 |
| ソーラーセル(受光素子) | 1 | 受信側用 |
| 可変抵抗器 | 2 | LCDコントラスト調整用 |
| 抵抗 10kΩ | 3 |
必要な工具
- 半田ごて
- 半田(鉛フリー推奨)
使用ソフトウェア・サービス
- Arduino IDE
このプロジェクトについて


このプロジェクトは「送信機(エミッター)」と「受信機(レシーバー)」の2つで構成され、キーパッドで入力したテキストをレーザー光で飛ばし、受信側のLCDに表示します。可視光通信(Li-Fi)の基本原理を学べる優れた教材です。
コード
送信側コード(LI-FI Transmitter Code V 2.0)
/* LI-FI Transmitter Code V 2.0
Written By HOUALEF AHMED RAMZI
Started on 29-9-2020 Last Update on 14-10-2020 */
#define LaserPin 2
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 6, d5 = 5, d6 = 4, d7 = 3;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int incomingchar;
int KeyPad_R[] = {A2, A1, 9, 7}; // キーパッド行ピン
int KeyPad_C[] = {8, 10, A3}; // キーパッド列ピン
int KeyReturn = 0; // 押されたキー番号(1-12)
int ABC = 0; // 1ボタンで3文字入力用
int Row, Column; // キーパッドスキャン用
int StCursor = 0, NdCursor = 0; // カーソル位置
int outcomingmatrix[32][5]; // 送信データバッファ
int m = 0; // バッファ有効長
// 5ビット符号化テーブル(A-Z, SPACE)
int A[] = {1,1,1,1,0}, B[] = {0,0,0,1,0}, C[] = {0,0,0,1,1}, D[] = {0,0,1,0,0},
E[] = {0,0,1,0,1}, F[] = {0,0,1,1,0}, G[] = {0,0,1,1,1}, H[] = {0,1,0,0,0},
I[] = {0,1,0,0,1}, J[] = {0,1,0,1,0}, K[] = {0,1,0,1,1}, L[] = {0,1,1,0,0},
M[] = {0,1,1,0,1}, N[] = {0,1,1,1,0}, O[] = {0,1,1,1,1}, P[] = {1,0,0,0,0},
Q[] = {1,0,0,0,1}, R[] = {1,0,0,1,0}, S[] = {1,0,0,1,1}, T[] = {1,0,1,0,0},
U[] = {1,0,1,0,1}, V[] = {1,0,1,1,0}, W[] = {1,0,1,1,1}, X[] = {1,1,0,0,0},
Y[] = {1,1,0,0,1}, Z[] = {1,1,0,1,0}, SPACE[] = {1,1,1,1,1};
void setup() {
lcd.begin(16, 2);
pinMode(LaserPin, OUTPUT);
Serial.begin(9600);
for(int i=0;i<4;i++) pinMode(KeyPad_R[i], OUTPUT);
for(int j=0;j<3;j++) pinMode(KeyPad_C[j], INPUT);
lcd.print("HOUALEF RAMZI");
delay(5000);
lcd.clear();
lcd.setCursor(0,0);
}
void conv(int alpha[5], char Char) {
for(int i=0;i<5;i++) outcomingmatrix[m][i] = alpha[i];
lcd.print(Char);
}
void start_bit() {
digitalWrite(LaserPin, HIGH);
delay(9);
digitalWrite(LaserPin, LOW);
}
void KeyPad() {
for(int i=0;i<4;i++) {
digitalWrite(KeyPad_R[i], HIGH);
for(int j=0;j<3;j++) {
if(digitalRead(KeyPad_C[j])==1) {
Row=i; Column=j;
digitalWrite(KeyPad_R[i], LOW);
if(Row==0) { if(Column==0) KeyReturn=1; else if(Column==1) KeyReturn=2; else KeyReturn=3; }
if(Row==1) { if(Column==0) KeyReturn=4; else if(Column==1) KeyReturn=5; else KeyReturn=6; }
if(Row==2) { if(Column==0) KeyReturn=7; else if(Column==1) KeyReturn=8; else KeyReturn=9; }
if(Row==3) { if(Column==0) KeyReturn=10; else if(Column==1) KeyReturn=11; else KeyReturn=12; }
}
}
}
Serial.println(KeyReturn);
}
void KeyToAscii(int KeyN, int FirtAsciiValue) {
if(KeyReturn==KeyN) {
incomingchar = FirtAsciiValue + ABC;
ABC++; if(ABC==3) ABC=0;
}
}
void CursorControler() {
lcd.setCursor(StCursor, NdCursor);
if(KeyReturn==10) { delay(100); StCursor++; m++; }
if(StCursor==16) { StCursor=0; NdCursor=1; }
}
void loop() {
KeyPad(); delay(150); CursorControler();
KeyToAscii(1,65); KeyToAscii(2,68); KeyToAscii(3,71);
KeyToAscii(4,74); KeyToAscii(5,77); KeyToAscii(6,80);
KeyToAscii(7,83); KeyToAscii(8,86); KeyToAscii(9,89);
KeyToAscii(11,32);
switch(incomingchar) {
case 65: conv(A,'A'); break; case 66: conv(B,'B'); break;
case 67: conv(C,'C'); break; case 68: conv(D,'D'); break;
case 69: conv(E,'E'); break; case 70: conv(F,'F'); break;
case 71: conv(G,'G'); break; case 72: conv(H,'H'); break;
case 73: conv(I,'I'); break; case 74: conv(J,'J'); break;
case 75: conv(K,'K'); break; case 76: conv(L,'L'); break;
case 77: conv(M,'M'); break; case 78: conv(N,'N'); break;
case 79: conv(O,'O'); break; case 80: conv(P,'P'); break;
case 81: conv(Q,'Q'); break; case 82: conv(R,'R'); break;
case 83: conv(S,'S'); break; case 84: conv(T,'T'); break;
case 85: conv(U,'U'); break; case 86: conv(V,'V'); break;
case 87: conv(W,'W'); break; case 88: conv(X,'X'); break;
case 89: conv(Y,'Y'); break; case 90: conv(Z,'Z'); break;
case 32: conv(SPACE,' '); break; case 33: conv(SPACE,' '); break;
}
if(KeyReturn==12) { // 送信ボタン
delay(100);
for(int j=0;j<m;j++) {
start_bit();
for(int i=0;i<5;i++) { digitalWrite(LaserPin, outcomingmatrix[j][i]); delay(10); }
digitalWrite(LaserPin, LOW); delay(20);
}
for(int k=0;k<32;k++) for(int l=0;l<5;l++) outcomingmatrix[k][l]=0;
}
incomingchar=0; KeyReturn=0;
}
受信側コード(LI-FI Receiver Code V 2.0)
/* LI-FI Receiver Code V 2.0
Written By HOUALEF AHMED RAMZI
Started on 29-9-2020 Last Update on 14-10-2020 */
#include <LiquidCrystal.h>
#define SolarCell A0
int StCursor = 0;
int A[] = {1,1,1,1,0}, B[] = {0,0,0,1,0}, C[] = {0,0,0,1,1}, D[] = {0,0,1,0,0},
E[] = {0,0,1,0,1}, F[] = {0,0,1,1,0}, G[] = {0,0,1,1,1}, H[] = {0,1,0,0,0},
I[] = {0,1,0,0,1}, J[] = {0,1,0,1,0}, K[] = {0,1,0,1,1}, L[] = {0,1,1,0,0},
M[] = {0,1,1,0,1}, N[] = {0,1,1,1,0}, O[] = {0,1,1,1,1}, P[] = {1,0,0,0,0},
Q[] = {1,0,0,0,1}, R[] = {1,0,0,1,0}, S[] = {1,0,0,1,1}, T[] = {1,0,1,0,0},
U[] = {1,0,1,0,1}, V[] = {1,0,1,1,0}, W[] = {1,0,1,1,1}, X[] = {1,1,0,0,0},
Y[] = {1,1,0,0,1}, Z[] = {1,1,0,1,0}, SPACE[] = {1,1,1,1,1};
const int rs=12, en=11, d4=5, d5=4, d6=3, d7=2;
int Cell_Input, Threshold, info[5];
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
pinMode(A0, INPUT);
Serial.begin(9600);
lcd.begin(16,2);
lcd.setCursor(0,0);
Threshold = analogRead(SolarCell) + 10;
lcd.print("READY TO RECEIVE");
delay(5000);
lcd.clear();
}
void BufferClear() { for(int i=0;i<5;i++) info[i]=0; }
void check_condition(int received[5], int ref[5], char c) {
if(received[0]==ref[0] && received[1]==ref[1] && received[2]==ref[2] &&
received[3]==ref[3] && received[4]==ref[4]) {
lcd.print(c); CursorControler();
}
}
void CursorControler() {
StCursor++;
if(StCursor==16) lcd.setCursor(0,1);
}
void loop() {
Cell_Input = analogRead(SolarCell);
if(Cell_Input > Threshold) { // スタートビット検出
delay(10);
for(int i=0;i<5;i++) {
info[i] = (analogRead(SolarCell) > Threshold) ? 1 : 0;
delay(10);
}
check_condition(info, A,'A'); check_condition(info, B,'B');
check_condition(info, C,'C'); check_condition(info, D,'D');
check_condition(info, E,'E'); check_condition(info, F,'F');
check_condition(info, G,'G'); check_condition(info, H,'H');
check_condition(info, I,'I'); check_condition(info, J,'J');
check_condition(info, K,'K'); check_condition(info, L,'L');
check_condition(info, M,'M'); check_condition(info, N,'N');
check_condition(info, O,'O'); check_condition(info, P,'P');
check_condition(info, Q,'Q'); check_condition(info, R,'R');
check_condition(info, S,'S'); check_condition(info, T,'T');
check_condition(info, U,'U'); check_condition(info, V,'V');
check_condition(info, W,'W'); check_condition(info, X,'X');
check_condition(info, Y,'Y'); check_condition(info, Z,'Z');
check_condition(info, SPACE,' ');
BufferClear();
}
}
回路図・配線説明
受信側(レシーバー)
フォトセル(ソーラーセル)はレーザーと正対する位置に設置してください。
LCD接続:
- VSS → GND
- VDD → Arduino 5V
- K(バックライト-) → GND
- A(バックライト+) → Arduino 5V
- RW → GND
- V0/VEE → 可変抵抗器の中央端子(コントラスト調整)
- RS → D12, EN → D11, D4 → D5, D5 → D4, D6 → D3, D7 → D2
ソーラーセル:
- マイナス極 → GND
- プラス極 → Arduino A0
送信側(トランスミッター)
キーパッドとLCDで送信文字を入力。一文字入力ごとに確定ボタン(キー10)、最後に送信ボタン(キー12)を押します。
LCD接続: 受信側と同様だが、D4→D6, D5→D5, D6→D4, D7→D3
キーパッド接続:
- 行:A→A2, B→A1, C→D9, D→D7
- 列:1→D8, 2→D10, 3→A3
- プルダウン抵抗(10kΩ):D8-GND, D10-GND, A3-GND
レーザーダイオード:
- カソード → GND
- アノード → D2


製造プロセス
- アルミニウムレーザーマーキング専門ガイド:精度、耐久性、産業用途
- レーザーマーキング総合ガイド:種類、メリット、用途
- ファイバーレーザーマーキング:現代産業向けの精度、速度、汎用性
- レーザーポインター:設計、製造、安全性の概要
- 半導体レーザー:現代技術を支える精密光生成
- 固体レーザー:技術、応用、将来動向
- DVDプレーヤー:歴史、技術、そして未来の革新
- レーザー誘導ミサイル:開発、製造、戦略的インパクト
- Arduino UNOとMAX7219で作るUFOアタックゲーム – レトロなドットマトリクスシューティング
- 革命的電気光学レーザーが30GHzパルスレート実現、超高速イメージングと通信へ道筋
- ブレイクスルー光ファイバーが1ペタビット/秒の伝送速度を達成