Bug in mblock code generator


#1

I was working with my class to build robots, and I found that several of the students robots were behaving incorrectly, despite having accurate programs. After several days of fussing, we found that the code generator wasn’t creating proper arduino code. I’m pasting a screenshot below, so people can see the problem. This really needs to get fixed.

edit: By the way, yes, I know the code isn’t correct. That’s not the issue, since this has occurred with correct code too.


#2

@kyancey

Which robot are you using, mBot, Starter Robot, something else?

Also, what exactly is wrong? The void setup() is only used to initialize things, it is not really meant for running the main program, so the compiler is including each of your function calls just once and ignoring multiple call. Here is a work-around for what I think you are trying to do.


The main part of the code should be in the void loop(), which will repeat forever, but I don’t think that is what you want.

Let me know if this helps.

Mike


#3

I see what you are saying, although I have to say that I find that behavior very counterintuitive. I didn’t realize the loop made that much of a difference. From my own programming background, I expected the forever loop to create an infinite while loop.


#4

@kyancey,

I agree, but when you consider the device with limited memory, etc., it helps to set things up this way. There really is no reason to exit the forever loop since it won’t do anything else (no OS to take over), you just turn it off when you’re done.

In my first example, the code is executed once, then drops into the forever loop (where there is no code, but it is still looping).

Mike


#5

Same issue occurs if you do not have a loop but try to re-use a counter variable. The variable does not get reset. For teaching this is counter-intuitive for the students.


#6

Hi mjbaynes,

Could you please paste your code here?


#7

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

#include <MeMCore.h>

double angle_rad = PI/180.0;
double angle_deg = 180.0/PI;
double count;

void setup(){
count = 0;
while(!(((count)==(10))))
{
count += 1;
}
}

void loop(){
_loop();
}

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

void _loop(){
}


#8


#9

Sorry for not efficiently submitting the bug.
The first is the generate code, not sure why the includes did not copy, but its from mBlock 3.3.2 on El Capitain.
The second is the Scratch source.
Notice not only does count not get zeroed the second time, but the second loop using it is optimized away as well.
The application is simplified to show the bug - it comes from a student exercise to count lines using the line finder, turn and sound a second number - so a loop is not needed.
Workaround is to use a second variable, eg count2 or as suggested by mddickey above to add a loop with a count of 1.


#10

@mjbaynes,

The issue is that the code is still executing in the void setup() area, which is optimized to remove redundant code. After all, you should only initialize something once. Below is an example of what I think you are looking for.

In your example of Set-RepeatUntil-Change-Set-RepeatUntil-Change, the compiler recognizes the pattern and removes the redundant code leaving only one set of Set-RepeatUntil-Change. Each of the items can be considered a top level structure. In my example, the top level structure is Repeat3. The subordinate structure Set-RepeatUntil-Change-Set-RepeatUntil-Change is not optimized because they are required parts of the Repeat3.

Since the student exercise is to count lines, I would suggest placing the counting code in the Forever Loop. Keep in mind though, the exit condition for the void loop is something that will never change the truth value, like 1=1 is always true, and 1=2 is always false, so it will keep looping forever. I the example below.

You can set up a condition that will allow your code to execute a certain number of times, and then never execute again, even though it is still in a loop.

I hope this helps to explain what is going on.

Mike


#11

Hi Mike,
Thanks for the reply. I do understand what is going on - I still think its a bug.

mBlock is for education and helping students start programming. They are supposed to program in Scratch and the translation into Sketch and the subsequent compilation should be automatic to them - though its good they can see and perhaps interact with the process, which mBlock permits.

For those starting learning software adding code that is not needed for their task is confusing (eg the repeat loop, or new variable) - the beauty of mBlock when it works is there is no syntactic sugar encrustation.

The Scratch to Sketch translator need not optimize the code - these programs are small. This is the simplest proper fix.
The Sketch to executable compilation system could still optimize and it would not remove the repeated initialization or the duplicate counting.


#12