網頁

2011年7月3日 星期日

使用AVR 玩弄 EL-Wire (冷光線)

EL-Wire(ElectroLuminescent Wire, 簡稱 冷光線),是一種利用電致發光原理的發光體,外觀類似電線。看起來像是電線,但依照所要發出不同顏色的光再批覆上不同的外皮,而且由於本體中心有一根單心銅線(依照本文所使用的 3mm 的冷光線線徑,銅線部分大約占整體的 1/3,也就是 1mm 左右的線徑)可根據設計的圖形、文字做不同的形狀變化。

本文主要的目的為介紹如何使用 AVR (其他為控制器亦可)控制冷光線,內容有:

  1. 冷光線介紹與焊接方法
  2. 冷光線DC(直流電)轉AC(交流電)電路(此處的AC是指有頻率的電壓,但所轉換的電壓不一定要通過電壓零點)。
  3. 冷光線控制電路
  4. 程式碼
  5. 實際例子影片
  • 冷光線介紹與焊接方法
冷光線的結構可以由下面圖片作解釋:

照片來源:http://en.wikipedia.org/wiki/Electroluminescent_wire

銅線(Cooper Core)、細銅線(Very Fine Copper Wire):這是接到交流電(AC)兩端的線,沒有極性的區別,直接接上即可。但要使冷光線發光並不是直接接上交流電就可以,必須符合冷光線的規格。規格如下(此處以本文所使用的冷光線規格為例做說明,實際應用以所購買的冷光線規格為主,但本文中的示例,適用於大多數的冷光線應用環境中):
工作電壓範圍(Operating Voltage Range,均方根值(Root Mean Square, RMS)):
20 ~ 220V,最佳工作電壓(Optimum Operating Voltage):120V
工作頻率(Frequency of Operation):
50 ~ 5000Hz,最佳工作頻率範圍:1500 ~ 2000 Hz
靜電容(Direct Capacitance):
6 nf/m (20℃,RH < 80%
發光亮度(Glow Brightness):
@電壓:120V,頻率:200 ~ 2000 Hz:30 ~ 126 cd/m2
消耗功率(Consumed Power):
@電壓:120V,頻率:200 ~ 2000 Hz:108 ~ 103226 mw/m
壽命(Working Life):
@電壓:100V,頻率:400 Hz,正常溫度與濕度下:大約 5000小時
連續工作溫度/相對濕度(Continuous Working Temperature/Relative Humidity):
-10℃ ~ +60℃;RH < 90%
保存溫度/相對溼度(Storage Temperature/Relative Humidity):
-10℃ ~ +60℃;RH < 65%
螢光粉塗層(Phosphor Coating):塗佈在銅線的外層並纏繞兩條非常纖細的裸線的磷層。
透明保護套(Clear Protective Sleeve):包覆在銅線、螢光粉塗層、細線的外層的透明PVC套
著色PVC套(Colored PVC Sleeve):在無其他外加因素下,冷光線的原色經由螢光粉塗層所發出的光是藍綠(Blue-Green)色,此最外層的著色PVC套是用來混色用的,經由此層的混色現在的冷光線有湖水藍、粉紅色、白色、紫色、黃色、青色、綠色、橙色、紅色、深藍色...等色彩。

冷光線跟LED、霓虹管比較有以下的優點:
  1. 很軟、可隨意彎曲,可做事物或是編在服飾上作為文字或是圖樣
  2. 整條都可發光,LED必須密集連接,因此在單位長度的價格上,冷光線價錢較低($100/m)
  3. 低耗電量。經由適當的電壓、頻率轉換,兩顆乾電池就可驅動 3m 的冷光線
  4. 操作時,冷光線不會發熱、發燙,而且對人體無害,適當的防護下可用於水中環境
冷光線可近似於有著每呎 1nF 電容量的同軸電容器,對其快速充電與放電之下可激發螢光粉發出可見光。因此冷光線可經由改變工作變壓或是工作頻率,控制亮度,但相對的壽命也會減少,每天使用5小時以5000小時做計算也可使用1000天,夠本了!

冷光線購買的時候,廠商會依據你所指定的長度事先幫你焊接好接頭。但大部分的情形下,懂得冷光線的焊接處理,是應用冷光線的必要手法。

下面這段影片可做為冷光線與接頭焊接過程的最佳範例,提供給各位看倌做參考,不一定要跟影片一樣做,重要的是要將銅線上的螢光粉塗層刮掉露出中心銅線,再將兩條細線與中心銅線隔開後焊接;這步驟錯誤的話,冷光線一定不會亮。再者,熱縮套管一定要接,不然冷光線與接頭線連接處很容易斷。影片中連接的方式很牢靠,建議可行的話可以嘗試這樣做。



實際上,沒用過剝線鉗剝過冷光線(影片示範者,一次就成功剝下並露出兩條細線,很羨慕!),我是利用刀片與打火機將線撥開,再進行焊接。

若是兩段冷光線要做連接,則只要銅線對銅線、細線對戲線做焊接即可。

最後如何測試冷光線是否正常焊接,接冷光線電源供應器是一種方式,但是利用三用電表開在歐姆檔測試也可以,確認端子兩端不導通就對了!

  • 冷光線驅動電路
本文中所使用的驅動電路,是在露天拍賣買的;DC3V驅動3公尺的大約是$150元,DC12V驅動15公尺是$250元。

若有興趣自己做可參考下面的線路。
資料來源:makezine:Vol. 21: Electroluminescent (EL) Wire

上半部是驅動電路,將555的弦波訊號振幅經過比例1:10的變壓器放大10倍,並且可利用前方的100 k Ohm 的可變電阻調頻率,控制冷光線的亮度。

下半部是冷光線閃爍驅動電路,AC電壓使用 TRIAC 做開關控制。

  • 冷光線控制電路
注意到下途中的 TRIAC 元件使用 Z0103,這很方便在電子零件行買到,若買不到就隨便拿一個TRIAC即可,不需要一定要一樣,前方的限流電阻(R2)使用1K(大部分的情形都用這個大小)即可。


TRIAC (Z0103)在使用的時候有方向性的區別,也就是必須使用 T1 接腳接地,不然冷光線會在AC電源開啟時就會一直亮,無法控制。正常的情形是在AC開啟時,冷光線必須在滅掉的狀態。



最重要的一點,則是接地。由於冷光線電壓供應器的輸出為AC,但AC無極性,所以電路中的 HVGND (J4)取AC任一腳皆可,並將此接腳與DC的 GND接在一起。

J1 與 J2 就是接你的冷光線。

根據上面這個電路模型,微控制器有多少I/O接腳就可以接多少條EL-Wire,將右邊線路多複製幾組就行了。

  • 程式碼
這個Demo的程式主要是利用 ATtiny2313 的 8-bit Timer0 作為延遲計時用,並且利用此計時功能切換 I/O 接腳輸出,形成冷光線的漸亮漸滅、一亮一滅的效果。

delay_us:使用 ATtiny2313 的 Timer0 計時,延遲的最小單位是 1us (CPU Speed 8MHz),最多計時延遲 256 us,但因為輸入是整數,取其正數則可計時延遲到 32,767 us (32.767ms)。
delay_ms:利用 4 次 250 us 的計時為 1 ms,能做 216-1 ms 的延遲計時
void delay_us(int x)
{
 int y, z, a;
 
 y = x / 256;
 z = x - y * 256;
 
 for (a = 0;a < y;a++)
 {
  TIFR |= (1 << TOV0); // Clear any interrupt flags on Timer1
  
  TCNT0 = 0; // 256 - 124 = 131: Preload timer 1 for x click. Should be 1us per click
  
  while (!(TIFR & (1 << TOV0))); // Wait until timer 1 overflow flag set.   
 }
 
 TIFR |= (1 << TOV0); // clear any interrupt flags on Timer1
 
 TCNT0 = 256 - z; // 256 - 125 = 131 : Preload timer 1 for x click. shoudle be 1us per click
 
 while(!(TIFR & (1 << TOV0))); // Wait until timer1 overflow flag set.
}

void delay_ms(uint16_t x)
{
 for (;x > 0;x--)
 {
  delay_us(250);
  delay_us(250);
  delay_us(250);
  delay_us(250);
 }
}
pulse:第一個參數 line 是所指定的接腳號碼。第二個參數 speed 是 PWM duty 的間隔,數值越小較亮或漸滅的速度越慢,解析度越高。PWM 每一波段的時間為10 ms。
void pulse(uint8_t line, int speed)
{
 int x;
 
 // EL wire progressive light on increased by PWM duty = x / 10100
 for (x = 0;x < 10000;x += speed)
 {
  line_on(line);
  delay_us(x + 100);
  line_off(line);
  delay_us(10000 - x);
 }
 
 // EL wire progressive light off decreased by PWM duty = x / 10100
 for (x = 0;x < 10000;x += speed)
 {
  line_on(line);
  delay_us(10100 - x);
  line_off(line);
  delay_us(x + 100);
 }
}
程式的狀態使用 PB0 接 LED 做為系統正常狀態的提示,LED為低態動作
void hello_word()
{
 int i;
 for (i = 0;i < 5;i++)
 {
  cbi(SYS_STATUS_PORT, SYS_STATUS_INDICATOR); // turn on LED, active low
  delay_ms(300);
  sbi(SYS_STATUS_PORT, SYS_STATUS_INDICATOR); // turn off LED
  delay_ms(300);
 }
}
line_on,line_off:確定每次只亮、只滅一條冷光線
void line_on(uint8_t EL)
{
 char temp;
 
 if(line_on_2 != 0) line_off(line_on_2); // can't have more than one line on at a time
 
 // keep track of what's on and in what sequence
 line_on_2 = line_on_1;
 line_on_1 = EL;
 
 temp = EL;
 
 PORTB |= (1 << temp); 
}

void line_off(uint8_t EL)
{
 char temp;
 
 if(EL == line_on_2) line_on_2 = 0;
 else if (EL == line_on_1)
 {
  line_on_1 = line_on_2;
  line_on_2 = 0;
 }
 
 temp = EL;
 
 PORTB &= ~(1 << temp);
}
cycle:程式中並沒有用到這部分。cycle 主要是將所有的冷光線依序做亮滅,因為程式中只使用一條冷光線,所以 x < 1。如果有 8 條冷光線,那麼就是 x < 8。
void cycle(int speed)
{
 int x;
 
 if(speed > 32000) speed = 32000;
 
 for (x = 0;x < 1;x++) // Now, the EL wire only one line.
 {
  line_on(x);
  delay_us(32100 - x);
 }
 
 for (x = 1; x > 0;x--)
 {
  line_on(x);
  delay_us(32100 - speed);
 } 
}
ATtiny2313 的 IO 埠初始化與初值設定,Timer0 的 prescale 設定為 8,也就是計時頻率為 1 MHz。
void ioinit()
{
 // PB0 - PB7 define as output
 DDRB = 0xFF;
 
 // PD6 define as output
 DDRD |= 0x40;
 sbi(SYS_STATUS_PORT, SYS_STATUS_INDICATOR); // turn off system status indicator
  
 TCCR0B = (1 << CS01); // Set prescaler to 8. CS01 = 1
}
下面這段程式碼是程式的標頭設定與主程式
main:chip I/O 與 Timer0 設定 --> 先say hello(hello_world)閃爍 LED 5次 --> 進入無窮迴圈
冷光線明滅 5 次 (speed 125)--> 閃爍 10 次(on 500ms, off 250ms) --> 閃爍 10 次(on 200ms, off 300ms) --> 明滅 5 次(speed 250)
#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#define EL_LINE_PORT     PORTB
#define EL_TEST_PIN      PB0
#define SYS_STATUS_PORT    PORTD
#define SYS_STATUS_INDICATOR PD6

// Define functions
//===========================
void ioinit(void);     // Initializes IO
void hello_word(void);   // To indicate system status
void delay_ms(uint16_t x); // General purpose delay
void delay_us(int x);

void pulse(uint8_t line, int speed);
void line_on(uint8_t EL);
void line_off(uint8_t EL);
void cycle(int speed);
//===========================

static char line_on_1 = 0;
static char line_on_2 = 0;

int main(void)
{
 int x;
 
 // chip I/O initialize
 ioinit();
 
 // chip say hello to world
 hello_word();
 
 while(1)
  {
   // EL wire fading
   for (x = 0; x < 5; x++)
   {
    pulse(0, 125);
    delay_ms(100);
   }
   
   // EL wire flashing
   for(x = 0; x < 10;x++)
   {
    line_on(0);
    delay_ms(500);
    line_off(0);
    delay_ms(250);
   }

   for(x = 0; x < 10;x++)
   {
    line_on(0);
    delay_ms(200);
    line_off(0);
    delay_ms(300);
   }
  
   line_off(0);
  
   for (x = 0;x < 4; x++)
   {
    pulse(0,250);
    delay_ms(100);
   }
  
   delay_ms(1000);   
    }
}
ATtiny2313 設定如下:主要是取消掉 CKDIV8,使用 Internal RC 8MHz


AVR Studio 4 專案檔下載
  • 實際例子影片
根據上面程式碼的解釋,使用一段15公分長的紫色冷光線做控制:


  1. 冷光線明滅 (Fading) 5 次,PWM Speed 125
  2. 冷光線閃爍 10 次(on 500ms, off 250ms) 
  3. 冷光線閃爍 10 次(on 200ms, off 300ms)
  4. 冷光線明滅 (Fading) 5 次,PWM Speed 250

就像 LED 一樣,只要基本的電路與程式一旦完成,接下來的變化就是看個人創意了!

希望此篇文章能夠對觀看本文的各位有所幫助,也期待與各位做個交流溝通,如果你有任何意見或是建議請不吝指教!

2 則留言:

  1. 先生您好
    我是機械背景的研究生
    只修過簡單的電路學
    因為興趣關係
    最近正嘗試使用arduino做led的明滅控制

    您的文章對我非常有啟發性
    謝謝您無私的貢獻

    回覆刪除
  2. 先生您好,請問hv接幾伏特都是看冷光線耐壓對吧?ac、dc(注意極性)都行?
    如果我用arduino驅動,跟您的方法一樣的八?

    回覆刪除