// ライブラリの実装 //
#import "@preview/codelst:2.0.1": sourcecode


//フォント設定//
#let gothic  = "YuMincho"

//本文フォント//
#set text(11pt, font: gothic, lang: "ja") 

//タイトル・見出しフォント//
#set heading(numbering: "1.1")
#let heading_font(body) = {
  show regex("[\p{scx: Han}\p{scx: Hira}\p{scx: Kana}]"): set text(font: gothic)
  body
}
#show heading: heading_font

// ページ設定 //
#set page(
    paper: "a4",
    margin: (x: 25mm, y: 25mm),
    columns: 1,
    //fill: 背景色,
    numbering: "1",
    number-align: center,
    header: [
        #set text(8pt)
    ]
)

// 数式の表示の仕方を表示 //
#set math.equation(numbering: "(1)")

//本文ここから//
= 演習の目的
実験を通して、フルカラーLED OSTA5131Aの使い方と仕組みの習得を目的とする。

= 演習の使用部品

== @LEDダイオード の電子部品 ( フルカラーLED OSTA5131A) を次のような点から調べなさい。

#figure(
  image("./img/LEDダイオード.png",width: 50%),
  caption: "LEDダイオード"
)<LEDダイオード>

=== どのような部品か
オプトサプライのフルカラーRGBLED。発光色を混ぜるとフルカラーを表現可能となる @rgbled_akituki 。

=== どのような仕組みか
フルカラーLEDには、それぞれ赤、緑、青で発光する半導体の小さな板（LEDチップ）が入っており、それぞれのLEDチップに流す電流の大きさを変えてそれぞれの色の光の強度を変え、3色の混合割合を変えると、発光色を変化させる  。

=== どのような入力を取り扱うのか
電流を入力として取り扱う。

#pagebreak() // ページを分ける

=== 入力に応じて出力がどう変化するのか (データシートや仕様書を参考に) <H_入力に応じて出力がどう変化するのか>

OptoSupplyによると、赤色は2.8Vぐらいを加えると最大光量に達成するが、緑と青色は、3.8Vぐらいを加えると最大光量に達成する @rgbled_datasheet 。
@LEDダイオードグラフ は、電圧が増加すると光量が増加する。グラフの形としては指数関数的に増加している。

#figure(
  image("./img/LEDダイオードグラフ.png",width: 50%),
  caption: "LEDダイオードグラフ"
)<LEDダイオードグラフ>

=== どのようなピンアサイン (各ピンの役割) か 

OptoSupplyによると、LEDのピンアサインは、緑が1番、青が2番、GNDが3番, 赤が4番である @rgbled_datasheet 。
@LEDダイオードピンアサイン は、ピンアサインを示している。

#figure(
  image("./img/LEDダイオードピンアサイン.png",width: 50%),
  caption: "LEDダイオードピンアサイン"
)<LEDダイオードピンアサイン>

=== 正しい動作の条件，範囲は何か

秋月電子通商によると、以下の通りとなる @rgbled_akituki 。

-  種別:砲弾型
-  色:赤・緑・青
-  ドミナント波長:赤635nm・緑525nm・青470nm
-  ドミナント波長赤:635nm
-  ドミナント波長緑:525nm
-  ドミナント波長青:470nm
-  光度:赤2000mcd・緑7000mcd・青2500mcd
-  光度赤:2000mcd
-  光度緑:7000mcd
-  光度青:2500mcd
-  順電圧:赤2V・緑3.6V・青3.6V
-  順電圧赤:2V
-  順電圧緑:3.6V
-  順電圧青:3.6V
-  順電流max.:赤30mA・緑30mA・青30mA
-  順電流max.赤:30mA
-  順電流max.緑:30mA
-  順電流max.青:30mA
-  逆電圧:赤5V・緑5V・青5V
-  逆電圧赤:5V
-  逆電圧緑:5V
-  逆電圧青:5V
-  許容損失max.:赤75mW・緑105mW・青105mW
-  許容損失max.赤:75mW
-  許容損失max.緑:105mW
-  許容損失max.青:105mW
-  半減角:30°
-  動作温度min.:-30℃
-  動作温度max.:85℃
-  構成:カソードコモン
-  端子部形状:ピン
-  実装タイプ:スルーホール
-  長さ:8.7mm
-  径:5mm


#pagebreak() // ページを分ける

= 課題内容

== フルカラーLEDを光らせる

=== 実験その１ (動作確認)

アナログ出力は以下の表4.2 のようになる。 表に従いフルカラーLED の各ピンへのアナログ出力値に対してフルカラーLED が何色に発光するかを確認しなさい。
あわせて @フルカラーLEDの発光色のアナログ出力値 の空欄箇所を埋めなさい。

// Definition of table format
#figure(
  table(
    columns: 4 * (1fr,),
    align: center ,

    table.cell(colspan: 3, "アナログ出力"), table.cell(colspan: 1, "状態"),
    [赤],[緑],[青],[],
    [255],[255],[255],[白],
    [0],[0],[0],[黒],
    [255],[0],[0],[赤],
    [],[],[],[緑],
    [],[],[],[水色],
    [255],[0],[255],[],
    [255],[100],[0],[],
  ),
  caption: [フルカラーLED の発光色のアナログ出力値],
) <フルカラーLEDの発光色のアナログ出力値>


*回路図* 

@実験1回路図 は、実験1の回路図を示す。
フルカラーLEDの各ピンにアナログ出力を入力し、フルカラーLEDを光らせる。
間に抵抗を入れて、電流を制限してLEDを保護する。

#figure(
  image("./img/実験1回路図.png",width: 50%),
  caption: "実験1回路図"
)<実験1回路図>

#pagebreak() // ページを分ける

*プログラム*

@アナログ出力値を切り替えるプログラム は、実験1で使用したアナログ出力値を切り替えるプログラムを示している。

#figure(
  sourcecode[```c
void setup(){
  pinMode(3,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
}

void loop(){
  analogWrite(3,255); // R
  analogWrite(5,255); // B
  analogWrite(6,255);  // G
  delay(1000);
}
    ```],
  caption: "アナログ出力値を切り替えるプログラム"
)<アナログ出力値を切り替えるプログラム>

- プログラムの概要
アナログ出力値を切り替えて、フルカラーLEDを光らせるプログラムである。
- プログラムの説明
  - 1–5 行目: ピンの設定
    - 2, 3, 4 行目でそれぞれ赤、青、緑のピンを出力に設定している。
  - 7–12 行目：プログラムの動作
    - 8, 9, 10 行目でそれぞれ赤、青、緑のアナログ出力値を255に設定している。
    - ここの値を手動で変更し、フルカラーLEDの発光色を変更できる。

*実験結果*

@フルカラーLEDの発光色のアナログ出力値の結果 は、フルカラーLEDの発光色のアナログ出力値の結果を示している。
全てのピンに255を入力したときに白色に発光するため、光の三原色である赤、緑、青の光を混ぜると白色になる現象と同一なため、他の色も光の三原色を利用して色の表現が可能になるとわかる。
また、赤色については、かなり他の色に比べて強く色が発色した。

#figure(
  table(
    columns: 4 * (1fr,),
    align: center,

    table.cell(colspan: 3, "アナログ出力"), table.cell(colspan: 1, "状態"),
    [赤],[緑],[青],[],
    [255],[255],[255],[白],
    [0],[0],[0],[黒],
    [255],[0],[0],[赤],
    [0],[255],[0],[緑],
    [0],[255],[255],[水色],
    [255],[0],[255],[紫色],
    [255],[100],[0],[黄色],
  ),
  caption: [フルカラーLEDの発光色のアナログ出力値の結果],
) <フルカラーLEDの発光色のアナログ出力値の結果>

*考察*

赤色については、かなり他の色に比べて強く色が発色する。
@H_入力に応じて出力がどう変化するのか より、グラフを参照すると、電圧が増加すると光量が増加する。
そのときに、赤色は2.8Vぐらいを加えると最大光量に達成するが、緑と青色は、3.8Vぐらいを加えると最大光量に達成する。
そのため、赤色は他の色に比べて強く発色すると考えられる。

=== 発展その1(ランダム関数の導入)

1秒ごとに、フルカラーLED の発光色がランダムに変わるようにしなさい。

*回路図・プログラム* 

回路図は実験その1 と同じものを使用する。
@ランダムでLEDを光らせるプログラム は、ランダムでLEDを光らせるプログラムを示している。

#figure(
  sourcecode[```c
void setup(){
  pinMode(3,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
}

void loop(){

  int r = random(0,255);
  int b = random(0,255);
  int g = random(0,255);

  analogWrite(3,r); // R
  analogWrite(5,b); // B
  analogWrite(6,g);  // G
  delay(1000);
}
    ```],
  caption: "ランダムでLEDを光らせるプログラム"
)<ランダムでLEDを光らせるプログラム>

- プログラムの概要
アナログ出力値を切り替えて、フルカラーLEDを光らせるプログラムである。
乱数を用いて、フルカラーLEDの発光色をランダムに変更する。
- プログラムの説明
  - 1–5 行目: ピンの設定
    - 2, 3, 4 行目でそれぞれ赤、青、緑のピンを出力に設定している。
  - 7–17 行目：プログラムの動作
    - 9–11 行目でそれぞれの発色をランダムに設定している。
    - 13–15 行目でそれぞれの色のアナログ出力値を設定している。
    - 16 行目で1秒待機している。

*実験結果・考察*

乱数を利用したため、様々な色を表現できるようになった。
Delayを無くすと色がすばやく点滅し、ほとんど白色に見える。 
Delayを行うことにより、Delayを行う前までの処理を一時停止して出力を切らないまま止める。 

#pagebreak() // ページを分ける

=== 発展その2(map 関数の導入)

好きな色を3 色選び、一定時間ごとにフルカラーLED が選んだ色に少しずつ変わるようにしなさい。
  例: 青(B) → (中間色M) →赤(R) → (中間色Y) →緑(G) → (中間色C) →青(B)
// @光の三原色 は、光の三原色を示している。
// #figure(
//   image("./img/光の三原色.png",width: 30%),
//   caption: "光の三原色"
// )<光の三原色>

*回路図・プログラム*

回路図は実験その1 と同じものを使用する。
@グラデーションをかけてLEDを光らせるプログラム は、グラデーションをかけてLEDを光らせるプログラムを示している。

#figure(
  sourcecode[```c
// ピンの指定
const int redPin = 3;
const int greenPin = 6;
const int bluePin = 5;
// ピンのセットアップ
void setup()
{
    pinMode(redPin, OUTPUT);
    pinMode(greenPin, OUTPUT);
    pinMode(bluePin, OUTPUT);
}

void loop()
{
    // グラデーションを行うループ
    fadeColor(0, 0, 255, 255, 0, 255, 2000);
    fadeColor(255, 0, 255, 255, 0, 0, 2000);
    fadeColor(255, 0, 0, 255, 255, 0, 2000);
    fadeColor(255, 255, 0, 0, 255, 0, 2000);
    fadeColor(0, 255, 0, 0, 255, 255, 2000);
    fadeColor(0, 255, 255, 0, 0, 255, 2000);
}

void fadeColor(int r1, int g1, int b1, int r2, int g2, int b2, int duration)
{
    // グラデーションの初期設定
    int steps = 255;
    // グラデーションを行う間隔を設定
    int stepDelay = duration / steps;

    // グラデーション開始
    for (int i = 0; i <= steps; i++)
    {
        // 0〜255の切り替えをr1~r2までの幅と同じスケールで変わっていくようにしてくれる
        int r = map(i, 0, steps, r1, r2);
        int g = map(i, 0, steps, g1, g2);
        int b = map(i, 0, steps, b1, b2);

        // 表示して
        analogWrite(redPin, r);
        analogWrite(greenPin, g);
        analogWrite(bluePin, b);
        // 短い間隔で止まる
        delay(stepDelay);
    }
}
    ```],
  caption: "グラデーションをかけてLEDを光らせるプログラム"
)<グラデーションをかけてLEDを光らせるプログラム>

- プログラムの概要
アナログ出力値を切り替えて、フルカラーLEDを光らせるプログラムである。
Mapを用いて、綺麗なグラデーションを行なう、また、Delayを細かく行うことで、ちらつかずに滑らかに色を変える。
- プログラムの説明
  - 1–11 行目: ピンの設定
    - 2–4 行目でそれぞれ赤、青、緑のピン番号を設定している。
    - 8–10 行目でそれぞれ赤、青、緑のピンの出力を設定している。
  - 13–46 行目：プログラムの動作
    - 16–21 行目でそれぞれの発色のグラデーションを設定している。
    - 24–46 行目でグラデーションを行う関数を設定している。
    - 27 行目でグラデーションの初期設定を行っている。
    - 29 行目でグラデーションを行う間隔を設定している。
    - 32–44 行目でグラデーションを行う処理を行っている。
    - 35–37 行目でmap関数を用いて、範囲を揃えて再マッピングを行っている。
    - 40–42 行目でそれぞれの色のアナログ出力値を設定している。
    - 44 行目でDelayを行っている。

*実験結果・考察*

Mapを用いると、綺麗にグラデーションを行える。 
Mapを用いると0~255の範囲と旧値と新値の範囲を揃えて再マッピングを行ない、上限までに到達する時間を揃えられるため、綺麗にグラデーションを行える。 
Delayを細かく行うと、ちらつかずに滑らかに色を変えれる。 

=== まとめ

LEDは光の三原色を用いることでフルカラーを表示できる。 
Random関数を使うと色を複雑な順序で変えれる。 
Mapと細かいDelayを用いると綺麗なグラデーションを作れる。 

#pagebreak() // ページを分ける

// bibファイルの指定 //
#bibliography("./bibliography.bib")

