ftduino set ftDuino LED %1 Switch the red ftDuino LED set ftDuino output %1 %2 Switch a ftDuino output start ftDuino motor %1 %2 with %3 Switch a ftDuino motor output stop ftDuino motor %1 Switch an ftDuino motor off set servo %1 to %2 degrees Set a ftDuino servo output reset ftDuino counter %1 Set the value of a ftDuino counter to 0 %1 on ftDuino input %2 Read the state of a ftDuino input ftDuino counter %1 Read the value of a ftDuino input distance in cm Read the distance from an ultrasonic distance sensor connected to C1 voltage in mV resistance switch state left \u21BA right \u21BB Check for ftDuino ... Controller not connected! Connected ftDuino: No ftDuino connected! ftduino schalte ftDuino LED %1 Schalte die rote ftDuino LED schalte ftDuino-Ausgang %1 %2 Schalte einen ftDuino-Ausgang starte ftDuino-Motor %1 %2 mit %3 Schalte einen ftDuino-Motor-Ausgang stoppe ftDuino-Motor %1 Schalte einen ftDuino-Motor-Ausgang aus setze Servo %1 auf %2 Grad Setze ein ftDuino-Servo-Ausgang Zähler %1 zurücksetzen Setze den Wert eines ftDuino-Zähler-Eingangs auf 0 %1 an ftDuino-Eingang %2 Lies den Zustand eines ftDuino-Eingangs ftDuino Zähler %1 Lies den aktuellen Wert eines ftDuino-Zähler-Eingangs Entfernung in cm Lies den aktuellen Wert eines Ultraschall-Sensors an C1 Spannung in mV Widerstand Schalterzustand links \u21BA rechts \u21BB Suche nach ftDuino ... Controller nicht verbunden! Verbundener ftDuino: Kein ftDuino verbunden! // register a callback function for anything the TXT code might // want to send back Code.plugins["ftduino"]["check_reply"] = function(msg) { if(msg == null) alert("{{noConFtd}}"); else alert("{{conFtd}}" + msg); } Code.plugins["ftduino"]["checkButton"] = function() { // send a message to the TXT and display reply if(!Code.connected) { alert("{{nocon}}"); return; } // send command to TXT Code.ws.send(JSON.stringify( { "plugin:ftduino:check": "true" } )); } console.log("ftduino plugin loaded") // this will immediately show up Code.workspace.registerButtonCallback("plugin:ftduino:checkButton", Code.plugins["ftduino"]["checkButton"]) { "message0": "{{input_message}}", "args0": [ { "type": "field_dropdown", "name": "type", "options": [ [ "{{input_voltage}}", "Voltage" ], [ "{{input_switch}}", "Switch" ], [ "{{input_resistor}}", "Resistance" ] ] }, { "type": "field_dropdown", "name": "input_port", "options": [ [ "I1", "I1" ], [ "I2", "I2" ], [ "I3", "I3" ], [ "I4", "I4" ], [ "I5", "I5" ], [ "I6", "I6" ], [ "I7", "I7" ], [ "I8", "I8" ] ] } ], "output": "Number", "colour": 220, "tooltip": "{{input_tooltip}}" } var type = block.getFieldValue('type'); var port = block.getFieldValue('input_port'); code = '{{_SELF}}.input_get("%1", "%2")'.replace("%1", type).replace('%2', port); return [code, Blockly.Python.ORDER_NONE]; { "message0": "{{distance_message}}", "output": "Number", "colour": 220, "tooltip": "{{distance_tooltip}}" } code = '{{_SELF}}.distance_get()'; return [code, Blockly.Python.ORDER_NONE]; { "message0": "{{counter_message}}", "args0": [{ "type": "field_dropdown", "name": "input_port", "options": [ [ "C1", "C1" ], [ "C2", "C2" ], [ "C3", "C3" ], [ "C4", "C4" ] ] } ], "output": "Number", "colour": 220, "tooltip": "{{counter_tooltip}}" } var port = block.getFieldValue('input_port'); code = '{{_SELF}}.counter_get("%1")'.replace("%1", port); return [code, Blockly.Python.ORDER_NONE]; { "message0": "{{counter_reset_message}}", "args0": [{ "type": "field_dropdown", "name": "input_port", "options": [ [ "C1", "C1" ], [ "C2", "C2" ], [ "C3", "C3" ], [ "C4", "C4" ] ] } ], "previousStatement": null, "nextStatement": null, "colour": 220, "tooltip": "{{counter_reset_tooltip}}" } var port = block.getFieldValue('input_port'); var cmd = '{{_SELF}}.counter_reset("%1")\n'.replace("%1", port); return cmd; { "message0": "{{output_message}}", "args0": [ { "type": "field_dropdown", "name": "port", "options": [ ["O1","O1"], ["O2","O2"], [ "O3","O3"], ["O4","O4"], ["O5","O5"], [ "O6","O6"], ["O7","O7"], [ "O8","O8"] ] }, { "type": "input_value", "name": "value", "check": "Number" }], "previousStatement": null, "nextStatement": null, "colour": 220, "tooltip": "{{output_tooltip}}" } var port = block.getFieldValue('port'); var value = Blockly.Python.valueToCode(block, 'value', Blockly.Python.ORDER_ATOMIC); var cmd = '{{_SELF}}.output_set("%1", %2)\n'.replace('%1', port).replace('%2', value); // console.log("CMD:", cmd); return cmd; { "message0": "{{led_message}}", "args0": [ { "type": "input_value", "name": "state", "check": "Number" }], "previousStatement": null, "nextStatement": null, "colour": 220, "tooltip": "{{led_tooltip}}" } var state = Blockly.Python.valueToCode(block, 'state', Blockly.Python.ORDER_ATOMIC); var cmd = '{{_SELF}}.led_set(%1)\n'.replace('%1', state); return cmd; { "message0": "{{motor_message}}", "args0": [ { "type": "field_dropdown", "name": "port", "options": [ ["M1","M1"], ["M2","M2"], [ "M3","M3"], [ "M4","M4"] ] }, { "type": "field_dropdown", "name": "dir", "options": [ ["{{left}}", "left"], ["{{right}}", "right"] ] }, { "type": "input_value", "name": "value", "check": "Number" }], "previousStatement": null, "nextStatement": null, "colour": 220, "tooltip": "{{motor_tooltip}}" } var port = block.getFieldValue('port'); var dir = block.getFieldValue('dir'); var value = Blockly.Python.valueToCode(block, 'value', Blockly.Python.ORDER_ATOMIC); var cmd = '{{_SELF}}.motor_set("%1", "%2", %3)\n'.replace('%1', port).replace('%2', dir).replace('%3', value); return cmd; { "message0": "{{motor_stop_message}}", "args0": [ { "type": "field_dropdown", "name": "port", "options": [ ["M1","M1"], ["M2","M2"], [ "M3","M3"], [ "M4","M4"] ] }], "previousStatement": null, "nextStatement": null, "colour": 220, "tooltip": "{{motor_stop_tooltip}}" } var port = block.getFieldValue('port'); var cmd = '{{_SELF}}.motor_set("%1", "brake", 0)\n'.replace('%1', port); return cmd; { "message0": "{{servo_message}}", "args0": [ { "type": "field_dropdown", "name": "port", "options": [ ["0","0"], ["1","1"] ] }, { "type": "input_value", "name": "value", "check": "Number" }], "previousStatement": null, "nextStatement": null, "colour": 220, "tooltip": "{{servo_tooltip}}" } var port = block.getFieldValue('port'); var value = Blockly.Python.valueToCode(block, 'value', Blockly.Python.ORDER_ATOMIC); var cmd = '{{_SELF}}.servo_set(%1, %2)\n'.replace('%1', port).replace('%2', value); return cmd; import ftduino_direct as ftd def __init__(self, parent): self.parent = parent print("ftDuino plugin init", parent) self.ftduino = self.ftd.ftduino() self.__ultrasonic_enabled = False def __ultrasonic_enable(self, enable): if enable != self.__ultrasonic_enabled: self.__ultrasonic_enabled = enable self.ftduino.comm("ultrasonic_enable " + ("true" if enable else "false")) #python equivalent for the arduino 'map' function to convert degrees to pulsewidth def __arduino_map(self, degrees, min_degrees, max_degrees, min_pulsewidth, max_pulsewidth): return int((degrees - min_degrees) * (max_pulsewidth - min_pulsewidth) / (max_degrees - min_degrees) + min_pulsewidth) # this function is invoked from the button from javascript side def check(self, str): if self.ftduino.getDevice() == None: self.parent.tx(json.dumps( { "plugin:ftduino:check_reply": None } )) else: self.parent.tx(json.dumps( { "plugin:ftduino:check_reply": self.ftduino.comm("ftduino_id_get") } )) # a plugin may implement a init functon which is called whenever a program is # being started def init(self): pass def input_get(self, a, b): self.ftduino.comm("input_set_mode "+b+" "+a) result=self.ftduino.comm("input_get "+b) return int(result) def output_set(self, a, b): self.ftduino.comm("output_set "+a+" 1 "+str(int(5.12*b))) def motor_set(self, a, b, c): self.ftduino.comm("motor_set "+a+" "+b+" "+str(int(5.12*c))) def servo_set(self, a, b): # map b -45 .. +45 to 63 .. 125 self.ftduino.comm("i2c_write 17 "+str(a)+" "+str(94 + int(b*31/45))) def led_set(self, a): self.ftduino.comm("LED_set "+str(int(bool(a)))) def counter_get(self, a): if a == "C1": self.__ultrasonic_enable(False) result=self.ftduino.comm("counter_get "+a) return int(result) def counter_reset(self, a): if a == "C1": self.__ultrasonic_enable(False) self.ftduino.comm("counter_set_mode " + a + " rising") self.ftduino.comm("counter_clear " + a) def distance_get(self): self.__ultrasonic_enable(True) result=self.ftduino.comm("ultrasonic_get") return int(result) # a plugin may implement a cleanup functon which is called whenever a program # has ended def cleanup(self): # switch off all outputs for o in range(8): self.ftduino.comm("output_set O"+str(o+1)+" 0 0");