Arduinowilliam hill官网
直播中

gjianw217

10年用户 688经验值
擅长:嵌入式技术 控制/MCU RF/无线
私信 关注
[问答]

【mBot试用体验】mBlock源码探究(Arduino)

       由于mBot主要的市场应该是针对儿童的,故提供了便于上手的“积本式”开发环境,通过自己组织积木,进行逻辑分配,便可以实现自己需要的功能,并且提供了基础的入手手册,可以帮助“孩子们”更快的接触编程,更快的实现自己的想法。但作为一个“大孩子”,还有想多问一个为什么,想要知道到底它是怎么实现的,由上一篇帖子知道,虽然在mBlock集成开发环境中,提供了arduino和积木两种共存的模式,但相互切换后,并不能看到真正的代码实现。故需要探究下其几部到底是怎么实现的。
一 mbot底板代码

        在mBlock的安装目录下,进入firmware目录,发现了如下所示的目录结构,即mblock针对不同的板子,设计了不同的板载固件。
QQ截图20160103214745.png

        进入mbot_firmware,用arduino打开mbot_firmware,可以清楚的看到有mbot的代码结构,也就是mbot通过arduino怎么实现其功能的。由于代码较多,现帖子主要的代码进行分享下:
(一 )头文件
        在mbot_firmware.ino中,只包括了这3个头文件,每一个应该是控制伺服电机的,第二个应该是控制一线或二线协议的,第三个似乎是针对开发板的,应该是很重要的一个头文件,具体分析见下面的第二部分。
  1. #include
  2. #include
  3. #include

(二 )模块变量
        在mbot_firmware.ino中,定义了如下所示的变量,从字面意思来看,都是和mBot相关的扩展模块,也就是说,mBlock,采用C++的语言,将mbot的扩展模块进行了封装,而为了在mBlock上,首先对需要的,支持的模块进行了定义或初始化,然后根据具体的条件或命令进行操作或控制这些模块的行为。
  1. Servo servos[8];  
  2. MeDCMotor dc;
  3. MeTemperature ts;
  4. MeRGBLed led(0,30);
  5. MeUltrasonicSensor us;
  6. Me7SegmentDisplay seg;
  7. MePort generalDevice;
  8. MeLEDMatrix ledMx;
  9. MeBuzzer buzzer;
  10. MeIR ir;
  11. MeGyro gyro;
  12. MeJoystick joystick;
  13. MeCompass Compass;
  14. MeHumiture humiture;
  15. MeFlameSensor FlameSensor;
  16. MeGasSensor GasSensor;

(三)启动函数
        在经典的setup函数中,分别进行初始化的设置,也就是默认启动时的操作,设置13引脚,它对应着板子上的RGB三色灯,即下面的执行顺序依次为:点亮RGB三色灯,延时300毫秒后熄灭,启动串口,使蜂鸣器发声50毫秒后停止,然后开启红外接收,led显示无色,最后启动陀螺仪。也就是说,把该用到模块,都启动了,并且通过指示灯和蜂鸣器来表示启动过程。
  1. void setup(){
  2.   pinMode(13,OUTPUT);
  3.   digitalWrite(13,HIGH);
  4.   delay(300);
  5.   digitalWrite(13,LOW);
  6.   Serial.begin(115200);
  7.   delay(500);
  8.   buzzer.tone(500,50);
  9.   delay(50);
  10.   buzzerOff();
  11.   ir.begin();
  12.   led.setpin(13);
  13.   led.setColor(0,0,0);
  14.   led.show();
  15.   gyro.begin();
  16. }

(四)主循环函数
        在主循环中,首先判断是否接收到红外的信号;然后读取串口的数据,也就是蓝牙模块的数据,也就是手机端控制的数据;最后根据调用parseData函数,根据不同的控制命令,进行不同的响应。
  1. void loop(){
  2.   currentTime = millis()/1000.0-lastTime;
  3.   if(ir.decode())
  4.   {
  5.     irRead = ((ir.value>>8)>>8)&0xff;
  6.     lastIRTime = millis()/1000.0;
  7.     irPressed = true;
  8.     if(irRead==0xa||irRead==0xd){
  9.       irIndex = 0;
  10.       irReady = true;
  11.     }else{
  12.       irBuffer+=irRead;
  13.       irIndex++;
  14.       if(irIndex>64){
  15.         irIndex = 0;
  16.         irBuffer = "";
  17.       }
  18.     }
  19.     irDelay = 0;
  20.   }else{
  21.     irDelay++;
  22.     if(irRead>0){
  23.      if(irDelay>5000){
  24.       irRead = 0;
  25.       irDelay = 0;
  26.      }
  27.    }
  28.   }
  29.   readSerial();
  30.   if(isAvailable){
  31.     unsigned char c = serialRead&0xff;
  32.     if(c==0x55&&isStart==false){
  33.      if(prevc==0xff){
  34.       index=1;
  35.       isStart = true;
  36.      }
  37.     }else{
  38.       prevc = c;
  39.       if(isStart){
  40.         if(index==2){
  41.          dataLen = c;
  42.         }else if(index>2){
  43.           dataLen--;
  44.         }
  45.         writeBuffer(index,c);
  46.       }
  47.     }
  48.      index++;
  49.      if(index>51){
  50.       index=0;
  51.       isStart=false;
  52.      }
  53.      if(isStart&&dataLen==0&&index>3){
  54.         isStart = false;
  55.         parseData();
  56.         index=0;
  57.      }
  58.   }
  59. }

        以上就是对mbot_firmware.ino的一个简单认识,可以对该代码进行修改、加工,完成自己想要的功能,而不用去拖动“积木”。但具体的模块的实现,还要找到其对应的实现源码,不然对具体接口的调用,还是无从下手。


二 mbot模块代码
        从上面的分析中,mbot主要包括了meMCore.h这个头文件,可见要想知道它们是怎么实现,就需要找到该文件,看看到底里面包括了些什么东西。在mBlock的安装目录下,,依次进Arduino-》ibraries-》makeblock-》src,可以看到如下图所示的源码。
QQ截图20160103215115.png


        从图中可知,mBlock根据不同的模块,封装了不同的代码实现,且它们都是以Me开头,以具体的模块名字结束,如MeRGBLed,表示该代码实现了对RGB Led灯的控制。我们找到刚才需要的meMCore.h这个头文件,打开后,它主要包括3部分,具体如下
(一)公共头文件


        其实,mBlock中的的代码由两部分组成,一部分是基于Arduino的,一部分是针对封装了mBlock中使用的模块代码。在meMCore.h只包括了如下两个头文件,而Meconfig,主要包括了utility目录下的文件和一些配置引脚定义。
  1. #include
  2. #include "MeConfig.h"


(二)模块头文件
        如下所示,在meMCore.h中,包括了所有的模块头文件,这也说明了,在每个mBlock实现中,都包括这一头文件的原因。
  1. /* Supported Modules drive needs to be added here */
  2. #include "Me7SegmentDisplay.h"
  3. #include "MeUltrasonicSensor.h"
  4. #include "MeMbotDCMotor.h"
  5. #include "MeRGBLed.h"
  6. #include "Me4Button.h"
  7. #include "MePotentiometer.h"
  8. #include "MeJoystick.h"
  9. #include "MePIRMotionSensor.h"
  10. #include "MeShutter.h"
  11. #include "MeLineFollower.h"
  12. #include "MeSoundSensor.h"
  13. #include "MeLimitSwitch.h"
  14. #include "MeLightSensor.h"
  15. #include "MeSerial.h"
  16. #include "MeBluetooth.h"
  17. #include "MeWifi.h"
  18. #include "MeTemperature.h"
  19. #include "MeGyro.h"
  20. #include "MeInfraredReceiver.h"
  21. #include "MeCompass.h"
  22. #include "MeUSBHost.h"
  23. #include "MeTouchSensor.h"
  24. #include "MeStepper.h"
  25. #include "MeEncoderMotor.h"
  26. #include "MeEncoderNew.h"
  27. #include "MeIR.h"
  28. #include "MeLEDMatrix.h"
  29. #include "MeBuzzer.h"
  30. #include "MeHumitureSensor.h"
  31. #include "MeFlameSensor.h"
  32. #include "MeGasSensor.h"


(三)引脚映射
        除了以上的头文件,在meMCore.h中,还定义了相对了mbot板上的引脚映射,纯数字代码数字引脚,带A的代表模拟引脚,具体为什么这样定义,应该看到下图就知道了。

  1. /*********************  Mbot Board GPIO Map *********************************/
  2. MePort_Sig mePort[11] =
  3. {
  4.   { NC, NC }, { 11, 12 }, { 9,  10 }, { A2, A3 }, { A0, A1 },
  5.   { NC, NC }, { NC, NC }, { A7, 13 }, { 8, A6 }, { 6, 7 },
  6.   { 5, 4 }
013256cy0g1qzuqqj2kjg1.png.thumb.jpg


(四)模块封装
        其实对于具体的模块,都会用到引脚,而mBlock针对引脚,封装了MePort基类,其他的的功能类,基本上都继承了该类,具体的分析,查看源码,应该更加清楚。


太晚了,明天还要上班,经过这几天的努力,总算是搞明白了mblock的代码框架,接下来就是实现自己的功能了!

回帖(14)

王志睿

2016-1-4 11:08:56
注意身体哈,工作注意休息
举报

gjianw217

2016-1-4 11:45:17
引用: 渴死的鱼儿 发表于 2016-1-4 11:08
注意身体哈,工作注意休息

谢谢关心!
举报

Elecfans管家

2016-1-4 14:14:36
引用: 渴死的鱼儿 发表于 2016-1-4 11:08
注意身体哈,工作注意休息

贴心小棉袄啊
举报

王志睿

2016-1-4 16:34:48
引用: Elecfans管家 发表于 2016-1-4 14:14
贴心小棉袄啊

{:11:}{:11:}这是前辈,哈哈,想想毕业后工作的状况那么累就很感叹!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分