天貓精靈(TmallGenie)+ESP32+巴法雲, 實現語音家電控制!
Tmall Genie + ESP32 + Bemfa Cloud, accomplish voice control of home appliances!
Architectures:
Fundamental:
Reference https://en.wikipedia.org/wiki/Tmall_Genie
天貓精靈是阿里巴巴人工智慧實驗室研發的智慧語音助理音箱,基於AliGenie,具有娛樂、生活、購物等多個領域的數百個功能,類似於Amazon Echo、Google Home、Apple HomePod。 天貓精靈於2017年7月5日發布,2017年8月8日正式開賣。
基本參數
產品類型 智慧音箱
揚聲器 內建4Ω揚聲器
輸出功率 3W
麥克風 支持,2個
產品功能 語音辨識控制功能,自訂喚醒詞,通話
無線 WiFi 2.4GB,藍牙4.2
其它參數
處理器 MTK MT8516
系統:AliGenie語音助理
顏色 紅色,白色
尺寸 134*65*59mm
重量 265g
供電方式 DC 12V/1A
電源性能 100-240V/50Hz
控制方式 按鍵,語音
介面 耳機介面
其它特點 內建功放:TI TAS5751M
支援智慧家庭控制、語音購物、手機儲值、叫外送、音頻音樂播放等功能,尤其是購物方面,只需要說出產品描述,然後透過聲紋驗證身份,就能直接下單
訂行程、備忘提醒、訂鬧鐘、查天氣、找手機、倒數、卡路里查詢、聽新聞、查星座運勢、查價格、查股票等功能
與普普藝術結合,波點酷設計,全屋場景體驗升級,就近換新
支援多台設備採用Multi-Room功能進行連動播放
連線方式 WiFi,藍牙
巴法云 C#/.NET SDK。支持TCP和MQTT协议接入,并提供超级简单的设备操作API。跨平台,支持Linux、Windows、OSX,支持树莓派。
Reference https://github.com/withsalt/BemfaCloud
https://cloud.bemfa.com/user/index.html
註冊你的帳號, 新增你的主題!
Reference the previous article link on blog:
ESP32 Code:
#include <WiFi.h>
#include <WiFiClient.h>
//巴法云服务器地址默认即可
#define TCP_SERVER_ADDR "bemfa.com"
//服务器端口,tcp创客云端口8344
#define TCP_SERVER_PORT "8344"
//********************需要修改的部分*******************//
#define DEFAULT_STASSID "Winson_Y52" //WIFI名称,区分大小写,不要写错
#define DEFAULT_STAPSW "8888888888" //WIFI密码
String UID = "your ID"; //用户私钥,可在控制台获取,修改为自己的UID
String TOPIC = "fan003"; //主题名字,可在控制台新建
String TOPIC1 = "adapter001"; //主题名字,可在控制台新建
String TOPIC2 = "led002"; //主题名字,可在控制台新建
//const int LED_Pin = D2; //单片机引脚
//-----Relay------------------
//-----Relay------------------
#define RELAY1 32
#define RELAY2 33
#define RELAY3 25
#define RELAY4 26
#define RELAY5 5
#define RELAY6 17
#define RELAY7 16
#define RELAY8 4
//**************************************************//
//最大字节数
#define MAX_PACKETSIZE 512
//设置心跳值30s
#define KEEPALIVEATIME 30*1000
//tcp客户端相关初始化,默认即可
WiFiClient TCPclient;
String TcpClient_Buff = "";
unsigned int TcpClient_BuffIndex = 0;
unsigned long TcpClient_preTick = 0;
unsigned long preHeartTick = 0;//心跳
unsigned long preTCPStartTick = 0;//连接
bool preTCPConnected = false;
//相关函数初始化
//连接WIFI
void doWiFiTick();
void startSTA();
//TCP初始化连接
void doTCPClientTick();
void startTCPClient();
void sendtoTCPServer(String p);
//风扇控制函数
void turnOn();
void turnOff();
/*
*发送数据到TCP服务器
*/
void sendtoTCPServer(String p){
if (!TCPclient.connected())
{
Serial.println("Client is not readly");
return;
}
TCPclient.print(p);
Serial.println("[Send to TCPServer]:String");
Serial.println(p);
}
/*
*初始化和服务器建立连接
*/
void startTCPClient(){
if(TCPclient.connect(TCP_SERVER_ADDR, atoi(TCP_SERVER_PORT))){
Serial.print("\nConnected to server:");
Serial.printf("%s:%d\r\n",TCP_SERVER_ADDR,atoi(TCP_SERVER_PORT));
String tcpTemp=""; //初始化字符串
String tcpTemp1=""; //初始化字符串
String tcpTemp2=""; //初始化字符串
tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC+"\r\n"; //构建订阅指令
sendtoTCPServer(tcpTemp); //发送订阅指令
tcpTemp="";//清空
tcpTemp1 = "cmd=1&uid="+UID+"&topic="+TOPIC1+"\r\n"; //构建订阅指令
sendtoTCPServer(tcpTemp1); //发送订阅指令
tcpTemp1="";//清空
tcpTemp2 = "cmd=1&uid="+UID+"&topic="+TOPIC2+"\r\n"; //构建订阅指令
sendtoTCPServer(tcpTemp2); //发送订阅指令
tcpTemp2="";//清空
preTCPConnected = true;
preHeartTick = millis();
TCPclient.setNoDelay(true);
}
else{
Serial.print("Failed connected to server:");
Serial.println(TCP_SERVER_ADDR);
TCPclient.stop();
preTCPConnected = false;
}
preTCPStartTick = millis();
}
/*
*检查数据,发送心跳
*/
void doTCPClientTick(){
//检查是否断开,断开后重连
if(WiFi.status() != WL_CONNECTED) return;
if (!TCPclient.connected()) {//断开重连
if(preTCPConnected == true){
preTCPConnected = false;
preTCPStartTick = millis();
Serial.println();
Serial.println("TCP Client disconnected.");
TCPclient.stop();
}
else if(millis() - preTCPStartTick > 1*1000)//重新连接
startTCPClient();
}
else
{
if (TCPclient.available()) {//收数据
char c =TCPclient.read();
TcpClient_Buff +=c;
TcpClient_BuffIndex++;
TcpClient_preTick = millis();
if(TcpClient_BuffIndex>=MAX_PACKETSIZE - 1){
TcpClient_BuffIndex = MAX_PACKETSIZE-2;
TcpClient_preTick = TcpClient_preTick - 200;
}
preHeartTick = millis();
}
if(millis() - preHeartTick >= KEEPALIVEATIME){//保持心跳
preHeartTick = millis();
Serial.println("--Keep alive:");
sendtoTCPServer("cmd=0&msg=keep\r\n");
}
}
if((TcpClient_Buff.length() >= 1) && (millis() - TcpClient_preTick>=200))
{//data ready
TCPclient.flush();
Serial.println("Buff");
Serial.println(TcpClient_Buff);
if((TcpClient_Buff.indexOf("fan003") > 0))
{
if((TcpClient_Buff.indexOf("&msg=on") > 0))
{
turnOn();
}
else if((TcpClient_Buff.indexOf("&msg=off") > 0))
{
turnOff();
}
}
//-------------------------------------------------------------
if((TcpClient_Buff.indexOf("adapter001") > 0))
{
if((TcpClient_Buff.indexOf("&msg=on") > 0))
{
turnAdapterOn();
}
else if((TcpClient_Buff.indexOf("&msg=off") > 0))
{
turnAdapterOff();
}
}
//-------------------------------------------------------------
if((TcpClient_Buff.indexOf("led002") > 0))
{
if((TcpClient_Buff.indexOf("&msg=on") > 0))
{
turnLedOn();
}
else if((TcpClient_Buff.indexOf("&msg=off") > 0))
{
turnLedOff();
}
}
/**
if((TcpClient_Buff.indexOf("&msg=on") > 0)) {
turnOn();
}else if((TcpClient_Buff.indexOf("&msg=off") > 0)) {
turnOff();
}**/
TcpClient_Buff="";
TcpClient_BuffIndex = 0;
}
}
void startSTA(){
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(DEFAULT_STASSID, DEFAULT_STAPSW);
}
/**************************************************************************
WIFI
***************************************************************************/
/*
WiFiTick
检查是否需要初始化WiFi
检查WiFi是否连接上,若连接成功启动TCP Client
控制指示灯
*/
void doWiFiTick(){
static bool startSTAFlag = false;
static bool taskStarted = false;
static uint32_t lastWiFiCheckTick = 0;
if (!startSTAFlag) {
startSTAFlag = true;
startSTA();
Serial.printf("Heap size:%d\r\n", ESP.getFreeHeap());
}
//未连接1s重连
if ( WiFi.status() != WL_CONNECTED ) {
if (millis() - lastWiFiCheckTick > 1000) {
lastWiFiCheckTick = millis();
}
}
//连接成功建立
else {
if (taskStarted == false) {
taskStarted = true;
Serial.print("\r\nGet IP Address: ");
Serial.println(WiFi.localIP());
startTCPClient();
}
}
}
//打開fan
void turnOn(){
Serial.println("Turn ON");
//digitalWrite(LED_Pin,LOW);
digitalWrite(RELAY1,LOW);
}
//关闭灯泡
void turnOff(){
Serial.println("Turn OFF");
digitalWrite(RELAY1,HIGH);
}
//打开灯泡
void turnAdapterOn(){
Serial.println("Turn1 ON");
//digitalWrite(LED_Pin,LOW);
digitalWrite(RELAY2,LOW);
}
//关闭灯泡
void turnAdapterOff(){
Serial.println("Turn1 OFF");
digitalWrite(RELAY2,HIGH);
}
//打开灯泡
void turnLedOn(){
Serial.println("Turn2 ON");
//digitalWrite(LED_Pin,LOW);
digitalWrite(RELAY3,LOW);
}
//关闭灯泡
void turnLedOff(){
Serial.println("Turn2 OFF");
digitalWrite(RELAY3,HIGH);
}
// 初始化,相当于main 函数
void setup() {
Serial.begin(9600);
pinMode(RELAY1,OUTPUT);
digitalWrite(RELAY1,HIGH);
pinMode(RELAY2,OUTPUT);
digitalWrite(RELAY2,HIGH);
pinMode(RELAY3,OUTPUT);
digitalWrite(RELAY3,HIGH);
pinMode(RELAY4,OUTPUT);
digitalWrite(RELAY4,HIGH);
pinMode(RELAY5,OUTPUT);
digitalWrite(RELAY5,HIGH);
pinMode(RELAY6,OUTPUT);
digitalWrite(RELAY6,HIGH);
pinMode(RELAY7,OUTPUT);
digitalWrite(RELAY7,HIGH);
pinMode(RELAY8,OUTPUT);
digitalWrite(RELAY8,HIGH);
}
//循环
void loop() {
doWiFiTick();
doTCPClientTick();
}
沒有留言:
張貼留言