聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

七月 24, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 升級 PHP Facebook SDK 到 4.0.x 版本

CodeIgniter

最近幫公司建立 Staging 環境,申請了新的 FB App 來,用原本 Facebook v3.2.3 SDK 發現已經不能 work 了,去翻了 Facebook Platform Changelog,看到今年 4 月 30 號以後申請的 App 會強制走 v2.0 Auth 機制,所以原本用 php sdk 3.2.3 版本的話,完全無法呼叫 Auth 2.0 API,導致整個網站爛掉,當然線上的網站是不會隨意換 App ID 及 secret,免得怎麼爆掉的都不知道。這次來教學在 CodeIgniter 轉換 PHP Facebook SDK,可以直接參考官方 4.0.0 的教學,原本 3.2.3 版本直接下載程式碼,放到 library 目錄,直接 include 就可以取得 Facebook 個人資料,4.0.0 版本以後,請先確認系統是否升級為 PHP 5.4 版本以上,並且支援 Composer 安裝,當然如果不用 Composer 也可以,只是要 include 很多檔案,真的比較麻煩。

先在根目錄建立 composer.json 內容填入

{
  "require" : {
    "facebook/php-sdk-v4" : "4.0.*"
  }
}

接著執行 composer install,系統會自動建立 vendor 目錄。在 application/libraries 建立 lib_login.php 檔案,並且寫入底下程式碼

<?php  if (! defined('BASEPATH')) exit('No direct script access allowed');

/**
* Name: Facebook Login Library
*
* Author: appleboy
*
*/

require 'vendor/autoload.php';

use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;

class Lib_login
{
    /**
     * CodeIgniter global
     *
     * @var string
     **/
    protected $ci;

    /**
     * __construct
     *
     * @return void
     * @author Ben
     **/
    public function __construct()
    {
        $this->ci =& get_instance();
        $this->ci->load->library('session');
        $this->ci->config->load('facebook');

        if (! isset($_SESSION)) {
            session_start();
        }
    }

    public function facebook()
    {
        $facebook_default_scope = explode(',', $this->ci->config->item("facebook_default_scope"));
        $facebook_app_id = $this->ci->config->item("facebook_app_id");
        $facebook_api_secret = $this->ci->config->item("facebook_api_secret");

        // init app with app id and secret
        FacebookSession::setDefaultApplication($facebook_app_id, $facebook_api_secret);

        // login helper with redirect_uri
        $helper = new FacebookRedirectLoginHelper(site_url('login/facebook'));
        // see if a existing session exists
        if (isset($_SESSION) && isset($_SESSION['fb_token'])) {
            // create new session from saved access_token
            $session = new FacebookSession($_SESSION['fb_token']);

            // validate the access_token to make sure it's still valid
            try {
                if (!$session->validate()) {
                    $session = null;
                }
            } catch (Exception $e) {
                // catch any exceptions
                $session = null;
            }
        }

        if (!isset($session) || $session === null) {
            // no session exists

            try {
                $session = $helper->getSessionFromRedirect();
            } catch(FacebookRequestException $ex) {
                // When Facebook returns an error
                // handle this better in production code
                print_r($ex);
            } catch(Exception $ex) {
                // When validation fails or other local issues
                // handle this better in production code
                print_r($ex);
            }
        }

        // see if we have a session
        if (isset($session)) {
            // save the session
            $_SESSION['fb_token'] = $session->getToken();
            // create a session using saved token or the new one we generated at login
            $session = new FacebookSession($session->getToken());

            // graph api request for user data
            $request = new FacebookRequest($session, 'GET', '/me');
            $response = $request->execute();
            // get response
            $graphObject = $response->getGraphObject()->asArray();
            $fb_data = array(
                'me' => $graphObject,
                'loginUrl' => $helper->getLoginUrl($facebook_default_scope)
           );
            $this->ci->session->set_userdata('fb_data', $fb_data);

        } else {
            $fb_data = array(
                'me' => null,
                'loginUrl' => $helper->getLoginUrl($facebook_default_scope)
           );
            $this->ci->session->set_userdata('fb_data', $fb_data);
        }

        return $fb_data;
    }
}

最後寫簡單 controller

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Login extends CI_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->library(array('session', 'lib_login'));
    }

    /**
     * facebook login
     *
     * @return void
     * @author appleboy
     **/
    public function facebook()
    {
        $fb_data = $this->lib_login->facebook();

        // check login data
        if (isset($fb_data['me'])) {
            var_dump($fb_data);
        } else {
            echo '<a href="' . $fb_data['loginUrl'] . '">Login</a>';
        }
    }
}

/* End of file login.php */
/* Location: ./application/controllers/login.php */

打開瀏覽器,直接執行 http://xxxx/login/facebook 就可以看到 Facebook 登入連結。所以程式碼都放在 Githubcodeigniter-facebook-php-sdk-v4,歡迎取用。

七月 20, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Automating your workflow with Gulp.js

gulp

今年 2014 COSCUP 在 7/19,20 中研院舉辦,由於 JSDC 今年比往年還要晚半年舉辦,所以本來想投在 JSDC 的議程,就先拿到投到 COSCUP 議程。去年 JSDC 講了 Javascript command line tool GruntJS 介紹,講完經過半年,Gulp.js 就出來了,我馬上跳過去嘗試,用過之後,就像變了心的女朋友,回不來了,底下是 Gulp.js Slides。

Automating your workflow with Gulp.js from Bo-Yi Wu

最後提到 Slush.js 這套 streaming scaffolding system,我寫了 html5 template engine generator,產生最簡單的開發環境以及 Gulp.js 設定檔,大家可以透過底下安裝嘗試:

$ npm install -g slush bower
$ npm install -g slush-html5-template

產生專案檔案

$ slush html5-template

這套 Slush html5 generator 程式檔來自 html5-template-engine

七月 4, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 在 Debian 安裝 Percona Xtradb Cluster 5.5.34 注意事項

percona

最近幫公司安裝新的三台機器,全部上 Debian 7.5 Server 版本,統一安裝 Percona Xtradb Cluster 最新版本 5.5.37。設定完第一台 Node,並且透過底下指令 boot up 成第一台 PXC。

$ /etc/init.d/mysql bootstrap-pxc

後續第二台要啟動跟第一台進行 SST,寫到一半直接噴底下錯誤訊息

WSREP_SST: [ERROR] Cleanup after exit with status:32 (20140702 10:57:28.004) WSREP_SST: [INFO] Removing the sst_in_progress file (20140702 10:57:28.006) 140702 10:57:28 [ERROR] WSREP: Process completed with error: wsrep_sst_xtrabackup –role ‘joiner’ –address ’192.168.1.101′ –auth ‘xxxxx:xxxxxx’ –datadir ‘/var/lib/mysql/’ –defaults-file ‘/etc/mysql/my.cnf’ –parent ’16042′: 32 (Broken pipe) 140702 10:57:28 [ERROR] WSREP: Failed to read uuid:seqno from joiner script. 140702 10:57:28 [ERROR] WSREP: SST failed: 32 (Broken pipe)

MySQL Performance Blog 找到一篇 5.5.34 Release Note,裡面提到在 5.5.34 版本以後,請使用 xtrabackup-v2 這是之前的 xtrabackup 重新命名過來的。如果重新啟動,還是持續出現此問題的話,請將系統的 MySQL Data 目錄清空,重新跑 SST 拉資料。

$ rm -rf /var/lib/mysql/* $ /etc/init.d/mysql restart

基本上這樣就可以了,另外 MySQL 裝好時,預設都沒有開啟任何 Log 紀錄,請務必將 Log 打開,不然怎麼 Debug,底下附上 Debian 的 my.cnf 設定

innodb_log_file_size = 64M
server-id               = 2
log_bin                 = /var/log/mysql/mysql-bin.log
log_error                      = /var/log/mysql/mysql-error.log
log_queries_not_using_indexes  = 1
slow_query_log                 = 1
slow_query_log_file            = /var/log/mysql/mysql-slow.log
long_query_time                = 1
default_storage_engine=InnoDB
binlog_format=ROW
log_slave_updates

另外 /etc/mysql/conf.d/wsrep.cnf

[MYSQLD]
wsrep_provider=/usr/lib/galera2/libgalera_smm.so
wsrep_cluster_address=gcomm://192.168.1.100,192.168.1.102
wsrep_sst_auth=xxxxx:xxxxx
wsrep_provider_options="gcache.size=2G"
wsrep_cluster_name=Percona
wsrep_sst_method=xtrabackup-v2
wsrep_node_name=db_02
wsrep_slave_threads=4
log_slave_updates
innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2

注意 wsrep_sst_method 務必使用 xtrabackup-v2,如果是 CentOS 系統無此 xtrabackup-v2 指令時,請透過 ln 指令 Link 過去即可。結論就是沒事別亂升級系統,另外第二台要啟動進行 SST 時,可以打開看 innobackupex.backup.log 內是否有錯誤訊息,後續 Node 無法啟動的原因也會紀錄在此。

七月 1, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 在 Ubuntu 建置 OpenWrt 編譯環境

openwrt-logo

紀錄一下如何在用 VirtualBox 架設 Ubuntu OpenWrt 編譯環境,請記住不要下載 Ubuntu Server Disk 來安裝,會遇到很多奇怪的問題,為了避免編譯出錯,請選擇 Ubuntu 12.04 Desktop 版本,安裝時空間請盡量調大,反正 VirtualBox 也不會吃掉這麼多空間,用多少吃多少。Ubuntu 安裝完成後,請先安裝 openssh server 套件。完成後透過 VirtualBox Network 開啟 22 port forwarding。

# 有 aptitude 指令
$ aptitude -y install openssh-server
# 無 aptitude 指令
$ apt-get -y install openssh-server

由於是安裝桌面版本,所以一開始就會直接打開 lightdm 服務,請透過之前寫的文章 Ubuntu 停止使用 GUI 介面 12.04 LTS 來把桌面停用,這樣開機就直接進去 Text mode 了,避免浪費記憶體在桌面。最後補上相依性套件安裝

$ aptitude -y install build-essential bison flex gettext g++ help2man help2man zlib1g-dev libssl-dev gawk unzip

如果編譯過程有看到 script 檔編譯不過,可能就要換 Bash 環境編譯,請先備份 /bin/sh

$ cp -r /bin/sh /bin/sh2
$ ln -sf /bin/bash /bin/sh

完整的 GCC 套件相依性安裝可以直接看 Github 上面的安裝紀錄

六月 25, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Ngnix 搭配 PHP-FPM 噴 php5-fpm.sock failed (13: Permission denied)

nginx-logo

Nginx 搭配 PHP-FPM 已經是架設 PHP 伺服器基本入門款了,這次升級 CentOS 機器完後,發現 Log 一直噴出底下訊息

nginx error connect to php5-fpm.sock failed (13: Permission denied)

透過 Stackoverflow 查到這篇解答 nginx error connect to php5-fpm.sock failed (13: Permission denied),裡面提到兩種作法,其中一解法是直接修改 /var/run/php5-fpm.sock 為 666,讓其他使用者可以直接存取此檔案,但是此作法在下次重新開機後一樣會出現同問題,最終解法請修改 /etc/php-fpm.d/www.conf 如果是搭配 Nginx 請使用底下設定

user = nginx
group = nginx
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
;                 mode is set to 0666
listen.owner = nginx
listen.group = nginx
listen.mode = 0666

六月 17, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Linode 推出每月 10 美金方案

linode_logo_gray

Linode 慶祝 11 週年慶,推出每月只要 10 美金的 VPS 方案,其實這方案就是原本最低的 Linode 2GB 直接打對折啦。流量每月 2TB,記憶體 1G,24GB SSD 硬碟空間,對外頻寬到 125 Mbps,總對外骨幹還是維持在 40 Gbps。重點是 Linode 現在可以用小時付費,但是每個月只要 10 美金,其實真的很便宜,草創時期用 Linode 真的是最好的方案,看來 DigitalOcean 的出現,這兩年讓 Linode 成長不少,也代表的以前的 Linode 賺很大 XD,補上現在的方案表

Plans and Pricing - Linode

六月 12, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 用 Google PageSpeed Insights 計算 Desktop 或 Mobile 網站分數

new-google-logo-knockoff

相信工程師在調整網站效能一定會使用 Google PageSpeed Insights 來得到測試效能數據報表,但是這僅限於使用 Chrome 或 Firefox 瀏覽器。每次跑 PageSpeed 時候,Chrome 就會出現哀號,並且吃下許多記憶體。有沒有 command line 可以直接用 Google PageSpeed Insights 測試 Desktop 或 Mobile 的分數。Google 工程師 @addyosmani 寫了一套 PageSpeed Insights for Node – with reporting 稱作 PSI,可以直接透過 Node 來產生基本 report,這 report 真的算很基本,跟 Chrome 的 extension 跑起來的 report 是不一樣的。這工具可以用來紀錄每次 deploy 網站時的一些數據變化。底下附上 Google 網站報告

google_psi_report

此工具是透過 gpagespeed 完成,如果你有用 GruntJS 可以直接參考 grunt-pagespeed。使用 psi command line 非常簡單,透過底下指令就可以正確產生出上面報表

$ npm install -g psi
$ psi http://www.google.com

如果有用 GulpJS 可以寫成兩個 Task 來跑

var gulp = require('gulp');
var psi = require('psi');
var site = 'http://www.html5rocks.com';
var key = '';

// Please feel free to use the `nokey` option to try out PageSpeed
// Insights as part of your build process. For more frequent use,
// we recommend registering for your own API key. For more info:
// https://developers.google.com/speed/docs/insights/v1/getting_started

gulp.task('mobile', function (cb) {
  psi({
    // key: key
    nokey: 'true',
    url: site,
    strategy: 'mobile'
  }, cb);
});

gulp.task('desktop', function (cb) {
  psi({
    nokey: 'true',
    // key: key,
    url: site,
    strategy: 'desktop'
  }, cb);
});

上面程式碼來自 psi-gulp-sample,psi 有提供 callback function

function(err, data){
  console.log(data.score);
  console.log(data.responseCode);
  console.log(data.id );
}

上面的 Task 可以改成

gulp.task('desktop', function (cb) {
  psi({
    nokey: 'true',
    // key: key,
    url: site,
    strategy: 'desktop'
  }, function(err, data){
    console.log(data.score);
    console.log(data.responseCode);
    console.log(data.id );
    cb();
  });
});

用此工具來紀錄每次網站更新後的測試數據,對於調整 Web Performance 來說是一個可以參考的指標。如果 API 使用量很大,請記得申請 Google API Key。

六月 11, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 安全使用 JavaScript Global Variables

剛開始學習 JavaScript 時候,一定會大量使用 Global Variables。但是使用 Global Variables 的同時,請務必使用 var 宣告,而不是直接使用阿,否則會常常遇到 ReferenceError 的錯誤。

function addToBlockList (item) {
  block_List.push(item);
}

addToBlockList ("add 127.0.0.1");

執行後你可以發現 console 噴出 Uncaught ReferenceError: block_List is not defined,加上一個判斷試試看。程式碼改成底下

function addToBlockList (item) {
  if (block_list) {
    block_List.push(item);
  }
}

addToBlockList ("add 127.0.0.1");

會噴出一樣的錯誤訊息,原因也是 block_List is not defined,最後將程式碼換成底下

function addToBlockList (item) {
  if (window.block_list) {
    window.block_List.push(item);
  }
}

addToBlockList ("add 127.0.0.1");

就可以正常跑了,也不會出現任何錯誤訊息,建議大家不要寫這樣的程式碼,能夠少用 window.xxxx 這種全域變數就盡量少用,不要任意宣告或修改 window 全域變數,上面程式碼可以換成底下會更好

(function() {
  var block_list = [];
  var addToBlockList = function (item) {
    if (block_list) {
      block_list.push(item);
    }
  };
    
  addToBlockList("127.0.0.1");
  console.log(block_list);
  
})();

這樣可以避免渲染 window Global Variable。如果你是用 CoffeeScript 來寫,可以寫成底下

(->
  block_list = []
  addToBlockList = (item) ->
    block_list.push item  if block_list
    return

  return
)()

但是我建議可以使用 block_list? 寫法

(->
  block_list = []
  addToBlockList = (item) ->
    block_List?.push item
    return

  return
)()

轉成的 JavaScript 會是

(function() {
  var addToBlockList, block_list;
  block_list = [];
  addToBlockList = function(item) {
    if (typeof block_List !== "undefined" && block_List !== null) {
      block_List.push(item);
    }
  };
})();

五月 26, 2014

Yuren's Info Area
yurinfore
Yuren's Info Area is about »

tag cloud

» 搬家了

改到 blog.yurenju.info 去,文章量太多了沒搬過去,新文章請那邊看。

五月 25, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 認識現今 Google 搜尋引擎

感謝 @Ly Cheng 針對第三點補充

new-google-logo-knockoff

1995 年 JavaScript 第1版出現,到了 1998 年 Google 推出第一代搜尋引擎,當時的 Google 根本不用在乎網頁如何使用 CSS 或 JavaScript,而當時的網頁也顯少使用 JavaScript 及 CSS。轉眼間到現在 2014 年,如今現在的 Web,已經離不開 JavaScript 及 CSS 了,而目前 SPA (Single Page Application) 的流行,也造成 Google 搜尋引擎讀取資料的困擾,所以 Google 團隊目前也正在朝這方向努力邁進。

傳統的網頁,Google 根本不需要在乎 JavaScript 或 CSS,直接從 Http Response 拿到 Body 內的資料進行分析,然而 JavaScript 的盛行,已經改變了此作法,Google 再也不能從 Body 內準確的拿到資料,原因就是現今的網頁,都已經由 JavaScript 透過 AJAX 方式跟後端存取資料,這樣對於 Google 搜尋引擎是非常不好的結果。

Google 為了改善此問題,現階段也開始著手改善爬蟲,讓爬蟲可以正確執行 JavaScript,當然也要根據 Client 端是否有打開 JavaScript。由於現在大多數的網站已經漸漸變成 SPA 方式,看到如今盛行的 JavaScript Framework 像是 Backbone.jsAngularJS 等。Google Webmaster 也開始正視這問題。

為了能讓 Google 可以正確取得網頁資料,底下有些資訊可以提供給開發者,可以對 Google 爬蟲更友善

  • 請不要將 JavaScript 或 CSS 寫入 robots.txt,這樣只是讓 Google 無法正確拿到 JavaScript 檔案
  • 注意 Server 不要拒絕 crawl requests,也就是要有能力承受 crawl 讀取 XD
  • 讓網頁可以支援舊版瀏覽器或尚未實做 JavaScript 的搜尋引擎,一樣可以正確取得網頁內容
  • JavaScript 寫的太複雜,導致 Google crawl 無法正確執行
  • 使用 JavaScript 移除 content 遠大於新增 content,避免影響 Google 做 index

現在 Google Webmaster Tools 也著手進行後台開發,讓開發者可以正確看到 Google crawl 行為。

此篇文章參考 Understanding web pages betterIt took Google’s Web crawlers 15 years to come to terms with JavaScript

五月 23, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» Gulp.js 工具包

gulp

本篇來整理關於 Gulp.js 的一些 GUI 工具,對於不瞭解 Gulp.js 可以參考之前我寫的 The streaming build system Gulp,會紀錄這篇最主要是看到有人在 Github 發了這篇 Is there any GUI tool for Gulp? 而 Gulp.js 底層作者 @robrich 跳出來列出了很多工具,整理如下

如果開發環境為 Apple Mac 你可以直接裝 @sindresorhus 寫的 gulp-app,或者是 g0v 作者 clkao 開發的 gullet。看大家喜歡哪些工具,請自行安裝。我比較推薦 Gulp Dev Tools for Chrome,可以在瀏覽器上直接執行 Gulp 所有 Task,如果之前有玩過 Grunt.js 大家應該都知道也有 Grunt Devtools

有使用 CoffeeScript 寫 Gulp.js 請務必在 gulpfile.coffee 加上

module.exports = gulp

接著修改 gulpfile.js 如下

require('coffee-script/register');
var gulp = require('./gulpfile.coffee');
module.exports = gulp;

程式碼可以直接參考 html5-template-engine

五月 9, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 免費下載 Percona MySQL eBooks

percona

玩 MySQL 的一定知道 Percona,這次 Percona MySQL 推出免費電子書,電子書內容是從 MySQLPerformanceBlog 裡面精心挑選文章收錄,文章內容也幾乎都是 MySQL 專家寫出來的,電子書內容包含了MySQL server, Percona Server, Percona XtraDB Cluster, MySQL performance, and MySQL troubleshooting,所有的電子書都是免費下載。

更多主題可以直接參考 MySQL eBooks

五月 8, 2014
» 自己的無線電自己修 – UV-5R

Bafong UV-5R Tower

去年為了登山用途,連續團購了好幾打中國製造的便宜業餘無線電 – 福建省南安市寶鋒電子有限公司的 UV-5R.英文名稱是 Baofeng,不過由於商標的權力衝突關係,目前已經逐漸改成 Pofung. 此款支援 UHF/VHF 雙頻守聽、 FM 電台功能,這款無線電改版多次,市面上有多種型號。中國售價大多不超過一千台幣,進口需額外負擔運費與關稅等,仍然相當便宜,因為實在太便宜了,深受登山客、業餘玩家喜愛,就連烏克蘭的民間武裝抗議人士也愛用。(圖為頓內次克政府建築外的親俄士兵)

A pro-Russian protester mans a barricade outside a government building in Donetsk.

A pro-Russian protester mans a barricade outside a government building in Donetsk. Konstantin Chernichkin / Reuters

韌體與硬體

我看過許多種不同的版本,型號有 UV-5R / UV-5RA / UV-5RPlus / UV-5Ra+ / UV5RB / UV5RE 等等千奇百怪針對不同市場的延生版。硬體基本上大同小異,改版主要是外型設計與韌體的改善,加強操作的便利性。

若想知道你所持有的手機是哪一種版本,可以按著 3 開機看韌體版本、按下 6 開機看硬體版本。你若發現韌體版本是 BFB297,那代表是新版的產品,真正的韌體版本資訊無法透過開機訊息查看,必須另外透過軟體檢查。

例如我手上的產品,早期購買版本

  •    BFB229
  •    201002 VER04

後期購入版本則是

  •  BFB297 (實際用軟體查看是 BFB307)
  •  130505N.

韌體功能

基本的韌體功能有

  • VHF/UHF 雙頻無線電對講機. 雙顯示/雙待機/跨段收發
  • 省電功能
  • 語音導引
  • 手電筒功能
  • 鍵盤鎖功能
  • 語音保密裝置
  • 點陣雙排顯示
  • 128組記憶頻道
  • 帶收音機功能
  • VOX聲控發射功能
  • 可調的三色背景燈
  • 1800MAH 鋰電池
  • VHF / UHF 4W/1W 可調整輸出功率
  • TCSS(50組) / DCS(105組)碼任設

 硬體資訊

UV-5R weight

  • 標準配備的重量為 204g, 單機重 108g
  • 天線 16g
  • 1800mah 電池約 80g
  • 3800mah 加長形電池 135g

manchine meightantenna

設定工具

UV-5R 的韌體提供一些基本的設定,像是設定固定頻道、開機訊息等。可以透過耳機麥克風接頭來進行設定。腳位如下圖

uv-5r dualjack

我個人有如下圖的 FT232RL TTL2USB 的接頭,因此可以找一條未用的耳機麥克風接頭改裝。當然你也可以花錢買一條專用的設定線。

FT232RLProgramming cable

至於設定的軟體可使用開放原始碼的 Chirp,這套軟體支援相當多的業餘無線電,也包含了 UV-5R 及其大量的延伸版本。軟體可以用來設定記憶無線電、DTCS 等,方便大量設定無線電,但並非所有設定選單的功能都可以透過電腦設定,詳細支援可見功能清單

Hacks

硬體設計相當容易維修,我曾經拆過試著維修喇叭等。以下是 UV-5RE 的拆解圖

UV-5RE 外觀主機板正面

 

主機板反面主機板特寫

 

小零件屏蔽金屬板

其中比較有趣的元件是

大神級的 Lior Elazary (KK6BWA) 做了許多的 hacks. 其中最 lelazary 做過最瘋狂、最有趣的是換掉 MCU ,外接的 arduino 來控制無線電,甚至直接用 STM32更換原本的微控制器

不像是 UV-3R 用的 MC81F8616 是可程式化的,UV-5R 用 EEPROM 加上自己的 MCU 只能 OTP (One Time Programmable),因此沒有升級的可能性。也沒無法像是 UV-3R 有機會硬幹自己的韌體

另外一個有趣的 hack 是 John BoilesTRRS Adapter。將 TRRS 端子 (Phone connector) 接到無線電上,因此可以將數位轉類比 RF,用 AFSK modulation 可以作到1200 bps.若接上智慧型手機如 iOS 的PocketPacket 或 Android 的 APRSdroid 可以作到自動位置報告系統 APRS (Automatic Position Reporting System)。而不用搞得到處飛線

如果想要用無線電做更快的數位傳輸,據說 RDA1864 可以設定關掉 audio filter ,因而可以作到 9600bps GMSK.

如果你的目的是為了改機亂接,建議玩 UV-B5,新的設計留了排線,比較容易介接。

延伸閱讀

五月 7, 2014
» 使用 Ubuntu 14.04 電子申報綜合所得稅

已經連續兩年都只用 Ubuntu/Firefox 申報稅務,雖然界面醜陋,使用經驗很糟糕。但是財政部算是努力支援不同的作業系統,今年甚至開始支援 Android Tablet 版本的電子申報程式

在 Linux/MacOS 上,你可以用網頁 Java Applet 版本的綜合所得稅電子結算申報繳稅系統網站 進行結算申報,這個系統大部分都是以 Java 完成,跨平台相容性頗佳。但如果你需要使用自然人憑證登入,需要額外安裝中華電信自然人憑證用戶端元件,這個元件使用 Native extension,跟往年一樣,只有支援 x86 版本。

根據 Ubuntu Popularity Contest 統計資料,amd64 (64 bit) 的使用者已經超越 i386 (32 bit)  使用者了。只支援 x86 ,代表使用者必須重新安裝一個新的作業系統才能正確執行自然人憑證用戶端元件。

去年,為了自然人憑證用戶端元件只支援 amd64 以及版次只支援舊版 Firefox,我發了信聯絡 HiPKI客服中心以及 關貿網路電子申報繳稅客服中心,收到兩封郵件

HiPKI客服中心: 關於綜合所得稅電子結算申報繳稅系統是由財政部委託關貿網路股份有限公司製作,若有使用上之建議請向財政部反應。

關貿網路電子申報繳稅客服中心: 客服中心已記錄您的建議事項,並反應給技術團隊,若造成您的困擾,敬請見諒!

 

沒有解決方案,最後是自己硬升級一包 Firefox extension 解決版次問題。至於 i386 只好建一個新的 Ubuntu 來安裝了。 希望來年可以直接支援 amd64 版本。另外今年的 irc.jar 裡面沒有不小心放進去的 .java.bak 檔案了。 (茶)

sbuild

在 amd64 環境安裝一個新的 i386 Ubuntu 有很多種方法,基本的工具是 debootstrap。 在 Ubuntu/Debian 中有不少工具可以協助你建立環境。我習慣用 sbuild / schroot ,這兩套平常當作編譯環境,但是借來快速建立 chroot 也非常方便。

最快速的方法,是用 mk-sbuild 設定一個新的環境,以下例子為建立一個 i386 的 trusty (14.04 LTS) Ubuntu chroot.

apt-get install schroot sbuild ubuntu-dev-tools pcscd
SCHROOT_PROFILE=default mk-sbuild --arch=i386 --debootstrap-include=firefox,fonts-unfonts-core,fonts-droid,openjdk-7-jre,icedtea-7-plugin --distro ubuntu trusty

完成之後,你可以用 schroot -l 來列出有哪些 chroot

$ schroot -l
chroot:trusty-i386
source:trusty-i386

接下來你需要更改預設的 profile 設定,檔案在 /etc/schroot/default/fstab 。請加入以下兩行,這是讓你在 schroot 中可以存取原系統中的檔案。其中 /var/run/pcscd 是 pcscd 的目錄,是系統用來接取自然人憑證用的。

/home        /home        none    rw,bind        0    0
/var/run/pcscd    /var/run/pcscd    none    rw,bind 0 0

注意 schroot -l 出現兩個名稱。你若使用 chroot:trusty-i386,系統會用 LVM snapshots 或 unions 建立一個暫時的環境,所有的改變都會在登出後遺失。所以你若需要更改 schroot 中安裝的的程式,請使用 source:trusty-i386.

sudo schroot -u root -c source:trusty-i386

若是一般使用者用途,則只需要

schroot -c chroot:trusty-i386

接下來即可執行 Firefox, 由於我們在兩個不同的系統間共用家目錄。我建議另外開一個專門的 Profile ,事後會比較容易清理。

DISPLAY=:0.0 firefox -no-remote -ProfileManager

接下來你就有一個在 i386 中執行的 Firefox 可以使用了。

這篇文章使用的軟體版本為


Ubuntu 14.04
debootstrap    1.0.59ubuntu0.1
firefox    29.0+build1-0ubuntu0.14.04.2
pcscd    1.8.10-1ubuntu1
sbuild    0.64.1-1ubuntu4
schroot    1.6.8-1ubuntu1
ubuntu-dev-tools    0.153

延伸閱讀

五月 3, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 修復 Ubuntu 開機 boot loader

logo-Ubuntu

昨天下午本來想幫自己的筆電 (Ubuntu OS) 升級記憶體,結果因為機型過於老舊,以現在的記憶體時脈 1600 裝上去後,直接讓 Ubuntu 當機,反覆重新開機,無法向下相容,加上現在記憶體狂漲價,找不到更低階的記憶體安裝了,無奈的是,店員幫忙測試筆電,換個記憶體,結果連 Ubuntu 的 boot loader 都可以壞掉。我看店員很緊張的說,不好意思,可以幫忙備份,幫忙我重灌。結果我還是自己拿回家處理比較安心。自己也不知道為什麼換個記憶體,可以讓 boot loader 消失。底下是修復 boot loader 過程

製作 Ubuntu Live USB

請先準備好 Ubuntu Live USB,製作方式很簡單,在 Windows 底下請先下載 unetbootin,以及 Ubuntu 任何一版 Desktop OS,可以參考高登寫的教學: 如何製作 Ubuntu Live USB

修復開機磁區

完成上述步驟後,請使用 USB 開機,選擇 Try Ubuntu Desktop,這時候會進到桌面,接著開啟系統內建的 Terminal,打入 fdisk -l 看看系統磁碟分割狀態

$ fdisk -l

Disk /dev/sda: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders, total 625142448 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0002c315

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048      194559       96256   83  Linux
/dev/sda2          196606   625141759   312472577    5  Extended
/dev/sda5          196608    78319615    39061504   82  Linux swap / Solaris
/dev/sda6        78321664   117381119    19529728   83  Linux
/dev/sda7       117383168   625141759   253879296   83  Linux

上述結果可以發現只有一顆硬碟 /dev/sda 開機磁驅為 /dev/sda1 這是 /boot,而根目錄則是 /dev/sda6,接著將這些磁驅掛載到 /mnt/

$ sudo mount /dev/sda6 /mnt
$ sudo mount /dev/sda1 /boot
$ sudo mount /dev/sda7 /home

使用 grub-install 指令重新製作開機 boot loader

$ sudo grub-install --root-directory=/mnt/ /dev/sda

最後重新啟動系統,將 USB 移除即可,就可以看到登入畫面了

五月 2, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud

» 在 Ubuntu 底下查詢記憶時脈體資訊

logo-Ubuntu

最近想升級 Notebook 記憶體到 16G,要查看 Ubuntu 底下記憶體時脈資訊,可以透過 dmidecode 指令來取的記憶體硬體裝置資訊,此指令不只是這樣而已,還可以得知整台電腦硬體 components 資訊,底下擷取如何得到記憶體裝置資訊

$ dmidecode --type 17 | more

輸出結果為

# dmidecode 2.11
SMBIOS 2.4 present.

Handle 0x0036, DMI type 17, 27 bytes
Memory Device
        Array Handle: 0x0035
        Error Information Handle: Not Provided
        Total Width: 64 bits
        Data Width: 64 bits
        Size: 2048 MB
        Form Factor: SODIMM
        Set: None
        Locator: DIMM0
        Bank Locator: BANK 0
        Type: DDR3
        Type Detail: Synchronous
        Speed: 1067 MHz
        Manufacturer: 80CE
        Serial Number: 621AD76C
        Asset Tag: Unknown
        Part Number: M471B5673FH0-CF8

可以看到目前其中一個記憶體插槽時脈為 1067 MHz,型態為 DDR3。這樣就可以直接去升級記憶體了 …

四月 29, 2014

小惡魔AppleBOY
AppleBOY
小惡魔 - 電腦技術 - 工作筆記 - AppleBOY is about »

tag cloud