Scratch3.0 & Blockly如何对Arduino编译下载

感谢伟大的开源思想,开源是自由的。

今天在这里一下如何使用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
 
  1. function buildArduinoCompile() {

  2. const {

  3. spawn

  4. } = require('child_process');//开一个子进程

  5. //需要到arduino_debug.exe的路径,我们使用arduino_debug进行编译,这里需要改写成你的

  6. let arduinoPath = __dirname + "Arduino/arduino_debug";

  7. //被编译下载的ino文件的路径,这里需要改写成你的

  8. let filePath = __dirname + "Arduino/build.ino";

  9. //获取积木块生成的arduino代码,这里需要改写成你的

  10. let code = Blockly.Arduino.workspaceToCode(Blockly.mainWorkspace);

  11. //这里需要将你的获取到的arduino代码写到之前要被编译的ino文件中

  12. let fs = require("fs");//文件

  13. fs.writeFile(filePath, code, function(err) {

  14. if (err) {

  15. return console.error(err);

  16. }

  17. });

  18. //设定一下编译的参数

  19. const spawnObj = spawn(arduinoPath, [

  20. //'-v',

  21. '--board',

  22. 'arduino:avr:uno',//主控板选型 这里使用uno,也可以使用nano、2560等

  23. '--pref',

  24. 'build.path=zrobot-builder',//指定一下构建目录,可以提升arduino的编译速度,几秒就完事,速度取决于电脑的配置

  25. '--verify',//编译

  26. filePath //被编译文件的路径

  27. ]);

  28. spawnObj.stderr.on('data', (data) => {

  29. //这里你可以打印arduino编译器返回来的错误数据,data

  30. });

  31. spawnObj.stdout.on('data', (data) => {

  32. //这里你可以打印arduino编译器返回来输出的数据,data

  33. });

  34. spawnObj.on('close', function(data) {

  35. })

  36. spawnObj.on('exit', (code) => {

  37. console.log('exit code : ' + code);

  38. if (code == 0) {

  39. //进程退出,也就意味着编译完成,你可以在这里写一些提示之类的东西

  40. } else {

  41. //这里说明你的编译过程中存在问题,从而导致子进程退出,

  42. //错误信息在spawnObj.stderr.on()里

  43. }

  44. });

  45. }

只要要调用我的buildArduinoCompile()方法就可以实现对Arduino的编译。

Arduino下载

1
 
  1. function arduinoUpload() {

  2. const {

  3. spawn

  4. } = require('child_process');//开一个子进程

  5. //需要到arduino_debug.exe的路径,我们使用arduino_debug进行编译,这里需要改写成你的

  6. let arduinoPath = __dirname + "Arduino/arduino_debug";

  7. //被编译下载的ino文件的路径,这里需要改写成你的

  8. let filePath = __dirname + "Arduino/build.ino";

  9. //获取积木块生成的arduino代码,这里需要改写成你的

  10. let code = Blockly.Arduino.workspaceToCode(Blockly.mainWorkspace);

  11. //这里需要将你的获取到的arduino代码写到之前要被编译的ino文件中

  12. let fs = require("fs");//文件

  13. fs.writeFile(filePath, code, function(err) {

  14. if (err) {

  15. return console.error(err);

  16. }

  17. });

  18. const spawnObj = spawn(arduinoPath, [

  19. '--board',

  20. 'arduino:avr:uno', //主控板选型 这里使用uno

  21. '--pref',

  22. 'build.path=zrobot-builder',//指定一下构建目录,可以提升arduino的编译速度,几秒就完事,速度取决于电脑的配置

  23. '--upload', //编译+下载

  24. '--port', //指定串口,这里需要到串口,所以需要用到node.serialPort模块

  25. serialName, //串口号

  26. filePath

  27. ]);

  28. spawnObj.stderr.on('data', (data) => {

  29. //这里你可以打印arduino编译器返回来的错误数据,data

  30. });

  31. spawnObj.stdout.on('data', (data) => {

  32. //这里你可以打印arduino编译器返回来输出的数据,data

  33. });

  34. spawnObj.on('close', function(data) {

  35. })

  36. spawnObj.on('exit', (code) => {

  37. console.log('exit code : ' + code);

  38. if (code == 0) {

  39. //进程退出,也就意味着编译完成,你可以在这里写一些提示之类的东西

  40. } else {

  41. //这里说明你的编译过程中存在问题,从而导致子进程退出,

  42. //错误信息在spawnObj.stderr.on()里

  43. }

  44. });

  45. }

这里需要注意的是,我们在下载的时候需要使用到串口,万幸的是Node.js也提供了SerialPort模块,我们直接使用就ok了,这样是实现了Arduino的代码下载。

总的来说实现Arduino的编译+下载并不难,利用这个原理我们也可以对STM32、ESP32、等都可以进行图形化编程。