2016年07月02日

フルカラーLED -第3回:カラーLEDの制御

はじめに

前回はカラーLED PL9823を動かすための回路を調べました。今回はPL9823を動かして見ます。
 

目次

 

1. 回路

図1がPL9823の基本的な回路です。
 
July01_回路図.png
図1 PL9823動作回路
 
電源ピンにはパスコンとして0.1[uF]のコンデンサ、データ入力ピンにはダンピング抵抗として33[Ω]の抵抗器を入れています。
あとはそれぞれのピンをArduinoと接続すれば動きます。
 

2. スケッチ

PL9823をArduinoで動かすにはGitHubに公開されているAdafruit NeoPixcel Libraryを使います。あとはサンプルスケッチをカラーLEDのRGBを指定すれば光らせることが出来ます。
とりあえずシリアル通信でRGBを設定できるスケッチを書きました。"R255"や"G064"、"B002"などとシリアル通信で送信すればRGBを設定できます。
 
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN            6

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      1

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800); //NEO_GRBをNEO_RGBへ変更

char type, buf_val[4]="000";
int i, red, green, blue; //LED関連

void setup() {

  /*
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code
  */
  Serial.begin(9600);

  red = 0;
  green = 0;
  blue = 0;
  pixels.begin(); // This initializes the NeoPixel library.
  pixels.setPixelColor(0, pixels.Color(red, green, blue)); // Moderately bright green color.
  pixels.show(); // This sends the updated pixel color to the hardware.
}

void loop() {

  if (Serial.available() >= 4) {
//  if (Serial.available() >= 5) {  //終端文字有りの場合
    type = Serial.read();
    for( i=0; i<3; i++ ){
      buf_val[i] = Serial.read();
    }
//    Serial.read(); //終端文字有りの場合
    switch(type){
      case 'R':
        red = atoi(buf_val);
        break;
        
      case 'G':
        green = atoi(buf_val);
        break;
        
      case 'B':
        blue = atoi(buf_val);
        break;
        
      default:
        Serial.println("Error");
        break;
        
    }

    Serial.print("R:");
    Serial.print(red);
    Serial.print(" G:");
    Serial.print(green);
    Serial.print(" B:");
    Serial.println(blue);

    pixels.setPixelColor(0, pixels.Color(red, green, blue));
    pixels.show(); // This sends the updated pixel color to the hardware.

  }

}
 
上記のスケッチでカラーLEDを光らせた写真を何枚か載せます。
 
P2280454.jpg
図2 R:255 G:255 B:255
 
P2280456.jpg
図3 R:255 G:0 B:0
 
P2280457.jpg
図4 R:16 G:0 B:0
 
P2280461.jpg
図5 R:16 G:16 B:0
 
このようにArduinoでPL9823の色や明るさを自由にいじることができました。
 

3. 活用

せっかくなのでカラーLEDを活用したインテリアっぽいものをつくりました(図6)。
 
P2280467.jpg
図6 作成物外観
 
外装は3Dプリントの造形物に塗装などを行い、作成しました。中にはカラーLEDを4つ入れています(図7)。
 
P2280463.jpg
図7 作成物中身
 
また、色をいちいち指定するのは面倒なので、電源を入れると勝手にフェード点灯/消灯を繰り返すようスケッチを書き換えました。
 
// NeoPixel Ring simple sketch (c) 2013 Shae Erisson
// released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN            6

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      4

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_RGB + NEO_KHZ800); //NEO_GRBをNEO_RGBへ変更

char type, buf_val[4]="000";
int i, led, red, green, blue; //LED関連

void setup() {

  /*
  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code
  */
  Serial.begin(9600);

  red = 0;
  green = 0;
  blue = 0;
  pixels.begin(); // This initializes the NeoPixel library.
  for(led=0; led<NUMPIXELS; led++)
    pixels.setPixelColor(led, pixels.Color(0, 0, 0));
  pixels.show(); // This sends the updated pixel color to the hardware.
}

void loop() {

  i=0;
  while(i<256){
    Serial.println(i);
    red=i;
    green=i;
    blue=0;
    for(led=0; led<NUMPIXELS; led++)
      pixels.setPixelColor(led, pixels.Color(red, green, blue)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
    delay(100);
    if(i<16) i=i+1;
    else if(i<32) i=i+2;
    else if(i<64) i=i+4;
    else if(i<128) i=i+8;
    else i=i+16;
  }

  i=255;
  while(i>-1){
    Serial.println(i);
    red=i;
    green=i;
    blue=0;
    for(led=0; led<NUMPIXELS; led++)
      pixels.setPixelColor(led, pixels.Color(red, green, blue)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
    delay(100);
    if(i<16) i=i-1;
    else if(i<32) i=i-2;
    else if(i<64) i=i-4;
    else if(i<128) i=i-8;
    else i=i-16;
  }
  
  i=0;
  while(i<256){
    Serial.println(i);
    red=i;
    green=0;
    blue=i;
    for(led=0; led<NUMPIXELS; led++)
      pixels.setPixelColor(led, pixels.Color(red, green, blue)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
    delay(100);
    if(i<16) i=i+1;
    else if(i<32) i=i+2;
    else if(i<64) i=i+4;
    else if(i<128) i=i+8;
    else i=i+16;
  }

  i=255;
  while(i>-1){
    Serial.println(i);
    red=i;
    green=0;
    blue=i;
    for(led=0; led<NUMPIXELS; led++)
      pixels.setPixelColor(led, pixels.Color(red, green, blue)); // Moderately bright green color.
    pixels.show(); // This sends the updated pixel color to the hardware.
    delay(100);
    if(i<16) i=i-1;
    else if(i<32) i=i-2;
    else if(i<64) i=i-4;
    else if(i<128) i=i-8;
    else i=i-16;
  }
  
}
 
実際に動かしたものがこちらです。
 
 

まとめ

カラーLED PL9823をArduinoで制御でき、また3Dプリントと組み合わせることでインテリアっぽい物が作れました。
これでカラーLEDのシリーズは終わりです。また何かネタが出来るまでブログの更新はお休みします。
 

はじめての「123D Design」 [ nekosan ]

価格:2,700円
(2016/7/2 11:49時点)
感想(3件)

ラベル:Led Arduino
posted by ました at 11:56| Comment(0) | TrackBack(0) | 電子工作の実践 | このブログの読者になる | 更新情報をチェックする

2016年06月30日

フルカラーLED -第2回:PL9823の調査2

はじめに

前回はカラーLED PL9823を動かすには電源ラインに外付け抵抗が必要なのか不要なのか分からないという話をしました。
今回は実験を行って、外付け抵抗の有無を調べます。
 

目次

 

1. 外付け抵抗有り

とりあえず外付け抵抗を付けた状態でカラーLEDを点灯させ、カラーLEDの電源波形を観察します。測定箇所は図1の通りです。
カラーLEDの色はRGBで指定できますのでR:192 G:128 B:64としました。
 
June30_カラーLED調査.png
図1 電源波形測定箇所
 
まずは100[Ω]を外付けして、波形を観察します。結果は図2です。
 
100orhm.png
図2 外付け抵抗100[Ω]時電源波形
 
図2より分かることはPL9823はPWMで色を調整しているということです。電圧が4段階ありますが、最も低い電圧のときは赤・緑・青が点灯、次に低いときは赤・緑が点灯、その次は赤のみ点灯、最も高いときは全て消灯しているものと思われます。
 
さて、次は外付け抵抗を47[Ω]にして波形を観察します。結果は図3です。
 
47orhm.png
図3 外付け抵抗47[Ω]時電源波形
 
電圧が4段階なのは100[Ω]時と同じです。しかし電圧が100[Ω]時と異なります。LED点灯時の電圧は100[Ω]時が2.8[V]〜3.4[V]なのに対して、47[Ω]時は3.2[V]〜4.1[V]と高いです。
仮にPL9823が抵抗を内蔵しておらずLEDだけであれば、外付け抵抗の値にかかわらず降下時の電圧は一定となるはずです。しかし、実験では外付け抵抗の値によって電圧に差が生まれました。
 
よってPL9823は抵抗を内蔵しており、外付け抵抗は不要の可能性が高いです。
 

2. 外付け抵抗無し

外付け抵抗は不要の可能性が高いので、外付け抵抗無しで実験を行います。とはいえ、外付け抵抗無しで実験を行って、過電流が流れると怖いです。
そこで、外付け抵抗有りの状態と無しの状態で電流値を測定し、過電流が流れないことを確認します。その結果が表1です。
 
表1 外付け抵抗と電流
 抵抗[Ω] 電流[mA] 
100  15.1 
47  16.5 
10  17.3 
17.5 
 
表1のように外付け抵抗無し(=0[Ω])でも過電流は流れませんでした。またPL9823に使われているカラーLED制御IC WS2811は18.5[mA]が標準ですので、外付け抵抗無しでの電流が標準に近いです。
ですので、PL9823は外付け抵抗無しで動かして問題なさそうです。
 
外付け抵抗無しでの波形が図4です。ノイズは多少乗っているものの5[V]で安定しており、特に問題はなさそうです。
 
0orhm_01.png
図4 外付け抵抗無し電源波形
 

まとめ

実験で外付け抵抗の必要性を調べたところ、PL9823に外付け抵抗は不要という結果が得られました。また、100[Ω]を外付けしたときはたまにカラーLEDが白く点灯しました。おそらく電圧降下によってカラーLEDの動作が不安定になっているものと思われます。
PL9823の外部回路が分かりましたので、次回はカラーLEDを動かします。
 

ラベル:Led 回路検討
posted by ました at 16:41| Comment(0) | TrackBack(0) | 電子工作の実践 | このブログの読者になる | 更新情報をチェックする

2016年06月21日

フルカラーLED -第1回:PL9823の調査1

はじめに

今回からフルカラーLEDを3〜4回ほどかけて扱っていきます。フルカラーLEDとはその名の通り、様々な色を出すことができるLEDです。
今回は使うカラーLEDについて調べていきます。
 

目次

 

1. 部品の概要

使用するフルカラーLEDはPL9823-F5です(図1)。
 
I-08411.jpg
図1 フルカラーLED PL9823(秋月電子通商 通販コード:I-08411)
 
PL9823はWS2811(3ch LEDコントローラIC)を内蔵していると商品ページに書いてあります。おそらくPL9823はコントローラIC以外にもRGB各色のLEDなども内蔵しており、それらをパッケージ化して砲弾型LEDにしたのだと思われます。
PL9823をArduinoで制御するにはAdafruit製フルカラーLED NeoPixelのライブラリを使います。NeoPixelはWS2811を内蔵しているWS2812を使っているため、同じライブラリでPL9823を制御することができます。
  

2. 回路の矛盾

PL9823を使うには回路を組むようがありますが、PL9823のデータシートがよく分かりません。
図2の特徴の欄には一番下の行に「外付け部品は不要」と書いてあります。
 
2016-06-20.png
図2 PL9823の特徴(データシートより抜粋)
 
一方、図3の参考回路では抵抗器とコンデンサを外付けしています。
 
2016-06-20 (1).png
図3 PL9823の参考回路(データシートより抜粋)
 
電源(VCC)-GND間のコンデンサはパスコンだと思われますので、0.1[uF]程度を外付けすれば問題はないと思います。
問題は抵抗器です。外付け部品不要と謳っていて、ここに抵抗器を接続するのは不可解です。
 
そこでコントローラIC WS2811のデータシートを確認しました。すると、図4のように確かに電源ラインに外付け抵抗があります。
 
2016-06-20 (2).png
図4 WS2811の参考回路(データシートより抜粋)
 
ただ、図4を見てもPL9823の電源ラインに外付け抵抗が必要かどうかはわかりません。なぜなら図3のように外付け抵抗を接続しても図4と同じ回路にならないからです。
仮にPL9823が各LEDのみ内蔵し抵抗器を内蔵しておらず、外付け抵抗を接続したとすると、図5のような回路になります。
 
June20_カラーLED.png
図5 PL9823に外付け抵抗を接続した場合の予想図
 
図4では各LEDは+5[V]と直接接続されていますが、PL9823に外付け抵抗を接続すると図5のように+5[V]とLEDの間に抵抗器が挟まれることが推測できます。
 
PL9823の外付け抵抗が必要なのか不要なのかの調査が必要です
 

まとめ

フルカラーLED PL9823を使おうとしましたが、データシートからでは正しい回路が分かりませんでした。
次回は実験などからPL9823が動く正しい回路を調べます。
 

Adafruit NeoPixel Ring 12連フルカラーシリアルLED 【1643】

価格:1,128円
(2016/6/21 21:27時点)
感想(0件)

ラベル:Led 回路検討
posted by ました at 21:27| Comment(0) | TrackBack(0) | 電子工作の実践 | このブログの読者になる | 更新情報をチェックする

2016年06月14日

シリアル通信の無線化 -第4回:作成

はじめに

お久しぶりです。多少はブログのネタもできてきたので、更新を再開しようかと思います。
ただし今までのように定期的な更新を行うのではなく、今後も不定期で更新しようと思ってます。
 

目次

 

1. おさらい

Bluetoothの使用方法はプロファイルというルールで決められており、SPP(Serial Port Profile)というプロファイルを使えばBluetoothでシリアル通信を行うことができます。RN-42はSPPに対応していますので、Bluetoothが載っているパソコンなどとシリアル通信を行えます。またRN-42にはシリアル通信のピンがありますので、有線でArduinoを繋ぐことができます。(図1)
 
June13_Bluetooth-SPP.png
図1 作成物概要
 
このようなものを作ります。
 

2. 実装

ハードウェア

図2が作成した回路です。
 
Wireless-LCD.png
図2 回路図
 
Arduino Unoは5[V]でRN-42は3.3[V]ですので、それらの間にはIC3(レベルシフタFXMA108)があります。これで5[V]-3.3[V]の変換を行います。また、RN-42用の電源としてIC4(三端子レギュレータTA48M033F)を使っています。
 
シリアル通信の線はArduinoのD10とD11に接続します。ですので、シリアル通信はソフト的に行います。
 
シリアル通信を行うだけならこれでいいのですが、それだけだと面白くないので以前作成したキャラクタ液晶(DIS1)も接続し、通信内容を表示できるようにします。
 
 
この程度の回路なら実装はブレッドボードでもできますが、基板設計の練習を兼ねてEagleで設計し、ユニクラフトに発注して、基板を作りました。
上にある部品がキャラクタ液晶、右下にある部品がRN-42です。Arduinoシールドとして使用できるように設計しています。
 
P2280374.jpg
図2 回路図
 
これで回路設計と基板実装ができました。
 

ソフトウェア

シリアル通信を行うだけなら、Software.Serialライブラリを使えば動かすことができます。
キャラクタ液晶で作成したスケッチをソフトウェアシリアル化したスケッチが以下です。
/* 使用しているライブラリ
 * 作者名:TOMO. "I2C液晶のArduinoライブラリ – ST7032". サイト名:オレ工房. http://ore-kb.net/archives/195, (参照日:2016-01-17)
 */

#include <Wire.h>
#include <ST7032.h>
#include <string.h>
#include <SoftwareSerial.h>

// initialize the library with the numbers of the interface pins
ST7032 lcd;
SoftwareSerial mySerial(10, 11); // RX, TX

int i, n, n1=0, n2=0;
char str1[30]="", str2[30]="";

void setup(){
  // set up the LCD's number of columns and rows: 
  lcd.begin(8, 2);
  lcd.setContrast(27);
  // initialize the mySerial communications:
  mySerial.begin(9600);
}

void loop()
{
  // when characters arrive over the mySerial port...
  if (mySerial.available()) {
    // wait a bit for the entire message to arrive
    delay(100);
    
    //1行目の文字列を2行目に移動
    strcpy(str2, str1);
    n2=n1;

    // read all the available characters
    i=0;
    while (mySerial.available() > 0) {
      // display each character to the LCD
      str1[i]=mySerial.read();
      i++;
    }
    str1[i]='\0';
    n1=i;

    //2行のうち、文字数が多い方を採用
    if(n2 > n1){
      n=n2-7;
    }
    else{
      n=n1-7;
    }

    lcd.clear();
    lcd.home();
    lcd.setCursor(0,0);
    lcd.print(str1);
    lcd.setCursor(0,1);
    lcd.print(str2);
  }
  // clear the screen
  
  //8文字以上の場合スクロール処理
  if(0<n){
    delay(1500);
    for(i=0; i<n; i++){
      //スクロール処理中にシリアル受信をしたらbreak
      if (mySerial.available()) {
        break;
      }
  
      lcd.scrollDisplayLeft();
      delay(500);
    }

    //breakによる脱出でなければスクロールを先頭に戻す
    if(i==n){
      delay(1000);
      if (mySerial.available()==0) {
        lcd.clear();
        lcd.home();
        lcd.setCursor(0,0);
        lcd.print(str1);
        lcd.setCursor(0,1);
        lcd.print(str2);
      }
    }
  }
}
 

3. 動作確認

では実際にBluetoothでシリアル通信を行います。
まず、パソコンとRN-42を接続します。画面でRNBT-4703と表示されているのがRN-42ですので、これとBluetoothで接続します。
 
2016-06-11 (4).png
図3 Bluetooth接続画面
 
あとは有線と同じようにポートを接続し、シリアル通信できます。
今回使用しているRN-42モジュールはシリアル通信の接続状態を示すためのLEDが実装されています。切断時は点滅、接続時は点灯します。
 
  

まとめ

Bluetooth SPPを使うことで、Arduinoのシリアル通信を無線化することができました。
  

Bluetooth無線でワイヤレスI/O [ トランジスタ技術編集部 ]

価格:2,808円
(2016/6/14 10:07時点)
感想(0件)

posted by ました at 10:08| Comment(0) | TrackBack(0) | 電子工作の実践 | このブログの読者になる | 更新情報をチェックする

2016年03月25日

シリアル通信の無線化 -第3回:回路設計

申し訳ないですが、今回は記事作成が間に合わないので仮の記事です。そのうちきちんと書きます。
前回はBluetoothモジュールRN-42のおおまかな仕様を確認しました。必要な回路は主に3つです。
  • 電源系
  • シリアル通信系
  • デジタルI/O系
RN-42の電源は3.3[V]ですので、Arduinoと直接接続することはできません。ですので3.3[V]電源やレベルシフタを接続する必要があります。また、RN-42にはGPIO(General Purpose Input/Output, 汎用入出力)があり、このピンで初期設定などができます。
それらを以下のように接続すれば、基本的な動作を行うことが出来ます。
 
Mar25_回路図.png
 
予定では各GPIOやレベルシフタの説明をするつもりでしたが、ちょっとできそうにないので回路図だけ載せておきます。
 
身の回りのことが落ち着いて忙しいのが一段落したら、もう一度記事を作り直します。
ラベル:回路設計 無線
posted by ました at 16:30| Comment(0) | TrackBack(0) | 電子工作の実践 | このブログの読者になる | 更新情報をチェックする