HomeKit server on ESP8266 with RTOS

前提

之前使用通过树莓派上搭建Domoticz和Homebridge服务器,将小米网关加入到iOS Home里,这样就可以使用iOS的HomeKit控制连接在小米网关的子设备。

偶然间找到单独使用ESP8266也可以支持iOS的HomeKit

实现过程

准备

  1. ESP8266-RTOS-SDK
  2. esp-open-sdk
    git clone --recursive https://github.com/pfalcon/esp-open-sdk.git

    这里面包含ESP8266交叉编译工具xtensa-lx106-elf

  3. 下载源码
    ESP8266-HomeKit

编译ESP8266-HomeKit

  1. 将交叉编译工具xtensa-lx106-elf/bin加入到全局变量里
  2. cd ESP8266-HomeKit打开deploy.sh 配置SDK_PATH(ESP8266-RTOS-SDK)
  3. ./deploy.sh
  4. 成功后显示

    1
    2
    ########## success ###########
    deployed lib/libhkc.a and include/hkc.h

测试Demo

下载Demo源码
ESP8266-HomeKit-Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
cd ESP8266-HomeKit-Demo/button-led
//修改user_main.c 加入自己WIFI SSID和密码
./gen_misc.sh
based on gen_misc.sh version 20150911

SDK_PATH:
/Users/angqinghua/Downloads/ESP8266/ESP8266_RTOS_SDK

BIN_PATH:
/Users/angqinghua/Downloads/ESP8266/ESP8266_RTOS_SDK/bin

Please check SDK_PATH & BIN_PATH, enter (Y/y) to continue:
y

Please follow below steps(1-5) to generate specific bin(s):
STEP 1: use boot_v1.2+ by default
boot mode: new

STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)
enter (0/1/2, default 0):

ignore boot
generate bin: eagle.flash.bin+eagle.irom0text.bin

STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)
enter (0/1/2/3, default 2):

spi speed: 40 MHz

STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)
enter (0/1/2/3, default 0):

spi mode: QIO

STEP 5: choose spi size and map
0= 512KB( 256KB+ 256KB)
2=1024KB( 512KB+ 512KB)
3=2048KB( 512KB+ 512KB)
4=4096KB( 512KB+ 512KB)
5=2048KB(1024KB+1024KB)
6=4096KB(1024KB+1024KB)
enter (0/2/3/4/5/6, default 0):
4
spi size: 4096KB
spi ota map: 512KB + 512KB

start...

Fri May 18 09:15:38 CST 2018

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C user clean; /Applications/Xcode.app/Contents/Developer/usr/bin/make -C driver clean;
...
...
...

编译在中间一个地方会卡一会,需要3-5分钟
编译结束用esptool烧写bin到ESP8266里

打开串口工具波特率为76800,可看到当前运行情况

在iOS Home里添加accessory

验证码是031-45-154

测试运行是否正常

可以发现LED,亮和灭正好和手机上显示相反(这颗LED GPIO低电平有效)
解决方法:修改gpio.h的宏定义反过来就行了
#define GPIO_OUTPUT(gpio_bits, bit_value) ...

可以手动开启关闭LED或者呼叫Siri来开启关闭LED

Demo视频

附上自己改过的一键编译烧写的gen_misc.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#!/bin/bash
:<<!
******NOTICE******
MUST set SDK_PATH & BIN_PATH firstly!!!
example:
export SDK_PATH=~/esp_iot_sdk_freertos
export BIN_PATH=~/esp8266_bin
!

echo -e "\033[31m based on gen_misc.sh version 20150911 \033[0m"
echo ""

export PATH=/Volumes/esptools/esp-open-sdk/xtensa-lx106-elf/bin:$PATH

if [ ! $SDK_PATH ]; then
export SDK_PATH=$(dirname $(dirname $(pwd)))
fi

echo -e "\033[32m SDK_PATH:"
echo "$SDK_PATH"
echo ""

if [ ! $BIN_PATH ]; then
export BIN_PATH=$SDK_PATH/bin
fi

echo "BIN_PATH:"

echo "$BIN_PATH"

echo -e "\033[0m"

echo "Please check SDK_PATH & BIN_PATH, enter (Y/y) to continue:"
read input

if [[ $input != Y ]] && [[ $input != y ]]; then
exit
fi

echo ""

echo "Please follow below steps(1-5) to generate specific bin(s):"
echo "STEP 1: use boot_v1.2+ by default"
boot=new

echo "boot mode: $boot"
echo ""

echo "STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)"
echo "enter (0/1/2, default 0):"
read input

if [ -z "$input" ]; then
if [ $boot != none ]; then
boot=none
echo "ignore boot"
fi
app=0
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
elif [ $input == 1 ]; then
if [ $boot == none ]; then
app=0
echo "choose no boot before"
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
else
app=1
echo "generate bin: user1.bin"
fi
elif [ $input == 2 ]; then
if [ $boot == none ]; then
app=0
echo "choose no boot before"
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
else
app=2
echo "generate bin: user2.bin"
fi
else
if [ $boot != none ]; then
boot=none
echo "ignore boot"
fi
app=0
echo "generate bin: eagle.flash.bin+eagle.irom0text.bin"
fi

echo ""

echo "STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)"
echo "enter (0/1/2/3, default 2):"
read input

if [ -z "$input" ]; then
spi_speed=40
elif [ $input == 0 ]; then
spi_speed=20
elif [ $input == 1 ]; then
spi_speed=26.7
elif [ $input == 3 ]; then
spi_speed=80
else
spi_speed=40
fi

echo "spi speed: $spi_speed MHz"
echo ""

echo "STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)"
echo "enter (0/1/2/3, default 0):"
read input

if [ -z "$input" ]; then
spi_mode=QIO
elif [ $input == 1 ]; then
spi_mode=QOUT
elif [ $input == 2 ]; then
spi_mode=DIO
elif [ $input == 3 ]; then
spi_mode=DOUT
else
spi_mode=QIO
fi

echo "spi mode: $spi_mode"
echo ""

echo "STEP 5: choose spi size and map"
echo " 0= 512KB( 256KB+ 256KB)"
echo " 2=1024KB( 512KB+ 512KB)"
echo " 3=2048KB( 512KB+ 512KB)"
echo " 4=4096KB( 512KB+ 512KB)"
echo " 5=2048KB(1024KB+1024KB)"
echo " 6=4096KB(1024KB+1024KB)"
echo "enter (0/2/3/4/5/6, default 0):"
read input

if [ -z "$input" ]; then
spi_size_map=0
echo "spi size: 512KB"
echo "spi ota map: 256KB + 256KB"
elif [ $input == 2 ]; then
spi_size_map=2
echo "spi size: 1024KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 3 ]; then
spi_size_map=3
echo "spi size: 2048KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 4 ]; then
spi_size_map=4
echo "spi size: 4096KB"
echo "spi ota map: 512KB + 512KB"
elif [ $input == 5 ]; then
spi_size_map=5
echo "spi size: 2048KB"
echo "spi ota map: 1024KB + 1024KB"
elif [ $input == 6 ]; then
spi_size_map=6
echo "spi size: 4096KB"
echo "spi ota map: 1024KB + 1024KB"
else
spi_size_map=0
echo "spi size: 512KB"
echo "spi ota map: 256KB + 256KB"
fi

echo ""

echo -e '\033[32m start... \033[0m'

echo -e '\033[31m'
date
echo -e '\033[0m'


make clean

make BOOT=$boot APP=$app SPI_SPEED=$spi_speed SPI_MODE=$spi_mode SPI_SIZE_MAP=$spi_size_map

echo -e '\033[31m'
date
echo -e '\033[0m'

SERIAL_PORT=$(ls /dev/cu.w*)
echo -e "\033[32m $SERIAL_PORT \033[0m"

esptool.py --port $SERIAL_PORT erase_flash
esptool.py --port $SERIAL_PORT write_flash 0x3FC000 $BIN_PATH/esp_init_data_default.bin
esptool.py --port $SERIAL_PORT write_flash 0x00000 $BIN_PATH/eagle.flash.bin 0x14000 $BIN_PATH/eagle.irom0text.bin