2015/04/30

Raspberry Pi 2與Windows 10

聽說Raspberry Pi 2可以跑Windows 10,叫做Windows 10 IoT Core Insider Preview的版本,來試試看吧。

看了一堆介紹,到了安裝設定的說明頁面,嗯嗯,怎麼感覺此頁面有點陽春啊,不管了,沒細看。看到要我下載Windows_IoT_Core_RPI2_BUILD.zip,嘿,需要以Microsoft帳戶登入,嘿,已經過了八百多年,都不知道跑哪去了,東找西找終於找到帳戶密碼,然後想登入,還要我確認身分,可是確認信卻跑去某個已無法存取的老舊email帳號,哇哩咧,繼續努力,東搞西搞之後終於進去了,下載完成。

下載後,要我燒錄裡頭的flash.ffu到Micro SD記憶卡,啥,這什麼檔案啊,好像是Windows Phone的Full Flash Update映像檔,要我使用好幾個沒聽過的指令進行燒錄,嘿,我還是試試看指令dd來燒錄吧,呃,不行,算了,這也在意料之中。

好吧,還是遵照該頁面的步驟吧,仔細閱讀後,發現一句話「The following steps can only be executed on a system running Windows 10 (build 10069 or higher).」,晴天霹靂,有沒有這麼慘啊?居然只能使用Windows 10,嘿,有沒有搞錯啊,不就是把一套軟體放進Pi 2,不就是把映像檔燒錄進記憶卡,還需要有Windows 10,真是夠了。

東摸摸西摸摸,喝了好幾杯茶和咖啡,Windows 10終於下載完成,嗯,怎麼安裝呢?我可沒有能跑Win 10的機器啊,只好在Mac OS X上以VirtualBox建立虛擬機器,然後安裝,又再喝了幾杯茶和咖啡,又再經過一堆設定,雖然畫面上顯示著「Just a moment...」,但那一串點點卻老是轉個不停,不管如何,最後Win 10總算安裝完成。

注意,下圖是一般的Win 10,不是Pi 2跑的Win 10。

呃,又遇到一個問題,把SD記憶卡插入Mac後,嘿,虛擬機器裡的Win 10看不到它,哇哩咧,趕快去拜孤狗大神,解決此問題。

準備好環境後,回到說明頁面,照著上面寫的步驟執行,馬上就遇到問題,「Open an admininistrator command prompt」,新系統新介面,command prompt在哪啊?翻箱倒櫃找到後,執行指令進行燒錄,呃,好慢啊,超級慢啊,大概是因為中間隔了虛擬機器的原因吧。
燒錄完後,記憶卡被分割成好幾個分割區。
把記憶卡放進Pi 2,開機!等啊等,等到藍色四小窗格。
等啊等,又等到這個圖示,不知道什麼意思。
途中應該會自動重開機,然後就會看到如下畫面。
嘿,成功開機囉,可看到IP位址。
然後隨著這份文件,開啟PowerShell。
遠端登入進去Pi 2,可以更改密碼,執行各種指令,查看Visual Studio Remote Debugger是否正常執行。
接下來,想要開發程式的話,須跟著之後的說明頁面,繼續在Win 10主機(非Pi 2)上安裝開發工具Visual Studio 2015,然後安裝WindowsDeveloperProgramForIoT.msi(在之前下載的Windows_IoT_Core_RPI2_BUILD.zip裡),之後會啟動Windows IoT Core Watcher,查看有哪些安裝了Windows 10 IoT Core的裝置。

然後開始寫程式開發專案,控制Pi 2的GPIO,到這裡看看範例專案,說聲Hello World吧,點我?這是模仿愛麗絲夢遊仙境的喝我嗎?
哇,點了之後出現IoT Core字樣耶。
然後試試控制GPIO吧。

2015/04/26

Raspberry Pi情報彙整(48)

我收集整理網路上看到的、感興趣的、跟Raspberry Pi相關的資訊,如果您發現任何新奇驚人的專案、新聞、活動等等,還請留言告知。

E-paper display HAT for the Raspberry Pi by Percheron Electronics Ltd — Kickstarter,電子紙擴充板,2.7吋,264x176。

Build Your Own Smartphone,打造智慧型手機,使用Adafruit的FONA。
Paul's Geek Dad Blog: Raspberry Pi Powered Ultra Sonic Sensing Minion Fart Gun Triggering Machine,嘿,以超音波偵測距離,然後發射「屁」;嗯,外國人似乎喜歡開這種玩笑。
來玩1,500日圓的BASIC電腦「IchigoJam」吧! - Make 國際中文版,嘿,樹莓派是選擇Python語言的電腦科學教學載具,而日本也有類似的產物喔,就是這款「草莓醬」,採用BASIC語言,其主晶片是NXP的LPC1114,一開機後就可開始輸入BASIC程式。
以 M2M 、 IoT 應用開發為目標客群,樹莓派專用 4G 模組 LTEPi 登場 | 癮科技,日本Robotoma推出的4G模組擴充板LTEPi。詳情請見官方網站(日文)。
Amazonian rainforest simulation | Raspberry Pi,哇賽,好厲害,模擬出亞馬遜熱帶雨林的環境,控制雨、風,產生霧氣,控制鹵素、燈光等等,有水上也有水下,太強啦。
VCF East X: Minicomputing With The Raspberry Pi | Hackaday,哇,模擬迷你電腦PDP-8,PDP-8於1965年由DEC推出,是PDP系列中第一款成功的機種。嘿,據說將來應會變成電子套件商品。
SlushEngine Stepper Motor Driver - by Roboteurs by Justin Policarpio and Reiner Schmidt — Kickstarter,步進馬達驅動擴充板。募資截止日期2015年5月7日。
Bitcoin Paper Wallet Treasure Chest… | blog.flo.cx,打造寶箱,保護你的Bitcoin私鑰吧;嗯,然後要怎麼保護這個寶箱呢?放到銀行裡?
Interfacing a VFD display to the raspberry pi - Dr. Scott M. Baker,連接VFD(真空螢光顯示器)。
Plotter from old CDROMs - HomoFaciens,從舊光碟機拆下步進馬達,製作繪圖機。
Robot Guitar - bringing unseen data sources into the real world,讓rpi來彈吉他,這會不會太強啦。
Mapillary For The Raspberry Pi | HackadayMapillary上有很多大家拍的街景照片,讓我們來取用吧。
LISIPAROI | A halo for your camera,為相機模組加上光源吧。
其他:

2015/04/24

Raspberry Pi:使用MATE

Raspbian預設的桌面環境很不錯,但有時也想換換口味。

Linux圖形使用者介面世界多采多姿,桌面環境與視窗管理員實在太多選擇了,令人眼花撩亂,GNOME、KDE、XFCE、LXDE、MATE、Mutter、Metacity等等,根本搞不清楚。

底下是在Pi 2上運行Raspbian(2015-02-16),其預設桌面環境的模樣。

Raspbian若要換成MATE,先修改檔案/etc/apt/sources.list,加入底下這一行:

deb http://archive.raspbian.org/mate wheezy main

然後更新套件清單,安裝MATE:

$ sudo apt-get update
$ sudo apt-get install mate-core mate-desktop-environment

接著修改檔案~/.xinitrc,加入底下這行:

exec mate-session

然後startx啟動,嘿,看到囉。
不過想用MATE,不一定得Raspbian,也有Ubuntu可用,到此下載適用於Pi 2的Ubuntu MATE,燒錄後開機,經過一些設定後,哈,看到囉。
執行一些軟體試試看吧。
Pi 2硬體效能提昇了,可用的Linux系統也更多,真不錯。

參考資料:

2015/04/16

LinkIt ONE小發現:類別的方法無實作,造成整支程式無法執行

一支很簡單的程式,如果沒有紅色的部份,就可以正常執行,LED會閃爍,序列埠可接收訊息。

#define BAUDRATE 115200
#define LED_PIN 13

class MyClass
{
public:
  void aMethod();
};

void aFunction(){
  MyClass x;
  x.aMethod();
}


void setup(){
  Serial.begin(BAUDRATE);
  pinMode(LED_PIN, OUTPUT);
}

void loop(){
  digitalWrite(LED_PIN, HIGH);
  Serial.println("LED high");
  delay(300);
  digitalWrite(LED_PIN, LOW);
  Serial.println("LED low");
  delay(300);
}


但若有紅色的部份,建置時會出現警告訊息「warning: undefined reference」,但編譯、連結仍成功,也可以燒錄到板子裡,但卻無法執行,LED不會動,序列埠什麼東西也沒有。

2015/04/14

LinkIt ONE:向NTP伺服器取得時間

透過WiFi,傳送UDP封包,向NTP伺服器取得時間。

底下程式碼中,關於NTP的部份,主要來自Arduino官網的範例Arduino - UdpNTPClient,改用LinkIt ONE的API。原始碼可到GitHub下載。

先看看執行結果,送序列埠送出控制字元,操控WiFi模組,連線後,送出UDP封包向NTP伺服器取得時間。有哪些控制字元,請見程式碼。


程式碼:

#include <stdarg.h>
#include <LWiFi.h>
#include <LWiFiUdp.h>

#define BAUDRATE 115200

// 請修改成你的WiFi名稱與密碼
#define WIFI_AP "__WiFi_AP_NAME__"
#define WIFI_PASSWD __WiFi_PASSWORD__"

// NTP伺服器
#define NTP_SERVER "time.stdtime.gov.tw" // (118, 163, 81, 61)
IPAddress ntpServerIP;
#define ntpServerPort 123

#define LOCAL_PORT 2390

#define NTP_PACKET_SIZE 48

// UDP客戶端
LWiFiUDP udpcli;

// 類似於printf
void pf(const char *fmt, ... ){
    char tmp[128]; // limited to 128 chars
    va_list args;
    va_start(args, fmt);
    vsnprintf(tmp, 128, fmt, args);
    va_end(args);
    Serial.print(tmp);
}


// 根據WiFi模組狀態,回傳容易看懂的字串
const char * const wifi_status_str(LWifiStatus ws){
  switch(ws){
    case LWIFI_STATUS_DISABLED:
      return "WiFi module status: disabled";
    break;
    case LWIFI_STATUS_DISCONNECTED:
      return "WiFi module status: disconnected";
    break;
    case LWIFI_STATUS_CONNECTED:
      return "WiFi module status: connected";
    break;
  }
  return "WiFi status: error, no such status";
}

void setup(){
  Serial.begin(BAUDRATE);
 
  udpcli.begin(LOCAL_PORT); // 綁定某的通訊埠
}


// 送出詢問時間的UDP封包,詳情請看RFC 5905 unsigned long sendNTPpacket(IPAddress &address)
{
  byte buf[NTP_PACKET_SIZE];
  memset(buf, 0, NTP_PACKET_SIZE); // set all bytes in the buffer to 0
  // Initialize values needed to form NTP request
  buf[0] = 0b11100011;   // LI, Version, Mode
  buf[1] = 0;     // Stratum, or type of clock
  buf[2] = 6;     // Polling Interval
  buf[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  buf[12]  = 49;
  buf[13]  = 0x4E;
  buf[14]  = 49;
  buf[15]  = 52;

  // send a packet requesting a timestamp:
  udpcli.beginPacket(address, ntpServerPort);
  udpcli.write(buf, NTP_PACKET_SIZE);
  udpcli.endPacket();
}


// 拿到秒數(從1900年1月1日 0時0分0秒),印出
// 轉成Unix epoch time,印出
// 捨棄年月日,印出時分秒,HH:MM:SS void printTime(unsigned long secsSince1900){
  pf("Seconds since Jan 1 1900: %u\n", secsSince1900);
 
  unsigned long epoch = secsSince1900 - 2208988800UL; // seventy years
  pf("Unix time: %u\n", epoch); // 00:00:00 1 January 1970, UTC
 
  epoch %= 86400L;
  unsigned long hh = epoch / 3600;
  epoch %= 3600;
  unsigned mm = epoch / 60;
  epoch %= 60;
  unsigned ss = epoch;
  pf("The UTC time: %02u:%02u:%02u\n", hh, mm, ss);
}


// 主迴圈,從序列埠接收控制字元,做該做的事情 void loop(){
  if(Serial.available()){
    char d = Serial.read();
    switch(d){
      case 'l':{ // 搜尋WiFi網路
        int i;
        int n_ap = LWiFi.scanNetworks();
        pf("Number of WiFi AP found: %d\n", n_ap);
        for(i = 0; i < n_ap; i++){
            pf("%d, %s, RSSI: %d\n", i, LWiFi.SSID(i), LWiFi.RSSI(i));
        }
      }
      break;
      case 's':{ // 印出狀態
        LWifiStatus ws = LWiFi.status();
        Serial.println(wifi_status_str(ws));
       
        uint8_t ma[VM_WLAN_WNDRV_MAC_ADDRESS_LEN] = {0};
        LWiFi.macAddress(ma);
        Serial.print("MAC address: ");
        int i;
        for(i = 0; i < VM_WLAN_WNDRV_MAC_ADDRESS_LEN-1; i++){
            pf("%02X:", ma[i]);
        }
        pf("%02X\n", ma[i]);
       
        if(ws == LWIFI_STATUS_CONNECTED){
          IPAddress ipa = LWiFi.localIP();
          Serial.print("localIP: ");
          ipa.printTo(Serial);
          Serial.println("");
         
          Serial.print("subnetMask: ");
          ipa = LWiFi.subnetMask();
          ipa.printTo(Serial);
          Serial.println("");
         
          Serial.print("gatewayIP: ");
          ipa = LWiFi.gatewayIP();
          ipa.printTo(Serial);
          Serial.println("");
        }
      }
      break;
      case 'b':{ // 開啟WiFi模組
        Serial.println("LWiFi.begin() turn on WiFi module");
        LWiFi.begin();
      }
      break;
      case 'e':{ // 關閉WiFi模組
        Serial.println("LWiFi.end() turn off WiFi module");
        LWiFi.end();
      }
      break;
      case 'c':{ // 連接WiFi AP
        Serial.print("Connecting...");
        if(LWiFi.connect(WIFI_AP, LWiFiLoginInfo(LWIFI_WPA, WIFI_PASSWD)) > 0){
          Serial.println(" succeed");
        }
        else{
          Serial.println(" failed");
        }
      }
      break;
      case 'd':{ // 切斷與WiFi AP的連線
        LWiFi.disconnect();
        Serial.println("Disconnected");
      }
      break;
      case 't':{ // 向NTP伺服器詢問時間
        if(ntpServerIP == INADDR_NONE){
          if(LWiFi.hostByName(NTP_SERVER, ntpServerIP) != 1){
            pf("DNS lookup failed: %s", NTP_SERVER);
          }
        }
        if(ntpServerIP != INADDR_NONE){
          pf("Send request to NTP server %s\n", NTP_SERVER);
          sendNTPpacket(ntpServerIP);
        }
      }
      break;
    }
  }
 
  if(udpcli.parsePacket()){ // 收到NTP伺服器傳回來的時間
    byte packetBuffer[NTP_PACKET_SIZE];
    udpcli.read(packetBuffer, NTP_PACKET_SIZE);
    const unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    const unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    const unsigned long secsSince1900 = highWord << 16 | lowWord;
    printTime(secsSince1900);
  }
}

2015/04/13

Raspberry Pi情報彙整(47)

我收集整理網路上看到的、感興趣的、跟Raspberry Pi相關的資訊,如果您發現任何新奇驚人的專案、新聞、活動等等,還請留言告知。

Raspi-LTSP is now PiNet: easily manage a Raspberry Pi classroom | Raspberry Pi,使用rpi來教授課程,要如何管理一堆學生的帳號、SD記憶卡、資料、程式碼呢?試試PiNet吧,設置一台中央伺服器,讓所有rpi靠著這台伺服器開機,取得最新版的作業系統,以及個人資料。

Bee behaviour mapped by tiny trackers - BBC News,莫非這是穿戴電子的未來?不是啦,為了研究蜜蜂,有必要記錄追蹤牠們的行為,裡頭有RFID與特製的極小天線。根據報導,有效距離是2.5公尺,嗯,是不是有點短。
The "Raspberry Pi" Pie,來做個派吧,做個形似Raspberry Pi的派。
NetPi - Raspberry Pi Network Analyzer - Blame The Network,自己打造網路封包分析器,完全開源。
Easily Distracted: Chicken Pi,什麼,摸摸這隻雞,牠就會下蛋,這真是太神奇了,傑克。
[活動] Raspberry Pi相機工作坊 #1 @ 2015/04/19,台灣樹莓派辦的相機模組工作坊。
Pi Spy Surveillance System - Make:,嘿,這是間諜攝影機嗎?當初戴著Google Glass走進酒吧會被打,戴著這個沒問題吧?。
Raspberry Pi in the theatre,使用rpi與Pimoroni Unicorn Hat,賦予綠野仙蹤的機器人一顆心臟。
The Young Innovators’ Club in Ulaanbaatar | Raspberry Pi,蒙古烏蘭巴托也使用rpi來教授Scratch、Python、電子學、機器人等。
Raspberry Pi Model C » RasPi.TV,rpi迅速推出Model C,嘿,4K相機、加入Arduino的ATmega328P、Gigabit以太網路、USB 3.0、等等,當然啦,這是個愚人節笑話,真佩服改圖者的功力啊。話說回來,應該加入WiFi、GPS、藍牙等等無線傳輸的功能吧。
PiKasa - The ultimate housing for Pi | Indiegogo,光是普通的外殼已經太遜了,還要有TFT LCD、鍵盤、鋰電池充電、等等周邊設備。嗯,聽起來應該就是筆電的組合套件。
GoPiGo Introduction - The Raspberry Pi Robotic Car,Dexter Industries的電動車套件,教學範例與文件非常豐富。
Your Photo on a t-shirt from Rapanui | Raspberry Pi,讓整間工廠成為IoT的一份子,你上傳設計照片,然後就能看到製作成T-shirt的樣子,嘿,當然啦,其中有塊rpi。
The Pi-Powered Hamster Hunter Part 4: Reflections | Finnian Anderson,這不是寵物自動餵食機,而是倉鼠獵殺機!。
CodeBug by CodeBug — Kickstarter,好玩有趣兼具學習用途的CodeBug。
Mushroom Cultivation Automation | Projects | Kyle Gabriel,電腦很聰明,會挑選土豆,rpi更厲害,能夠照顧香菇。
LEGO spectrometers | Raspberry Pi,樂高光譜儀,重點是光譜儀,但吸引人目光的卻是五顏六色的樂高積木。
emonPi: Open-Hardware Raspberry Pi-Based Energy Monitor by OpenEnergyMonitor — Kickstarter,能源監控機,看起來相當不錯,結合rpi、Arduino與各種感測器,偵測電器用電量、太陽能Solar PV、熱、溫度、等等。
How to build a subjective camera robot car with Raspberry Pi & Arduino - Project log,完整詳細的步驟指引,零件非常多,相當複雜。
Automated Weatherproof Timelapse System with DSLR and Raspberry Pi | Hackaday,防雪的縮時攝影系統。
ARDHAT: Raspberry Pi gets Real. by ubIQio — Kickstarter,又一款為rpi加上Arduino能力的擴充板,雖然此類產品已經不少,每一款產品各自都有其特別之處與適用的情況,總是多多益善。
UART HAT For Raspberry PI by SALICON Technologies — Kickstarter,雖然個人電腦都沒有RS-232了,通通被USB取代,有多少人還記得那使用9針接頭(DE-9)的滑鼠呢?但Serial序列見面依然長青,需要的話,加上這塊UART擴充板吧。
其他: