2016年12月22日 星期四

CC2541 Peripheral傳送1bits以上方法 最多20bits

BLE空中的数据包内容长度最长是一个包20字节,就是20x8=160bits。
这个只需要你稍微修改一下程序就能达到。TI的示例只是用1个字节做例子而已。比如simpleBLEPeripheral中的characteristic 4 就是notification属性,你把这个改成一个20字节的数组:static uint8 simpleProfileChar4 = 0; , 在simpleProfile_ReadAttrCB() 里面*pLen = 1; 改成20,然后编译不过的地方相应修改一下即可。

2016年11月29日 星期二

IAR for 8051

IAR可以將C轉換成8051,

接著再用BTool等工具將8051程式碼燒錄到晶片上

但TI提供的Souce code很複雜

裡面有OSAL這個半OS的核心在運行

可以參考
http://thinkingiot.blogspot.tw/2015/02/ti-ble-stack-osal-cc254x.html

如果開發板不屬於TI, 可以porting 自己的 driver 到 HAL 內, 所以可以在 SW 繼續使用 HAL 定義的 API


IO控制
https://my.oschina.net/u/184090/blog/333164


類似成品 - 成大BLE 藍牙貼片體溫計
http://blog.mainpi.com/archives/190

BLE Peripheral用法
http://gogoprivateryan.blogspot.tw/2014/09/cc2540-bluetooth-low-energy-3.html

藍芽學習ADC
http://www.cnblogs.com/chenzhao207/p/4539197.html

ADC 2541
http://www.cnblogs.com/chenzhao207/p/4539197.html

藍牙溫度傳送
http://www.voidcn.com/blog/feilusia/article/p-4982949.html

CC2541 2.4-GHz Bluetooth™ low energy and Proprietary System-on-Chip

現在改用TI的CC2541, 裡面有藍芽、MCU

http://www.deyisupport.com.edgekey.net/question_answer/wireless_connectivity/bluetooth/f/103/t/89363.aspx

http://www.deyisupport.com.edgekey.net/question_answer/wireless_connectivity/bluetooth/f/103/p/50367/154200.aspx



CC2540/CC2541的基本操作
http://www.programgo.com/article/63055415794/


CC2541 BLE Peripheral工程的建立

http://ziye334.lofter.com/post/2435a3_295a74c


TI CC2541的狗日的Key

http://www.cnblogs.com/Montauk/p/5892047.html

2016年10月13日 星期四

在Android上繪出折線圖、條狀圖、圓餅圖


要在Android上畫圖,這次選擇了AChartEngine,

jar下載 -> http://code.google.com/p/achartengine/downloads/detail?name=achartengine-1.0.0.jar&can=2&q=



配置自己要的位置做一個linearlayout, 就可以把圖放進去想要的地方
View chart = ChartFactory.getLineChartView(this, dataset, renderer);
layout.addView(chart,new LayoutParams(LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));

http://cheng-min-i-taiwan.blogspot.tw/2012/09/android.html

http://cheng-min-i-taiwan.blogspot.tw/2013/09/android.html

Android Studio 無顯示layout預覽圖原因

先前裝1.3.1版Android Studio,

在對應到SDK21之後常會有無法顯示預覽圖的情況

更新版本到2.2.1就改善了,而且現在不只有實際的Layout

還有一個虛擬的配置圖,可以看到重疊的部分等等的

2016年10月6日 星期四

PIC16LF1782 終於搞定ADC

換了一顆PIC之後順遂多啦!

原來FVR功能就只是拿來當參考電壓,之前搞得太複雜了

網路狀態會影響MPLAB X 3.40開啟的失敗

   uint16_t ADCResult,TM;
    uint8_t adhundreds, adtens, adones, adoneth, adtenth;
    double VTao;
typedef unsigned char uint8_t;

void USART_putstring(char* StringPtr){
    while(*StringPtr != 0x00){
     EUSART_Write(*StringPtr);
     StringPtr++;}
}

void get_temperature()
{
    char charADC[8];

   ADCResult = 0x0000;
   ADCResult = ADC_GetConversion(channel_AN4);
   ADCResult &= 0x0FFF;
 
 
 
//    sprintf(charADC,"%u",ADCResult);
//    USART_putstring("ADCResult AN4 = ");
//    USART_putstring(charADC);
//    USART_putstring("\r\n");

    VTao = ADCResult*0.5;
//    sprintf(charADC,"%d",VTao);
//    USART_putstring("VTao = ");
//    USART_putstring(charADC);
//    USART_putstring("\r\n");
   
    TM=211048.6 - ( 192.1 *  VTao);
    adtens = TM/10000;
    adtens = adtens%10;
   
    adones = TM/1000;
    adones = adones%10;
   
    adoneth = TM/100;
    adoneth = adoneth%10;
   
    adtenth = TM/10;
    adtenth = adtenth%10;
   
    adhundreds = TM;
    adhundreds = adhundreds%10;

    sprintf(charADC,"%d%d.%d%d%d",adtens,adones,adoneth,adtenth,adhundreds);
    USART_putstring(charADC);
//    USART_putstring("\r\n");
}


/*
                         Main application
 */
void main(void) {
    SYSTEM_Initialize();
    while (1) {
        get_temperature();
        __delay_ms(500);
    }
}

搞定了硬體方面,現在要開始搞App囉

BluetoothLeScanner.startScan with Android 5 or later

要多一個 permission

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />



LOLLIPOP之後的要使用startScan();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    mBluetoothAdapter.startScan();
} else {
    mBluetoothAdapter.startLeScan(mLeScanCallback);
}

2016年9月20日 星期二

2B楷模頒獎

待補

PIC12LF1572 ADC FVR

PIC12的ADC使用非常多細節需要注意

也在MircoChip開了一個討論串

http://www.microchip.com.tw/modules/newbb/viewtopic.php?start=0&topic_id=19496&viewmode=compact&order=ASC


若用12bits的ADC,則可以精準制小數五位

ADC12 Result (decimal) mV Degree Celsius Current Value Degree Celsius Moving Average
2643968.131925.1942425.19424
2643968.131925.1942425.19424
2642967.765625.2649325.21781
2642967.765625.2649325.22959
2643968.131925.1942425.22252
2644968.498225.1235625.20603
2642967.765625.2649325.21444

2016年8月29日 星期一

Uint8 Uint16 Uint32...


Unsigned:表示無號,沒有負號,所以其範圍為正值
Singed:表示有號,有負號(一般沒有特別指名為 Unsigned皆為Singed)

uint80 to 255Unsigned 8-bit integer
uint160 to 65,535Unsigned 16-bit integer
uint320 to 4,294,967,295Unsigned 32-bit integer
uint640 to 18,446,744,073,709,551,615Unsigned 64-bit integer

2016年8月19日 星期五

英國網站購買 myprotein whey

本來想在costco購買on, 但已經沒貨了,

心一橫就去英國網站直接拉來了!!

紀錄一下購物流程


http://www.myprotein.com/home.dept

此時是25% off (太早買了, 應該要等35% off或是買二送一的時候)

購買了 5公斤胡桃鉗+2.5公斤藍莓起司蛋糕+GBP40運費

總共106英鎊(約1:42)

MYPROTEIN 08450949889
2016/08/152016/08/16
$4,309
GB $106.29

海外交易手續費
2016/08/152016/08/16
$65

583NT / 1KG 目前看來好像挺便宜的, 只希望別被扣稅了!

一開始會收到寄件資訊, 過大概半天就可以去查了

Delivery Information:
Order Number: 75578648


Track Your Order:

Tracking Number: HUT1862GB00174503601

To track your order online: Click here 
* Tracking Link will be active when the courier scans the parcel in their hub - estimated 12 hours.
Delivery Address:
Rm. 5, 5F., No.22 Wenchang 2nd St., Guishan Dist.
台灣桃園市龜山區文昌二街22號505室
Taoyuan City
Taiwan
TW
333

再過一天之後 收到EMS包裹資訊



Please find confirmation that your parcel shipped from THE HUT GROUP via TRAKPAK has been processed.
You may track your parcel using HUT1862GB00174503601 at www.trackmytrakpak.com
Alternatively, you may track your parcel using the local delivery partners tracking website using tracking number EK653716010ES via http://www.correos.es/ss/Satellite/site/pagina-localizador_envios/busqueda-sidioma=en_GB?numero=EK653716010ES 


Should you have any queries regarding the delivery of your parcel please contact  THE HUT GROUP, alternatively you may choose to contact the local delivery partner.


Please don't reply to this email – it's been automatically generated by our computer.

這時候可以用單號去中華郵政查 "國際快捷單號"

http://postserv.post.gov.tw/webpost/CSController?cmd=POS4004_1&_SYS_ID=D&_MENU_ID=189&_ACTIVE_ID=191

接下來就開始等吧(到這邊為止大概三個工作天)


郵件號碼:EK653716010ES
 
目前最新處理結果
狀態處理日期時間處理局詳細資料
投遞成功2016/08/24-10:10:59桃園郵局桃園快捷股
 

郵件詳細處理過程
狀態處理日期時間處理局詳細資料
投遞不成功2016/08/24-05:26:07桃園郵局桃園快捷股 未妥投原因:其他
後續處理方式:今天再(試)投
離開寄達國互換局2016/08/23-19:00:56台北郵件中心包進股 本件將轉往:桃園郵局桃園快捷股
清單號碼:1911
到達寄達國互換局2016/08/23-18:09:01台北郵件中心包進股 總包號碼:317
出口資料-詳如最右方2016/08/17-08:59:00 寄達國:中華民國
寄達互換局:TAIPEI
總包號碼:0317
交寄郵件2016/08/16-18:48:00 寄達國:中華民國

2016年8月11日 星期四

BLE 解析

Software: OSAL, HAL, BLE Protocol Stack (PS), profiles, application


[OSAL]
Operating System Abstraction Layer, 整個BLE 都是基於 OSAL 來做的, OSAL 不是一個完整的 OS, 但是他依然提供了不少 OS 會有的東西例如 Task, Event, Timer, Message Service...

[HAL]

HAL 為 Hardware Abstraction Layer, 他算是一個 HW/SW 中間的介面

[BLE Protocol Stack]

<Generic Access Profile (GAP)>

主要是處理 device access mode 和一些重要的 procedures 如
  • device discovery
  • link establishment
  • link termination
  • initiation of security features
  • device configuration.
GAP layer 可以扮演以下四種角色:
  • Broadcaster: 負責廣播資料, 無法被建立連線 (non-connectable)
  • Observer: 掃描並讀取其他裝置的廣播資訊 (advertisement), 但不能起始一個連線 (non-connectable)
  • Peripheral: 可以接受連線的 advertiser, 屬於一個 link layer slave 的角色
  • Central: 掃描 advertisement 並且可以起始和 peripheral 的連線, 是 link layer connection master 的角色. 目前的 TI BLE central stack 支援三個同時的連線.
<Generic Attribute Profile (GATT)>

  • GATT Client: 對 GATT Server 做 Read/Write data 的動作
  • GATT Server: 本身含有資料, 可以提供給 GATT Client 做 Read/Write 的動作
特別注意, GATT Role 和 GAP Role 是不相關的, GAP master/slave 都可以是 GATT Client/Server, GATT Role 是以資料放在誰那邊做區分, GAP Role 則是以誰發起連線需求做區分 (這邊非常容易搞混)

GATT Server 會包含多個 GATT Services, 也就是提供資料的服務集合, 那其中有兩個 Services 是 Mandatory (必要) 的:
  • Mandatory GAP Service: 裝置跟存取相關的資訊, 例如裝置名稱, 提供者, 產品ID 等等, 每個 BLE 裝置一定要有這個 GAP Service, TI BLE Lib 內建此 GAP Service, 不提供 source code.
  • Mandatory GATT Service: GAT Server 的資訊, 每個 GATT Server 一定要有這個 Service,TI BLE Lib 內建此 GAP Service, 不提供 source code.
Service 下面會有 Characteristics, 也就是此 Service 的 Value, GATT Server 的 Characteristics value 和其 properties/configurations (descriptors) 會放在 attribute table 內, 由很多 attribute 所組成, 除了資料本身外, 每個 attribute 包含了以下三個欄位:
  • Handle: 可以看成是此 attribute 的 address (unique)
  • Type: 哪一種資料型態, 通常會是一個 "UUID" (universal unique identifier), 對應到一個 predefined type (Bluetooth SIG 定義的), 但也可以是 custom type
  • Permissions: 說明 GATT client 如何存取資料 
GATT Server/Client 之間的通訊可以透過以下的 sub-procedures 達到:
  • Read Characteristic Value: 讀取某 handle 的資料
  • Read Using Characteristic UUID: 一次讀取某特定 Type (UUID) 的所有 Characteristics 資料, 會取得多組 handle/value, GATT client 不用知道 handle 就可以讀
  • Read Multiple Characteristic Values: 一次讀取多個 handles 的資料
  • Read Characteristic Descriptor: 由 handle 去讀取 characteristic descriptor 的資料
  • Discover Characteristic by UUID: GATT client 由 type 去取得 GATT server characteristic 的 handle
  • Write Characteristic Value: 寫入某個 handle 的資料值
  • Write Characteristic Descriptor: 寫入某個 characteristic descriptor 值, 藉由 handle
[Profile]



2016年8月2日 星期二

“Gradle Version 2.10 is required.” Error

Android Studio 遭遇

Warning:Gradle version 2.10 is required. Current version is 2.8. If using the gradle wrapper, try editing the distributionUrl in C:\Users\blahblah\myproject\gradle\wrapper\gradle-wrapper.properties to gradle-2.10-all.zip


即為Gradle版本過低,

解決步驟

1) File > Settings > Builds,Execution,Deployment > Build Tools > Gradle >Default

2) 開啟 Project\gradle\wrapper\gradle-wrapper.properties

輸入 distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

小孩額溫計 - 初期晶片選用 (嵌入式系統開發)

大致來說, 嵌入式系統組成主要是基於

Sensor ----- MCU ----- Client

在這個案子中, 因為Sensor部分只有Temperature,

資料處理簡單, 因此初步先嘗試直接用BT模組的8051來當作MCU使用,

Sensor - TI - tmp107

BT module - MICROCHIP - BM70

APP - iOS + Android


很簡單的應用, 難度主要在於利用最簡單的元件,

達成省電以及設定的需求



--------------------------------

BM70目前使用MCP2000來做UART to USB的介面,

但在電腦上驅動怎麼裝都裝不起來...

MicroChip的討論串
http://www.microchip.com.tw/modules/newbb/viewtopic.php?topic_id=19316&start=0

測了幾台電腦, 就我的工作機不work, 好吧...

先不管它了, 要燒錄再用自己的筆電吧...



--------------------------------


經過測試,TMP107在20~42的溫差過高,不適合用於體溫偵測

因此改採LMT70兩顆,其中一顆作為環境溫度補償機制

並新增MCU PIC12F1572 來作為控制器

2016年7月18日 星期一

iOS Development with Swift Tutorial (version bucky)


Windows IDE : IBM Sandbox

學習網址
https://www.youtube.com/playlist?list=PL6gx4Cwl9DGDgp7nGSUnnXihbTLFZJ79B

影片數量 : 40部

預計學習時間 : 10小時

開始時間 : 2016/7/18
結束時間 : 2016/7/19(暫停, 使用vmware練習效率極低)


1 - Apple Developer Registration
2 - iOS Developer Program
3 - Installing Xcode 6
4 - Setting Up a New Project
5 - Quick Tour of the Interface
6 - Creating a Simple Design

2016年7月17日 星期日

iOS Session

lesson 1,2

2016/7/14, 2016/7/15
(10hours)

Github : https://github.com/jicianho/XCode-Tutorial

//: Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"

var question:Int = 23 ; var q1:Int = 4

var emotion:String = " 😂"
//Edit -> emoji
var name:String = "James"
Int.max
print("people \(name) \(question) emotion is \(emotion) ")

if emotion.isEmpty{
    print (" the string was emptied")
}else{
    print (emotion+name)
}

//str can addtion by "+" or ".write"
name.write("ho")


// String of SWIFT is value type
var newStr:String = name
newStr.write("Hello")

if name.hasPrefix("Ja"){
    print("yes")
}

// uppercased let String uppercase, is a new memory space(orginal string still here)
name.uppercased()


name.characters.count

//Constant, Tuple, Optional
//常數 多樣數 可能沒有數

//"let" will let var be constant
let month = 12

var number = 1
let fab = number*2

var strQuestion = "23"
//Int? is mean maybe Int, so it's type Int?, not Int ,if "strQuestion" isn't int, pulse nil
var intques:Int? = Int(strQuestion)
// after Int? , should use "!", ! is warpped

if intques != nil{
    var ques:Int = intques!
}
// as same as
if let value = intques{
    var ques = value
}


// ? is convert, ! is convert "by force"
var name2:String? = " Bucky "
name2?.write("roberts")

var name3:String? = " Bucky "
name3!.write("roberts")

// all name4 is name4!
var name4:String! = " Bucky "
name4.write("roberts")



//-- Tuple --

var person:(String, Int) = ("Jane", 23)
person.0
person.1

var car:(vendor:String, year:Int) = ("Honda",1999)
car.vendor
car.year

var (x,y):(Int, Int) = (100,20)
x
y



var numa4r:Int? = Int(arc4random_uniform(33445555))

var intNuma4r:Int = numa4r!

if (intNuma4r % 11 == 0) && (intNuma4r % 13 == 0) {
    print("Find it!")
}


//-- function --

func abGame(fguess:Int ) -> (fa:Int,fb:Int) {
    let fquestion:Int = 23
    let fq1:Int = fquestion / 10 ; let fq2:Int = fquestion % 10
    let fg1:Int = fguess / 10
    let fg2:Int = fguess % 10
    var fa:Int = 0 ; if fq1 == fg1 {
        fa=fa+1
    }
    if fq2 == fg2 {
        fa=fa+1 }
    var fb:Int = 0
 
    if fq1 == fg2 {
        fb+=1 }
 
    if fq2 == fg1 {
        fb+=1
    }
    print("\(fa) A \(fb) B")
    return (fa,fb)
}


var r = abGame(fguess:23)
abGame(fguess:02)
r.0
r.1

func sum(x1:Int, x2:Int) -> Int{
    return x1+x2
}

var sum_num = sum(x1:10,x2:20)



func test(arg:Int){
    "Test Int"
}
func test(arg:Float){
    "Test Float 123"
}
func test(arg:Double){
    "Test Double 123"
}

//test(6.0)  // which function is called




var count = 6
while count > 0{
    print("**")
    count -= 1
}

//"for-in" new write method
for index in 1..<6  {
    print("*\(index)*")
}

//same as "do-while"
repeat {
    print("*****")
    count = count - 1
} while count>0



var input: String = "4321"
for char:Character in input.characters {
    var str = "\(char)"
    var num = Int(str)!
    print("\(num*2)")
}


func password_check(pasw:String){
    var num_exist:Bool = false
    var upcase_exist:Bool = false
    var lowcase_exist:Bool = false
    var over_count:Int = 0
 
    for char:Character in pasw.characters {
        let str = "\(char)"
        let num:Int? = Int(str)
     
        if num != nil {
            num_exist = true
        }
     
        if str.uppercased() == str {
            upcase_exist = true
        }
     
        if str.lowercased() == str {
            lowcase_exist = true
        }
     
        over_count += 1
    }
    if !num_exist || !upcase_exist || !lowcase_exist || over_count >= 8 {
        print("failure")
    }else{
        print("OK!")
    }
}

password_check(pasw: "s")

//-- collecttion --
// is value type

var names_1:[String] = ["Michael", "James", "Robert"]
var names_2:Array<String> = ["Michael", "James", "Robert"]


names_1.count
if names_1.isEmpty {
    "Empty"
}else {
    "Not empty"
}

names_1[1] = "Allen"
names_1

names_2[0..<2] = ["Scent","Scent"]
names_2

names_2 += ["Bucky"]

names_2.insert("Tom", at: 1)
names_2.remove(at: 2)


var cars:[String] = ["Toyota","BMW"]

cars[1] = "Mercedes"

var vars2 = cars


for (index, object) in cars.enumerated() {
    print("index \(index) is \(object)")
}

var ages = Array<Double>(repeating:2.0, count:3)

var name2_sum = 0
for (index, object) in names_2.enumerated() {
    name2_sum += object.characters.count
    print("\(name2_sum)")
}
print("\(name2_sum)")


var addressBook:Dictionary<String, String> = ["Michael":"0912345678","James":"0988776655", "Robert":"0922334455" ]

//var addressBook:[String:String] = ["Michael":"0912345678","James":"0988776655", "Robert":"0922334455" ]

addressBook.count

addressBook.updateValue("0912345678", forKey: "Michael")
addressBook
addressBook.updateValue("0912345678", forKey: "Bucky")
addressBook.keys
addressBook.values

var dict:[String:Int] = ["Michael": Int(arc4random_uniform(30)),
                         "James":Int(arc4random_uniform(30)),
                         "Bucky":Int(arc4random_uniform(30)),
                         "Jeanifer":Int(arc4random_uniform(30)),
                         "Yuma":Int(arc4random_uniform(30))]

//array has many dictionry
//watch out type define of array1 and array2
var newArray:[[String:Int]] = []
var newArray2:[(String,Int)] = []

for (name,age) in dict {
    if age < 18 {
        newArray2.append((name,age))
        newArray.append([name:age])
        print("\(name),\(age)")
    }
}

print("\(newArray)")
print("\(newArray2)")



//--- nsarray ----
var address:[String] = ["1","2"]
//NSMutableArray is immutable array
var nsaddress:NSMutableArray = NSMutableArray()
nsaddress.add("Michael")
print("\(nsaddress)")

var nsAddress2 = nsaddress

nsAddress2.add("James")

print("\(address)")
print("\(nsAddress2)")



//--- struct ---
struct PlayGround {
    var question = 23
    func randomQuestion(){
    }
    func abGame(guess:Int) -> (a:Int, b:Int) {
        return (0,0)
    }
}


var play:PlayGround = PlayGround()
// if var question is has not inital, must give it
//var play:PlayGround = PlayGround(question:9)
//or play.question = 45

//let play2:PlayGround = PlayGround()
//play2.question = 33




// --- lottery picking balls ---
//mutating <--> self (like "this")
struct PlayGround_mutating {
    var question:Int
    //init is SWIFT's Constructor, like func but without word "func"
    init(){
        question = 23
        randomQuestion()
    }
    mutating func randomQuestion(){
     
        let num = 2
        var balls:[Int] = [Int](repeating: 9, count: 10 )
        for index in 0..<balls.count {
            balls[index] = index
        }
     
        var questions = [Int](repeating: 10, count: num )
        for count:Int in 0..<num {
            let uValue = UInt32(count)
            //every times sub one ball
            let selectedIndex:UInt32 = arc4random_uniform(10 - uValue)
            let intIndex:Int = Int(selectedIndex)
            questions[count] = balls[intIndex]
            balls.remove(at:intIndex)
            print(questions)
        }
        self.question = questions[0] * 10 + questions[1]
    }
}

//Three define method of array
//var names:[String] = Array<String> or () or [String]

var playg:PlayGround_mutating = PlayGround_mutating()
playg.randomQuestion()

//Struct is value type
//all value will be copied when assignment
var play1:PlayGround = PlayGround()
play1.question = 67
var play2:PlayGround = play1
play2.question = 23

play1.question
play2.question


//--- Object ---
var components:NSURLComponents? =  NSURLComponents(string:"https:www.google.com.tw")

components?.scheme = "http"
components?.scheme
//instance is means it's have memory spaces


var newURL = NSURL(string: "http://www.apple.com")
newURL!

var formatter:DateFormatter = DateFormatter()
var date = NSDate()
formatter.dateFormat = "YYYY-MMM-dd GGG hh:mm:ss"
formatter.string(from:date as Date)


//--- Custom Class ---
//(use class complier)



//--- Inheritance ---
//(use class complier)



2016年7月11日 星期一

LAMP Server

「L」表示「Linux」作業系統
「A」表示「Apache」網頁伺服器
「M」表示「MySQL資料庫
「P」表示「PHP」程式語言

sudo tasksel install lamp-server

LAMP使用Apache作為網頁伺服器,網站的預設根目錄是在「/var/www/html」下,剛安裝完LAMP後,會在根目錄下自動放置「index.html」檔案,就是用網頁瀏覽器開啟「http://127.0.0.1/」時看到的網頁。

啟動Apache
sudo service apache2 start

中止Apache
sudo service apache2 stop

重新啟動Apache
sudo service apache2 restart

參考資料
https://magiclen.org/lamp/

JavaScript ActiveXObject not work for chrome

chrome 不支援 Active 控制

因此原本要做的讀檔要用到ActiveXObject

就沒辦法再chrome執行了

之後可能嘗試html5來進行讀檔?

2016年7月6日 星期三

讀書心得 富爸爸與窮爸爸

房子、車子等不算資產,而是負債

只要錢是從口袋流出去都是負債

放到口袋才是資產

例如:房地產買賣、收租、股票買賣、債券、專利使用費等



讓錢為你賺錢,不要為錢賺錢


聰明人只請比自己更聰明的人


所以如果你想成為富有,只須在一生中不斷地買入資產就行了。

2016年7月4日 星期一

JavaScript Tutorial

JavaScript 理解

JavaScript 一種可以崁入在HTML的語言

和PHP不同的是JavaScript 是明碼

2016/7/11使用方法幾乎完全等於JAVAif-esle, switch, for等等都相同
- 參數設定 var  xxx = "abc" or 123; 
- 輸出部分變成 document.write , 記得使用""來做網頁字串輸出


學習網址
https://www.youtube.com/playlist?list=PL46F0A159EC02DF82

影片數量 : 40部

預計學習時間 : 10小時

開始時間 : 2016/7/6
結束時間 : 2016/7/18

Github : https://github.com/jicianho/JavaScript-Tutorial-

1 - Introduction to JavaScript
2 - Comments and Statements
3 - Variables
4 - Different Types of Variables
5 - Using Variables with Strings
6 - Functions
7 - Using Parameters with Functions
8 - Functions with Multiple Parameters
9 - The return Statement
10 - Calling a Function From Another Function
11 - Global & Local Variables
12 - Math Operators
13 - Assignment Operators
14 - if Statement
15 - if/else Statement
16 - Nesting and Fridays!
17 - Complex Conditions
18 - switch
19 - for Loop
20 - while Loop
21 - do while
22 - Event Handlers
23 - onMouseOver & onLoad
24 - Objects
25 - Creating Our Own Objects
26 - Object Initializers
27 - Adding Methods to Our Objects
28 - Arrays
29 - Other Ways to Create Arrays
30 - Array Properties and Methods
31 - join and pop
32 - reverse, push, sort
33 - Add Array Elements Using a Loop
34 - Cool Technique to Print Array
35 - Associative Arrays
36 - Math Objects
37 - Date Objects
38 - Accessing Forms
39 - Accessing Form Elements
40 - Simple Form Validation

PHP Tutorial

PHP理解

PHP是一種可以崁入在HTML的語言

可以被建成一個 Apache 模組




學習網址
https://www.youtube.com/playlist?list=PL442FA2C127377F07

影片數量 : 200部

預計學習時間 : 30小時

2016年6月29日 星期三

XHTML and CSS Tutorial

IDE : Visual Studio Code 1.2.1
Web Server : Ubuntu 14.02 + Apache/2.4.10 + VMware WorkStation 12

完成時間6/25-7/4,共約16小時
練習檔案 https://github.com/jicianho/CSS-Tutorial

7/5發現Html功能不足,無法做到讀取server資料夾等資訊,以及接收post資料
將繼續學習 JavaScript與HTML5之應用

參考連結

https://www.youtube.com/playlist?list=PLC1322B5A0180C946

Ubunut 架設 apache2 (web server)

sudo apt-get install apache2

sudo /etc/init.d/apache2 start

/etc/httpd/conf/httpd.conf Apache 的主要設定檔。
/etc/rc.d/init.d/httpd 啟動、停止、重新啟動 Apache 的 script。
/usr/bin/htpasswd 設定使用者認證資料時所使用的指令。
/usr/sbin/apachectl 這是另一支可以控制 Apache 服務的 script。
/usr/sbin/httpd Apache 執行的主程式 (daemon)。
/var/www 存放網頁資料的目錄。

/var/log/httpd 紀錄檔存放位置。





參考網頁

http://www.arthurtoday.com/2010/05/ubuntu-apache2-server.html

2016年6月28日 星期二

2016年6月27日 星期一

客製化的 mosquitto

進入 src/mosquitto.c

main function裡面有從開啟server之後的動作

首先他先載入 config 也就是我們輸入的命令


接著
_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "mosquitto version %s (build date %s) starting", VERSION, TIMESTAMP);
    _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "add-plus Mosquitto-server-saving");

開始的message

/*J-強制載入 /etc/mosquitto/mosquitto.conf*/

config.config_file = "/etc/mosquitto/mosquitto.conf";
bool config_exist = file_exists(config.config_file);

if (config_exist){
   _mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Config loaded from %s.", config.config_file);
}else{
_mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Can't find config at %s.", config.config_file);
}


在handle_read中

讓mosquitto把接收到的資訊存下來

    /* J-"Payload"" is the message what publisher are sending */
_mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received PUBLISH from %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", context->id, dup, qos, retain, mid, topic, (long)payloadlen);
_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Topic : %s, From : %s", topic, context->id);
_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "Message here : %s", payload);

/*將檔案寫入使用者目錄,檔名=TOPIC、內容=PAYLOAD*/
FILE *pFile;
    char buffer[50];
sprintf(buffer,"/home/cche/mqtt_state/%s.txt",topic);
pFile = fopen( buffer,"w" );
if( NULL == pFile ){
        _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG,"open failure" );
    }else{
        fwrite(payload,1,sizeof(payload)-1,pFile);
_mosquitto_log_printf(NULL, MOSQ_LOG_INFO, "File context : %s", payload);
    }
fclose(pFile);
/*-J*/



mosquitto 執行命令後面輸入的東西會出現在

conf.c 裡面的 mqtt3_config_parse_args 裡面




2016年6月24日 星期五

Mosquitto database

mosquitto.conf中,開啟
# Persistence
# Logging
以下的註解



Error: Invalid user 'mosquitto'.
-->> useradd mosquitto
##創造使用者

1466750350: Saving in-memory database to /var/lib/mosquitto/mosquitto.db.
1466750350: Error saving in-memory database, unable to open /var/lib/mosquitto/mosquitto.db.new for writing.
1466750350: Error: Permission denied.
-->> cche@ubuntu:/var/lib$ sudo chown mosquitto:mosquitto mosquitto
##把它資料夾所有者改成mosquitto


But, database of Mosquitto created can't provide look up (what's it can do??)
So, We will maybe do second dev. from Mosquitto,

doing..
1. Subscribe appoing topic.
2. Daliy system to subscribe topic.
3. A process subscribe and processing data, and sent to B process.

2016年6月23日 星期四

MQTT mossquitto.conf設定

mosquitto.comf 是mosquitto的配置文件。

放在mosquitto讀取的路徑下就可以,mosquitto預設不需要mosquitto.comf ,即使用預設值。
mosquitto -v
    【-v】打印更多的调试信息
mosquitto -c /etc/mosquitto/mosquitto.conf

mosquitto_sub -v -t test
mosquitto_sub -u name -P Passwd -v -t test
    【-t】指定主题,此处为test
    【-v】打印更多的调试信息

mosquitto_pub -t test  -m test123
mosquitto_pub -u name -P Passwd -t test -m test123

參考來源
http://qinfei.lexinsmart.com/2015/09/mosquitto%E5%8D%8F%E8%AE%AE%E4%B9%8Bmosquitto-conf5-%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8%E9%85%8D%E7%BD%AE/

2016年6月22日 星期三

Mosquitto + Ubuntu 14.02 Source install

Source code

https://github.com/eclipse/mosquitto


環境 : VMware + putty

sudo apt-get install openssh-server gcc openssl

sudo apt-get install libssl-dev build-essential zlibc zlib-bin libidn11-dev libidn11


./mosquitto_internal.h:51:12: fatal error: 'ares.h' file not found

wget http://c-ares.haxx.se/download/c-ares-1.10.0.tar.gz

tar -zxf c-ares-1.10.0.tar.gz

cd c-ares-1.10.0

./configure

sudo make install


uuid.h

sudo apt-get install uuid-dev


xsltproc: Command not found

sudo apt-get install xsltproc

/usr/share/xml/docbook/stylesheet/docbook-xsl/manpages/docbook.xsl

sudo apt-get install  docbook-xsl

libmosquitto.so.1 not find

su

cat /etc/ld.so.conf

echo "/usr/local/lib" >> /etc/ld.so.conf

ldconfig

exit

回到mosquitto資料夾

sudo make

sudo make install

done

mosquitto -v
    【-v】打印更多的调试信息

mosquitto_sub -v -t test
    【-t】指定主题,此处为test
    【-v】打印更多的调试信息

mosquitto_pub -t test  -m test123


參考來源
http://blog.csdn.net/yajun0601/article/details/41982583
http://houjixin.blog.163.com/blog/static/3562841020156142544694/
http://www.360doc.com/content/14/1010/17/12928831_415836429.shtml
http://www.openchange.org/cookbook/initializing.html
http://m.blog.csdn.net/article/details?id=51395812

Ubuntu Samba setup

安裝Samba
sudo apt-get install samba
設定Samba 
編輯 /etc/samba/smb.conf
 
(1)
[global]
workgroup = root
security = share
 
(2)尾部加入
[分享資料夾的名稱]
path = 分享資料夾的路徑
writable = yes
guest account = root
force user = root
public = yes
force group = root
 
[3]重新啟動 Samba Server
sudo /etc/init.d/samba restart
 
[4]Windows設定
在網路上的芳鄰圖示下按右鍵,
 "連線網路磁碟機"
磁碟機: 任選
資料夾: \\Ubuntu下所設IP\分享資料夾的名稱

參考
http://flykof.pixnet.net/blog/post/23028119-ubuntu%E4%B8%8Bsamba%E5%AE%89%E8%A3%9D%E8%A8%AD%E5%AE%9A