手上買了一個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的service與characteristics定義,但因為我不是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));
寫完,收工~~~~~~