mBlock Ranger Motors and Arduino IDE Fix!


#1

Summary: A while back I posted that the motors did not work if I compiled code generated by mBlock inside the Arduino IDE. I was told that it worked with Arduino 1.6.5 and at first I thought that was true but it actually wasn’t.

The real problem is in the constructor and the loop() methods for the MeEncoderOnBoard class.

A workaround is to add the following two lines in setup():

void setup() {
  //ADD THE FOLLOWING 2 lINES OF CODE
  Encoder_1.reset(SLOT1);
  Encoder_2.reset(SLOT2);
  ...
}

Description: In the constructor, there is a private variable called _enabled which is by default set to false:

MeEncoderOnBoard::MeEncoderOnBoard(int slot)
{
  _enabled = false;
  _Slot = slot;
  _Port_A = encoder_Port[slot].port_A;
...

Now the _enabled variable is never set to true except in the reset() method, which isn’t called by the generated code.

In the loop() method you see that if _enabled == false it simply returns… no work is done. This is why the motors do not run (why this works in mBlock I do not know, my guess is the code in Git and what they are using is not in synch).

void MeEncoderOnBoard::loop(void)
{
  if(!_enabled)return;
  updateCurPos();
  updateSpeed();

The following is code generated by the mBlock IDE will run the motors properly in the Arduino IDE:

// generated by mBlock5 for mBot Ranger
// codes make you happy

#include <Arduino.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include <MeAuriga.h>

MeEncoderOnBoard Encoder_1(SLOT1);
MeEncoderOnBoard Encoder_2(SLOT2);
MeLightSensor lightsensor_12(12);

void isr_process_encoder1(void)
{
  if(digitalRead(Encoder_1.getPortB()) == 0){
    Encoder_1.pulsePosMinus();
  }else{
    Encoder_1.pulsePosPlus();
  }
}
void isr_process_encoder2(void)
{
  if(digitalRead(Encoder_2.getPortB()) == 0){
    Encoder_2.pulsePosMinus();
  }else{
    Encoder_2.pulsePosPlus();
  }
}
void move(int direction, int speed)
{
  int leftSpeed = 0;
  int rightSpeed = 0;
  if(direction == 1){
    leftSpeed = -speed;
    rightSpeed = speed;
  }else if(direction == 2){
    leftSpeed = speed;
    rightSpeed = -speed;
  }else if(direction == 3){
    leftSpeed = -speed;
    rightSpeed = -speed;
  }else if(direction == 4){
    leftSpeed = speed;
    rightSpeed = speed;
  }
  Encoder_1.setTarPWM(leftSpeed);
  Encoder_2.setTarPWM(rightSpeed);
}

void _delay(float seconds) {
  if(seconds < 0.0){
    seconds = 0.0;
  }
  long endTime = millis() + seconds * 1000;
  while(millis() < endTime) _loop();
}

void setup() {
  //ADD THE FOLLOWING 2 lINES OF CODE
  Encoder_1.reset(SLOT1);
  Encoder_2.reset(SLOT2);
  
  TCCR1A = _BV(WGM10);
  TCCR1B = _BV(CS11) | _BV(WGM12);
  TCCR2A = _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(CS21);
  attachInterrupt(Encoder_1.getIntNum(), isr_process_encoder1, RISING);
  attachInterrupt(Encoder_2.getIntNum(), isr_process_encoder2, RISING);
  randomSeed((unsigned long)(lightsensor_12.read() * 123456));

  move(2, 50 / 100.0 * 255);
  _delay(2);
  move(2, 0);
  Encoder_1.setTarPWM(0);
  Encoder_2.setTarPWM(0);
  _delay(0.5);

}

void _loop() {
  Encoder_1.loop();
  Encoder_2.loop();
}

void loop() {
  _loop();
}

#2

This issue was first mentioned back in July - see Ranger motors work fine in mBlock but not using Arduino IDE .

I think Makeblock should allow users to add reference link from on each post in order to help others to find solutions. Adding link here referring back to the beginning post of this issue is indeed backward.


#3

thanks for your suggest,will feedback your advice to internal team.