Discuss Scratch

robobaron
New Scratcher
3 posts

scratch to c code?

Anybody tried generating c code from a scratch project file? In conjunction with some custom i/o pin blocks I'd like to be able to run simple programs written in scratch on a microcontroller. For proof-of-concept let's limit the scope to Scratch 2 only.

I'm fine ignoring motion/looks/sound/pen/etc. blocks for now and supporting only directly compatible blocks from Data, Control, and Operators.

I'm pretty sure the nicely structured json project file makes this tractable, but any tips or pointers to similar projects would be helpful.
blob8108
Scratcher
1000+ posts

scratch to c code?

Obviously Scratch doesn't translate very well to C. The main problem is that Scratch allows multiple scripts to run at once. But it's certainly doable as a proof-of-concept (particularly if you only allow projects containing a single script).

The easiest way is probably to use my Python library Kurt, which can read (and write) Scratch project files.

Someone used it (sadly an older version) to compile Scratch scripts to C code that runs on Lego Mindstorms robots. Download PyNXC from this page http://web.bryant.edu/~bblais/pages/projects.html and
look for “ScratchNXC”. It uses the standard NXT firmware, as opposed to Enchanting, a Scratch mod which compiles to LeJOS (Java).
procd
Scratcher
100+ posts

scratch to c code?

My compiler effectively converts a scratch 2 project to C# before compiling to cil. This project may give you an idea of what it is like. I hope to add Scratch extensions at some point, why not just use an extension? Why not just use C?
robobaron
New Scratcher
3 posts

scratch to c code?

Correct… single script is an appropriate constraint for my question.

@blob8108 Kurt look useful, but besides easily supporting scratch 1.4 and 2 is there value added to the intermediate structure? Looking at the nice hierarchical json in the scratch project I can imagine a recursive parser that just directly traverses the tree structure dumping to an output stream (or equivalent). Am I headed for a “gotchya” with this approach though? At very least your code will be helpful as a reference.

@procd I saw procd in my research and it looks awesome, but C# or cil would still require converting to c (limitation of the microcontroller compilers) and I know less about those than python. If you ever release source I'd love to take a look though. I'm already using an extension to interact with the micro in real time, but I don't see how to generate c with the extension protocol. Of course I could just use C and forget scratch, but where's the fun in that?
procd
Scratcher
100+ posts

scratch to c code?

robobaron wrote:

Correct… single script is an appropriate constraint for my question.

@blob8108 Kurt look useful, but besides easily supporting scratch 1.4 and 2 is there value added to the intermediate structure? Looking at the nice hierarchical json in the scratch project I can imagine a recursive parser that just directly traverses the tree structure dumping to an output stream (or equivalent). Am I headed for a “gotchya” with this approach though? At very least your code will be helpful as a reference.

@procd I saw procd in my research and it looks awesome, but C# or cil would still require converting to c (limitation of the microcontroller compilers) and I know less about those than python. If you ever release source I'd love to take a look though. I'm already using an extension to interact with the micro in real time, but I don't see how to generate c with the extension protocol. Of course I could just use C and forget scratch, but where's the fun in that?

Single script shouldn't be a constraint as C is as good at threading as any other language and besides doesn't need to anyway as Scratch doesn't either! You just need to write your own scheduler. Thanks to nXIII mine is now pretty close to Scratch. I was just trying to make the point that it is possible and I could've use C instead of C#. The reason I went the C# route was that it offers more flexibility across platforms and the libraries are better for what was needed IMO.
I'd've thought an extension would be better as you then keep Scratch but can interact with external devices. It just means you need the microcontroller always connected to the PC. So I suppose you want the microcontroller to run standalone?
blob8108
Scratcher
1000+ posts

scratch to c code?

robobaron wrote:

besides easily supporting scratch 1.4 and 2 is there value added to the intermediate structure?
The resulting structure is nicer to work with, yes. I think it does also do some minor tweaks when loading, such as parsing custom blocks sensibly. But essentially you don't have to parse the ZIP/JSON yourself.

I think procd was suggesting writing an Scratch extension, ie. adding extra blocks to Scratch that let you control the microcontroller in real-time, as an alternative to compiling.
procd
Scratcher
100+ posts

scratch to c code?

blob8108 wrote:

robobaron wrote:

besides easily supporting scratch 1.4 and 2 is there value added to the intermediate structure?
The resulting structure is nicer to work with, yes. I think it does also do some minor tweaks when loading, such as parsing custom blocks sensibly. But essentially you don't have to parse the ZIP/JSON yourself.

I think procd was suggesting writing an Scratch extension, ie. adding extra blocks to Scratch that let you control the microcontroller in real-time, as an alternative to compiling.

Exactly. With an extension you could have your c code running on the microcontroller and talk to it using Scratch with blocks for the custom IO pins. Just means a PC has to interface to the microcontroller and would be a better way of doing things unless you want the microcontroller entirely standalone.
nXIII
Scratcher
1000+ posts

scratch to c code?

Or you could use an extension to provide blocks that have no Scratch equivalents, and then compile projects written using those extension blocks to C.
robobaron
New Scratcher
3 posts

scratch to c code?

That's exactly what I've already done. The scratch extension (with my custom micro i/o blocks) is already running and communication with the micro in real time (pretty cool how easy that was!) which got me wondering if I could flash programs down to run disconnected from scratch.

Sounds like the answer is (a) yes its possible with moderate effort, but (b) nobody's done it yet.

@procd I only meant complexity of multi-script support was beyond the proof-of-concept nature of my question, not that it was impossible. Not only could you implement multi-script support in c, you could connect a robot arm to the micro with a pen taped on and handle the pen commands, too… a speaker for the audio… etc. But for for now getting the simple subset of scratch working would suffice.

procd
Scratcher
100+ posts

scratch to c code?

robobaron wrote:

That's exactly what I've already done. The scratch extension (with my custom micro i/o blocks) is already running and communication with the micro in real time (pretty cool how easy that was!) which got me wondering if I could flash programs down to run disconnected from scratch.

Sounds like the answer is (a) yes its possible with moderate effort, but (b) nobody's done it yet.

@procd I only meant complexity of multi-script support was beyond the proof-of-concept nature of my question, not that it was impossible. Not only could you implement multi-script support in c, you could connect a robot arm to the micro with a pen taped on and handle the pen commands, too… a speaker for the audio… etc. But for for now getting the simple subset of scratch working would suffice.

Go for it ! I expect the worst part to be the difference in type. C is strongly/statically typed while Scratch…..isn't! For C# I ended up creating my own ScratchValue class to handle all the type conversion issues.
piif
New Scratcher
13 posts

scratch to c code?

robobaron wrote:

Anybody tried generating c code from a scratch project file?

I'm currently working on that : Github project
(readme files are in french, but it's more “draft notes” than doc for the moment, I will translate them later)

In fact, I began to write a Scratch extension to drive a LED strip connected to an arduino.
It communicates thru a node.js code which serves the extension and make the brigde between a websocket (scratch side) and serial port (arduino side).

Now, I'd like to make a “native” version to be able to program an animation in Sratch and translate it in Arduino C++ to play it “standalone”

As other posts said, “parallel” execution is a problem (no good thread lib on Arduino), block about costumes, sounds and so on have no sense, and extensions have to be adapted to native code.

The current status is that I can compile the generated code on PC from an example scratch project, but I still not tried it on arduino nor tried a code doing actually something.
Next steps : handle extension blocks and try in real
Then I'll try to do a “multi thread” version.

Feel free to give it a try ;-)
MegaApuTurkUltra
Scratcher
1000+ posts

scratch to c code?

piif wrote:

robobaron wrote:

Anybody tried generating c code from a scratch project file?

I'm currently working on that : Github project
(readme files are in french, but it's more “draft notes” than doc for the moment, I will translate them later)

In fact, I began to write a Scratch extension to drive a LED strip connected to an arduino.
It communicates thru a node.js code which serves the extension and make the brigde between a websocket (scratch side) and serial port (arduino side).

Now, I'd like to make a “native” version to be able to program an animation in Sratch and translate it in Arduino C++ to play it “standalone”

As other posts said, “parallel” execution is a problem (no good thread lib on Arduino), block about costumes, sounds and so on have no sense, and extensions have to be adapted to native code.

The current status is that I can compile the generated code on PC from an example scratch project, but I still not tried it on arduino nor tried a code doing actually something.
Next steps : handle extension blocks and try in real
Then I'll try to do a “multi thread” version.

Feel free to give it a try ;-)
Cool stuff! Can you link to your repo please?
Edit: whoops, seems you did. Wonder why it doesn't show up in your post…

Last edited by MegaApuTurkUltra (Nov. 7, 2014 14:09:46)

Blueinkproductions
Scratcher
1000+ posts

scratch to c code?

MegaApuTurkUltra wrote:

Cool stuff! Can you link to your repo please?
Edit: whoops, seems you did. Wonder why it doesn't show up in your post…
Links don't work for New Scratchers.
gtoal
Scratcher
1000+ posts

scratch to c code?

blob8108 wrote:

Obviously Scratch doesn't translate very well to C. The main problem is that Scratch allows multiple scripts to run at once. But it's certainly doable as a proof-of-concept (particularly if you only allow projects containing a single script).

Actually that part I think is relatively tractable - using “pthreads” or even fairly simple home-made coroutines. What I think is the biggest stumbling block is the support library that implements the Scratch runtime as C procedures. procd seems to have written a fairly robust one for C# but I don't know of anyone who has done this for C yet.

The mechanics of translating from Scratch to C syntax are pretty easy. Have a look at http://gtoal.com/scratch/sb2c/sb.c.html - that code currently just translates to Scratchblock format, but changing the format strings and a few small tweaks would allow it to generate C (which I'll do some time but right now I'm working on a video game :-) ) It's the runtime that's the real work.

UPDATE: C generating version - http://gtoal.com/scratch/sb2c/sb2c.c.html

Graham

Last edited by gtoal (Sept. 11, 2016 03:03:57)

nXIII
Scratcher
1000+ posts

scratch to c code?

gtoal wrote:

blob8108 wrote:

Obviously Scratch doesn't translate very well to C. The main problem is that Scratch allows multiple scripts to run at once. But it's certainly doable as a proof-of-concept (particularly if you only allow projects containing a single script).

Actually that part I think is relatively tractable - using “pthreads” or even fairly simple home-made coroutines.
Scratch doesn't allow multiple scripts to run at once in the atomic sense. It allows scripts to run one at a time and switches between active scripts at well-defined yield points. You won't be able to reproduce this with pthreads.
piif
New Scratcher
13 posts

scratch to c code?

nXIII wrote:

Scratch doesn't allow multiple scripts to run at once in the atomic sense. It allows scripts to run one at a time and switches between active scripts at well-defined yield points. You won't be able to reproduce this with pthreads.

does the “well-defined yield points” list is clearly defined ?
at end of each loop in infinite repeat I suppose, but are there other points ?
piif
New Scratcher
13 posts

scratch to c code?

gtoal wrote:

What I think is the biggest stumbling block is the support library that implements the Scratch runtime as C procedures.

It can be simplified if you target only a subset of scratch runtime.
If you want to translate to arduino, costumes and sounds can be ignored for example.
You just have to manage them to handle hats about backdrop changes for example, but without rendering them.

What I did in C++ is a beginning for this but I still have to test it on arduino.
For the moment, it compiles code which runs correctly on PC, but I need to test with smaller cpu and memory
nXIII
Scratcher
1000+ posts

scratch to c code?

piif wrote:

does the “well-defined yield points” list is clearly defined ?
at end of each loop in infinite repeat I suppose, but are there other points ?
When run-without-screen-refresh is disabled:
  • After evaluating one cycle of a loop (repeat, forever, etc.)
  • When waiting for the response to a blocking extension reporter or command.
  • During the execution of a timed block (glide, say…for, etc.) or a block that pauses the thread (ask…and wait, wait, wait until)
  • When waiting for a broadcast to finish in a broadcast…and wait block.
  • When waiting for a backdrop to finish in a switch backdrop to…and wait block.
  • Before a procedure call that is recursive (with up to four intermediate calls).
When run-without-screen-refresh is enabled:
  • If execution time has exceeded 500 ms, at any of the yield points above or before calling a procedure.
piif
New Scratcher
13 posts

scratch to c code?

wow .. I just added that to my “todo list” ;-)

By the way, I just ran my first arduino code generated from a scratch project
Project http://scratch.mit.edu/projects/28479940 becomes https://github.com/piif/ArduinoScratch/blob/master/data/guirlande.cpp and runs correctly on an arduino plugedd to an addressable led strip
(grrr, links still don't work … you'll have to copy/paste them)

Still lot of work to do, at least to make it easier to compile, but I think I'm on a good way

Last edited by piif (Nov. 15, 2014 22:35:29)

gtoal
Scratcher
1000+ posts

scratch to c code?

piif wrote:

wow .. I just added that to my “todo list” ;-)

By the way, I just ran my first arduino code generated from a scratch project
Project http://scratch.mit.edu/projects/28479940 becomes https://github.com/piif/ArduinoScratch/blob/master/data/guirlande.cpp and runs correctly on an arduino plugedd to an addressable led strip
(grrr, links still don't work … you'll have to copy/paste them)

Still lot of work to do, at least to make it easier to compile, but I think I'm on a good way

Your converter looks good, and there's definitely room for multiple projects in this area, but just in case you weren't aware of it… have you seen “Sniff” yet? It integrates a scratch-like language and Arduino… http://www.sniff.org.uk/

G

Powered by DjangoBB