add io blocks
This commit is contained in:
parent
d1d7a447bc
commit
eca3bf16a1
@ -27,6 +27,7 @@ import './BlocklyComponent.css';
|
||||
import Blockly from 'blockly/core';
|
||||
//import locale from 'blockly/msg/en';
|
||||
import 'blockly/blocks';
|
||||
import Toolbox from './toolbox/Toolbox';
|
||||
|
||||
//Blockly.setLocale(locale);
|
||||
|
||||
@ -61,13 +62,11 @@ class BlocklyComponent extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children } = this.props;
|
||||
|
||||
|
||||
return <React.Fragment>
|
||||
<div ref={this.blocklyDiv} id="blocklyDiv" />
|
||||
<xml xmlns="https://developers.google.com/blockly/xml" is="blockly" style={{ display: 'none' }} ref={this.toolbox}>
|
||||
{children}
|
||||
</xml>
|
||||
<Toolbox toolbox={this.toolbox} />
|
||||
</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
import './loops';
|
||||
import './sensebox';
|
||||
import './logic';
|
||||
import './sensebox-sensors';
|
||||
import './sensebox-sensors';
|
||||
import './sensebox-telegram';
|
||||
import './io';
|
257
src/components/Blockly/blocks/io.js
Normal file
257
src/components/Blockly/blocks/io.js
Normal file
@ -0,0 +1,257 @@
|
||||
/**
|
||||
* @license Licensed under the Apache License, Version 2.0 (the "License"):
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Blocks for Arduino Digital and Analogue input and output
|
||||
* functions. The Arduino function syntax can be found at
|
||||
* http://arduino.cc/en/Reference/HomePage
|
||||
*
|
||||
* TODO: maybe change this to a "PIN" BlocklyType
|
||||
*/
|
||||
import { defineBlocksWithJsonArray } from 'blockly';
|
||||
import Blockly from 'blockly/core';
|
||||
import { selectedBoard } from '../helpers/board'
|
||||
|
||||
|
||||
Blockly.Blocks['io_digitalwrite'] = {
|
||||
/**
|
||||
* Block for creating a 'set pin' to a state.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setHelpUrl('http://arduino.cc/en/Reference/DigitalWrite');
|
||||
this.setColour(250);
|
||||
this.appendValueInput('STATE')
|
||||
.appendField(Blockly.Msg.ARD_DIGITALWRITE)
|
||||
.appendField(new Blockly.FieldDropdown(
|
||||
selectedBoard().digitalPins), 'PIN')
|
||||
.appendField(Blockly.Msg.ARD_WRITE_TO)
|
||||
// .setCheck(Blockly.Types.BOOLEAN.checkList);
|
||||
this.setInputsInline(false);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip(Blockly.Msg.ARD_DIGITALWRITE_TIP);
|
||||
},
|
||||
/**
|
||||
* Updates the content of the the pin related fields.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
updateFields: function () {
|
||||
Blockly.Arduino.Boards.refreshBlockFieldDropdown(
|
||||
this, 'PIN', 'digitalPins');
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['io_digitalread'] = {
|
||||
/**
|
||||
* Block for creating a 'read pin'.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setHelpUrl('http://arduino.cc/en/Reference/DigitalRead');
|
||||
this.setColour(250);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.ARD_DIGITALREAD)
|
||||
.appendField(new Blockly.FieldDropdown(
|
||||
Blockly.Arduino.Boards.selected.digitalPins), 'PIN');
|
||||
this.setOutput(true, Blockly.Types.BOOLEAN.output);
|
||||
this.setTooltip(Blockly.Msg.ARD_DIGITALREAD_TIP);
|
||||
},
|
||||
/** @return {!string} The type of return value for the block, an integer. */
|
||||
getBlockType: function () {
|
||||
return Blockly.Types.BOOLEAN;
|
||||
},
|
||||
/**
|
||||
* Updates the content of the the pin related fields.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
updateFields: function () {
|
||||
Blockly.Arduino.Boards.refreshBlockFieldDropdown(
|
||||
this, 'PIN', 'digitalPins');
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['io_builtin_led'] = {
|
||||
/**
|
||||
* Block for setting built-in LED to a state.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setHelpUrl('http://arduino.cc/en/Reference/DigitalWrite');
|
||||
this.setColour(250);
|
||||
this.appendValueInput('STATE')
|
||||
.appendField(Blockly.Msg.ARD_BUILTIN_LED)
|
||||
.appendField(new Blockly.FieldDropdown(
|
||||
Blockly.Arduino.Boards.selected.builtinLed), 'BUILT_IN_LED')
|
||||
.appendField(Blockly.Msg.ARD_WRITE_TO)
|
||||
.setCheck(Blockly.Types.BOOLEAN.checkList);
|
||||
this.setInputsInline(false);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip(Blockly.Msg.ARD_BUILTIN_LED_TIP);
|
||||
},
|
||||
/**
|
||||
* Updates the content of the the pin related fields.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
updateFields: function () {
|
||||
Blockly.Arduino.Boards.refreshBlockFieldDropdown(
|
||||
this, 'BUILT_IN_LED', 'builtinLed');
|
||||
},
|
||||
/** @return {!string} The type of input value for the block, an integer. */
|
||||
getBlockType: function () {
|
||||
return Blockly.Types.BOOLEAN;
|
||||
},
|
||||
};
|
||||
|
||||
Blockly.Blocks['io_analogwrite'] = {
|
||||
/**
|
||||
* Block for creating a 'set pin' to an analogue value.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setHelpUrl('http://arduino.cc/en/Reference/AnalogWrite');
|
||||
this.setColour(250);
|
||||
this.appendValueInput('NUM')
|
||||
.appendField(Blockly.Msg.ARD_ANALOGWRITE)
|
||||
.appendField(new Blockly.FieldDropdown(
|
||||
Blockly.Arduino.Boards.selected.pwmPins), 'PIN')
|
||||
.appendField(Blockly.Msg.ARD_WRITE_TO)
|
||||
.setCheck(Blockly.Types.NUMBER.output);
|
||||
this.setInputsInline(false);
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
this.setTooltip(Blockly.Msg.ARD_ANALOGWRITE_TIP);
|
||||
},
|
||||
/**
|
||||
* Updates the content of the the pin related fields.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
updateFields: function () {
|
||||
Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, 'PIN', 'pwmPins');
|
||||
},
|
||||
/** @return {!string} The type of input value for the block, an integer. */
|
||||
getBlockType: function () {
|
||||
return Blockly.Types.NUMBER;
|
||||
},
|
||||
};
|
||||
|
||||
Blockly.Blocks['io_analogread'] = {
|
||||
/**
|
||||
* Block for reading an analogue input.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setHelpUrl('http://arduino.cc/en/Reference/AnalogRead');
|
||||
this.setColour(250);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.ARD_ANALOGREAD)
|
||||
.appendField(new Blockly.FieldDropdown(
|
||||
Blockly.Arduino.Boards.selected.analogPins), 'PIN');
|
||||
this.setOutput(true, Blockly.Types.NUMBER.output);
|
||||
this.setTooltip(Blockly.Msg.ARD_ANALOGREAD_TIP);
|
||||
},
|
||||
/** @return {!string} The type of return value for the block, an integer. */
|
||||
getBlockType: function () {
|
||||
return Blockly.Types.NUMBER;
|
||||
},
|
||||
/**
|
||||
* Updates the content of the the pin related fields.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
updateFields: function () {
|
||||
Blockly.Arduino.Boards.refreshBlockFieldDropdown(this, 'PIN', 'analogPins');
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['io_highlow'] = {
|
||||
/**
|
||||
* Block for creating a pin state.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.setHelpUrl('http://arduino.cc/en/Reference/Constants');
|
||||
this.setColour(250);
|
||||
this.appendDummyInput()
|
||||
.appendField(
|
||||
new Blockly.FieldDropdown([[Blockly.Msg.ARD_HIGH, 'HIGH'], [Blockly.Msg.ARD_LOW, 'LOW']]),
|
||||
'STATE');
|
||||
this.setOutput(true, Blockly.Types.BOOLEAN.output);
|
||||
this.setTooltip(Blockly.Msg.ARD_HIGHLOW_TIP);
|
||||
},
|
||||
/** @return {!string} The type of return value for the block, an integer. */
|
||||
getBlockType: function () {
|
||||
return Blockly.Types.BOOLEAN;
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['io_pulsein'] = {
|
||||
/**
|
||||
* Block for measuring the duration of a pulse in an input pin.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.jsonInit({
|
||||
"type": "math_foo",
|
||||
"message0": Blockly.Msg.ARD_PULSE_READ,
|
||||
"args0": [{
|
||||
"type": "input_value",
|
||||
"name": "PULSETYPE",
|
||||
"check": Blockly.Types.BOOLEAN.check
|
||||
}, {
|
||||
"type": "field_dropdown",
|
||||
"name": "PULSEPIN",
|
||||
"options": Blockly.Arduino.Boards.selected.digitalPins
|
||||
}
|
||||
],
|
||||
"output": Blockly.Types.NUMBER.output,
|
||||
"inputsInline": true,
|
||||
"colour": 250,
|
||||
"tooltip": Blockly.Msg.ARD_PULSE_TIP,
|
||||
"helpUrl": 'https://www.arduino.cc/en/Reference/PulseIn'
|
||||
});
|
||||
},
|
||||
/** @return {!string} The type of input value for the block, an integer. */
|
||||
getBlockType: function () {
|
||||
return Blockly.Types.NUMBER;
|
||||
}
|
||||
};
|
||||
|
||||
Blockly.Blocks['io_pulsetimeout'] = {
|
||||
/**
|
||||
* Block for measuring (with a time-out) the duration of a pulse in an input
|
||||
* pin.
|
||||
* @this Blockly.Block
|
||||
*/
|
||||
init: function () {
|
||||
this.jsonInit({
|
||||
"type": "math_foo",
|
||||
"message0": Blockly.Msg.ARD_PULSE_READ_TIMEOUT,
|
||||
"args0": [{
|
||||
"type": "input_value",
|
||||
"name": "PULSETYPE",
|
||||
"check": Blockly.Types.BOOLEAN.check
|
||||
}, {
|
||||
"type": "field_dropdown",
|
||||
"name": "PULSEPIN",
|
||||
"options": Blockly.Arduino.Boards.selected.digitalPins
|
||||
}, {
|
||||
"type": "input_value",
|
||||
"name": "TIMEOUT",
|
||||
"check": Blockly.Types.NUMBER.check
|
||||
}
|
||||
],
|
||||
"output": Blockly.Types.NUMBER.output,
|
||||
"inputsInline": true,
|
||||
"colour": 250,
|
||||
"tooltip": Blockly.Msg.ARD_PULSETIMEOUT_TIP,
|
||||
"helpUrl": 'https://www.arduino.cc/en/Reference/PulseIn'
|
||||
});
|
||||
},
|
||||
/** @return {!string} The type of input value for the block, an integer. */
|
||||
getBlockType: function () {
|
||||
return Blockly.Types.NUMBER;
|
||||
}
|
||||
};
|
17
src/components/Blockly/blocks/sensebox-telegram.js
Normal file
17
src/components/Blockly/blocks/sensebox-telegram.js
Normal file
@ -0,0 +1,17 @@
|
||||
import Blockly from 'blockly';
|
||||
|
||||
Blockly.Blocks["sensebox_telegram"] = {
|
||||
init: function () {
|
||||
this.setColour(120);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.senseBox_telegram_init);
|
||||
this.appendDummyInput()
|
||||
.setAlign(Blockly.ALIGN_LEFT)
|
||||
.appendField("telegram")
|
||||
.appendField(new Blockly.FieldTextInput("token"), "telegram_token");
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,16 +1,4 @@
|
||||
import Blockly from 'blockly';
|
||||
|
||||
Blockly.Blocks["sensebox_telegram"] = {
|
||||
init: function () {
|
||||
this.setColour(120);
|
||||
this.appendDummyInput()
|
||||
.appendField(Blockly.Msg.senseBox_telegram_init);
|
||||
this.appendDummyInput()
|
||||
.setAlign(Blockly.ALIGN_LEFT)
|
||||
.appendField("telegram")
|
||||
.appendField(new Blockly.FieldTextInput("token"), "telegram_token");
|
||||
this.setPreviousStatement(true, null);
|
||||
this.setNextStatement(true, null);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -2,4 +2,6 @@ import './generator';
|
||||
import './loops';
|
||||
import './sensebox';
|
||||
import './logic';
|
||||
import './math';
|
||||
import './io';
|
||||
|
||||
|
32
src/components/Blockly/generator/io.js
Normal file
32
src/components/Blockly/generator/io.js
Normal file
@ -0,0 +1,32 @@
|
||||
import * as Blockly from 'blockly/core';
|
||||
import { Block } from 'blockly';
|
||||
|
||||
/**
|
||||
* Function for 'set pin' (X) to a state (Y).
|
||||
* Arduino code: setup { pinMode(X, OUTPUT); }
|
||||
* loop { digitalWrite(X, Y); }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {string} Completed code.
|
||||
*/
|
||||
Blockly.Arduino['io_digitalwrite'] = function (block) {
|
||||
var pin = block.getFieldValue('PIN');
|
||||
var stateOutput = Blockly.Arduino.valueToCode(
|
||||
block, 'STATE', Blockly['Arduino'].ORDER_ATOMIC) || 'LOW';
|
||||
Blockly['Arduino'].setupCode_['pinMode'] = 'pinMode(' + pin + ', OUTPUT);';
|
||||
var code = 'digitalWrite(' + pin + ', ' + stateOutput + ');\n';
|
||||
return code;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function for reading a digital pin (X).
|
||||
* Arduino code: setup { pinMode(X, INPUT); }
|
||||
* loop { digitalRead(X) }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['io_digitalread'] = function (block) {
|
||||
var pin = block.getFieldValue('PIN');
|
||||
Blockly['Arduino'].setupCode_['pinMode' + pin] = 'pinMode(' + pin + ', INPUT);'
|
||||
var code = 'digitalRead(' + pin + ')';
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
344
src/components/Blockly/generator/math.js
Normal file
344
src/components/Blockly/generator/math.js
Normal file
@ -0,0 +1,344 @@
|
||||
|
||||
import * as Blockly from 'blockly/core';
|
||||
import { Block } from 'blockly';
|
||||
|
||||
/**
|
||||
* @license Licensed under the Apache License, Version 2.0 (the "License"):
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Generating Arduino code for the Math blocks.
|
||||
*
|
||||
* TODO: Math on list needs lists to be implemented.
|
||||
* math_constant and math_change needs to be tested in compiler.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generator for a numeric value (X).
|
||||
* Arduino code: loop { X }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_number'] = function (block) {
|
||||
// Numeric value.
|
||||
var code = parseFloat(block.getFieldValue('NUM'));
|
||||
if (code == Infinity) {
|
||||
code = 'INFINITY';
|
||||
} else if (code == -Infinity) {
|
||||
code = '-INFINITY';
|
||||
}
|
||||
return [code, Blockly.Arduino.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generator for a basic arithmetic operators (X and Y) and power function
|
||||
* (X ^ Y).
|
||||
* Arduino code: loop { X operator Y }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_arithmetic'] = function (block) {
|
||||
var OPERATORS = {
|
||||
ADD: [' + ', Blockly.Arduino.ORDER_ADDITIVE],
|
||||
MINUS: [' - ', Blockly.Arduino.ORDER_ADDITIVE],
|
||||
MULTIPLY: [' * ', Blockly.Arduino.ORDER_MULTIPLICATIVE],
|
||||
DIVIDE: [' / ', Blockly.Arduino.ORDER_MULTIPLICATIVE],
|
||||
POWER: [null, Blockly.Arduino.ORDER_NONE] // Handle power separately.
|
||||
};
|
||||
var tuple = OPERATORS[block.getFieldValue('OP')];
|
||||
var operator = tuple[0];
|
||||
var order = tuple[1];
|
||||
var argument0 = Blockly.Arduino.valueToCode(block, 'A', order) || '0';
|
||||
var argument1 = Blockly.Arduino.valueToCode(block, 'B', order) || '0';
|
||||
var code;
|
||||
// Power in C++ requires a special case since it has no operator.
|
||||
if (!operator) {
|
||||
code = 'Math.pow(' + argument0 + ', ' + argument1 + ')';
|
||||
return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||
}
|
||||
code = argument0 + operator + argument1;
|
||||
return [code, order];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generator for math operators that contain a single operand (X).
|
||||
* Arduino code: loop { operator(X) }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_single'] = function (block) {
|
||||
var operator = block.getFieldValue('OP');
|
||||
var code;
|
||||
var arg;
|
||||
if (operator == 'NEG') {
|
||||
// Negation is a special case given its different operator precedents.
|
||||
arg = Blockly.Arduino.valueToCode(block, 'NUM',
|
||||
Blockly.Arduino.ORDER_UNARY_PREFIX) || '0';
|
||||
if (arg[0] == '-') {
|
||||
// --3 is not legal in C++ in this context.
|
||||
arg = ' ' + arg;
|
||||
}
|
||||
code = '-' + arg;
|
||||
return [code, Blockly.Arduino.ORDER_UNARY_PREFIX];
|
||||
}
|
||||
if (operator == 'ABS' || operator.substring(0, 5) == 'ROUND') {
|
||||
arg = Blockly.Arduino.valueToCode(block, 'NUM',
|
||||
Blockly.Arduino.ORDER_UNARY_POSTFIX) || '0';
|
||||
} else if (operator == 'SIN' || operator == 'COS' || operator == 'TAN') {
|
||||
arg = Blockly.Arduino.valueToCode(block, 'NUM',
|
||||
Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0';
|
||||
} else {
|
||||
arg = Blockly.Arduino.valueToCode(block, 'NUM',
|
||||
Blockly.Arduino.ORDER_NONE) || '0';
|
||||
}
|
||||
// First, handle cases which generate values that don't need parentheses.
|
||||
switch (operator) {
|
||||
case 'ABS':
|
||||
code = 'abs(' + arg + ')';
|
||||
break;
|
||||
case 'ROOT':
|
||||
code = 'sqrt(' + arg + ')';
|
||||
break;
|
||||
case 'LN':
|
||||
code = 'log(' + arg + ')';
|
||||
break;
|
||||
case 'EXP':
|
||||
code = 'exp(' + arg + ')';
|
||||
break;
|
||||
case 'POW10':
|
||||
code = 'pow(10,' + arg + ')';
|
||||
break;
|
||||
case 'ROUND':
|
||||
code = 'round(' + arg + ')';
|
||||
break;
|
||||
case 'ROUNDUP':
|
||||
code = 'ceil(' + arg + ')';
|
||||
break;
|
||||
case 'ROUNDDOWN':
|
||||
code = 'floor(' + arg + ')';
|
||||
break;
|
||||
case 'SIN':
|
||||
code = 'sin(' + arg + ' / 180 * Math.PI)';
|
||||
break;
|
||||
case 'COS':
|
||||
code = 'cos(' + arg + ' / 180 * Math.PI)';
|
||||
break;
|
||||
case 'TAN':
|
||||
code = 'tan(' + arg + ' / 180 * Math.PI)';
|
||||
break;
|
||||
}
|
||||
if (code) {
|
||||
return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||
}
|
||||
// Second, handle cases which generate values that may need parentheses.
|
||||
switch (operator) {
|
||||
case 'LOG10':
|
||||
code = 'log(' + arg + ') / log(10)';
|
||||
break;
|
||||
case 'ASIN':
|
||||
code = 'asin(' + arg + ') / M_PI * 180';
|
||||
break;
|
||||
case 'ACOS':
|
||||
code = 'acos(' + arg + ') / M_PI * 180';
|
||||
break;
|
||||
case 'ATAN':
|
||||
code = 'atan(' + arg + ') / M_PI * 180';
|
||||
break;
|
||||
default:
|
||||
throw 'Unknown math operator: ' + operator;
|
||||
}
|
||||
return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generator for math constants (PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2),
|
||||
* INFINITY).
|
||||
* Arduino code: loop { constant }
|
||||
* TODO: Might need to include "#define _USE_MATH_DEFINES"
|
||||
* The arduino header file already includes math.h
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {string} Completed code.
|
||||
*/
|
||||
Blockly.Arduino['math_constant'] = function (block) {
|
||||
var CONSTANTS = {
|
||||
'PI': ['M_PI', Blockly.Arduino.ORDER_UNARY_POSTFIX],
|
||||
'E': ['M_E', Blockly.Arduino.ORDER_UNARY_POSTFIX],
|
||||
'GOLDEN_RATIO': ['(1 + sqrt(5)) / 2', Blockly.Arduino.ORDER_MULTIPLICATIVE],
|
||||
'SQRT2': ['M_SQRT2', Blockly.Arduino.ORDER_UNARY_POSTFIX],
|
||||
'SQRT1_2': ['M_SQRT1_2', Blockly.Arduino.ORDER_UNARY_POSTFIX],
|
||||
'INFINITY': ['INFINITY', Blockly.Arduino.ORDER_ATOMIC]
|
||||
};
|
||||
return CONSTANTS[block.getFieldValue('CONSTANT')];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generator for math checks: if a number is even, odd, prime, whole, positive,
|
||||
* negative, or if it is divisible by certain number. Returns true or false.
|
||||
* Arduino code: complex code, can create external functions.
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_number_property'] = function (block) {
|
||||
var number_to_check = Blockly.Arduino.valueToCode(block, 'NUMBER_TO_CHECK',
|
||||
Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0';
|
||||
var dropdown_property = block.getFieldValue('PROPERTY');
|
||||
var code;
|
||||
if (dropdown_property == 'PRIME') {
|
||||
var func = [
|
||||
'boolean ' + Blockly.Arduino.DEF_FUNC_NAME + '(int n) {',
|
||||
' // https://en.wikipedia.org/wiki/Primality_test#Naive_methods',
|
||||
' if (n == 2 || n == 3) {',
|
||||
' return true;',
|
||||
' }',
|
||||
' // False if n is NaN, negative, is 1.',
|
||||
' // And false if n is divisible by 2 or 3.',
|
||||
' if (isnan(n) || (n <= 1) || (n == 1) || (n % 2 == 0) || ' +
|
||||
'(n % 3 == 0)) {',
|
||||
' return false;',
|
||||
' }',
|
||||
' // Check all the numbers of form 6k +/- 1, up to sqrt(n).',
|
||||
' for (int x = 6; x <= sqrt(n) + 1; x += 6) {',
|
||||
' if (n % (x - 1) == 0 || n % (x + 1) == 0) {',
|
||||
' return false;',
|
||||
' }',
|
||||
' }',
|
||||
' return true;',
|
||||
'}'];
|
||||
var funcName = Blockly.Arduino.addFunction('mathIsPrime', func.join('\n'));
|
||||
Blockly.Arduino.addInclude('math', '#include <math.h>');
|
||||
code = funcName + '(' + number_to_check + ')';
|
||||
return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||
}
|
||||
switch (dropdown_property) {
|
||||
case 'EVEN':
|
||||
code = number_to_check + ' % 2 == 0';
|
||||
break;
|
||||
case 'ODD':
|
||||
code = number_to_check + ' % 2 == 1';
|
||||
break;
|
||||
case 'WHOLE':
|
||||
Blockly.Arduino.addInclude('math', '#include <math.h>');
|
||||
code = '(floor(' + number_to_check + ') == ' + number_to_check + ')';
|
||||
break;
|
||||
case 'POSITIVE':
|
||||
code = number_to_check + ' > 0';
|
||||
break;
|
||||
case 'NEGATIVE':
|
||||
code = number_to_check + ' < 0';
|
||||
break;
|
||||
case 'DIVISIBLE_BY':
|
||||
var divisor = Blockly.Arduino.valueToCode(block, 'DIVISOR',
|
||||
Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0';
|
||||
code = number_to_check + ' % ' + divisor + ' == 0';
|
||||
break;
|
||||
}
|
||||
return [code, Blockly.Arduino.ORDER_EQUALITY];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generator to add (Y) to a variable (X).
|
||||
* If variable X has not been declared before this block it will be declared as
|
||||
* a (not initialised) global int, however globals are 0 initialised in C/C++.
|
||||
* Arduino code: loop { X += Y; }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_change'] = function (block) {
|
||||
var argument0 = Blockly.Arduino.valueToCode(block, 'DELTA',
|
||||
Blockly.Arduino.ORDER_ADDITIVE) || '0';
|
||||
var varName = Blockly.Arduino.variableDB_.getName(
|
||||
block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);
|
||||
return varName + ' += ' + argument0 + ';\n';
|
||||
};
|
||||
|
||||
/** Rounding functions have a single operand. */
|
||||
Blockly.Arduino['math_round'] = Blockly.Arduino['math_single'];
|
||||
|
||||
/** Trigonometry functions have a single operand. */
|
||||
Blockly.Arduino['math_trig'] = Blockly.Arduino['math_single'];
|
||||
|
||||
/**
|
||||
* Generator for the math function to a list.
|
||||
* Arduino code: ???
|
||||
* TODO: List have to be implemented first. Removed from toolbox for now.
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_on_list'] = Blockly.Arduino.noGeneratorCodeInline;
|
||||
|
||||
/**
|
||||
* Generator for the math modulo function (calculates remainder of X/Y).
|
||||
* Arduino code: loop { X % Y }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_modulo'] = function (block) {
|
||||
var argument0 = Blockly.Arduino.valueToCode(block, 'DIVIDEND',
|
||||
Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0';
|
||||
var argument1 = Blockly.Arduino.valueToCode(block, 'DIVISOR',
|
||||
Blockly.Arduino.ORDER_MULTIPLICATIVE) || '0';
|
||||
var code = argument0 + ' % ' + argument1;
|
||||
return [code, Blockly.Arduino.ORDER_MULTIPLICATIVE];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generator for clipping a number(X) between two limits (Y and Z).
|
||||
* Arduino code: loop { (X < Y ? Y : ( X > Z ? Z : X)) }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_constrain'] = function (block) {
|
||||
// Constrain a number between two limits.
|
||||
var argument0 = Blockly.Arduino.valueToCode(block, 'VALUE',
|
||||
Blockly.Arduino.ORDER_NONE) || '0';
|
||||
var argument1 = Blockly.Arduino.valueToCode(block, 'LOW',
|
||||
Blockly.Arduino.ORDER_NONE) || '0';
|
||||
var argument2 = Blockly.Arduino.valueToCode(block, 'HIGH',
|
||||
Blockly.Arduino.ORDER_NONE) || '0';
|
||||
var code = '(' + argument0 + ' < ' + argument1 + ' ? ' + argument1 +
|
||||
' : ( ' + argument0 + ' > ' + argument2 + ' ? ' + argument2 + ' : ' +
|
||||
argument0 + '))';
|
||||
return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generator for a random integer between two numbers (X and Y).
|
||||
* Arduino code: loop { math_random_int(X, Y); }
|
||||
* and an aditional math_random_int function
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {array} Completed code with order of operation.
|
||||
*/
|
||||
Blockly.Arduino['math_random_int'] = function (block) {
|
||||
var argument0 = Blockly.Arduino.valueToCode(block, 'FROM',
|
||||
Blockly.Arduino.ORDER_NONE) || '0';
|
||||
var argument1 = Blockly.Arduino.valueToCode(block, 'TO',
|
||||
Blockly.Arduino.ORDER_NONE) || '0';
|
||||
var functionName = Blockly.Arduino.variableDB_.getDistinctName(
|
||||
'math_random_int', Blockly.Generator.NAME_TYPE);
|
||||
Blockly.Arduino.setups_['init_rand'] = 'randomSeed(analogRead(0));';
|
||||
Blockly.Arduino.math_random_int.random_function = functionName;
|
||||
var func = [
|
||||
'int ' + Blockly.Arduino.DEF_FUNC_NAME + '(int min, int max) {',
|
||||
' if (min > max) {',
|
||||
' // Swap min and max to ensure min is smaller.',
|
||||
' int temp = min;',
|
||||
' min = max;',
|
||||
' max = temp;',
|
||||
' }',
|
||||
' return min + (rand() % (max - min + 1));',
|
||||
'}'];
|
||||
var funcName = Blockly.Arduino.addFunction('mathRandomInt', func.join('\n'));
|
||||
var code = funcName + '(' + argument0 + ', ' + argument1 + ')';
|
||||
return [code, Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||
};
|
||||
|
||||
/**
|
||||
* Generator for a random float from 0 to 1.
|
||||
* Arduino code: loop { (rand() / RAND_MAX) }
|
||||
* @param {!Blockly.Block} block Block to generate the code from.
|
||||
* @return {string} Completed code.
|
||||
*/
|
||||
Blockly.Arduino['math_random_float'] = function (block) {
|
||||
return ['(rand() / RAND_MAX)', Blockly.Arduino.ORDER_UNARY_POSTFIX];
|
||||
};
|
44
src/components/Blockly/helpers/board.js
Normal file
44
src/components/Blockly/helpers/board.js
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Define boards and pins
|
||||
*
|
||||
*/
|
||||
const sensebox_mcu = {
|
||||
description: 'senseBox Microcontroller Unit based on Microchip SAMD21G18A',
|
||||
compilerFlag: 'arduino:samd',
|
||||
digitalPins: [['D1', '1'], ['D2', '2'], ['D3', '3'], ['D4', '4'], ['D5', '5'], ['D6', '6']],
|
||||
digitalPinsLED: [['BUILTIN_1', '7'], ['BUILTIN_2', '8'], ['D1', '1'], ['D2', '2'], ['D3', '3'], ['D4', '4'], ['D5', '5'], ['D6', '6']],
|
||||
digitalPinsButton: [['on Board', '0'], ['D1', '1'], ['D2', '2'], ['D3', '3'], ['D4', '4'], ['D5', '5'], ['D6', '6']],
|
||||
pwmPins: [['D1', '1'], ['D2', '2'], ['D3', '3'], ['D4', '4'], ['D5', '5'], ['D6', '6']],
|
||||
serial: [['serial', 'SerialUSB'], ['serial_1', 'Serial1'], ['serial_2', 'Serial2']],
|
||||
serialPins: {
|
||||
SerialUSB: [['RX', ''], ['TX', '']],
|
||||
Serial1: [['RX', '11'], ['TX', '10']],
|
||||
Serial2: [['RX', '13'], ['TX', '12']]
|
||||
},
|
||||
serialSpeed: [['300', '300'], ['600', '600'], ['1200', '1200'],
|
||||
['2400', '2400'], ['4800', '4800'], ['9600', '9600'],
|
||||
['14400', '14400'], ['19200', '19200'], ['28800', '28800'],
|
||||
['31250', '31250'], ['38400', '38400'], ['57600', '57600'],
|
||||
['115200', '115200']],
|
||||
spi: [['SPI', 'SPI']],
|
||||
spiPins: { SPI: [['MOSI', '19'], ['MISO', '21'], ['SCK', '20']] },
|
||||
spiClockDivide: [['2 (8MHz)', 'SPI_CLOCK_DIV2'],
|
||||
['4 (4MHz)', 'SPI_CLOCK_DIV4'],
|
||||
['8 (2MHz)', 'SPI_CLOCK_DIV8'],
|
||||
['16 (1MHz)', 'SPI_CLOCK_DIV16'],
|
||||
['32 (500KHz)', 'SPI_CLOCK_DIV32'],
|
||||
['64 (250KHz)', 'SPI_CLOCK_DIV64'],
|
||||
['128 (125KHz)', 'SPI_CLOCK_DIV128']],
|
||||
i2c: [['I2C', 'Wire']],
|
||||
i2cPins: { Wire: [['SDA', '17'], ['SCL', '16']] },
|
||||
i2cSpeed: [['100kHz', '100000L'], ['400kHz', '400000L']],
|
||||
builtinLed: [['BUILTIN_1', '7'], ['BUILTIN_2', '8']],
|
||||
interrupt: [['interrupt1', '1'], ['interrupt2', '2'], , ['interrupt3', '3'], ['interrupt4', '4'], ['interrupt5', '5'], ['interrupt6', '6']],
|
||||
analogPins: [['A1', 'A1'], ['A2', 'A2'], ['A3', 'A3'], ['A4', 'A4'], ['A5', 'A5'], ['A6', 'A6']],
|
||||
serial_baud_rate: 9600,
|
||||
parseKey: '_*_'
|
||||
};
|
||||
|
||||
export const selectedBoard = () => {
|
||||
return sensebox_mcu;
|
||||
};
|
110
src/components/Blockly/toolbox/Toolbox.js
Normal file
110
src/components/Blockly/toolbox/Toolbox.js
Normal file
@ -0,0 +1,110 @@
|
||||
import React, { Component } from 'react';
|
||||
import BlocklyComponent, { Block, Value, Field, Shadow, Category } from '../';
|
||||
|
||||
|
||||
class Toolbox extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<xml xmlns="https://developers.google.com/blockly/xml" id="blockly" style={{ display: 'none' }} ref={this.props.toolbox}>
|
||||
<Category name="senseBox" colour="120">
|
||||
<Category name="Sensoren" colour="120" >
|
||||
<Block type="sensebox_sensor_temp_hum" />
|
||||
</Category >
|
||||
<Category name="Telegram">
|
||||
<Block type="sensebox_telegram" />
|
||||
</Category>
|
||||
</Category>
|
||||
<Category name="Logic" colour="#b063c5">
|
||||
<Block type="control_if" />
|
||||
<Block type="controls_ifelse" />
|
||||
<Block type="logic_compare" />
|
||||
<Block type="logic_operation" />
|
||||
<Block type="logic_negate" />
|
||||
<Block type="logic_boolean" />
|
||||
</Category>
|
||||
<Category id="lops" name="Loops" colour="10">
|
||||
<Block type="controls_repeat_ext">
|
||||
<Value name="TIMES">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">10</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="controls_whileUntil" />
|
||||
<Block type="controls_for">
|
||||
<Value name="FROM">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">1</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="TO" >
|
||||
<Block type="math_number" >
|
||||
<Field name="NUM">10</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="BY" >
|
||||
<Block Type="math_number" >
|
||||
<Field name="NUM">1</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="controls_flow_statements" />
|
||||
</Category>
|
||||
<Category id="catMath" name="Math" colour="230">
|
||||
<Block type="math_number"></Block>
|
||||
<Block type="math_arithmetic"></Block>
|
||||
<Block type="math_single"></Block>
|
||||
<Block type="math_trig"></Block>
|
||||
<Block type="math_constant"></Block>
|
||||
<Block type="math_number_property"></Block>
|
||||
<Block type="math_change">
|
||||
<Value name="DELTA">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">1</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="math_round"></Block>
|
||||
<Block type="math_modulo"></Block>
|
||||
<Block type="math_constrain">
|
||||
<Value name="LOW">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">1</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="HIGH">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">100</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="math_random_int">
|
||||
<Value name="FROM">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">1</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
<Value name="TO">
|
||||
<Block type="math_number">
|
||||
<Field name="NUM">100</Field>
|
||||
</Block>
|
||||
</Value>
|
||||
</Block>
|
||||
<Block type="math_random_float"></Block>
|
||||
{/* <Block type="base_map"></Block> */}
|
||||
</Category>
|
||||
<sep></sep>
|
||||
<Category name="Input/Output">
|
||||
<Block type="io_digitalwrite"></Block>
|
||||
<Block type="io_digitalread"></Block>
|
||||
</Category>
|
||||
</xml>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default Toolbox;
|
@ -7,8 +7,9 @@ import BlocklyComponent, { Block, Value, Field, Shadow, Category } from './Block
|
||||
import * as Blockly from 'blockly/core';
|
||||
import * as De from './Blockly/msg/de'; // de locale files
|
||||
//import * as En from './Blockly/msg/en'; // de locale files
|
||||
import './Blockly/blocks/index';
|
||||
import './Blockly/generator/index';
|
||||
import './Blockly/blocks/';
|
||||
import './Blockly/generator/';
|
||||
|
||||
|
||||
|
||||
|
||||
@ -43,27 +44,7 @@ class Home extends React.Component {
|
||||
drag: true,
|
||||
wheel: true
|
||||
}}
|
||||
initialXml={''}>
|
||||
<Category name="loops" >
|
||||
<Block type="controls_for" />
|
||||
<Block type="controls_repeat_ext" />
|
||||
<Block type="controls_whileUntil" />
|
||||
</Category>
|
||||
<Category name="senseBox" colour="120" >
|
||||
<Category name="Sensoren" colour="120" >
|
||||
<Block type="sensebox_sensor_temp_hum"></Block>
|
||||
</Category>
|
||||
<Block type="sensebox_telegram" />
|
||||
</Category>
|
||||
<Category name="Logic" colour="#b063c5">
|
||||
<Block type="control_if"></Block>
|
||||
<Block type="controls_ifelse"></Block>
|
||||
<Block type="logic_compare"></Block>
|
||||
<Block type="logic_operation"></Block>
|
||||
<Block type="logic_negate"></Block>
|
||||
<Block type="logic_boolean"></Block>
|
||||
</Category>
|
||||
</BlocklyComponent>
|
||||
initialXml={''} />
|
||||
<WorkspaceFunc generateCode={this.generateCode} />
|
||||
</div>
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user