基于dueros的智能语言家居-Arduino中文社区 - Powered by Discuz! Archiver

芥末秋刀鱼 发表于 2017-10-20 00:53

基于dueros的智能语言家居

本帖最后由 芥末秋刀鱼 于 2017-10-21 01:49 编辑

前言:最近语言控制玩的很火啊,几乎所有的互联网大佬都开始搞自己的智能语言音响,没出音响的也出了相应的平台,可以说语言控制在2017年一下子都冒出来了,那么我们也跟风做个物联网智能语言家居吧!
先说下原理吧,音响主要分为两部分:一是搭载在树莓派上百度的dueros,可以识别中文,进行中文对话,查询天气、放歌等,语言家居是通过识别出中文然后将识别到的命令发送给中移动的ONENET平台; 二是ESP32连wifi然后也接入ONENET接收树莓派上识别出的命令然后控制灯、舵机等。
材料准备:
树莓派
dueros个人开发板
ESP32
LED
舵机
音响
WS2812
onenet平台



树莓派端:
以下很多制作参考小李飞刀刀大神来的,非常感谢其开源精神!!!
将树莓派和duer个人板连接好然后插上带有dueros系统的TF卡:镜像下载地址
下载好镜像后使用Etcher-Portable为TF卡烧录镜像

插上树莓派后用网线连接至路由器,然后扫描IP,通过ssh远程桌面连接树莓派(注意:树莓派3B没开ssh端口,需要在boot目录下新建一个ssh的空白文件,具体百度树莓派SSH连接即可)
连接上ssh后配置wifi:
查看树莓派是否识别到wifi
sudo iwlist wlan0 scannano编辑器配置wifi
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf 进入文件后在末尾添加:
network={      ssid="XXXX"//你的wifi名称和密码    psk="XXXX"}这样就连接到wifi了
然后对着树莓派喊“小度小度”就可以唤醒了,这样dueros就在树莓派上搭载成功了

在树莓派上搭载提取日志代码及连接onenet
首先注册onenet云平台(其他支持mqtt协议的也可以),进入开发者中心

然后选择创建产品

这里只要接入协议为mqtt即可,其他默认的就行

然后进入你创建的产品中然后开始创建设备和数据流

首先添加设备:

名称和鉴权信息自己写,要记住自己的鉴权信息用来接入设备,这里需要创建两个设备,一个ESP32一个树莓派

然后添加数据流模板:

这样onenet平台工作就准备好了,这里你需要记住的有:产品ID、两个设备ID和鉴权信息、数据流名称、还有onenet平台默认的tcp://183.230.40.39:6002即可,这些信息自己对应自己的,然后在代码中改为自己的即可
然后在树莓派上下载mqtt客户端:
在树莓派终端输入下面的命令来下载源码:
git clone https://github.com/eclipse/paho.mqtt.c.git然后安装openssl库
sudo apt-get updatesudo apt-get install libssl-dev这样就安装好了,然后用ls命令可以看到这个目录

进入test文件夹中,使用官方的test代码,因为自己不会写make。。。。
cd paho.mqtt.c/test/然后改其中的一个示例代码
sudo vi test1.c然后把里面的东西全部删除添加自己的代码:(感谢小李飞刀刀大佬的代码,学长用python提取失败了!)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>

#include <unistd.h>
#include <time.h>
#include "MQTTClient.h"

#define ADDRESS "tcp://183.230.40.39:6002"//这里替换成OneNET的,或者百度物接入IoT的(这个数固定的)
#define CLIENTID "你自己的" //clientID在OneNET上是 设备ID
#define TOPIC "你自己的"//主题在OneNET上是 数据流模板里面的数据流名称
//#define PAYLOAD "Hello World!"//这里是我们要测试发送的内容
#define QOS 1
#define TIMEOUT 10000L
volatile MQTTClient_deliveryToken deliveredtoken;

//这两行也弄成全局的吧
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
//这里添加了两行
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;

int sign=0;//暂时定一个标志,代表有指令要发送
char cmd;//1K字符数组来保存要stringcmp后的指令。

char *word={
//两个词一组排好,把左边的替换成右边的,""代表删除左边的词
"给我","",
"把我","",
"的","",
"就","",
"是","",
"麻烦","",
"请您","",
"请你","",
"求你","",
"求您","",
"我们","",
"他们","",
"她们","",
"客人","",
"朋友","",
"闺蜜","",
"主人","",
"你","",
"您","",
"我","",
"把","",
"一个","",
"个","",
"快点","",
"赶快","",
"立即","",
"马上","",
"迅速","",
"火速","",
"打开","开",
"开下","开",
"关掉","关",
"关了","关",
"关上","关",
"关闭","关",
"一下","",
"下","",
"想看","开",
"要看一下","开",
"要看","开",
"马上","",
"现在","",
"一会","",
"儿","",
"会","",
"一点","点",
"点亮","开",
"点","",
"电视放开","电视开",
"放电视","开电视",
"烧热水","开热水器",
"烧洗澡水","开热水器",
"澡澡","澡",
"想洗澡","开热水器",
"要洗澡","开热水器",
"什么","",
"啥都","",
"都","",
"啥","",
"也","",
"啦","",
"看不见","开灯",
"太黑了","开灯",
"太暗了","开灯",
"睡觉","关灯",
"太亮了","关灯",
"了","",
"等一下","",
"等","",
"去","",
"嘛","",
"呗","",
"都","",
"好","",
"吧","",
"吗","",
"啊","",
"可不","",
"可以","",
"可","",
"能不","",
"能","",
"要放电视","开电视",
"不要放电视","关电视",
"不开电视","关电视",
"家里","",
"家庭","",
"用电器","电器",
"电器关","关",
"全部关","关",
"电器","",
"全关","关所有",
"开单","开灯"
};

/*字符串对比*/
int stringcmp(char *a,char *b)
{
    int i=0;
      for(i=0;a!='\0' && b!='\0';i++)
            if(a!=b){
                break;
            }
      if(a==b)
            return 1;
      else
            return 0;
}
/*将str1字符串中第一次出现的str2字符串替换成str3*/
void replaceFirst(char *str1,char *str2,char *str3)
{
    char str4;
    char *p;
    strcpy(str4,str1);
    if((p=strstr(str1,str2))!=NULL)/*p指向str2在str1中第一次出现的位置*/
    {
      while(str1!=p&&str1!=NULL)/*将str1指针移动到p的位置*/
      {
            str1++;
      }
      str1='\0';/*将str1指针指向的值变成/0,以此来截断str1,舍弃str2及以后的内容,只保留str2以前的内容*/
      strcat(str1,str3);/*在str1后拼接上str3,组成新str1*/
      strcat(str1,strstr(str4,str2)+strlen(str2));/*strstr(str4,str2)是指向str2及以后的内容(包括str2),strstr(str4,str2)+strlen(str2)就是将指针向前移动strlen(str2)位,跳过str2*/
    }
}
/*将str1出现的所有的str2都替换为str3*/
void replace(char *str1,char *str2,char *str3)
{
    while(strstr(str1,str2)!=NULL)
    {
      replaceFirst(str1,str2,str3);
    }
}

/*返回str1中最后一次出现str2的位置(下标),不存在返回-1*/
int lastIndexOf(char *str1,char *str2) {
      char *p=str1;
      int i=0,len=strlen(str2);
      p=strstr(str1,str2);
      if(p==NULL) return -1;
      while(p!=NULL) {
                for(;str1!=p;str1++)i++;
                p=p+len;
                p=strstr(p,str2);
      }
      return i;
}

//发送消息时候调用
int publish()
{
pubmsg.payload = cmd;
pubmsg.payloadlen = strlen(cmd);
pubmsg.qos = QOS;
pubmsg.retained = 0;
MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
}

/*对日志抓取和解析指令*/
int Pretreatment()   
{   
FILE *fstream=NULL;
char buff;//定义1K数组来保存获得的日志内容
char result;//定义1000字节组数来保存语音识别结果
int strpoint;
int j=0;
int i=0;
memset(buff,0,sizeof(buff)); //清空数组
memset(result,0,sizeof(result));
//打开一个通向tail的管道
if(NULL==(fstream=popen("tail -f /duer/duer_linux.log","r")))
{
   printf("管道打不开!");
   return 1;
}
while (NULL!=fgets(buff, sizeof(buff), fstream))//这里fgets()是阻塞的
{
    strpoint=lastIndexOf(&buff,"-命中唤醒词");
      if(strpoint!=-1)               
      {
                sprintf(cmd,"%s", "{\"cmd\":\"WakeUP\"}");
                sign=1;
      }
      else
      {
                strpoint=lastIndexOf(&buff,"-识别结果:");
                if(strpoint!=-1)               
                {
                        j=0;
                        //下面这段代码用于实现字符串截取功能,提取语音识别结果
                        for(j=strpoint+14;buff!='\0';j++)result=buff;
                        result='\0';
                        printf("识别结果为:%s\n",result);
                        for(i=0;i<180;i+=2)replace(result,word,word);
                            printf("替换后的结果:%s\n",result);
                        if(stringcmp(result,"开电视") || stringcmp(result,"电视开")) {
                              sprintf(cmd,"%s", "{\"cmd\":\"OpenTV\"}");
                              sign=1;
                        }
                        else if(stringcmp(result,"关电视") || stringcmp(result,"电视关")) {
                              sprintf(cmd,"%s", "{\"cmd\":\"CloseTV\"}");
                              sign=1;
                        }
                        else if(stringcmp(result,"关所有")|| stringcmp(result,"所有关")|| stringcmp(result,"关")) {
                              sprintf(cmd,"%s", "{\"cmd\":\"CloseALL\"}");
                              sign=1;
                        }
                        else if(stringcmp(result,"开热水器")|| stringcmp(result,"热水器开")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"OpenRSQ\"}");
                            sign=1;
                        }
                        else if(stringcmp(result,"关热水器")|| stringcmp(result,"热水器关")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CloseRSQ\"}");
                              sign=1;
                        }
                        else if(stringcmp(result,"开卧室灯")|| stringcmp(result,"卧室灯开")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"OpenWSD\"}");
                              sign=1;
                        }
                        else if(stringcmp(result,"关卧室灯")|| stringcmp(result,"卧室灯关")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CloseWSD\"}");
                         sign=1;
                        }
                        else if(stringcmp(result,"开客厅灯")|| stringcmp(result,"客厅灯开")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"OpenKTD\"}");
                         sign=1;
                        }
                        else if(stringcmp(result,"关客厅灯")|| stringcmp(result,"客厅灯关")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CloseKTD\"}");
                        sign=1;
                        }
                        else if(stringcmp(result,"开餐厅灯")|| stringcmp(result,"餐厅灯开")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"OpenCTD\"}");
                        sign=1;
                        }
                        else if(stringcmp(result,"关餐厅灯")|| stringcmp(result,"餐厅灯关")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CloseCTD\"}");
                        sign=1;
                        }
                        else if(stringcmp(result,"门开")|| stringcmp(result,"开门")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"OpenDOO\"}");
                        sign=1;
                        }
                        else if(stringcmp(result,"门关")|| stringcmp(result,"关门")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CloseDOO\"}");
                        sign=1;
                        }
                        else if(stringcmp(result,"关书房灯")|| stringcmp(result,"书房灯关")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CloseSFD\"}");
                        sign=1;
                        }
                        else if(stringcmp(result,"开书房灯")|| stringcmp(result,"书房灯开")) {
                        sprintf(cmd,"%s", "{\"cmd\":\"OpenSFD\"}");
                        sign=1;
                        }

                        else if(stringcmp(result,"关台灯")|| stringcmp(result,"台灯关")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CloseTD\"}");
                         sign=1;
                        }
                        else if(stringcmp(result,"关灯")|| stringcmp(result,"灯关")|| stringcmp(result,"所有灯关")|| stringcmp(result,"关所有灯")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CloseALL\"}");
                         sign=1;
                        }
                        else if(stringcmp(result,"开灯")|| stringcmp(result,"灯开")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"OpenALL\"}");
                         sign=1;
                        }
                        else if(stringcmp(result,"扫地")|| stringcmp(result,"地扫")) {
                            sprintf(cmd,"%s", "{\"cmd\":\"CleanRM\"}");
                         sign=1;
                        }
                }
      }
      if(sign==1)
      {
                publish();
                sign=0;
      }
}
pclose(fstream);
return 0;
}


int ping()
{
      FILE *fstream=NULL;
      char buff;//定义1K数组来保存获得的日志内容
      memset(buff,0,sizeof(buff)); //清空数组
      int k=0;
      int strpoint;
      //打开一个通向tail的管道
while(k==0)
{
      if(NULL==(fstream=popen("ping www.baidu.com","r")))
         {
   printf("管道打不开!");
   return 0;
         }
      while (NULL!=fgets(buff, sizeof(buff), fstream))//这里fgets()是阻塞的
      {
                printf(buff);
                strpoint=lastIndexOf(&buff," bytes from ");
                if(strpoint!=-1)               
                {
                        k=1;
                        break;
                }
      }
      pclose(fstream);
      if(k==0)
                sleep(6);
}
return 1;
}



//貌似是发送消息后的回调
void delivered(void *context, MQTTClient_deliveryToken dt)
{
//printf("Message with token value %d delivery confirmed\n", dt);
deliveredtoken = dt;
}

//收到消息后的回调
int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
int i;
char* payloadptr;
printf("收到消息!\n");
printf(" 主题为: %s\n", topicName);
printf(" 消息内容: ");
payloadptr = message->payload;
for(i=0; i<message->payloadlen; i++)
{
putchar(*payloadptr++);
}
putchar('\n');
MQTTClient_freeMessage(&message);
MQTTClient_free(topicName);
return 1;
}
//断线后的回调
void connlost(void *context, char *cause)
{
printf("\nConnection lost\n");
printf(" cause: %s\n", cause);
exit(0);//暂时先强退吧,后面有空把断线重连之类的代码写进去
}
int main(int argc, char* argv[])
{
int rc;
int ch;
memset(cmd,0,sizeof(cmd));//清空一下cmd数组
ping();//一直ping 百度官网,ping通了再执行后面的数据。
MQTTClient_create(&client, ADDRESS, CLIENTID,
MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 130;//OneNET的keepalive需要120秒以上
conn_opts.cleansession = 1;
conn_opts.username = "你自己的";//这里添加用户名参数,在OneNET上对应的是 产品ID
conn_opts.password = "你自己的";//这里添加密码参数,在OneNET上对应之前提到过的 鉴权信息
MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(EXIT_FAILURE);
}
printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
"Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
MQTTClient_subscribe(client, TOPIC, QOS);//这里按平常的说法就是 加入QQ群了

while(1)
{
      Pretreatment();//这里去读取识别结果和解析文本
}
MQTTClient_disconnect(client, 10000);
MQTTClient_destroy(&client);
return rc;
}

然后保存退出vi,然后返回到paho.mqtt.c目录下(使用cd ..返回)然后:
sudo make等待make完成,然后进入:
cd build/output/test/里面的test1文件检索make好的文件
然后./test1运行后唤醒小度看有无信息输出,若连接成功会返回这样的,onenet平台也会显示设备正在运行


这样树莓派端就搭建好了!!
ESP32搭建:我这里用的是DFrobot的ESP32,arduino开发,相关资料去DFwiki找即可
需要准备的库文件:
ArduinoJson.h
Adafruit_MQTT.h
ESP32_Servo.h
WiFi.h
Adafruit_NeoPixel.h
然后打开arduino IDE选择ESP32开发板烧入一下代码:
#include <ArduinoJson.h>//JSON库
//mqtt库
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
//舵机
#include <ESP32_Servo.h>
Servo servo1;
//wifi部分
#include <WiFi.h>
#include <WiFiMulti.h>
WiFiMulti wifiMulti;
//唤醒灯WS2812
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

#define PIN            D6

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS      16
// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

//onenet设置
#define AIO_SERVER      "183.230.40.39"//OneNET服务器ip地址(固定的)
#define AIO_SERVERPORT6002 //OneNET服务器端口(没引号!)
#define AIO_USERNAME    "你自己的" //OneNET的产品ID
#define TOPIC         "你自己的"//OneNET上的数据流模板
//电视机
#define AIO_USERID      "你自己的"//OneNET的设备ID(不能和树莓派的一样,另一个的ID)
#define AIO_KEY         "你自己的"//OneNET的鉴权信息


//设置LED 灯
#define LED_PIN D9//WIFI连接灯_板载
#define LIGHT_LIVING D2
#define LIGHT_BEDROOM D3
#define LIGHT_RES D4
#define LIGHT_STUDY D7

//舵机
int servo1Pin = D5;
int minUs = 500;
int maxUs = 2400;
int pos = 0;


WiFiClient client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERID, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/

Adafruit_MQTT_Publish photocell = Adafruit_MQTT_Publish(&mqtt,TOPIC);
// Setup a feed called 'onoff' for subscribing to changes to the button
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt,TOPIC, MQTT_QOS_1);


//收到消息后的回调,控制端指令就在这里接收处理了
void onoffcallback(char *data, uint16_t len) {
   Serial.println(data);
   StaticJsonBuffer<200> jsonBuffer;
   JsonObject& root = jsonBuffer.parseObject(data);
   if (!root.success()){
      Serial.println("parseObject() failed");
      return;
   }
   Stringcmd= root["cmd"];
   Serial.println(cmd.equals(""));
   //这里可以各种if判断cmd变量收到的是什么指令
    if(cmd.equals("WakeUP"))//如果收到唤醒信号就”睁开眼睛“
    {
    for(int i=0;i<NUMPIXELS;i++){

    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255
    pixels.setPixelColor(i, pixels.Color(255,127,0)); // Moderately bright green color.

    pixels.show(); // This sends the updated pixel color to the hardware.

    delay(40); // Delay for a period of time (in milliseconds).

}
    for(int j=0;j<NUMPIXELS;j++){

    pixels.setPixelColor(j, pixels.Color(0,0,0));

    pixels.show();

    delay(40);

}

    }
    //总灯
    if(cmd.equals("OpenALL"))
    {
         digitalWrite(LIGHT_LIVING,HIGH);
         digitalWrite(LIGHT_BEDROOM,HIGH);
         digitalWrite(LIGHT_RES,HIGH);
         digitalWrite(LIGHT_STUDY,HIGH);
    }
    if(cmd.equals("CloseALL"))
    {
         digitalWrite(LIGHT_LIVING,LOW);
         digitalWrite(LIGHT_BEDROOM,LOW);
         digitalWrite(LIGHT_RES,LOW);
         digitalWrite(LIGHT_STUDY,LOW);
    }
    //客厅
    if(cmd.equals("OpenKTD"))
    {
      digitalWrite(LIGHT_LIVING,HIGH);
    }
    if(cmd.equals("CloseKTD"))
    {
      digitalWrite(LIGHT_LIVING,LOW);
    }
    //卧室
    if(cmd.equals("OpenWSD"))
    {
      digitalWrite(LIGHT_BEDROOM,HIGH);
    }
    if(cmd.equals("CloseWSD"))
    {
      digitalWrite(LIGHT_BEDROOM,LOW);
    }
    //餐厅
    if(cmd.equals("OpenCTD"))
    {
      digitalWrite(LIGHT_RES,HIGH);
    }
    if(cmd.equals("CloseCTD"))
    {
      digitalWrite(LIGHT_RES,LOW);
    }
    //书房
    if(cmd.equals("OpenSFD"))
    {
      digitalWrite(LIGHT_STUDY,HIGH);
    }
    if(cmd.equals("CloseSFD"))
    {
      digitalWrite(LIGHT_STUDY,LOW);
    }
    //门
    if(cmd.equals("OpenDOO"))
    {
      servo1.write(180);
    }
    if(cmd.equals("CloseDOO"))
    {
      servo1.write(0);
    }
}


void setup() {
// put your setup code here, to run once:
   Serial.begin(115200);
   delay(10);
   //板载灯
   pinMode(LED_PIN, OUTPUT);
   pinMode(LIGHT_LIVING, OUTPUT);
   pinMode(LIGHT_BEDROOM, OUTPUT);
   pinMode(LIGHT_RES, OUTPUT);
   pinMode(LIGHT_STUDY, OUTPUT);
   //舵机
   servo1.attach(servo1Pin, minUs, maxUs);
   servo1.write(pos);   
   WiFi.begin();
   Serial.println(F("Adafruit MQTT demo"));
   
   //可以添加多组wifi(你的WIFI名称和密码)
   wifiMulti.addAP("dueros", "dueros");
   wifiMulti.addAP("Develop", "ccbfudevelop");
   //连接成功返回IP
   Serial.println("Connecting Wifi...");
    if(wifiMulti.run() == WL_CONNECTED) {
      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
    }

    onoffbutton.setCallback(onoffcallback);
// Setup MQTT subscription for time feed.
    mqtt.subscribe(&onoffbutton);
    // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
// End of trinket special code

pixels.begin(); // This initializes the NeoPixel library.

}
bool sk;
void loop() {
//检查wifi
if(wifiMulti.run() != WL_CONNECTED) {
      Serial.println("WiFi not connected!");
      delay(1000);
    }
   
   if(wifiMulti.run() == WL_CONNECTED) {
   digitalWrite(LED_PIN,HIGH);
    }

   
sk=MQTT_connect();

//等待订阅消息和回调子循环(尽量在这里消耗时间)
mqtt.processPackets(10000);

if(sk)
{
   //ping 服务器来保持mqtt连接活性
   if(! mqtt.ping()) {
       Serial.println("lose mqqt connect!");
       mqtt.disconnect();
   }
}
//发送消息
//if (! photocell.publish("{\"msg\":{\"type\": 1,\"dev_id\":4656519,\"ds_id\":\"controlmyhome\",\"value\":42}}")) {
//Serial.println(F("Failed"));
//} else {
//Serial.println(F("OK!"));
//}
}
// 功能连接和重新连接以MQTT服务器(应该在循环函数中调用,如果连接,它会很小心)
bool MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
    return true;
}
Serial.println("ReConnecting to MQTT... ");
if(mqtt.connect() == 0)
   Serial.println("MQTT Connected!");
else
   return false;
return true;
}

烧录即可
ESP32硬件连接:

连接好之后给ESP32供电即可,ESP32连接到wifi后板载的灯常亮即连接成功,onenet也显示在线,现在就可以语音控制家居了!!!
视频:
http://v.youku.com/v_show/id_XMzA5NjgzNTc2NA

http://v.youku.com/v_show/id_XMzA5Njg0OTAzMg
说明:
这次外观啥的做的有点粗糙,但已经通过语音控制了LED的开关所以你可以换为继电器等来实际控制家里的灯了,还可以控制舵机,意味着可以控制家里需要旋钮的地方,还可以使用红外发射管写好程序后可以控制家里大多用红外控制的家电了,像如电视、空调等。
非常感谢学长和小李飞刀刀大佬!



syl312 发表于 2017-10-20 08:10

占位留言评论~2333

单片机菜鸟 发表于 2017-10-20 09:23

二楼评论~2333

suoma 发表于 2017-10-20 19:33

小鹿小鹿,联网了吗?

ldy2370 发表于 2017-10-20 21:01

这个666如果有教程的话打算做一个

cmy110110 发表于 2017-10-20 23:16

666666666666666666666666666

cmy110110 发表于 2017-10-20 23:16

期待教程

芥末秋刀鱼 发表于 2017-10-21 15:36

syl312 发表于 2017-10-20 08:10
占位留言评论~2333

快给我加鸡腿:lol

芥末秋刀鱼 发表于 2017-10-21 15:36

suoma 发表于 2017-10-20 19:33
小鹿小鹿,联网了吗?

小度小度!!!!!是联网的

芥末秋刀鱼 发表于 2017-10-21 15:37

cmy110110 发表于 2017-10-20 23:16
期待教程

给你!!
页: [1] 2
查看完整版本: 基于dueros的智能语言家居