2016年4月28日 星期四

仁寶待十年了.......


累積到第二張牌了.
這回是壓克力的...

遙控變色燈

相信很多人去逛IKEA都對這蠟燭台很有印象,感覺很好看,但又不知道買了要做啥.
顏色還很多種可以挑選呢.燭台.感覺有點危險,

或許拿來當營燈也不錯,網路上有很多達人都改裝成不同的LED.
要是跟大家都一樣,創意算是抄襲的.
所以囉.來點不一樣的.我的版本是遙控變色LED燈


材料如下:
IKEA蠟燭台,
Arduino Nano控制板,
3.7V手機電池,
5V升壓板,
AT89S52 315M遙控模組,
NeoPixel LED Ring,
泡棉一塊....


預計規劃的功能如下
當按下遙控器按鈕A 開啟紅燈,再次按下則關閉紅燈.
當按下遙控器按鈕B 開啟藍燈,再次按下則關閉藍燈.
當按下遙控器按鈕C 開啟綠燈,再次按下則關閉綠燈.
藉由ABC三個按鈕的交叉組合可以出現以下七種顏色變化
如按鈕D啟動, 則呈現DEMO展示,呈現彩虹色環的旋轉變化
程式碼的部分直接使用Adafruit_NeoPixel的DEMO code.小改一下很快就完成了.

剩下就是買零件組合.
這回要利用廢棄的手機電池當作電源的來源,需要是3.7V轉5V的電源供應機制.
如果不想用手機電池,其實可以用三顆1.2V的充電電池搭配電池盒與升壓板組合.
但考慮到只有狹小的燭台頂部空間可以收納這些零件.還是使用手機電池好了.

以下是直接修改DEMO code的文件 加入AT89S52 315M的控制於PIN8/9/10/11.
NeoPixel的控制接在PIN6,總計目前使用五個訊號端.
不過.目前手上還有一個G Sensor.可以考慮一下放進去.如果燈發生搖晃時.發生閃爍嗎?不過Arduino的I2C我還不懂.這可以當作下回的練習.



#include 

#define PIN 6

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel.  Avoid connecting
// on a live circuit...if you must, connect GND first.

// defines pins numbers
const int PinD0 = 8; // D8 link to AT89S52 315M AVR D0
const int PinD1 = 9; // D9 link to AT89S52 315M AVR D1
const int PinD2 = 10; // D10 link to AT89S52 315M AVR D2
const int PinD3 = 11; // D11 link to AT89S52 315M AVR D3
const int Pulses = 200; //Define delay time 1000 = 1 sec
int BTN_A = 0;
int BTN_B = 0;
int BTN_C = 0;
int BTN_D = 0;
int VAL_R = 127;
int VAL_B = 127;
int VAL_G = 127;
int Color_R;
int Color_B;
int Color_G;

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  Serial.begin(9600);
  Serial.println("Hello! I'm Arduino LED Ring.\n");
  // Sets the 4 pins as Input from AT89S52 315M
  pinMode(PinD0, INPUT);
  pinMode(PinD1, INPUT);
  pinMode(PinD2, INPUT);
  pinMode(PinD3, INPUT);
}

void loop() {
  BTN_A = digitalRead(PinD0);
  BTN_B = digitalRead(PinD1);
  BTN_C = digitalRead(PinD2);
  BTN_D = digitalRead(PinD3);
  // Some example procedures showing how to display to the pixels:

  if (BTN_A == 1) { // Red enable
    Color_R = VAL_R;
  }
  else {
    Color_R = 0;
  }
  if (BTN_B == 1) { // Blue enable
    Color_B = VAL_B;
  }
  else {
    Color_B = 0;
  }
  if (BTN_C == 1) { // Green enable
    Color_G = VAL_G;
  }
  else {
    Color_G = 0;
  }
  if (BTN_D == 1) { // DEMO mode
    rainbow(20);
    rainbowCycle(20);
    theaterChaseRainbow(50);
  }
  else { // Normal mode
    colorWipe(strip.Color(Color_R, Color_G, Color_B), 20)
    theaterChase(strip.Color(Color_R, Color_G, Color_B), 50);
  }

  //  colorWipe(strip.Color(255, 0, 0), 50); // Red
  //  colorWipe(strip.Color(0, 255, 0), 50); // Green
  //  colorWipe(strip.Color(0, 0, 255), 50); // Blue
  //  // Send a theater pixel chase in...
  //  theaterChase(strip.Color(127, 127, 127), 50); // White
  //  theaterChase(strip.Color(127,   0,   0), 50); // Red
  //  theaterChase(strip.Color(  0,   0, 127), 50); // Blue

}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Slightly different, this makes the rainbow equally distributed throughout
void rainbowCycle(uint8_t wait) {
  uint16_t i, j;

  for (j = 0; j < 256 * 5; j++) { // 5 cycles of all colors on wheel
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j = 0; j < 10; j++) { //do 10 cycles of chasing
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, c);  //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j = 0; j < 256; j++) {   // cycle all 256 colors in the wheel
    for (int q = 0; q < 3; q++) {
      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (int i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  if (WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

2016年4月23日 星期六

Linkit-7688 duo & Arduino IDE Error.

Linkit-7688 duo可以使用 Arduino IDE操作使用,用法就跟Arduino完全一樣
但事前的準備可多囉,首先是IDE的部分要追加LinLit 7688的資料庫(細節可以參考以下網址)
http://oranwind.org/linkit-7688-linkit-smart-76887688-duo-ji-chu-jiao-xue/
直到能夠出現以下畫面的操作參數,方可將程式碼上傳,


如操作這一部分應該只用到MCU(Microcontroller Unit),也就是ATmega 32U4.
跟7688的強項完全無關,只能說是Arduino的附身.

但要上傳Code可能會出現很可怕的錯誤訊息.可能看不懂對吧
https://labs.mediatek.com/forums/posts/list/4392.page
其中有個描述
USBCore.cpp: In function 'int USB_RecvControl(void*, int)':
這段描述就直接指出USBCore.cpp這個檔案中的描述有問題

總之得要手工微調檔案內容了.先找到檔案位置.
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino
開啟USBCore.cpp這個檔案.
找到第430以及435行,將Auto改成int後存檔
就可以解決這個問題了.


2016年4月21日 星期四

Arduino lightsaber Debug

終於等到材料了實際運作上有幾個問題

1.購買的LED尺寸規格小於預期, 48顆LED的長度才能達到60公分.因此全部的Digital pin都要用於LED使用.所以要用於作業的LED串就需要一點勞作的實力了.

一整包的LED要如何排排站好呢?用手抓,別鬧了.烙鐵溫度300度,

至於要如何快速又簡單的將LED串接起來,首先就要先設計製具,
以下直接找個瓦楞紙盒,先規劃好距離,針對LED的位置開孔.
接著貼上一層鋁箔.散熱使用,避免烙鐵直接將瓦楞紙燒毀.

瞧,排隊整齊劃一,輕輕一點錫就接合焊好,輕鬆愉快.

速度快的話20分鐘就弄出這麼多組啦.


2. MP3 module未能如期發出聲音來.可能是程式碼有問題,或是IC的使用上還需要花點時間認識.最後重新改寫控制,先刪除MP3 player的部分,並追加新的LED控制pin,以及一分鐘無任何震動後關閉的設定.


#include 
int LEDstatus = 0; //定義變量為LEDstatus
int Touchstatus = 0;
int hum[4];
int sensorValue;
int prevValue;
int StopCount;
const int LEDdelay = 20;  //定義延遲0.020秒進行一次LED升降50FPS
const int BreatheStep = 5;
const int PowerSW = 0; // A0
const int WaveSW = 1; // A1
const int LEDMartix[12] = {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2} ; //設定LED Martix
const int PWMpin[12] = {0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0}; // PWM: 3, 5, 6, 9, 10, 11. Provide 8-bit PWM output with the analogWrite() function.

int CheckTouch(int AnalogPin) {
  prevValue = sensorValue;
  sensorValue = analogRead(AnalogPin);
  if (sensorValue >= 1023 && sensorValue >= prevValue) {
    return 1;
  }
  if (sensorValue < 1010 & prevValue  <=  1010) {
    return 0;
  }
}

void SaberInital() {
  for (int i = 11; i >= 0; i--) {
    digitalWrite(LEDMartix[i], LOW);
  }
  LEDstatus = 0;
  StopCount = 0;
}

void SaberON() {
  for (int i = 0; i <= 11; i++) {
    digitalWrite(LEDMartix[i], HIGH);
    delay(LEDdelay);
    LEDstatus = 1;
  }
}

void SaberOFF() {
  for (int i = 11; i >= 0; i--) {
    digitalWrite(LEDMartix[i], LOW);
    delay(LEDdelay);
    LEDstatus = 0;
  }
}

void SaberFlickON() {
  for (int j = 0 ; j <= 100; j++) {
    for (int i = 0; i <= 11; i++) {
      if (i != 11) {
        digitalWrite(LEDMartix[i], LOW);
      }
      if (i != 0) {
        digitalWrite(LEDMartix[i - 1], HIGH);
      }
    }
    delay( LEDdelay / 2); //定義延遲0.01秒進行
  }
  LEDstatus = 1;
}

void SaberBreatheON() {
  for (int j = 255 ; j >= 0   ; j - BreatheStep) {
    for (int i = 0; i <= 11; i++) {
      if (PWMpin[i] == 0) {
        if (i != 11) {
          digitalWrite(LEDMartix[i], LOW);
        }
        if (i != 0 || PWMpin[i - 1] != 1 ) {
          digitalWrite(LEDMartix[i - 1], HIGH);
        }
      }
      if (PWMpin[i] == 1) {
        analogWrite(LEDMartix[i], j);
      }
    }
    delay( LEDdelay);  //定義延遲0.02秒進行
  }
  for (int j = 0 ; j <= 255   ; j + BreatheStep) {
    for (int i = 0; i <= 11; i++) {
      if (PWMpin[i] == 0) {
        if (i != 11) {
          digitalWrite(LEDMartix[i], LOW);
        }
        if (i != 0 || PWMpin[i - 1] != 1 ) {
          digitalWrite(LEDMartix[i - 1], HIGH);
        }
      }
      if (PWMpin[i] == 1) {
        analogWrite(LEDMartix[i], j);
      }
    }
    delay( LEDdelay);  //定義延遲0.02秒進行
  }
  LEDstatus = 1;
}

void setup () {
  pinMode(2, OUTPUT); //設定D2為輸出端,劍尾端
  pinMode(3, OUTPUT); //設定D3為輸出端
  pinMode(4, OUTPUT); //設定D4為輸出端
  pinMode(5, OUTPUT); //設定D5為輸出端
  pinMode(6, OUTPUT); //設定D6為輸出端
  pinMode(7, OUTPUT); //設定D7為輸出端
  pinMode(8, OUTPUT); //設定D8為輸出端
  pinMode(9, OUTPUT); //設定D9為輸出端
  pinMode(10, OUTPUT);  //設定D10為輸出端
  pinMode(11, OUTPUT);  //設定D11為輸出端
  pinMode(12, OUTPUT);  //設定D12為輸出端
  pinMode(13, OUTPUT);  //設定D13為輸出端,劍首端,接近劍柄
  pinMode(A0, INPUT);  //LED啟動開關接腳在A0,為輸入端
  pinMode(A1, INPUT);  //設定震動開關接腳在A1,為輸入端
  SaberInital();
}

void loop() {
  if (LEDstatus == 0 && CheckTouch(PowerSW) == 1) { //當有開關觸發LED亮
    SaberON();
  }
  if (LEDstatus == 1 &&  CheckTouch(PowerSW) == 1) { //當有開關再次觸發LED暗
    SaberOFF();
  }
  if (LEDstatus == 1) { //當光劍啟動時紀錄震動開關觸發狀態
    for (int i = 0; i < 4; i++) {
      hum[i] = CheckTouch(WaveSW);
      delay(250);
    }
    if ((hum[0] != 0 && hum[1] != 0 && hum[2] != 0 && hum[3] != 0) || (hum[0] != 1 && hum[1] != 1 && hum[2] !=  1 && hum[3] != 1)) {
      SaberFlickON();
      StopCount = 0;
    }
    else {
      StopCount = StopCount + 1;
      if (StopCount >> 2400) {
        SaberOFF();
      }
    }
  }
}

2016年4月5日 星期二

599小孩沙龍(洗加剪)

夏天的腳步 終於到來了 長髮女孩的煩惱就是 洗頭 吹頭很麻煩
為了減輕負擔 伴哄半騙的 終於肯去剪頭髮了
老大惜髮如金, 這回告訴他是去洗頭. 天啊~~這太誇張了吧!! 沒錯.


安穩的坐在位子上 準備要開始剪了. 竟然沒哭.


洗頭很舒服的樣子,這表情 我都想去試看看了