carlosperate / ardublockly

Visual programming for Arduino. Based on blockly, implements Arduino code generation and facilitates program uploading.
http://ardublockly.embeddedlog.com
Apache License 2.0
451 stars 279 forks source link

Generic Code Block #24

Open MadTooler opened 8 years ago

MadTooler commented 8 years ago

It would be useful to have a generic block that allowed for code to be directly added. ArduBlock had this feature, and I found it useful in adding additional functionality when I needed to add libraries or just a little bit of manual code to enhance the visual functions.

Great job so far! I am looking forward to showing ardublockly to several youth groups and as a fun tool to go with my robot kits.

carlosperate commented 8 years ago

Thanks @MadTooler, and also thank you for reporting these issues!.

About adding a "write your code here" block, I'm not quite sure it integrates well with the philosophy of the project, as ideally a block program (without warnings) should be able to compile without errors. Once you allow arbitrary code to be injected, it then becomes quite difficult to identify issues when errors appear. Apart from that, from my point of view, if the users are getting comfortable enough to start writing their own code, then maybe it's time to move from Ardublockly to Arduino code. On the other hand, if a teacher/instructor needs to add additional code, then ideally it should be done in the form of block, where there is more control on the generated code and available options.

carlosperate commented 8 years ago

Btw, in the future I was planning to create a simpler "block creator", to facilitate this task. This has been briefly discussed in issue https://github.com/carlosperate/ardublockly/issues/22.

MadTooler commented 8 years ago

I was trying to play with the block creator I think you had some hand in for blocklyduino. Did not have any luck getting everything running proper. This is surely mostly a lack of understanding of XML and the other aspects of compiling and placing all of the required files. For a simple test of new hardware with blocklyduino, it just wasn't practical.

A generic code block would be useful where projects are outside of the existing blocks capabilities, and the longer term application is yet to be determined as worthy of further effort to make blocks. With some of the experience I had the ardublock, I made code filled functions that I set to the side of the screen so the younger users were able to just use the simple function calls. After I saw what worked and didn't, I narrowed down the code and made libraries for arduino that worked with ardublock. The task of going straight to making new blocks probably would have been much more involved, especially for users that are not very knowledgeable/experienced.

The use of a generic pass thru code block would obviously be discouraged for constant use, as I agree it could work against the philosophy. However, it could also keep the project useful with that one off application with that brand new or custom piece of hardware that none of the smart people have made blocks for just yet. This could also help empower those new to coding to try that custom line of code before they are really confident in moving all the way to the arduino IDE.

carlosperate commented 8 years ago

Unfortunately I wasn't able to spend much time working on the blocklyduino version of the block creator, life got in the way for a while, and when things settled down I had a lot of catch up to do with Ardublockly and other projects.

I am still a bit hesitant to add a "write your code" block, but I certainly agree with having an easy way to inject your code for testing and prototyping features. Generally speaking, when you use those types of blocks, is the code included self contained, or is it using data and interfaces created by the rest of the block application? The reason I ask, is because before adding the "use blockly to create blockly blocks" feature, I could work on a much simple blockly factory implementation that could allow you to include C code in a "custom" block, which could then be included in Ardublockly. This way the "instructor" could prototype with that and add an uneditable block that's safe for the user.

MadTooler commented 8 years ago

"Generally speaking, when you use those types of blocks, is the code included self contained, or is it using data and interfaces created by the rest of the block application? "

Still to be determined, I guess. I have done it both ways as needed while working around what I am capable of Frankensteining together with my limited coding skills.

If I had my choice, I would prefer being able to interface. At least by accessing variables set in ardublockly. That way, as with an example I am working on right now, I could have a simple block that says "turn right" with the input of a variable named "speed" that would then generate arduino code accessing the proper libraries and functions I have created while passing the value of "speed." It would then be nice to be able to have a return value there as well, for example a confirmation that it made the turn and is ready for the next instruction. The return is not as important now, but I am sure there would be uses for it if it was available.

I am hacking at the stepper.js generator file right now to make a basic motor driver version that would output single pin pwm and a single digital. Maybe a dual motor driver as well. Beyond playing around with the js files, what is the current proper way of adding blocks?

carlosperate commented 8 years ago

With this proposed "enhanced-but-simple block factory" you could still have an "input to the block" and "block output". So for example, in this default factory block: https://blockly-demo.appspot.com/static/demos/blockfactory/index.html#96t4n5 The enhanced version would allow you to type the C code in the generator stub, so instead of seeing:


Generator stub: JavaScript

Blockly.JavaScript['math_foo'] = function(block) {
  var value_input_name = Blockly.JavaScript.valueToCode(block, 'INPUT_NAME', Blockly.JavaScript.ORDER_ATOMIC);
  // TODO: Assemble JavaScript into code variable.
  var code = '...';
  // TODO: Change ORDER_NONE to the correct strength.
  return [code, Blockly.JavaScript.ORDER_NONE];
};

You could see something like:


C code generator

Block input can be used as $INPUT_NAME$
// Write your C code here, eg: $INPUT_NAME$ * 2

A block with an output notch would be forced to be a single line without semicolons (as it can be inlined inside other blocks), and without an output notch could contain multiple lines and be more flexible, so you could put something together like :


C code generator

Block input can be used as $INPUT_NAME$

Type your code here:

// example of code taking multiple lines
if ($INPUT_NAME$ * 2) {
    // do something
} else {
    // do something else
}

But of course, this might be more complex or less usable than expected, so I will need to experiment with it a little bit.

With respect of a proper way of adding blocks, the official blockly documentation is quite comprehensive: https://developers.google.com/blockly/custom-blocks/overview

Apart from that, @SebCanet created a good tutorial in http://tic.technologiescollege.fr/wiki/doku.php/en/blockly_rduino/create_blocks , with a brief discussion in issue https://github.com/carlosperate/ardublockly/issues/17.

MadTooler commented 8 years ago

Thanks again.

That may work, as long as I understand it correctly that it is all within the ardublockly environment.

As for the block additions, I was just trying to make sure there was nothing additional necessary for binding the blocks to your derivative of blockly.

carlosperate commented 8 years ago

There is some additional functionality, like the "reserving a pin" for the block, which all it does is add warnings to other blocks that attempt to use the same pin: https://github.com/carlosperate/ardublockly/blob/a87881a8cddb1e17bbee92fa2d68002b05b456da/blockly/generators/arduino.js#L254

The main difference would be that for defining the input and output types of the blocks instead of simple strings, there is a JS object, which is basically used as a dictionary/associative array: https://github.com/carlosperate/ardublockly/blob/a87881a8cddb1e17bbee92fa2d68002b05b456da/blockly/core/static_typing.js#L30 But this is is very likely to change to add more data to the "types" allowing compatible types, and things like promotions. This change is required to bring floats back.

Also any block with an output notch should define it's type, using the function getBlockType(), which could be derived from any input blocks.

MadTooler commented 8 years ago

Carlos,

I am starting to get back to this and other custom blocks. I am having trouble getting changes from within the /blocks (test, grove, etc) to show up during execution. Do I need to do some sort of rebuild or refresh for the changes to become active?

MadTooler commented 8 years ago

Carlos,

I have been able to create some new custom blocks and get it to work, sort of. For some reason, the Electron gui and the chrome keep taking turns on which will show the current changes. The Electron seems to be most reliable. I am not running in developer mode right now.

carlosperate commented 8 years ago

As far as being able to test custom blocks you will have to either build every time, or run the uncompressed sources. I've added instructions to https://github.com/carlosperate/ardublockly/wiki/Runninng-Uncompressed-Ardublockly showing how to run uncompressed.

From my personal experience I would highly recommend chrome to ensure you are always running the latest changes in your filesystem. I've had issues, even with hard refreshes, with Firefox and Electron (the refresh option in the development gui for Electron is meant to do a hard reset). Chrome is the only browser that has reliably always been able to skip the cache, juat make sure you have the developer tools out and right click on the refresh button to select "empty cache and hard reload".

MadTooler commented 8 years ago

Thanks for the instructions. I will try the hard reload.