前言
本章内容是对Mixly 图像化编程软件进行的二次开发,需要一定的编程基础,需要用到的概念和知识点有: 绑定与事件概念, JavaScript的基本语法, .xml脚本的标签定义
限于篇幅,本章内容中笔者不做原理和JS脚本的剖析和讲解! 如参考阅读时困难, 恕笔者精力有限, 暂不不能提供详细内容, 当然,若笔者有空余时间, 自会补充相关原理讲解和脚本内容剖析. 还请各位读者知悉!
简介&软件准备:
-
Mixly0.998
-
官方指南: Instructions -使用Mixly写自定义库
-
第三方库范例: dfrobot、Otto
-
文本编辑工具: notepad, sublime
此教程中所有文件可新建文本文档,修改其后缀实现编译。
这里用的编译器是Sublime,脚本语言是JavaScript
Mixly二次开发 文件结构
block/xxx.js文件定义了你定制的图形化模块的样子。
generator/xxx.js文件定义了每一个图形化模块对应的 Arduino C语言代码。
-
block和generator 文件夹下各有一个与项目同名但内容不同的xxx.js文件,一个控制“外观”,另一个控制“内涵”。
xxx.xml
-
必须的,所有模块的路径,相当于字典
开发内容:
使用U8g2库,做二次开发,使其自定义库模块可显示中文,
如下图所示:
开发开始:
-
开发内容: OLED中文显示模块
-
开发准备: u8g2库
-
关于OLED显示中文,以及u8g2库的使用,可参考博客里另一个文章
新建文件,如下图:
-
在 block 和 generator 文件夹中新建文本文档,并重命名为 kivinOLED.js , 如下图所示:
-
再新建一个 kivinOLED 文件夹,放入u8g2库文件,如下图所示:
-
----->
开始编程:
共分为3个部分, 也就是说,需要编写3个必要的脚本
首先,我们使用 sublime 编译器, 打开 block文件夹下 kivinOLED.js 脚本
脚本如下:(此脚本定义和配置了模块的图形化,注意!方法和变量的名称!!!!在以下三个脚本中必须严格保持一致,且大小写敏感!!!!)
//下列三行代码,为刚需,此提供了下列所有代码的入口
'use strict';
goog.provide('Blockly.Blocks.kivinOLED');//注意脚本类别及路径名称
goog.require('Blockly.Blocks');
// ---OLED模块图形配置---
//include模块
Blockly.Blocks.U8g2lib_include = {
init: function() {
this.setColour(120);//模块图形颜色
this.appendDummyInput("")//此行代码刚需,为模块创建提供入口
.appendField("#include <") //代码块上的文字内容
.appendField(new Blockly.FieldTextInput('U8g2lib'), 'INCLUDE')//创建文本输入对象
.appendField(".h>");
this.setPreviousStatement(true);//是否可以与上一模块连接
this.setNextStatement(true);//是否可以与下一模块连接
}
};
//配置构造函数模块
Blockly.Blocks.config = {
init: function() {
this.setColour(120);
this.appendDummyInput("")
.appendField("配置构造函数")
.appendField("U8g2 SSD1306 128X64")
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setInputsInline(false);//是否开启模块单行显示(true为单行,false为多行)
}
};
//开启 U8g2驱动模块
Blockly.Blocks.initOled = {
init: function() {
this.setColour(120);
this.appendDummyInput("")
.appendField("开启U8g2驱动程序")
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
}
};
//中文输入模块
Blockly.Blocks.displayCN = {
init: function() {
this.setColour(50);
this.appendDummyInput("")
.appendField("输入字符串...")
this.appendValueInput("VALUE", String)
.setCheck([String,Number])
.setAlign(Blockly.ALIGN_RIGHT);//开启模块右侧可连接
this.setPreviousStatement(true, null);
this.setNextStatement(false, null);
}
};
其次,打开根文件夹中的 kivinOLED.xml 文件
脚本如下:(此脚本为全局路径配置, 注意方法和变量的名称!!!)
<!--该注释为!!!路径!!!,此为刚需!
type="company"
block="block/kivinOLED.js"
generator="generator/kivinOLED.js"
-->
<script type="text/javascript" src="../../blocks/company/kivinOLED.js"></script>
<script type="text/javascript" src="../../generators/arduino/company/kivinOLED.js"></script>
<!--根路径&外观配置&所有模块的内容物-->
<category id="kivin OLED demo" name="OLED中文显示" colour= 20>
<!-- OLED模块 -->
<!--include模块-->
<block type="U8g2lib_include">
<value name="String">
<shadow type="text"> <!--可编辑文本-->
<field name="_text">U8g2lib.h</field>
</shadow>
</value>
</block>
<!--配置构造函数模块-->
<block type="config" name="U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2">
</block>
<!--开启 U8g2驱动模块-->
<block type="initOled">
</block>
<!--中文输入模块-->
<block type="displayCN">
<value name="disCN">
<shadow type="text">
<field name="_text">textOled</field>
</shadow>
</value>
</block>
</category>
最后,打开 generator 文件夹中 kivinOLED.js 脚本
脚本如下:
//下列三行代码,为刚需,此提供了下列所有代码的入口
'use strict';
goog.provide('Blockly.Arduino.kivinOLED');//注意脚本类别及路径名称
goog.require('Blockly.Arduino');
// ---OLED模块图形转代码---
//include模块
Blockly.Arduino.U8g2lib_include = function() {
var INCLUDE = this.getFieldValue('INCLUDE');//使用INCLUDE 变量来存储,block文件夹中的kivinOLED.js脚本,文本输入对象的值
Blockly.Arduino.definitions_['define_'+INCLUDE] = '#include <'+INCLUDE+'.h>';//严格函数,固定写法(转include调用内容)
return '';
};
//配置构造函数模块
Blockly.Arduino.config = function() {
Blockly.Arduino.definitions_['define_'] = 'U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0,SCL,SDA);\n';
return '';
};
//开启 U8g2驱动模块
Blockly.Arduino.initOled = function() {
Blockly.Arduino.setups_['setup_intOled'] = 'u8g2.begin();\n';//严格函数固定写法(转setup函数中代码)
return '';
};
//中文输入模块
Blockly.Arduino.displayCN=function(){
var value = Blockly.Arduino.valueToCode(this, 'VALUE', Blockly.Arduino.ORDER_ATOMIC) || '\"\"';
return 'u8g2.firstPage();' + '\n' + 'do {' + '\n' + 'u8g2.setFont(u8g2_font_unifont_t_chinese1);' + '\n' + 'u8g2.drawUTF8(0,15,' +value+ ');' + '\n' + '} while ( u8g2.nextPage() );' + '\n' + 'delay(1000);';
};