Gravity: UART OBLOQ - IoT物联网模块

简介

物联网是将嵌入式系统技术、移动技术、网页技术全都融合在一起的,其发展的灵魂是以用户体验为核心,特点是与硬件、网络、平台、服务等完全不同的产业领域的相关者直接合作或者融合。 随着物联网的发展,其热度不断增加,目前国内外已有多个成熟物联网平台,但绝大部分物联网平台都是面向专业开发人员,操作复杂,上手困难。为此我们推出了OBLOQ物联网模块,搭配DFRobot自有的物联网平台,大大降低了物联网的使用门槛。 OBLOQ是一款基于ESP8266设计的串口转WIFI物联网模块,用以接收和发送物联网信息。尺寸紧凑,价格低,接口简单,即插即用,适用于3.3V~5V的控制系统。软件编程简单,无需复杂的基础知识,就能迅速搭建出一套物联网应用。 板载固件升级开关,可方便的进行固件的升级。

技术规格

引脚说明

引脚定义

标号 名称 功能描述
1 TX 串口发送端
2 RX 串口接收端
3 GND
4 VCC 电源

EASY IOT教程

OBLOQ模块具备的两个基础功能:发送数据到物联网和接收物联网数据。下面通过实验演示这两个功能:

扩展程序,可实现更强大的功能,如:监听多个设备(一个OBLOQ最多监听5个物联网设备),发送多个传感器数据,远程控制继电器,小灯,风扇等等设备。

准备工作

进入工作间

点击+号

修改设备名

成功创建设备Button

OBLOQ模块的TX,RX,GND和VIN引脚分别连接到Arduino UNO的D10,D11,GND和VCC引脚,温度传感器LM35连接到A0引脚。可通过修改程序来自定义相关引脚,此次测试硬件连接参考下图: 发射和接收(无扩展板)

Mind+(基于Scratch3.0)图形化编程

1、下载及安装软件。下载地址:https://www.mindplus.cc 详细教程:Mind+基础wiki教程-软件下载安装

2、切换到“上传模式”。 详细教程:Mind+基础wiki教程-上传模式编程流程

3、“扩展”中选择“主控板”中的“Arduino Uno” ,扩展小模块选择“通信模块”中的“OBLOQ物联网模块”。 详细教程:Mind+基础wiki教程-加载扩展库流程

4、进行编程,程序如下图:

5、菜单“连接设备”,“上传到设备”

注意: 1、需点击"OBLOQ初始化"上的齿轮图标设置wifi和easyiot网站参数。

2、绿色引脚只能选择2或者3号引脚。

3、上传完毕点击软件右下方小黑窗(串口监视器),点击打开串口,即可查看从网页上发送的数据。

4、可以使用小程序查看数据了,微信小程序中搜索“easyiot”即可。

Easy IoT Arduino IDE教程

点击查看教程

Azure IOT教程

OBLOQ模块具备的两个基础功能:发送数据到物联网和接收物联网数据。下面通过实验演示向Azure IOT设备发送数据的功能,更多样例见附件:

准备工作

OBLOQ模块的TX,RX,GND和VIN引脚分别连接到Arduino UNO的D10,D11,GND和VCC引脚,温度传感器LM35连接到A0引脚。可通过修改程序来自定义相关引脚,此次测试硬件连接参考下图:

发射和接收(无扩展板))

发送传感器数据

实现功能:Arduino读取温度传感器LM35数据,通过OBLOQ模块发送温度数据到Azure IOT设备。修改代码中以下信息,然后烧录代码到Arduino UNO.

//you need change all these according to your own situations
#define WIFISSID "DFRobot-guest"
#define WIFIPWD  "dfrobot@2017"
//Azure IOT 设备连接字符串,连接不同的设备需要修改这个字符串
const String connectionString = "HostName=dfrobot.azure-devices.cn;DeviceId=temperature;SharedAccessKey=CR5gUclNaT7skX9WP+e6oIB/BnkZnTIEReKBX870SNY=";
#include <Arduino.h>
#include <SoftwareSerial.h>


#define WIFISSID "DFRobot-guest"
#define WIFIPWD  "dfrobot@2017"

//Azure IOT 设备连接字符串,连接不同的设备需要修改这个字符串
const String connectionString = "HostName=dfrobot.azure-devices.cn;DeviceId=temperature;SharedAccessKey=CR5gUclNaT7skX9WP+e6oIB/BnkZnTIEReKBX870SNY=";

const String separator = "|";
bool pingOn = true;
bool createIoTClientSuccess = false;
static unsigned long previoustGetTempTime = 0;
static unsigned long pingInterval = 2000;
static unsigned long sendMessageInterval = 10000;
unsigned long previousPingTime = 0;
String receiveStringIndex[10] = {};
bool wifiConnect = false;
bool wifiAbnormalDisconnect = false;

SoftwareSerial softSerial(10,11);

enum state{
    WAIT,
    PINGOK,
    WIFIOK,
    AZURECONNECT
}obloqState;

/********************************************************************************************
Function    : sendMessage
Description : 串口发送消息
Params      : message 设备连接字符串
Return      : �
********************************************************************************************/
void sendMessage(String message)
{
    softSerial.print(message+"\r");
}

/********************************************************************************************
Function    : ping
Description : 检查串口是否正常通信,串口接收到敲门命令会返回:|1|1|\r
Return      : �
********************************************************************************************/
void ping()
{
    String pingMessage = F("|1|1|");
    sendMessage(pingMessage);
}

/********************************************************************************************
Function    : connectWifi
Description : 连接wifi,连接成功串口返回:|2|3|ip|\r
Params      : ssid  wifi账号
Params      : pwd   wifi密码
Return      : �
********************************************************************************************/
void connectWifi(String ssid,String pwd)
{
    String wifiMessage = "|2|1|" + ssid + "," + pwd + separator;
    sendMessage(wifiMessage);
}

/********************************************************************************************
Function    : createIoTClient
Description : 创建设备凭据,创建成功串口返回:|4|2|1|1|\r
Params      : connecttionString  设备连接字符串
Return      : �
********************************************************************************************/
void createIoTClient(String connecttionString)
{
    String azureConnectMessage = "|4|2|1|" + connecttionString + separator;
    sendMessage(azureConnectMessage);
}

/********************************************************************************************
Function    : subscribeDevice
Description : 监听设备,接收到消息会返回消息内容,
Params      : �
Return      : �
********************************************************************************************/
void subscribeDevice()
{
    String subscribeDeviceMessage = "|4|2|2|";
    sendMessage(subscribeDeviceMessage);
}

/********************************************************************************************
Function    : unsubscribeDevice
Description : 取消对设备的监听,发送成功串口返回:|4|2|6|1|\r
Params      : �
Return      : �
********************************************************************************************/
void unsubscribeDevice()
{
    String unsubscribeDeviceMessage = "|4|2|6|";
    sendMessage(unsubscribeDeviceMessage);
}


/********************************************************************************************
Function    : publish
Description : 发送消息 ,必须先创建设备凭据
Params      : message 发布的消息内容,发送成功串口返回: |4|2|3|1|\r
Return      : �
********************************************************************************************/
void publish(String message)
{
    String publishMessage = "|4|2|3|" + message + separator;
    sendMessage(publishMessage);
}

/********************************************************************************************
Function    : disconnect
Description : 销毁设备凭据: |4|2|4|1|\r
Params      : �
Return      : �
********************************************************************************************/
void distoryIotClient()
{
    String distoryIotClientMessage = "|4|2|4|";
    sendMessage(distoryIotClientMessage);
}

/********************************************************************************************
Function    : recreateIoTClient
Description : 重新穿件设备凭据,创建成功返回: |4|2|1|1|\r
Params      : �
Return      : �
********************************************************************************************/
void recreateIoTClient()
{
    String recreateIoTClientMessage = "|4|2|5|";
    sendMessage(recreateIoTClientMessage);
}

/********************************************************************************************
Function    : splitString
Description : 切割字符串
Params      : data 存储切割后的字符数组
Params      : str  被切割的字符串
Params      : data 切割字符串的标志
Return      : �
********************************************************************************************/
int splitString(String data[],String str,const char* delimiters)
{
  char *s = (char *)(str.c_str());
  int count = 0;
  data[count] = strtok(s, delimiters);
  while(data[count]){
    data[++count] = strtok(NULL, delimiters);
  }
  return count;
}

/********************************************************************************************
Function    : handleUart
Description : 处理串口数据
Params      : �
Return      : �
********************************************************************************************/
void handleUart()
{
    while(softSerial.available() > 0)
    {
        String receivedata = softSerial.readStringUntil('\r');
        const char* obloqMessage = receivedata.c_str();
        if(strcmp(obloqMessage, "|1|1|") == 0)
        {
            Serial.println("Pong");
            pingOn = false;
            obloqState = PINGOK;
        }
        if(strcmp(obloqMessage, "|2|1|") == 0)
        {
            if(wifiConnect)
            {
                wifiConnect = false;
                wifiAbnormalDisconnect = true;
            }
        }
        else if(strstr(obloqMessage, "|2|3|") != 0 && strlen(obloqMessage) != 9)
        {
            Serial.println("Wifi ready");
            wifiConnect = true;
            if(wifiAbnormalDisconnect)
            {
                wifiAbnormalDisconnect = false;
                createIoTClientSuccess = true;
                return;
            }
            obloqState = WIFIOK;
        }
        else if(strcmp(obloqMessage, "|4|2|1|1|") == 0)
        {
            Serial.println("Azure ready");
            obloqState = AZURECONNECT;
        }
    }
}

/********************************************************************************************
Function    : sendPing
Description : 验证串口是否正常通信
Params      : �
Return      : �
********************************************************************************************/
void sendPing()
{
    if(pingOn && millis() - previousPingTime > pingInterval)
    {
        previousPingTime = millis();
        ping();
    }
}

/********************************************************************************************
Function    : execute
Description : 根据不同的状态发送不同的命令
Params      : �
Return      : �
********************************************************************************************/
void execute()
{
    switch(obloqState)
    {
        case PINGOK: connectWifi(WIFISSID,WIFIPWD); obloqState = WAIT; break;
        case WIFIOK: createIoTClient(connectionString);obloqState = WAIT; break;
        case AZURECONNECT : obloqState = WAIT; break;
        default: break;
    }
}

/********************************************************************************************
Function    : getTemp
Description : 获得LM35测得的温度
Params      : �
Return      : �
********************************************************************************************/
float getTemp()
{
    uint16_t val;
    float dat;
    val=analogRead(A0);//Connect LM35 on Analog 0
    dat = (float) val * (5/10.24);
    return dat;
}

/********************************************************************************************
Function    : checkWifiState
Description : 接收消息的回调函数:
Params      : message  接收到的消息字符串
Return      : �
********************************************************************************************/
void checkWifiState()
{
    static unsigned long previousTime = 0;
    if(wifiAbnormalDisconnect && millis() - previousTime > 60000)  //wifi异常断开后一分钟重连一次
    {
        previousTime = millis();
        createIoTClientSuccess = false;
        connectWifi(WIFISSID,WIFIPWD);
    }
}

void setup()
{
    Serial.begin(9600);
    softSerial.begin(9600);
}

void loop()
{
    sendPing();
    execute();
    handleUart();
    checkWifiState();
    //每隔5秒发送一次数据
    if(createIoTClientSuccess && millis() - previoustGetTempTime > 5000)
    {
        previoustGetTempTime = millis();

        //获取温度传感器数据
        float temperature = getTemp();
        publish((String)temperature);
        Serial.println(temperature);
    }
}

结果演示

程序烧录成功后,复位OBLOQ模块,再复位Arduino。当没有连接wifi的时候,OBLOQ指示灯显示红色,正在连接wifi时显示蓝色,连接到wifi后,OBLOQ指示灯显示绿色。 打开Arduino串口,观察上传到Azure IOT设备的数据,打开Device Explorer工具,监听发送消息的设备查看温度数据。

串口数据 DeviceExplorer监听数据

拓展

OBLOQ除了能连接标志的MQTT协议的物联网,还能连接Microsoft Azure IOT,更多样例代码可参考附件

常见问题

Q 1. 如何上传多个传感器数据?

A:

Q 2. 如何监听多个传感器设备?

A: 监听设备需要时间,所以在前一个设备监听成功的情况下再去监听另外一个设备,以此内推,具体代码可参考附件,

Q 3. OBLOQ指示灯一直显示蓝色?

A: 表示OBLOQ正在连接wifi,需要一定时间,如果超过一分钟依然显示蓝灯,则可能为wifi账号密码设置错误,请检查程序

Q 4. OBLOQ指示灯一直显示紫色?

A: 表示OBLOQ的wifi连接成功但是mqtt异常断开,尝试检查所在wifi是否断网,也有可能easyiot服务器问题,等待一会儿再连接或联系论坛管理员。如果使用的是siot,则检查obloq与siot服务器所在的电脑是否在一个wifi下,同时用另外一台手机访问siot网页,如果不能访问则说明被防火墙拦截了,需要关闭防火墙,允许siot通过网络,点击查看: siot常见问题

Q 5. OBLOQ指示灯一直显示红色?

A: 表示OBLOQ的wifi连接不成功,尝试检查是否tx和rx接反了(调换一下tx和rx接线顺序),或者是wifi有问题(使用手机开热点,不要用中文WIFI名称),然后就是参数有没有填错(物联网网站里面的参数)。

附件

DFshopping_car1.png DFRobot商城购买链接