2019年4月25日 星期四

新增 PM2.5 Homekit 裝置

markdown

手上買了一個Sharp GP2Y1010AU0F PM2.5的感測器,就只在買來的當下用UNO測試了一下,嗯~~可用,就收起來了,一直到這次要整合在一個能夠顯示時間又有Homekit功能的系統板上(暫且稱它為家庭顯示中心吧),才又把它拿出來了。

把UNO的code  Ctrl+C、Ctrl+V到ESP32下,理論上應該是沒問題的,所以就做啦,只把Delay的部分修改為vTaskDelay,因為我是採用ESP-IDF + RTOS + Arduino 的平台,Flash完,怎麼收到的電壓都是0V,用VR分壓測試,A/D沒問題啊,怎麼沒收到GP2Y的電壓,換回UNO,一切正常啊,甚麼問題???

好,Hardward沒問題,Firmware我只修改Delay,問題不會就在這吧

沒錯,在UNO下的Delay是
delayMicroseconds(280)
ESP32是
vTaskDelay(280/portTICK_RATE_MS)
這可是差1000倍呀!!

既然在ESP-IDF下已經有支援arduino的套件,那就在這裡也改用delayMicroseconds函數吧,應該不至於影響整個系統太多,畢竟我還有其他task在執行

compiler...  flash... run... ,Yes~ got it ,讀到值啦,那就繼續往下一步去,增加到Homekit裝置

新增Homekit裝置時,都需要滿足Apple的servicecharacteristics定義,但因為我不是ios developer,所以也不知道定義的方式為何,不過沒關係,網路上很多神人的,下面就有一個 characteristics.h 的定義檔可以參考

characteristics.h

用一個開關當範例說明 (參考characteristics.h)

在SERVICE中需要的的是ON這個Characteristics
NAME就列為選項,可有可無了

/**
 Defines that the accessory contains a switch.
 
 Required Characteristics:
 - ON
 
 Optional Characteristics:
 - NAME
 */
#define HOMEKIT_SERVICE_SWITCH HOMEKIT_APPLE_UUID2("49")


ON這個Characteristics的定義如下

(第6行).permissions中有read、write與notify三個函數
(第9行).value中描述值為BOOL

所以我們共要有三個函數加一個BOOL值

#define HOMEKIT_CHARACTERISTIC_ON HOMEKIT_APPLE_UUID2("25")
#define HOMEKIT_DECLARE_CHARACTERISTIC_ON(_value, ...) \
    .type = HOMEKIT_CHARACTERISTIC_ON, \
    .description = "On", \
    .format = homekit_format_bool, \
    .permissions = homekit_permissions_paired_read \
                 | homekit_permissions_paired_write \
                 | homekit_permissions_notify, \
    .value = HOMEKIT_BOOL_(_value), \
    ##__VA_ARGS__

回到程式碼中,(第13行)struct hap\_characteristic switch1[]中
switch\_state 就是.value的 BOOL 定義,true 就是switch on,false即為switch off
switch1\_read、switch1\_write與switch1\_notify 就分別是三個函數啦
void *accessory_object = hap_accessory_add(acc);
    struct hap_characteristic cs[] = {
        {HAP_CHARACTER_IDENTIFY, (void *)true, NULL, identify_read, NULL, NULL},
        {HAP_CHARACTER_MANUFACTURER, (void *)MANUFACTURER_NAME, NULL, NULL, NULL, NULL},
        {HAP_CHARACTER_MODEL, (void *)MODEL_NAME, NULL, NULL, NULL, NULL},
        {HAP_CHARACTER_NAME, (void *)ACCESSORY_NAME, NULL, NULL, NULL, NULL},
        {HAP_CHARACTER_SERIAL_NUMBER, (void *)"0123456789", NULL, NULL, NULL, NULL},
        {HAP_CHARACTER_FIRMWARE_REVISION, (void *)"1.0", NULL, NULL, NULL, NULL},
    };
    hap_service_and_characteristics_add(acc, accessory_object, HAP_SERVICE_ACCESSORY_INFORMATION, cs, ARRAY_SIZE(cs));


struct hap_characteristic switch1[] = {
        {HAP_CHARACTER_ON, (void *)switch_state,NULL, switch1_read, switch1_write, switch1_notify},
    };
    hap_service_and_characteristics_add(acc, accessory_object, HAP_SERVICE_SWITCHS, switch1, ARRAY_SIZE(switch1));

switch1\_read、switch1\_write與switch1\_notify 三個函數範例程式如下

void *switch1_read(void *arg)
{
    return (void *)switch_state;
}

void switch1_write(void *arg, void *value, int len)
{
    switch_state= ((int)value) ? true : false;

    if (switch_state)
        LED_ON();
    else
        LED_OFF();

    if (_switch1_ev_handle)
        hap_event_response(acc, _switch1_ev_handle, (void *)switch_state);
    return;
}

void switch1_notify(void *arg, void *ev_handle, bool enable)
{
    if (enable)
        _switch1_ev_handle = ev_handle;
    else
        _switch1_ev_handle = NULL;
}



好了,進入主題了,新增PM2.5的Homekit裝置

當我們要使用 air quality 時,需要AIR\_QUALITY的Characteristics,PM2\.5(PM25_DENSITY) 則是列為選項

/**
 Defines that the accessory contains a air quality sensor.
 Required Characteristics:
 - AIR_QUALITY
 
 Optional Characteristics:
 - NAME
 - STATUS_ACTIVE
 - STATUS_FAULT
 - STATUS_TAMPERED
 - STATUS_LOW_BATTERY
 - OZONE_DENSITY
 - NITROGEN_DIOXIDE_DENSITY
 - SULPHUR_DIOXIDE_DENSITY
 - PM25_DENSITY
 - PM10_DENSITY
 - VOC_DENSITY
 - CARBON_MONOXIDE_LEVEL
 - CARBON_DIOXIDE_LEVEL
 */
#define HOMEKIT_SERVICE_AIR_QUALITY_SENSOR HOMEKIT_APPLE_UUID2("8D")

來看看 AIR\_QUALITY 的Characteristics
.permissions 列出 read與notitfy
.value 是 0, 1, 2, 3, 4, 5,共六個有效值

#define HOMEKIT_CHARACTERISTIC_AIR_QUALITY HOMEKIT_APPLE_UUID2("95")
#define HOMEKIT_DECLARE_CHARACTERISTIC_AIR_QUALITY(_value, ...) \
    .type = HOMEKIT_CHARACTERISTIC_AIR_QUALITY, \
    .description = "Air Quality", \
    .format = homekit_format_uint8, \
    .permissions = homekit_permissions_paired_read \
                 | homekit_permissions_notify, \
    .min_value = (float[]) {0}, \
    .max_value = (float[]) {5}, \
    .min_step = (float[]) {1}, \
    .valid_values = { \
        .count = 6, \
        .values = (uint8_t[]) { 0, 1, 2, 3, 4, 5 }, \
    }, \
    .value = HOMEKIT_UINT8_(_value), \
    ##__VA_ARGS__

PM25\_DENSITY 的Characteristics
.permissions 列出 read與notitfy
.value 是 0~1000 的範圍

#define HOMEKIT_CHARACTERISTIC_PM25_DENSITY HOMEKIT_APPLE_UUID2("C6")
#define HOMEKIT_DECLARE_CHARACTERISTIC_PM25_DENSITY(_value, ...) \
    .type = HOMEKIT_CHARACTERISTIC_PM25_DENSITY, \
    .description = "PM25 Density", \
    .format = homekit_format_float, \
    .permissions = homekit_permissions_paired_read \
                 | homekit_permissions_notify, \
    .min_value = (float[]) {0}, \
    .max_value = (float[]) {1000}, \
    .value = HOMEKIT_FLOAT_(_value), \
    ##__VA_ARGS__

有上面這些資料,就可以變成我們的code了,範例如下

struct hap_characteristic air_quality[] = {
    {HAP_CHARACTER_AIR_QUALITY , (void *)air_quality_value,NULL, air_quality_read, NULL, air_quality_notify},
    {HAP_CHARACTER_PM2_5_DENSITY , (void *)pm25_ugm3_value,NULL, pm25_ugm3_read, NULL, pm25_ugm3_notify},
}  
hap_service_and_characteristics_add(acc, accessory_object, HAP_SERVICE_AIR_QUALITY_SENSOR , air_quality,ARRAY_SIZE(air_quality));


寫完,收工~~~~~~






2019年4月22日 星期一

單顆按鍵程式庫 OneButton

markdown
最近在開發的板子,因為當初僅設計一個按鍵,現在又需要進行更多的設定操作,結果外接的IO腳位不夠使用了,便上網搜尋了一下,找到了OneButton Library可以用,連結如下

https://github.com/mathertel/OneButton

它可以透過一個按鍵判斷Click、Double Click、Long Press的狀態,剛好可以滿足現在的應用了

下面是把所有OneButton的Function都列出,可以把需要的Function保留下來就好

#include "OneButton.h"
OneButton button1(GPIO_NUM_0, true);

void click1(){
......
}

void doubleclick1(){
......
}

void longPressStart1(){
......
}

void longPressStop1(){
......
}

void longPress1(){
......
}

void setup(){
    button1.attachClick(click1);
    button1.attachDoubleClick(doubleclick1);
    button1.attachLongPressStart(longPressStart1);
    button1.attachLongPressStop(longPressStop1);
    button1.attachDuringLongPress(longPress1);
}

2019年4月17日 星期三

讓MAC下的終端機bash有顏色




用編輯器打開 ~/.profile
加入
export CLICOLOR="true"
export LSCOLORS="gxfxcxdxcxegedabagacad"
export PS1="\[\e[0;31m\]\u@\[\e[m\e[0;34m\]\h\[\e[m \e[0;32m\]\W >\[\e[m\]"

LSCOLORS 的字串設定順序:

directory
symbolic link
socket
pipe
executable
block special
character special
executable with setuid bit set
executable with setgid bit set
directory writable to others, with sticky bit
directory writable to others, without sticky bit

顏色的對應值:
a -> black
b -> red
c -> green
d -> brown
e -> blue
f -> magenta
g -> cyan
h -> light grey

A -> bold black, usually shows up as dark grey
B -> bold red
C -> bold green
D -> bold brown, usually shows up as yellow
E -> bold blue
F -> bold magenta
G -> bold cyan
H -> bold light grey; looks like bright white
x -> default foreground or background

每個檔案型態有兩個值,前景色和背景色。

以LSCOLORS="gxfxcxdxcxegedabagacad" 做說明,前面的 gx 是設定資料夾顯示的顏色為青色(cyan),底色是預設的前景和背景色;fx
是 symbolic link 的設定,顯示的字是洋紅(magenta),底色是預設的前景和背景色,依此類推。

若希望自已修改,又不想一個字一個字輸入,網路上有小工具,直接用 GUI 設定和預覽,設定好想要的顏色之後,就產生設定字串出來啦。

website: http://geoff.greer.fm/lscolors/

Free ERP on the Raspberry Pi (odoo)

  #更新系統軟體 sudo apt update && sudo apt upgrade -y #安裝資料庫 sudo apt install postgresql -y #安裝py程序 sudo apt install python3-pip -y #安裝od...