Mind+积木编程控制小水泵给宠物喂水

这篇具有很好参考价值的文章主要介绍了Mind+积木编程控制小水泵给宠物喂水。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

          前期用scratch,带着小朋友做了大鱼吃小鱼、桌面弹球、小学生计算器3个作品,小朋友收获不小。关键是小家伙感兴趣,做出来后给家人炫耀了一圈后,兴趣大增,嚷嚷着要做更好玩的。

         最近,娃妈从抖音上买了个小猫喝水的容器,一通电,水龙头就自动出水,猫咪就跑过来了。小朋友又发现了新大陆,摆弄起了开关,逗着猫咪。看到这,我心想这玩意能搞成自动化,跟scratch结合起来,正好又卡着小朋友的兴趣点,连玩带学,一箭双雕。

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

以上为背景。


因为上学的时候折腾过单片机,初步判定这个功能用单片机控制肯定是可行的,大概搜了下scratch这类少儿编程软件也支持单片机,所以整体方案可行,初步制定了功能如下:

  • 基础功能:图形化编程,用积木控制,角色可以是小猫,运动来触发单片机
  • 增强功能:如果孩子感兴趣,继续增加灯光控制,与水龙头联动
  • 增强功能:如果孩子感兴趣,继续增加光电控制,用红外线或者声音触发水龙头开关

功能定义清楚后,然后就是寻找资料,分析技术可行性:

编程软件选型

上文提及了,孩子之前用的是Scratch,因为一些原因,Scratch在国内逐步被替换,可选的有如下:

  • Kittenblock
  • ClipCC
  • Mind+
  • PictoBlox

大概看了下,功能都差不多,基本与Scratch旗鼓相当,因为要连单片机,我主要关注扩展性,就选了Mind+,其实Kittenblock也差不多,先入为主就选了Mind+

官方网站:Mind+官网传送门

选择Mind+的另一个原因是,Mind+的开发者网站有大量电子积木的教程,与我的诉求匹配,无脑选了它了,

开发者网站:https://mindplus.dfrobot.com.cn/

扩展库选型

之所以要讨论这个,主要原因看Mind+教程,如果要控制单片机,无非就是usb口转串口,那么不得不用有线的方式连接单片机和控制设备。目前给小朋友编程用的是华为的平板,如果再连个usb线,恐怕小朋友会丧失玩下去的乐趣,所以要考虑无线连接,硬件方面(下个章节讨论)应该没问题,软件层面要支持无线连接的,从Mind+网站上看可以有python和nodejs两种,对应python和js两种语言,小朋友还没上小学,代码编程自然是不考虑的,所以要把上述两种语言“封装”到积木中,把涉及TCP数据包收发的逻辑的嵌入到积木中。显然js和python都可以胜任TCP收发任务。

在Mind+中,python扩展是包含在“Python”模式中的,每个积木对应着一段python代码,通过搭积木的方式组织代码。对于学龄前小朋友,这个可视化功能还是有点太深奥了,暂不考虑。另外,Python模式下,角色功能也不可用(猜测是python模式更偏代码逻辑,弱化了角色),而我家小朋友还处于启蒙阶段,没有了角色,兴趣也会大大减弱。

在Mind+中,nodejs扩展是集成到“实时”模式中的,实时模式就是普通的模式,包含了场景和角色,和我的诉求很贴合。从官方的说明,nodejs类里面可以扩展实时模式用户库,库里面可以构造一个或者多个block,可以自定义block的外观,以及自定义block的运行逻辑。

Mind+从V1.6.5开始开放 实时模式用户库,内部兼容 Scratch扩展语法,,本文档将介绍如何开发Mind+实时模式用户库,阅读此文档需要你掌握 JavaScript的基础知识以及了解一些ES6的新特性。
如果你在阅读过程中产生疑惑, 请加入官方交流群(671877416)。
在开发之前, 你需要知道 能做出什么东西.
添加不依赖硬件的模块 可以很方便的使用第三方JS库
为mind+中已有的主板/套件增加硬件小模块
添加自己的硬件套件并通信

从上述官方教程引用看,实时模式用户库完全符合我的诉求,就选它了。

硬件选型

因为喝水的容器已经小水泵已经有了,如下图:

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

那么剩下的就是买单片机、电机驱动板、LED灯,以及必要的连接线了,Mind+官方支持Arduino,ESP32,ESP8266,这些都是市面上很常见的,

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

从节约成本的角度,就选ESP32了,其他的随便买。

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

元件列表


以下开始教程:


硬件连接

马云家买的元件,购买链接怎么连硬件基本说的很清楚了,需要注意的就是注意电压及正负极,别烧板子了。

如下 图:

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

ESP32固件:

基于Arduino的示例代码,简单改下即可,注释不多,凑合看,不复杂。

定义了3个gpio口

5 --输出口,连电机驱动板,用于控制小水泵的启动/停止

17 --输出口,直接连一个小LED灯

16 --输入口,连红外传感器,用于控制电机的启动/停止

代码运行逻辑为:水泵受两个管脚的控制,一个是来自上位机(Mind+)的指令,一个是红外传感器,红外传感器的优先级高于上位机指令,实现的效果就是小猫靠近,水龙头打开;小猫离开,水龙头由上位机控制。

/*
 WiFi Web Server LED/Motor Control

 */

#include <WiFi.h>

const char* ssid     = "xxxxx";
const char* password = "xxxxx";
const int MOTOR = 5;
const int LIGHT = 17;
const int NEAR = 16;

WiFiServer server(80);

void setup()
{
    Serial.begin(115200);
    pinMode(MOTOR, OUTPUT); 
    pinMode(LIGHT, OUTPUT); 
    pinMode(NEAR, INPUT); 
    
    delay(10);

    // We start by connecting to a WiFi network

    Serial.println();
    Serial.println();
    Serial.print("Connecting to ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected.");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    
    server.begin();

}

int lastValue = LOW;

void loop(){

 int state = digitalRead(NEAR);
 
 
 if (state != lastValue ) {
  lastValue = state;
  if (state == HIGH){
    Serial.println("receive near signal: HIGH");
    digitalWrite(MOTOR, HIGH);
    return;
   } else {
    Serial.println("receive near signal: LOW");
    digitalWrite(MOTOR, LOW);
   }
 }

 sleep(1);
 WiFiClient client = server.available();   // listen for incoming clients
 Serial.println("server created, wating ...");  
 
  if (client) {                             // if you get a client,
    Serial.println("New Client.");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        //Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          if (currentLine.startsWith("motoron")) {
            digitalWrite(MOTOR, HIGH);               // GET /H turns the LED on
          }
          if (currentLine.startsWith("motoroff")) {
            digitalWrite(MOTOR, LOW);                // GET /L turns the LED off
          }

          if (currentLine.startsWith("lightoff")) {
            digitalWrite(LIGHT, LOW);                // GET /L turns the LED off
          }

          if (currentLine.startsWith("lighton")) {
            digitalWrite(LIGHT, HIGH);                // GET /L turns the LED off
          }
          
          Serial.println("receive msg:" + currentLine);  
          currentLine = "";
          break;
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
  }
}

代码写完后,上传到ESP32中(教程很多,不展开说明了),可以通过网络调试助手这类工具,发送“motoron”等指令,确保ESP工作正常。

Nodejs Block定义

Nodejs中定义两个Block,分别控制LED灯和水泵的开关,并且定义两个控制函数(motor和light),分别控制LED和水泵的运行逻辑,不复杂,直接上代码了。

import ArgumentType from './extension-support/argument-type';
import BlockType from './extension-support/block-type';
import blockIconURI from './image/icon.svg';

class YourExtension{
    constructor(runtime) {
        this.runtime = runtime;
    }

    getInfo () {
        const operator_values = [["打开","1"],["关闭","0"]];
        return {
            name: '小猫喝水',
            blockIconURI: blockIconURI,
            blocks: [
                {  
                    opcode: 'motor',
                    blockType: BlockType.COMMAND,
                    text: ' [OPERATOR] 小猫喝水的龙头 ',
                    arguments: {
                        OPERATOR: {
                            type: ArgumentType.STRING,
                            onlyField: true,
                            options: operator_values,
                            defaultValue: operator_values[1][1]
                        }
                    }
                },
                {  
                    opcode: 'light',
                    blockType: BlockType.COMMAND,
                    text: ' [OPERATOR] 水龙头的灯泡 ',
                    arguments: {
                        OPERATOR: {
                            type: ArgumentType.STRING,
                            onlyField: true,
                            options: operator_values,
                            defaultValue: operator_values[1][1]
                        }
                    }
                },
            ],
        }
    }
    // block运行函数, 与opcode同名
    motor (args) {
        // NUM1与NUM2参数都是'ArgumentType.STRING'类型, 所以要parseInt解析成number
        var msg = '';
        switch (args.OPERATOR){
            case "1":
                msg = "motoron\n";
                break;
            case "0":
                msg = "motoroff\n";
                break;
            default:
                msg = "motoroff\n";
                break;
        }
        const net = require("net");
        const HOST = "192.168.5.130";
        const PORT = 80;

        const client = new net.Socket();


        client.connect(PORT, HOST, function() {
            //客户端向服务端socket发送数据
             client.write(msg);
            });
    }

    light (args) {
        // NUM1与NUM2参数都是'ArgumentType.STRING'类型, 所以要parseInt解析成number
        var msg = '';
        switch (args.OPERATOR){
            case "1":
                msg = "lighton\n";
                break;
            case "0":
                msg = "lightoff\n";
                break;
            default:
                msg = "lightoff\n";
                break;
        }
        const net = require("net");
        const HOST = "192.168.5.130";
        const PORT = 80;

        const client = new net.Socket();


        client.connect(PORT, HOST, function() {
            //客户端向服务端socket发送数据
             client.write(msg);
            });
    }
}
module.exports = YourExtension;

其中:

const HOST="192.168.5.130";要改成ESP在局域网下的真实IP地址,可以通过ESP上电后控制台打印的log查看。

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

ESP log

在代码目录下执行npm run build,确保编译成功

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

npm build

Mind+操作步骤

在上述nodejs编译成功后,在Mind+中添加用户库,具体教程参考,也不展开讲了。

https://mindplus.dfrobot.com.cn/ext-js

注意,官方教程有个坑,nodejs的版本不能用最新的,建议用14.16.0版本,配套的Mind+版本是1.7.3,笔者用这两个版本配合没有问题,用最新的nodejs就出怪异问题。

按官方教程操作,编译,添加扩展后,最终,在Mind+实时模式下,可以看到如下两个用户自定义Block

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

写了两份示例代码,当然,这个大家就可以发挥想象力了,没有固定的模板。

案例一:用空格键切换水泵的开启/关闭状态

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

案例2:用角色移动,控制水泵的开启/关闭

Mind+积木编程控制小水泵给宠物喂水,scratch,mind+,esp32,nodejs

硬件也简单整理下,看上去像是一个具有实用价值的工具兼玩具。

运行效果视频

积木运行效果

教程结束,enjoy!文章来源地址https://www.toymoban.com/news/detail-602876.html

到了这里,关于Mind+积木编程控制小水泵给宠物喂水的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 最新Ai创作源码ChatGPT商用运营源码/支持GPT4.0+支持ai绘画+支持Mind思维导图生成

    本系统使用Nestjs和Vue3框架技术,持续集成AI能力到本系统! 支持GPT3模型、GPT4模型 Midjourney专业绘画(全自定义调参)、Midjourney以图生图、Dall-E2绘画 Mind思维导图生成 应用工作台(Prompt) AI绘画广场 自定义聚合套餐 风控系统(接入百度API敏感词、自定义敏感词) 其他等等功

    2024年02月15日
    浏览(72)
  • 2023最新ChatGPT商用源码+支持ai绘画(Midjourney)+GPT4.0+Dall-E2绘画+支持Mind思维导图生成

    目录 1.系统演示 1.1 GPT模型提问 1.3 Midjourney专业绘画 1.4 mind思维导图 1.5 AI绘画广场 2.SparkAi商用系统介绍 2.1前台演示站点 2.2 SparkAi源码下载 2.3 源码部署教程 3.开始搭建 3.1基础env环境配置 4.环境安装 4.1 Node版本 4.2 安装pnpm模块 4.3 安装Redis 5.部署跑起来 5.1 新建站点 5.2 配置

    2024年02月15日
    浏览(53)
  • 2023最新ChatGPT商业运营版网站源码+支持ChatGPT4.0+GPT联网+支持ai绘画(Midjourney)+支持Mind思维导图生成

    使用Nestjs和Vue3框架技术,持续集成AI能力到系统! 同步mj图片重新生成指令 同步 Vary 指令 单张图片对比加强 Vary(Strong) | Vary(Subtle) 同步 Zoom 指令 单张图片无限缩放 Zoom out 2x | Zoom out 1.5x 新增GPT联网提问功能、签到功能 系统用户端页面 ​ ​ ​ 系统演示 源码 以下教程使用

    2024年02月15日
    浏览(50)
  • 基于单片机设计的智能水泵控制器

    在一些场景中,如水池、水箱等水体容器的管理中,保持水位的稳定是至关重要的。传统上,人们通常需要手动监测水位并进行水泵的启停控制,这种方式不仅效率低下,还可能导致水位过高或过低,从而对水体及相关设备造成损坏。 为了解决这个问题,设计了一个基于单片

    2024年04月11日
    浏览(49)
  • scratch 鼠标控制角色移动

    scratch 鼠标控制角色 本程序使用鼠标操作“机器人”角色跟随鼠标,距离较小时暂停移动;“小狗”角色连续在随机位置生成、水平移动、碰到边缘反弹、碰到“机器人”角色时删除。 目前scratch程序的制作已经告一段落了,进一步开发需要更多规划。本人整体感受是scratch程

    2024年02月12日
    浏览(33)
  • Scratch编程入门-画图模块3【鼠标的画笔之旅】

    上一节课带领大家制作了小的案例使用键盘上的方向键自由的控制画笔。   记不清的朋友可以点击下方链接回顾一下上一节课的内容。 Scratch编程入门-画图模块键盘控制的画笔 这一节课的内容和上一节课的内容比较接近, 上一节课我们需要使用键盘控制画笔,这一次我们需

    2024年02月12日
    浏览(35)
  • 竞赛无人机搭积木式编程(三)---用户自定义航点自动飞行功能(全局定位,指哪打哪)

    竞赛无人机搭积木式编程(三)---用户自定义航点自动飞行功能(全局定位,指哪打哪) 无名小哥 2023年6月10日 用户通过对前面两讲中全国大学生电子设计竞赛真题植保无人机(2021)、送货无人机(2022)完整方案的学习。细心一点的客户可以发现:在激光雷达SLAM/T265双目相

    2024年02月12日
    浏览(43)
  • 蓝桥杯、编程考级、NOC、全国青少年信息素养大赛—scratch列表考点

    1.准备工作 (1)选择背景 Colorful City; (2)保留角色小猫,选择角色Ballerina。 2.功能实现 (1)角色小猫初始位置在舞台左下方,角色Ballerina初始位置在舞台右下方,如下图所示; (2)点击小猫,小猫询问\\\"请输入一段英文\\\",输入的英文只包含大写字母、空格和标点符号;

    2024年01月21日
    浏览(64)
  • 竞赛无人机搭积木式编程(四)---2023年TI电赛G题空地协同智能消防系统(无人机部分)

    无名小哥 2023年9月15日 赛题分析与解题思路综述         飞控用户在学习了TI电赛往届真题开源方案以及用户自定义航点自动飞行功能方案讲解后,能基于二次开发模式中已有的飞行控制API函数,即自动飞行支持函数和导航控制函数去实现特定赛题飞行动作、轨迹、航点等

    2024年02月08日
    浏览(43)
  • 小行助学答题系统编程等级考试scratch三级真题2023年3月(含题库答题软件账号)

    青少年编程等级考试scratch真题答题考试系统请点击 电子学会-全国青少年编程等级考试真题Scratch一级(2019年3月)在线答题_程序猿下山的博客-CSDN博客_小航答题助手 1. 计算“2+4+8+……+128”,用变量n表示每项,根据变化规律,变量n的赋值用下列哪个最合适?( ) A. B. C.

    2023年04月19日
    浏览(67)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包