一、实验目的及要求
实现掌控板抢答器功能。
二、实验原理与内容
基于TinywebDB实现云数据库出题
基于掌控板实现按键抢答和判题
基于MQTT实现多端同步通讯
三、实验软硬件环境
硬件:掌控板
软件:Mind+
四、主要平台使用
1. Easy IoT平台
EasyIoT是一个比较简单的物联网管理平台,我们使用它来进行MQTT消息通讯。因为我们之前使用过了,也比较熟悉它的具体使用步骤了,所以此处不再详细介绍它使用。
在后面的配置MQTT参数时,我们主要使用这里的用户名、密码和其中的一个Topic即可。点击此处进去Easy IoT平台
http://iot.dfrobot.com.cn/workshop.html
2. TinyWebDB数据库
TinyWebDB服务器是网络微数据库,开源免费的,我们使用它来存储我们的数据,然后我们再从这个数据库获取数据。
我们首先注册新账号,也可以使用公共账户(账号、密码均为share)进行登录。请点击此处进行登录或注册http://tinywebdb.appinventor.space/
登录进去后我们后面的操作主要用到这里的API地址、用户名和密钥。
我们点击"数据浏览",然后会进入到数据浏览的页面。在这里我们可以查询、添加和修改标签。
这是此实验中使用到需要进行抢答的题目,系统会随机从数据库中获取题目的。
五、实现逻辑
1. 出题
出题者启动程序成功后,确保WiFi、MQTT和数据库连接成功的情况下,首先按下A键通过MQTT的topic1发送可以抢答的通知消息给多个抢答方,然后在按下B键通过MQTT的topic2发送从数据库中随机读取到的题目给多个抢答方。后面出题方会一直在监听此题目抢答成功的结果,第一个抢答的人的姓名(抢答成功者)会显示在出题方的掌控板屏幕上。
2. 抢答
抢答方启动程序成功后,确保WiFi、MQTT的情况下,会接收到出题方发送的可以抢答的通知消息,看到抢答的题目后,然后按下B键进行抢答,第一个抢答的人的姓名(抢答成功者)会通过MQTT的topic3被发送到出题方那里,出题方就会看到此题目抢答成功者的姓名。
3. 判断
当抢答成功者抢答成功后,接着就可以按下A键通过MQTT发送此题的答案给出题方,出题方从数据库中读取此题的真正的答案来和抢答成功者的答案进行比较看抢答者是的回答正确,出题方最后会把抢答者的答题结果(错误/正确)发送给抢答成功者的掌控板的屏幕上。
六、实验过程
1. 出题方的实现
连接热点
MQTT连接
TinyWebDB数据库连接
从数据库中读题目
MQTT发送题目
接收并显示抢答成功者
完整的图形化编程
2. 抢答方的实现
连接热点
MQTT连接
接收到抢答的通知
接收到抢答的题目
开始抢答题目
完整的图形化编程
3. 时间显示的实现
七、实验代码
1. 出题方的代码
/*!
* MindPlus
* mpython
*
*/
#include <MPython.h>
#include <DFRobot_Iot.h>
#include <mPython_tinywebdb.h>
// 动态变量
String mind_s_QiangDaXinXi, mind_s_WenTi;
volatile float mind_n_KaiShiJiShi, mind_n_XiTongJiShi, mind_n_JingDu, mind_n_Miao,
mind_n_Fen, mind_n_YaoYiYao, mind_n_XianZhi, mind_n_JiShiZhuangTai;
// 函数声明
void DF_XianShiShiJian();
void obloqMqttEventT2(String& message);
// 静态常量
const String topics[5] = {"c3PBcmFMR","hZYvpiFGR","MzFOpiFMR","",""};
const MsgHandleCb msgHandles[5] = {NULL,NULL,obloqMqttEventT2,NULL,NULL};
// 创建对象
DFRobot_Iot myIot;
mPython_TinyWebDB mydb;
// 主程序开始
void setup() {
mPython.begin();
dfrobotRandomSeed();
myIot.setMqttCallback(msgHandles);
myIot.wifiConnect("MEIZU 16th", "66666666");
while (!myIot.wifiStatus()) {yield();}
display.setCursorLine(1);
display.printLine("Wi-Fi连接成功");
myIot.init("iot.dfrobot.com.cn","Z0h15mFMg","","WA2JcmKMgz",topics,1883);
myIot.connect();
while (!myIot.connected()) {yield();}
display.setCursorLine(1);
display.printLine("MQTT连接成功");
mydb.setServerParameter("http://tinywebdb.appinventor.space/api", "ktmzl","9c06bd73");
mind_n_YaoYiYao = 0;
mind_n_XianZhi = 0;
mind_s_QiangDaXinXi = mydb.getTag("0");
mind_s_WenTi = mydb.getTag((String((random(3, 8+1)))));
display.setCursor(84, 13);
display.print("00");
display.setCursor(36, 13);
display.print(":");
display.setCursor(52, 13);
display.print("00");
display.setCursor(68, 13);
display.print(". ");
display.setCursor(20, 13);
display.print("00");
mind_n_JiShiZhuangTai = 1;
mind_n_XianZhi = 0;
}
void loop() {
if ((buttonA.isPressed())) {
display.setCursorLine(3);
display.printLine(mind_s_WenTi);
mind_n_YaoYiYao = 1;
mind_n_KaiShiJiShi = millis();
display.setCursor(36, 13);
display.print(":");
display.setCursor(68, 13);
display.print(". ");
while (!(mind_n_JiShiZhuangTai==0)) {
if ((buttonB.isPressed())) {
myIot.publish(topic_0, mind_s_QiangDaXinXi);
myIot.publish(topic_1, mind_s_WenTi);
}
DF_XianShiShiJian();
yield();
}
}
}
// 自定义函数
void DF_XianShiShiJian() {
display.setCursor(84, 13);
display.print(" ");
display.setCursor(52, 13);
display.print(" ");
display.setCursor(20, 13);
display.print(" ");
mind_n_XiTongJiShi = (millis() - mind_n_KaiShiJiShi);
mind_n_JingDu = (((int)(mind_n_XiTongJiShi / 10)) % ((int)100));
if ((mind_n_JingDu<10)) {
display.setCursor(84, 13);
display.print((String("0") + String((((int)mind_n_JingDu) % ((int)100)))));
}
else {
display.setCursor(84, 13);
display.print(mind_n_JingDu);
}
mind_n_XiTongJiShi = ((millis() - mind_n_KaiShiJiShi) / 1000);
mind_n_Miao = (((int)mind_n_XiTongJiShi) % ((int)60));
if ((mind_n_Miao<10)) {
display.setCursor(52, 13);
display.print((String("0") + String((((int)mind_n_Miao) % ((int)100)))));
}
else {
display.setCursor(52, 13);
display.print(mind_n_Miao);
}
mind_n_Fen = (((int)(mind_n_XiTongJiShi / 60)) % ((int)60));
if ((mind_n_Fen<10)) {
display.setCursor(20, 13);
display.print((String("0") + String((((int)mind_n_Fen) % ((int)100)))));
}
else {
display.setCursor(20, 13);
display.print(mind_n_Fen);
}
}
// 事件回调函数
void obloqMqttEventT2(String& message) {
if ((mind_n_XianZhi==0)) {
mind_n_JiShiZhuangTai = 0;
delay(2000);
display.setCursorLine(4);
display.printLine((String(message) + String("抢答成功!")));
mind_n_XianZhi = 1;
}
}
2. 抢答方的代码
/*!
* MindPlus
* mpython
*
*/
#include <MPython.h>
#include <DFRobot_Iot.h>
#include <mPython_tinywebdb.h>
// 动态变量
volatile float mind_n_KeYiQiangDa;
// 函数声明
void obloqMqttEventT0(String& message);
void obloqMqttEventT1(String& message);
void onButtonBPressed();
// 静态常量
const String topics[5] = {"c3PBcmFMR","hZYvpiFGR","MzFOpiFMR","",""};
const MsgHandleCb msgHandles[5] = {obloqMqttEventT0,obloqMqttEventT1,NULL,NULL,NULL};
// 创建对象
DFRobot_Iot myIot;
mPython_TinyWebDB mydb;
// 主程序开始
void setup() {
mPython.begin();
myIot.setMqttCallback(msgHandles);
buttonB.setPressedCallback(onButtonBPressed);
myIot.wifiConnect("MEIZU 16th", "66666666");
while (!myIot.wifiStatus()) {yield();}
display.setCursorLine(1);
display.printLine("WIFI连接成功");
myIot.init("iot.dfrobot.com.cn","Z0h15mFMg","","WA2JcmKMgz",topics,1883);
myIot.connect();
while (!myIot.connected()) {yield();}
display.setCursorLine(2);
display.printLine("MQTT连接成功");
mydb.setServerParameter("http://tinywebdb.appinventor.space/api", "ktmzl","ktmzl");
}
void loop() {
}
// 事件回调函数
void obloqMqttEventT0(String& message) {
display.fillScreen(0);
display.setCursorLine(1);
display.printLine(message);
if ((message==String("你可以开始抢答问题了"))) {
display.setCursorLine(2);
display.printLine("抢答开始!");
mind_n_KeYiQiangDa = 1;
}
}
void obloqMqttEventT1(String& message) {
display.setCursorLine(3);
display.printLine(message);
}
void onButtonBPressed() {
if ((1==mind_n_KeYiQiangDa)) {
myIot.publish(topic_2, "马振乐");
}
}
八、实验结果
1. 出题方的结果截图
第一次发送题目显示
第一次抢答成功的结果显示
第二次发送题目显示
第二次抢答成功的结果显示
2. 抢题方的结果截图
两次抢答方的抢答显示
3. Easy IoT接收消息截图
九、实验总结
通过这个实验,我实现了掌控板抢答器功能,懂得了它的实现原理。完成了此实验后,我既掌握了一些新的知识,也巩固了以前学过的知识技术。在实验中,我们使用到了Easy IoT和TinyWebDB数据库等操作,这些都是我们之前使用过的技术,巩固了对这些知识的掌握。此外,我们还实现了时间显示的操作,学会了如何通过Mind+编程处理复杂的时间来实现计时。在此实验中,还需要注意的是多个抢题方的MQTT初始化参数和服务器参数的设置要与出题方保持一致,这样才能实现相互通讯和操作同一个数据库。通过此实验,我掌握了更多的物联网知识和相关技术。