感谢伟大的开源思想,开源是自由的。
今天在这里一下如何使用Scratch3.0 & Blockly去编译Arduino(当然编译其他的原理都一样)这里就以Arduino为例了,正文如下:
CMD-Arduino编译
其实Arduino的官方已经提供了使用第三方编译的方式,可以通过命令行的方式去进行构建编译以及上传,我们就以windows下的CMD实现编译下载:
我们可以实现打开文件,编译,烧写,安装库文件等操作。
1-首先我们cd到Arduino安装路径的下,或者配置一下环境变量,就可以省略这一步;
2-在windows环境下,如果没有任何参数,在cmd命令提示符里面敲arduino加回车就会和常规的打开IDE窗口的效果,同时这种命令行方法在windows下有个问题,使用arduino这个命令的话,会触发他的GUI界面,即使是只想arduino --verify blink.ino也会出现那个IDE初始化界面闪一下,而且命令提示符界面里什么反馈都没有,这里就要用到arduino_debug这个同样在Arduino的安装目录里的exe文件,使用它就不会出现GUI闪过,而且会有很多正常的编译或者烧写反馈。这里我还是使用最简单的Blink来做演示。
3-首先我们在桌面新建一个Blink/Blink.ino文件,然后在文件中写入
4-然后在cmd中输入arduino_debug --verify C:/Users/znjco/Desktop/Blink/Blink.ino,就完成了编译
5-假如我将代码写错,少写一个分号,重新编译,会提示我们存在错误
6-实现编译并上传,开发板和串口默认是上次的选择,将arduino与我们的电脑相连,查看端口,我的是COM22 ;使用命令arduino_debug --board arduino:avr:uno --pref build.path=zrobot-builder --upload --port COM22 C:/Users/znjco/Desktop/Blink/Blink.ino 就完成了编译下载
7-参考https://github.com/arduino/Arduino/blob/master/build/shared/manpage.adoc
在Scratch3.0 & Blockly中调用
无论在是S3.0中还是Blockly都是采用Node.js去写,而我们要脱离cmd取编译Arduino我们就需要使用一个子进程来代替cmd,而恰好node.js提供了原生模块child_process,我们直接使用它就即可,
Arduino编译
1
function buildArduinoCompile() {
const {
spawn
} = require('child_process');//开一个子进程
//需要到arduino_debug.exe的路径,我们使用arduino_debug进行编译,这里需要改写成你的
let arduinoPath = __dirname + "Arduino/arduino_debug";
//被编译下载的ino文件的路径,这里需要改写成你的
let filePath = __dirname + "Arduino/build.ino";
//获取积木块生成的arduino代码,这里需要改写成你的
let code = Blockly.Arduino.workspaceToCode(Blockly.mainWorkspace);
//这里需要将你的获取到的arduino代码写到之前要被编译的ino文件中
let fs = require("fs");//文件
fs.writeFile(filePath, code, function(err) {
if (err) {
return console.error(err);
}
});
//设定一下编译的参数
const spawnObj = spawn(arduinoPath, [
//'-v',
'--board',
'arduino:avr:uno',//主控板选型 这里使用uno,也可以使用nano、2560等
'--pref',
'build.path=zrobot-builder',//指定一下构建目录,可以提升arduino的编译速度,几秒就完事,速度取决于电脑的配置
'--verify',//编译
filePath //被编译文件的路径
]);
spawnObj.stderr.on('data', (data) => {
//这里你可以打印arduino编译器返回来的错误数据,data
});
spawnObj.stdout.on('data', (data) => {
//这里你可以打印arduino编译器返回来输出的数据,data
});
spawnObj.on('close', function(data) {
})
spawnObj.on('exit', (code) => {
console.log('exit code : ' + code);
if (code == 0) {
//进程退出,也就意味着编译完成,你可以在这里写一些提示之类的东西
} else {
//这里说明你的编译过程中存在问题,从而导致子进程退出,
//错误信息在spawnObj.stderr.on()里
}
});
} 只要要调用我的buildArduinoCompile()方法就可以实现对Arduino的编译。
Arduino下载
1
function arduinoUpload() {
const {
spawn
} = require('child_process');//开一个子进程
//需要到arduino_debug.exe的路径,我们使用arduino_debug进行编译,这里需要改写成你的
let arduinoPath = __dirname + "Arduino/arduino_debug";
//被编译下载的ino文件的路径,这里需要改写成你的
let filePath = __dirname + "Arduino/build.ino";
//获取积木块生成的arduino代码,这里需要改写成你的
let code = Blockly.Arduino.workspaceToCode(Blockly.mainWorkspace);
//这里需要将你的获取到的arduino代码写到之前要被编译的ino文件中
let fs = require("fs");//文件
fs.writeFile(filePath, code, function(err) {
if (err) {
return console.error(err);
}
});
const spawnObj = spawn(arduinoPath, [
'--board',
'arduino:avr:uno', //主控板选型 这里使用uno
'--pref',
'build.path=zrobot-builder',//指定一下构建目录,可以提升arduino的编译速度,几秒就完事,速度取决于电脑的配置
'--upload', //编译+下载
'--port', //指定串口,这里需要到串口,所以需要用到node.serialPort模块
serialName, //串口号
filePath
]);
spawnObj.stderr.on('data', (data) => {
//这里你可以打印arduino编译器返回来的错误数据,data
});
spawnObj.stdout.on('data', (data) => {
//这里你可以打印arduino编译器返回来输出的数据,data
});
spawnObj.on('close', function(data) {
})
spawnObj.on('exit', (code) => {
console.log('exit code : ' + code);
if (code == 0) {
//进程退出,也就意味着编译完成,你可以在这里写一些提示之类的东西
} else {
//这里说明你的编译过程中存在问题,从而导致子进程退出,
//错误信息在spawnObj.stderr.on()里
}
});
} 这里需要注意的是,我们在下载的时候需要使用到串口,万幸的是Node.js也提供了SerialPort模块,我们直接使用就ok了,这样是实现了Arduino的代码下载。
总的来说实现Arduino的编译+下载并不难,利用这个原理我们也可以对STM32、ESP32、等都可以进行图形化编程。