# 基于GPRS AIR202的超级简单插座设计
## 一、简介
**免配网+最小,最简洁**
**免配网+最小,最简洁**
**免配网+最小,最简洁**
**一分钟上手**
**采用的是GPRS模块+LUA语言开发,超级简单**
**妈妈再也不用担心我不懂C语音啦**
**原件就几个,焊接五分钟完事**
**通过云智能和天猫精灵控制开关动作**
**开始以为2G会有很严重的时延,不过测试很完美。详见附件**
## 二、功能描述
**采用的是通用MQTT接入阿里云,通过心跳保持设备在线。**
**设备心跳上报超时,APP和天猫精灵上就会提示不在线。**
**云端数据处理全部在阿里云,本地负责上报开关的情况**
## 三、设计特点
### 1.把元器件做了两面,把体积做到了最小,可以直接放到电风扇里边,或者放到音箱里边,或者插排里边
### 2.预留了一个KEY,轻触开关,不过想到板子带220V.控制权还是全部留给手机APP和天猫精灵了
### 3.下载接口采用的是TOP面单面焊盘,可以直接使用串口压针压住下载
### 4.设计的时候考虑到家里的路由器没办法给WIFI配网,就直接用了2G的。配网还是一件挺麻烦的事情,影响用户体验的
### 5.代码使用的是LUA开发,跟C没有啥关系,调用接口完事。所以代码调试时间很短
### 6.考虑到是直接放进去电器里边,所以没有考虑到外壳。
### 7.PCB面积(宽3.5cm 长4.5cm)在嘉立创打样限制的10cm*10cm以内,打板成本极低。
## 四、元器件选型
### 1.主控使用AIR 202,直接驱动NUD3124LT1G拉动继电器(谢谢EDA的老师推荐的神器)。因为主控复位期间GPIO8是高阻,所以不需要考虑加辅助电路。
### 2.下载采用的是下载串口和主电路板分离,不然电路板体积要加大,做不到精简
### 3.电源使用的是HLK-PM01,出来就是5V的电压供给继电器动作。主要是担心继电器动作的时候会把电压拉低以及给主控DCDC供电,所以加了一个固态电容100UF的。继电器使用的是JZC-32F/005-HS3(555)驱动电压是5V,主控需要的电压是3.3V-4.2V,所以使用了一个DCDC,SW5033H的DCDC,从5V输出取电,主控供电并联了两个电容降低ESR,一个100UF的固态加一个22UF的0603。
### 4.没有使用PCB天线,主要是做阻抗匹配比较麻烦一些,所以直接一个一代IPEX出来外接天线了,信号强度比较理想CSQ能到23这样。需要注意天线的净空处理,不然容易翻车
### 5.接线采用两个2P端子,开始想做单火取电,想想手上刚好没材料,所以放弃了
### 6.指示灯只是一个0805的蓝色LED,主要通过慢闪和快闪来区分联网状态。因为打算把成品放到家电里,所以没做指示灯,继电器状态可以通过APP查看或者直接问天猫精灵
## 五、布局布线设计
### 1.202的摆放比较随意,主要是天线要做净空处理还有就是IPEX焊接要保证焊接到位即可(注意是两面,不然影响信号,到时候连不上网就翻车了)
### ![微信截图_20200817170955.png](//image.lceda.cn/pullimage/vmg5ZvbtBkvGEnxNK2ITjwEtya9aqzgDGfP48ppr.png) ![微信截图_20200817171030.png](//image.lceda.cn/pullimage/b4xcZWaE4DPQscJaFrRcb8gXoU9O8bFHOvtDYbmH.png)
### 2.强电和弱电的隔离。物理距离大概有3MM这样,主要还是比较担心,所以中间加了一个开槽。开槽有1.5MM的宽度
### ![微信截图_20200817171235.png](//image.lceda.cn/pullimage/aXxX8eH0ShcHvMi0bxU0vNdt7rv1iAWamAf8uu0J.png)
### 3.覆铜处理,主要是增加天线的反射平面,所以不规则的打了比较多的过孔
![微信截图_20200817171235.png](//image.lceda.cn/pullimage/TfLPUCydKZosWMJnGtyF9QqDugR9aT59pV87X3cd.png)
## 六、设计心得和调试过程
### 开始考虑用2G方案,天生它就没有WIFI的时延低,一般都要延时一秒到两秒。开始以为在APP发出控制指令要等好久,结果测试挺完美的(延时时间基本在1秒以内,用户使用无延时感)。算得上比较完美,也进一步证明阿里的的云平台比较牛逼。以前阿里平台是APP上线或者问天猫设备的状态,阿里的服务器会过来问设备的状态,然后设备回应。现在模式改了,改成了服务器下发开的指令之后,本地设备处理完开的指令后,上报一个开的状态。后来提交工单问了一下才知道改了。
## 七、焊接过程**原件就几个,焊接几下就弄完了**
**![微信图片_20200817171947.jpg](//image.lceda.cn/pullimage/wnycOpLfd32Fs5ECUfujXRiOdbOBZEUPtMmEcn7i.jpeg)**
**![微信图片_20200817171939.jpg](//image.lceda.cn/pullimage/nDuD49oh2hJjY3TsnSM6IRWUAy09X6OA5GtKtjQX.jpeg)**
**![9.jpg](//image.lceda.cn/pullimage/Ga0t7zn98pVpYwfqnePedkChWYVecf0tkiOMAj4u.jpeg)**
## 八 LUA代码(相对比较简单,调用相关API即可)
```
module(...,package.seeall)
require"aLiYun"
require"misc"
require"pm"
local PRODUCT_KEY = "your key"
local function getDeviceName()
return misc.getImei()
end
local function setDeviceSecret(s)
misc.setSn(s)
end
local function getDeviceSecret()
return misc.getSn()
end
local sConnected
local publishCnt = 1
local function publishTestCb(result,para)
log.info("testALiYun.publishTestCb",result,para)
sys.timerStart(publishTest,20000)
publishCnt = publishCnt+1
end
function publishTest()
if sConnected then
aLiYun.publish("/"..PRODUCT_KEY.."/"..getDeviceName().."/update","qos1data",1,publishTestCb,"publishTest_"..publishCnt)
end
end
local function rcvCbFnc(topic,qos,payload)
log.info("testALiYun.rcvCbFnc",topic,qos,payload)
end
local function connectCbFnc(result)
log.info("testALiYun.connectCbFnc",result)
sConnected = result
if result then
aLiYun.subscribe({["/"..PRODUCT_KEY.."/"..getDeviceName().."/get"]=0, ["/"..PRODUCT_KEY.."/"..getDeviceName().."/get"]=1})
aLiYun.on("receive",rcvCbFnc)
publishTest()
end
end
local function authCbFnc(result)
log.info("testALiYun.authCbFnc",result)
end
aLiYun.setup(PRODUCT_KEY,nil,getDeviceName,getDeviceSecret)
aLiYun.on("auth",authCbFnc)
aLiYun.on("connect",connectCbFnc)
require"aLiYunOta"
local function otaCb(result,filePath)
log.info("testALiYun.otaCb",result,filePath)
if result then
local uartID = 1
sys.taskInit(
function()
local fileHandle = io.open(filePath,"rb")
if not fileHandle then
log.error("testALiYun.otaCb open file error")
if filePath then os.remove(filePath) end
return
end
pm.wake("UART_SENT2MCU")
uart.on(uartID,"sent",function() sys.publish("UART_SENT2MCU_OK") end)
uart.setup(uartID,115200,8,uart.PAR_NONE,uart.STOP_1,nil,1)
while true do
local data = fileHandle:read(1460)
if not data then break end
uart.write(uartID,data)
sys.waitUntil("UART_SENT2MCU_OK")
end
aLiYunOta.setVer("MCU_VERSION_1.0.1")
uart.close(uartID)
pm.sleep("UART_SENT2MCU")
fileHandle:close()
if filePath then os.remove(filePath) end
end
)
else
if filePath then os.remove(filePath) end
end
end
function
local str = ...
local off = '{"method":"thing.service.property.set","id":"","params":{"powerstate":0},"version":"1.0.0"}'
local on = '{"method":"thing.service.property.set","id":"","params":{"powerstate":1},"version":"1.0.0"}'
res,res1,res2 = json.decode(str)
if res["params"]["powerstate"] == 0 then
local led = pins.setup(pio.P0_8,0)
led(0)
return off, 1
elseif res["params"]["powerstate"] == 1 then
local led = pins.setup(pio.P0_8,1)
led(1)
return on, 1
else
return str,1
end
end
```
## 九 实物演示(APP控制和天猫精灵语音控制)