2019年8月18日 星期日

呼吸燈設計

https://4rdp.blogspot.com/2019/08/blog-post.html?m=0

以 mBot 當載體,以 ROSA 為程式架構,設計呼吸燈

為 4rdp 拼圖夜燈設計燈光控制,這程式包含了亮度控制、呼吸燈、變色燈三種模式,現在簡易說明如下:

顏色控制 ─ 以 RGB 三色混光,每色數值 0 ~ 255
亮度控制 ─ lit_speed = 0 時,lit_auto 決定亮度,lit_auto = 0 燈滅, lit_auto = 255 燈最亮
呼吸燈 ─ lit_auto = 0 時,lit_speed 控制呼吸速度,1 最快,9 最慢,變化範圍 0.3 ~ 2.7 秒
變色燈 ─ lit_auto = 1~7 時,lit_speed 控制變色速度,1 最快,9 最慢,變化範圍 0.3 ~ 2.7 秒

程式碼如下:

// (C) 2015, Bridan Wang, CC BY-NC-SA 3.0 TW
// http://4rdp.blogspot.tw/search/label/ROSA%20(Arduino)

// lit_auto    lit_speed
//    0           0         bright  off
//    1                             min
//   255                            max
//
//    0           1         breathe fast
//                5                 normal
//                9                 slow
//
//   1~7          1         color   fast
//                5                 normal
//                9                 slow


// pin 13   LED
#include "adafruit_neopixel.h"
#define LEDPIN  13
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, LEDPIN, NEO_GRB + NEO_KHZ800);

unsigned long  now;
byte red = 200;
byte green = 200;
byte blue = 200;
byte lit_speed = 0;     // 0 fixed    1 fast     9 slow
byte lit_auto = 2;    // 0 breathe     1~7 color setting
char dir = 1;

void PROCESS_LIT_COLOR(void)
{
  char i;
  switch (lit_auto) {
    case 1:
      for (i=0 ; i<4 ; i++)
        strip.setPixelColor(i, strip.Color(red, 0, 0));
      break;
    case 2:
      for (i=0 ; i4 ; i++)
        strip.setPixelColor(i, strip.Color(red, green, 0));
      break;
    case 3:
      for (i=0 ; i4 ; i++)
        strip.setPixelColor(i, strip.Color(0, green, 0));
      break;
    case 4:
      for (i=0 ; i4 ; i++)
        strip.setPixelColor(i, strip.Color(0, green, blue));
      break;
    case 5:
      for (i=0 ; i4 ; i++)
        strip.setPixelColor(i, strip.Color(0, 0, blue));
      break;
    case 6:
      for (i=0 ; i4 ; i++)
        strip.setPixelColor(i, strip.Color(red, 0, blue));
      break;
    default:
      if (lit_speed != 0)
         lit_auto = 0;
      for (i=0 ; i4 ; i++)
        strip.setPixelColor(i, strip.Color(red, green, blue));
      break;
  }
  if (lit_speed != 0)
    lit_auto += 1;
  strip.show();
}

void PROCESS_LIT_BREATHE(byte tm)
{
  char i;
  byte red0;
  byte green0;
  byte blue0;

  if (lit_speed == 0) {
    red0 = ((unsigned int)red * tm) >> 8;
    green0 = ((unsigned int)green * tm) >> 8;
    blue0 = ((unsigned int)blue * tm) >> 8;
  } else if (dir == 1) {
    red0 = red / (lit_speed * 3) * (lit_speed * 3 - tm);
    green0 = green / (lit_speed * 3) * (lit_speed * 3 - tm);
    blue0 = blue / (lit_speed * 3) * (lit_speed * 3 - tm);
  } else {
    red0 = red / (lit_speed * 3) * tm;
    green0 = green / (lit_speed * 3) * tm;
    blue0 = blue / (lit_speed * 3) * tm;
  }

  for (i=0 ; i4 ; i++)
      strip.setPixelColor(i, strip.Color(red0, green0, blue0));
  strip.show();
}

void PROCESS_10ms(void){
}

void PROCESS_100ms(void){
  static byte  tm_300ms = 3*5;
  if (lit_speed == 0) {
      PROCESS_LIT_BREATHE(lit_auto);  
  } else if (--tm_300ms == 0) {
    tm_300ms = 3 * lit_speed;
    if (lit_auto == 0) {
      if (dir == 1)
         dir = -1;
      else
         dir = 1;
      PROCESS_LIT_BREATHE(tm_300ms);    
    } else {
      PROCESS_LIT_COLOR();
    }
  } else if (lit_auto == 0) {
      PROCESS_LIT_BREATHE(tm_300ms);    
  }
}

void PROCESS_1sec(){
}

void SYS_TIMER() {
  static byte  tm_10ms = 0;
  static byte  tm_100ms = 0;
  static byte  tm_1sec = 0;

   while (millis() - now >= 10) {
    now += 10;
    tm_10ms++;
    tm_100ms++;
    tm_1sec++;
  }
  if (tm_1sec >= 100) {
    tm_1sec -= 100;
    PROCESS_1sec();
  }
  if (tm_100ms >= 10) {
    tm_100ms -= 10;
    PROCESS_100ms();
  }
  if (tm_10ms != 0) {
    tm_10ms -= 1;
    PROCESS_10ms();
  }
}

void setup() {
  // pin 13
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  // system timer0
  now = millis();
}

void loop() {
  SYS_TIMER();      // work on timer0
}

延伸閱讀:
http://4rdp.blogspot.com/2015/10/rosa-9-led.html

沒有留言:

張貼留言