2016年6月3日 星期五

Moonlight Stream on ASUS A66 and OUYA

nVidia的論壇中出現一篇文章 表示可以在ARM的系統上串流電玩
https://forums.geforce.com.tw/viewtopic.php?f=7&t=558
前提是要先有nVidia 6xx系列以上的顯示卡,以及適恰的軟體.

就nVidia的網站上提供的GameStream指的就是能搭配nVidia Shield的串流功能
那非nVidia的產品該如何使用這串流呢?根據分享的文章中提到Moonlight Stream.
但我其實是先注意到Moonlight Stream,在查詢經驗分享的時候注意到已經有高手先分享了.那我就做點不一樣的

先前在OUYA上有類似的stream分享軟體叫 kainy 缺點是遠端遙控螢幕
操控上並無針對遊戲優化,且未付費的版本是灰階畫面.這就可惜了
nVidia Shield本身的出發點就是Gaming,所以由這點來看的確不用擔心遊戲的優化問題.

Andriod的朋友可以在此下載
https://play.google.com/store/apps/details?id=com.limelight&hl=zh_HK

就OUYA的APP store中可以免費的下載完整版的Moonlight Stream,
https://www.ouya.tv/game/Moonlight-Game-Streaming/
於PC端的設定先確定Stream的選項是開啟的.剩下就是啟動畫面上是否能搜尋到在同網域下的PC.如成功點選,還真的直接呈現出該台電腦中的遊戲,還會下載該遊戲封面.一整個就是專業.

因為OUYA無法截圖,所以改用手機連線操作.沒想到ASUS A66這隻老手機,也可跑得很順暢.或是說自家的WIFI環境不差,所以可以跑得很順暢吧.
那就先來個格鬥體驗吧.手機對應的話會在畫面上出現虛擬鍵盤,如果是OUYA的話直接就是由藍芽手把控制,不會出現虛擬鍵盤.


等待會稍微久一點,因為PC端跟遠端的畫面都會出現GAMESTREAM的logo.
圖中間藍色的圈,正是PC端的滑鼠.


遊戲畫面終於跑出來了.

這回的測試沒出現可怕的延遲現象,還可以打贏電腦唷.KO就是證明,格鬥遊戲只要出現延遲就是一定等著輸啊~

同系列的另外一檔 鐵拳VS快打一樣順暢

換個遊戲.號稱有真胸模式的宅男必玩遊戲DOA5

不過換到DOA5在OUYA上跑真的比較Delay了.PC端的畫面真的就是比較快.
另外OUYA在執行上異常的高溫......整個鋁皮都發燙了.看來也不適合玩太久.

結論:
1.沒想到專業的ARM遊戲機OUYA的效能竟然輸給 ASUS A66
2,遊戲如果是Steam的版本,整合度很高
3.遊戲如果是Origin的版本,整合度較差,會反覆出現登入Origin的畫面後才可進行遊戲.
4.操控性與該由是否支援XBOX 360搖桿有關.只要是支援搖桿都不用煩惱設定的問題.



2016年5月28日 星期六

六福村野生動物園遊記


天氣晴朗,前往關西一趟.這是新竹的關西,走國道接66號,順著指標就到了六福村
如果怕走錯 其實跟著小人國的指標也是可以找到的.
停車場這邊就有一堆動物模型在歡迎著大家
天氣真的很好,熱到快中暑,小孩也受不了.一入園先往能避暑的地方逃去
那就是阿拉伯皇宮,其實這時候是早上11點,快接近中午也是得先找個地方吃午餐
沒想到吃的東西單價不便宜...咖哩飯套餐要200左右
有上回新兒童樂園的經驗,已經很認命了,身高未滿110的小孩去遊樂場能玩的只有
 旋轉木馬
 但兩姊妹很愛,正好這不是很熱門的項目,可以連續排連續玩,騎到滿意為止
這個項目在兒童新樂園是有身高限制,但在六福村只要有大人陪伴就可以玩,
算是我女兒愛玩的項目之一,大嘴鳥可以自由控制高度旋轉,旋轉的速度不會很快
是很安全的項目,
雷同的遊樂設施,旋轉靴子,這也是我女兒愛的,但爸爸轉到暈了,迴轉半徑比較小
速度感比較快,小孩很愛玩,玩了兩輪,爸爸我眼冒金星想要吐,還要硬撐拍照.
 寧寧很配合,可惜閉上眼了.
另外一個可以玩的是小型摩天輪,真的很小,但也就是要陪伴.就跟著上去了.至於樂趣嗎?就是給別人看看囉.....

以上就是六福村三歲兒童版本的遊樂設施,其他的知名器材,大怒神,火山歷險,笑傲飛鷹...等等族繁不及備載的.請參閱其他玩家的介紹囉.

畢竟這回帶小孩來的目的是要親近野生動物,小時候我爸爸帶我來還是開車進園區看獅子老虎的.動物區的大門 有許多狐獴的雕像,真的園區內歡迎大家的就是狐獴.過去只能在國家地理頻道看到的,可以親眼看到超可愛的.連我大女兒都大喊我想要一隻.
動物的照片就沒多拍了,因為要多跟小孩互動,所以只有隨意地拍幾張作紀念
希望小孩以後會有回憶,但小女兒完全不領情,一路上只吵著要喝奶.
非洲羚羊出現也不管.
看到狒狒出來逛大街,也不在乎,對於動物一點感覺都沒有 
 路過長頸鹿的時候有稍微認出來是長頸鹿,這讓我有點寬心點.
草食動物的部分是搭開放空間的小火車.所以可以聞到濃濃的生物遺留物的味道.
整個園區的規劃真的很適合教學.
經過解說員的介紹,我才知道原來.六福村最厲害的是復育稀有的白犀牛,園內有大大小小三十多隻犀牛.但路過的時候都在避暑只能看到大大的屁股.

其他還有可以近距離接觸的羊,鳥園等.想要好好地逛,可能一天都不夠用.
整天逛下來,發覺這個園區,真的規劃的很棒.針對不同的取向玩家都有照顧到.
要刺激有刺激,要動物有動物,要玩水也可以.不過只能說相見恨晚.遊樂設施的部分 還真的是第一次進去.雖不算新穎,但十幾年的設備可以看出當時的盛況.
話說上回去主題樂園是十年前去遠雄海洋公園.前東家的員工旅遊去的.
時間過得真快.現在身邊多了兩個小孩了.遊樂場的確是可以帶來歡樂的好地方
但要避開連續假日的人潮,才能好好地玩耍一番.當然啦!還要努力賺錢才能買得起門票啊!

回到家後,問一下姊妹倆看到啥.姐姐還會很開心的說 看到很多動物,有看到獅子,還問獅子有沒有媽媽,老虎打哈欠,猴子啥的...那問妹妹呢.竟然跟我說有大象.好吧~可能是看到白犀牛的大屁股,跟大象的大屁股好像長得一樣的. 還是說,園區內有個大象的雕像被他有注意到?其實入園前我也真的以為非洲動物區會有大象呢.






2016年5月21日 星期六

告別外公


我的外公.就我開始認識他,記憶中就是一位校長.
做人做事很嚴肅,小時候會怕他,長大也依舊會怕.












時間的流逝總是讓人感傷,這樣的場合.現在只能回顧往事.
隨著年紀的增長,一路求學到大,後來才知道.其實外公對我的影響蠻大的.
某些在課業上的堅持,或是一直想要拚個博士念,但後來考慮到經濟壓力
以及自己的生涯規劃後沒有往學術發展.
某方面來講其實有點想在他的心中能多點份量.

比較讓我感到難過的是,一個人即便有多大的成就,老了還是要面對病痛.
失智等困擾.或許失智本身就是上帝要讓人們忘卻煩惱的一個設計,
但這樣的過程卻是讓家屬們魂牽夢縈的楸心.

還記得我結婚的當時在台中的這場,有邀請外公前往,一路上還一直提醒他孫子要結婚,請他做大位.沒一會又問要去哪裡.就這樣一路半哄半騙得帶他去到會場.
吃飯的時候忽然很開心說,我孫子結婚了.當時還真的很開心.

第一次注意到,其實不一定要有傑出得表現,也可以讓長輩開心.


















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小孩沙龍(洗加剪)

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


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


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

2027日本旅遊行程規劃

這回還是請出厲害的Grok + Chatgpt 兩位大神一起討論旅遊計畫,以下是討論結果   京阪神  6 天 5 夜   家族溫馨祈福之旅計畫書( 2027 年 1 月 23 日~ 28 日   國泰版) 四大兩小(含 65 歲長輩與國中生)|住一黑門酒店|全程大眾交通|體力優...