diff --git a/boards/default_src/micropython/blocks/actuator_onboard.js b/boards/default_src/micropython/blocks/actuator_onboard.js
index 42e0b567..e5f2c228 100644
--- a/boards/default_src/micropython/blocks/actuator_onboard.js
+++ b/boards/default_src/micropython/blocks/actuator_onboard.js
@@ -998,4 +998,209 @@ export const set_all_power_output = {
this.setInputsInline(true);
this.setTooltip(Blockly.Msg.MIXLY_MIXBOT_MOTOR_EXTERN_TOOLTIP);
}
+}
+
+export const analog_keyboard_input = {
+ init: function () {
+ this.setColour(ACTUATOR_ONBOARD_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.ANALOG+Blockly.Msg.MIXLY_KEYBOARD_INPUT);
+ this.appendValueInput('special')
+ .appendField(Blockly.Msg.MIXLY_SPECIAL_KEY);
+ this.appendValueInput('general')
+ .appendField(Blockly.Msg.MIXLY_GENERAL_KEY);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_RELEASE)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MICROPYTHON_DISPLAY_YES, "True"],
+ [Blockly.Msg.MICROPYTHON_DISPLAY_NO, "False"]
+ ]),'release');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.ANALOG + Blockly.Msg.MIXLY_KEYBOARD_INPUT);
+ }
+};
+
+export const special_key = {
+ init: function () {
+ this.setColour(ACTUATOR_ONBOARD_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_SPECIAL_KEY0,"0"],
+ [Blockly.Msg.MIXLY_SPECIAL_KEY1, "1"],
+ [Blockly.Msg.MIXLY_SPECIAL_KEY2, "2"],
+ [Blockly.Msg.MIXLY_SPECIAL_KEY1, "4"],
+ [Blockly.Msg.MIXLY_SPECIAL_KEY8, "8"],
+ [Blockly.Msg.MIXLY_SPECIAL_KEY16, "16"],
+ [Blockly.Msg.MIXLY_SPECIAL_KEY32, "32"],
+ [Blockly.Msg.MIXLY_SPECIAL_KEY64, "64"],
+ [Blockly.Msg.MIXLY_SPECIAL_KEY128, "128"]
+ ]), 'op')
+ this.setOutput(true);
+ }
+};
+
+export const general_key = {
+ init: function () {
+ this.setColour(ACTUATOR_ONBOARD_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_SPECIAL_KEY0,"0"],
+ ['A', "0x04"],
+ ['B', "0x05"],
+ ['C', "0x06"],
+ ['D', "0x07"],
+ ['E', "0x08"],
+ ['F', "0x09"],
+ ['G', "0x0A"],
+ ['H', "0x0B"],
+ ['I', "0x0C"],
+ ['J', "0x0D"],
+ ['K', "0x0E"],
+ ['L', "0x0F"],
+ ['M', "0x10"],
+ ['N', "0x11"],
+ ['O', "0x12"],
+ ['P', "0x13"],
+ ['Q', "0x14"],
+ ['R', "0x15"],
+ ['S', "0x16"],
+ ['T', "0x17"],
+ ['U', "0x18"],
+ ['V', "0x19"],
+ ['W', "0x1A"],
+ ['X', "0x1B"],
+ ['Y', "0x1C"],
+ ['Z', "0x1D"],
+ ['ONE', "0x1E"],
+ ['TWO', "0x1F"],
+ ['THREE', "0x20"],
+ ['FOUR', "0x21"],
+ ['FIVE', "0x22"],
+ ['SIX', "0x23"],
+ ['SEVEN', "0x24"],
+ ['EIGHT', "0x25"],
+ ['NINE', "0x26"],
+ ['ZERO', "0x27"],
+ ['ENTER', "0x28"],
+ ['ESC', "0x29"],
+ ['BACKSPACE', "0x2A"],
+ ['TAB', "0x2B"],
+ ['SPACE', "0x2C"],
+ ['MINUS', "0x2D"],
+ ['EQUAL', "0x2E"],
+ ['LEFT_BRACE', "0x2F"],
+ ['RIGHT_BRACE', "0x30"],
+ ['BACKSLASH', "0x31"],
+ ['SEMICOLON', "0x33"],
+ ['QUOTE', "0x34"],
+ ['TILDE', "0x35"],
+ ['COMMA', "0x36"],
+ ['PERIOD', "0x37"],
+ ['SLASH', "0x38"],
+ ['CAPS_LOCK', "0x39"],
+ ['F1', "0x3A"],
+ ['F2', "0x3B"],
+ ['F3', "0x3C"],
+ ['F4', "0x3D"],
+ ['F5', "0x3E"],
+ ['F6', "0x3F"],
+ ['F7', "0x40"],
+ ['F8', "0x41"],
+ ['F9', "0x42"],
+ ['F10', "0x43"],
+ ['F11', "0x44"],
+ ['F12', "0x45"],
+ ['PRINTSCREEN', "0x46"],
+ ['SCROLL_LOCK', "0x47"],
+ ['PAUSE', "0x48"],
+ ['INSERT', "0x49"],
+ ['HOME', "0x4A"],
+ ['PAGE_UP', "0x4B"],
+ ['DELETE', "0x4C"],
+ ['END', "0x4D"],
+ ['PAGE_DOWN', "0x4E"],
+ ['RIGHT', "0x4F"],
+ ['LEFT', "0x50"],
+ ['DOWN', "0x51"],
+ ['UP', "0x52"],
+ ['NUM_LOCK', "0x53"],
+ ['NUMPAD_SLASH', "0x54"],
+ ['NUMPAD_ASTERISK', "0x55"],
+ ['NUMPAD_MINUS', "0x56"],
+ ['NUMPAD_PLUS', "0x57"],
+ ['NUMPAD_ENTER', "0x58"],
+ ['NUMPAD_1', "0x59"],
+ ['NUMPAD_2', "0x5A"],
+ ['NUMPAD_3', "0x5B"],
+ ['NUMPAD_4', "0x5C"],
+ ['NUMPAD_5', "0x5D"],
+ ['NUMPAD_6', "0x5E"],
+ ['NUMPAD_7', "0x5F"],
+ ['NUMPAD_8', "0x60"],
+ ['NUMPAD_9', "0x61"],
+ ['NUMPAD_0', "0x62"],
+ ['NUMPAD_PERIOD', "0x63"]
+ ]), 'op')
+ this.setOutput(true);
+ }
+};
+
+
+export const analog_mouse_input = {
+ init: function () {
+ this.setColour(ACTUATOR_ONBOARD_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.ANALOG+Blockly.Msg.MIXLY_MOUSE_INPUT);
+ this.appendValueInput('key')
+ .appendField(Blockly.Msg.MIXLY_MOUSE_KEYS);
+ this.appendValueInput('x')
+ .appendField(Blockly.Msg.MIXLY_X_Y_CHANGES+'x:');
+ this.appendValueInput('y')
+ .appendField('y:');
+ this.appendValueInput('wheel')
+ .appendField(Blockly.Msg.MIXLY_WHEEL_CHANGES);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_RELEASE)
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MICROPYTHON_DISPLAY_YES, "True"],
+ [Blockly.Msg.MICROPYTHON_DISPLAY_NO, "False"]
+ ]),'release');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ this.setTooltip(Blockly.Msg.ANALOG + Blockly.Msg.MIXLY_KEYBOARD_INPUT);
+ }
+};
+
+export const mouse_key = {
+ init: function () {
+ this.setColour(ACTUATOR_ONBOARD_HUE);
+ this.appendDummyInput("")
+ .appendField(new Blockly.FieldDropdown([
+ [Blockly.Msg.MIXLY_SPECIAL_KEY0,"0"],
+ [Blockly.Msg.MIXLY_MOUSE_LEFT_KEY, "1"],
+ [Blockly.Msg.MIXLY_MOUSE_RIGHT_KEY, "2"],
+ [Blockly.Msg.MIXLY_MOUSE_MID_KEY, "4"]
+ ]), 'op')
+ this.setOutput(true);
+ }
+};
+
+export const analog_keyboard_str = {
+ init:function(){
+ this.setColour(ACTUATOR_ONBOARD_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.ANALOG+Blockly.Msg.MIXLY_KEYBOARD_INPUT);
+ this.appendValueInput('str')
+ .appendField(Blockly.Msg.MIXLY_STR_PRINT);
+ this.appendValueInput('time')
+ .appendField(Blockly.Msg.MIXLY_STR_PRINT_TIME_DELAY);
+ this.appendDummyInput()
+ .appendField('ms');
+ this.setPreviousStatement(true);
+ this.setNextStatement(true);
+ this.setInputsInline(true);
+ }
}
\ No newline at end of file
diff --git a/boards/default_src/micropython/blocks/sensor_extern.js b/boards/default_src/micropython/blocks/sensor_extern.js
index 080073fe..564cf700 100644
--- a/boards/default_src/micropython/blocks/sensor_extern.js
+++ b/boards/default_src/micropython/blocks/sensor_extern.js
@@ -349,6 +349,7 @@ export const sensor_use_i2c_init = {
["ADXL345", "ADXL345"],
["LTR308", "LTR308"],
["LTR381RGB", "LTR381RGB"],
+ ["LTR390UV","LTR390UV"],
["HP203X", "HP203X"],
["SHTC3", "SHTC3"],
["AHT21", "AHT21"],
diff --git a/boards/default_src/micropython/generators/actuator_onboard.js b/boards/default_src/micropython/generators/actuator_onboard.js
index 25081dfd..5cbb76c0 100644
--- a/boards/default_src/micropython/generators/actuator_onboard.js
+++ b/boards/default_src/micropython/generators/actuator_onboard.js
@@ -442,4 +442,50 @@ export const set_all_power_output = function (_, generator) {
generator.definitions_['import_' + version + '_onboard_bot'] = 'from ' + version + ' import onboard_bot';
var code = 'onboard_bot.usben(freq = ' + duty + ')\n';
return code;
+}
+
+export const analog_keyboard_input = function (_, generator) {
+ var version = Boards.getSelectedBoardKey().split(':')[2]
+ var sp = generator.valueToCode(this, 'special', generator.ORDER_ATOMIC);
+ var ge = generator.valueToCode(this, 'general', generator.ORDER_ATOMIC);
+ var re = this.getFieldValue('release');
+ generator.definitions_['import_' + version + '_onboard_bot'] = 'from ' + version + ' import onboard_bot';
+ var code = "hid_keyboard(special="+sp+",general="+ge+",release="+re+")\n";
+ return code;
+}
+
+export const special_key = function (_, generator) {
+ var code = this.getFieldValue('op');
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const general_key = function (_, generator) {
+ var code = this.getFieldValue('op');
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const analog_mouse_input = function (_, generator) {
+ var version = Boards.getSelectedBoardKey().split(':')[2]
+ var key = generator.valueToCode(this, 'key', generator.ORDER_ATOMIC);
+ var x = generator.valueToCode(this, 'x', generator.ORDER_ATOMIC);
+ var y = generator.valueToCode(this, 'y', generator.ORDER_ATOMIC);
+ var wheel = generator.valueToCode(this, 'wheel', generator.ORDER_ATOMIC);
+ var re = this.getFieldValue('release');
+ generator.definitions_['import_' + version + '_onboard_bot'] = 'from ' + version + ' import onboard_bot';
+ var code = "hid_mouse(keys="+key+",move=("+x+","+y+"),wheel="+wheel+",release="+re+")\n";
+ return code;
+}
+
+export const mouse_key = function (_, generator) {
+ var code = this.getFieldValue('op');
+ return [code, generator.ORDER_ATOMIC];
+}
+
+export const analog_keyboard_str = function (_, generator) {
+ var version = Boards.getSelectedBoardKey().split(':')[2]
+ var str = generator.valueToCode(this, 'str', generator.ORDER_ATOMIC);
+ var t = generator.valueToCode(this, 'time', generator.ORDER_ATOMIC);
+ generator.definitions_['import_' + version + '_onboard_bot'] = 'from ' + version + ' import onboard_bot';
+ var code = "onboard_bot.hid_keyboard_str("+str+",delay="+t+")\n";
+ return code;
}
\ No newline at end of file
diff --git a/boards/default_src/micropython/generators/sensor_extern.js b/boards/default_src/micropython/generators/sensor_extern.js
index 5452d658..c9f15997 100644
--- a/boards/default_src/micropython/generators/sensor_extern.js
+++ b/boards/default_src/micropython/generators/sensor_extern.js
@@ -175,10 +175,13 @@ export const sensor_use_i2c_init = function (_, generator) {
code = v + ' = adxl345.' + key + "(" + iv + ')\n';
} else if (key == 'LTR308') {
generator.definitions_['import_ltr308al'] = 'import ltr308al';
- code = v + ' = ltr308al.LTR_308ALS(' + iv + ')\n';
+ code = v + ' = ltr308al.LTR308ALS(' + iv + ')\n';
} else if (key == 'LTR381RGB') {
generator.definitions_['import_ltr381rgb'] = 'import ltr381rgb';
code = v + ' = ltr381rgb.LTR_381RGB(' + iv + ')\n';
+ }else if (key == 'LTR390UV'){
+ generator.definitions_['import_ltr390uv'] = 'import ltr390uv';
+ code = v + ' = ltr390uv.ALS_UVS(' + iv +')\n';
} else if (key == 'HP203X') {
generator.definitions_['import_hp203x'] = 'import hp203x';
code = v + ' = hp203x.HP203X(' + iv + ')\n';
diff --git a/boards/default_src/micropython_esp32/template.xml b/boards/default_src/micropython_esp32/template.xml
index 134db199..e5444aa5 100644
--- a/boards/default_src/micropython_esp32/template.xml
+++ b/boards/default_src/micropython_esp32/template.xml
@@ -306,6 +306,7 @@
+
@@ -6637,6 +6638,18 @@
+
+
+
+
+
+ url
+
+
+
+
+
+
diff --git a/boards/default_src/micropython_esp32c2/origin/build/lib/mini_bot.py b/boards/default_src/micropython_esp32c2/origin/build/lib/mini_bot.py
index 7c2f9f16..a03e85e8 100644
--- a/boards/default_src/micropython_esp32c2/origin/build/lib/mini_bot.py
+++ b/boards/default_src/micropython_esp32c2/origin/build/lib/mini_bot.py
@@ -1,289 +1,323 @@
-"""
-MINI_WCH
-
-Micropython library for the MINI_WCH(TOUCH*2, MIC*1, Buzzer*1, PWM*2, Matrix8x12)
-=======================================================
-@dahanzimin From the Mixly Team
-"""
-import time
-from esp import flash_read
-from micropython import const
-from framebuf import FrameBuffer, MONO_VLSB
-
-_BOT035_ADDRESS = const(0x13)
-_BOT5_TOUCH = const(0x01)
-_BOT035_MIC = const(0x05)
-_BOT035_SPK = const(0x07)
-_BOT035_PWM = const(0x0B)
-_BOT035_FLAG = const(0x0F)
-_BOT035_LEDS = const(0x10)
-_BOT035_PGA = const(0x20)
-_FONT_W = const(5)
-_FONT_H = const(8)
-_LEDS_W = const(12)
-_LEDS_H = const(8)
-_FONT5x8_CODE = const(b'\x05\x08\x00\x00\x00\x00\x00\x00\x00_\x00\x00\x00\x07\x00\x07\x00\x14\x7f\x14\x7f\x14$*\x7f*\x12#\x13\x08db6IV P\x00\x08\x07\x03\x00\x00\x1c"A\x00\x00A"\x1c\x00*\x1c\x7f\x1c*\x08\x08>\x08\x08\x00\x80p0\x00\x08\x08\x08\x08\x08\x00\x00``\x00 \x10\x08\x04\x02>QIE>\x00B\x7f@\x00rIIIF!AIM3\x18\x14\x12\x7f\x10\'EEE9A]YN|\x12\x11\x12|\x7fIII6>AAA"\x7fAAA>\x7fIIIA\x7f\t\t\t\x01>AAQs\x7f\x08\x08\x08\x7f\x00A\x7fA\x00 @A?\x01\x7f\x08\x14"A\x7f@@@@\x7f\x02\x1c\x02\x7f\x7f\x04\x08\x10\x7f>AAA>\x7f\t\t\t\x06>AQ!^\x7f\t\x19)F&III2\x03\x01\x7f\x01\x03?@@@?\x1f @ \x1f?@8@?c\x14\x08\x14c\x03\x04x\x04\x03aYIMC\x00\x7fAAA\x02\x04\x08\x10 \x00AAA\x7f\x04\x02\x01\x02\x04@@@@@\x00\x03\x07\x08\x00 TTx@\x7f(DD88DDD(8DD(\x7f8TTT\x18\x00\x08~\t\x02\x18\xa4\xa4\x9cx\x7f\x08\x04\x04x\x00D}@\x00 @@=\x00\x7f\x10(D\x00\x00A\x7f@\x00|\x04x\x04x|\x08\x04\x04x8DDD8\xfc\x18$$\x18\x18$$\x18\xfc|\x08\x04\x04\x08HTTT$\x04\x04?D$<@@ |\x1c @ \x1c<@0@> 26
- buffer = bytearray( 12 * (font_width // 8 + 1))
- flash_read(_Uincode_ADDR + font_address, buffer)
- return buffer, font_width
-
- def shift(self, x, y, rotate=False):
- """Shift pixels by x and y"""
- if x > 0: # Shift Right
- for _ in range(x):
- for row in range(0, _LEDS_H):
- last_pixel = self.pixel(_LEDS_W - 1, row) if rotate else 0
- for col in range(_LEDS_W - 1, 0, -1):
- self.pixel(col, row, self.pixel(col - 1, row))
- self.pixel(0, row, last_pixel)
- elif x < 0: # Shift Left
- for _ in range(-x):
- for row in range(0, _LEDS_H):
- last_pixel = self.pixel(0, row) if rotate else 0
- for col in range(0, _LEDS_W - 1):
- self.pixel(col, row, self.pixel(col + 1, row))
- self.pixel(_LEDS_W - 1, row, last_pixel)
- if y > 0: # Shift Up
- for _ in range(y):
- for col in range(0, _LEDS_W):
- last_pixel = self.pixel(col, _LEDS_H - 1) if rotate else 0
- for row in range(_LEDS_H - 1, 0, -1):
- self.pixel(col, row, self.pixel(col, row - 1))
- self.pixel(col, 0, last_pixel)
- elif y < 0: # Shift Down
- for _ in range(-y):
- for col in range(0, _LEDS_W):
- last_pixel = self.pixel(col, 0) if rotate else 0
- for row in range(0, _LEDS_H - 1):
- self.pixel(col, row, self.pixel(col, row + 1))
- self.pixel(col, _LEDS_H - 1, last_pixel)
- self.show()
-
- def shift_right(self, num, rotate=False):
- """Shift all pixels right"""
- self.shift(num, 0, rotate)
-
- def shift_left(self, num, rotate=False):
- """Shift all pixels left"""
- self.shift(-num, 0, rotate)
-
- def shift_up(self, num, rotate=False):
- """Shift all pixels up"""
- self.shift(0, -num, rotate)
-
- def shift_down(self, num, rotate=False):
- """Shift all pixels down"""
- self.shift(0, num, rotate)
-
- def map_invert(self, own):
- """Graph invert operation"""
- result = bytearray()
- for i in range(len(own)):
- result.append(~ own[i])
- return result
-
- def map_add(self, own, other):
- """Graph union operation"""
- result = bytearray()
- for i in range(min(len(own), len(other))):
- result.append(own[i] | other[i])
- return result
-
- def map_sub(self, own, other):
- """Graphic subtraction operation"""
- result = bytearray()
- for i in range(min(len(own), len(other))):
- result.append((own[i] ^ other[i]) & own[i])
- return result
-
- def set_buffer(self, buffer):
- for i in range(len(buffer)):
- self._buffer[i] = self._buffer[i] | buffer[i]
-
- def _ascall_bitmap(self, buffer, x=0):
- if -_FONT_W <= x <= _LEDS_W:
- for _x in range(_FONT_W):
- for _y in range(_FONT_H):
- if (buffer[_x] >> _y) & 0x1:
- self.pixel(x + _x, _y, 1)
-
- def _uincode_bitmap(self, buffer, x=0):
- _buffer, width = buffer
- if -width < x < _LEDS_H:
- for _y in range(12):
- for _x in range(width):
- if _buffer[_y * ((width + 7) // 8) + _x // 8] & (0x80 >> (_x & 7)):
- self.pixel(_y, _LEDS_H - (x + _x), 1)
-
- def shows(self, data, space=1, center=True):
- """Display character"""
- if data is not None:
- self.fill(0)
- if type(data) in [bytes, bytearray]:
- self.set_buffer(data)
- self.show()
- else:
- data = str(data)
- x = (_LEDS_W - len(data) * (_FONT_W + space) + space) // 2 if center else 0
- for char in data:
- self._ascall_bitmap(self._chardata(char), x)
- x = _FONT_W + x + space
- self.show()
-
- def frame(self, data, delay=500):
- """Display one frame per character"""
- if data is not None:
- data = str(data)
- for char in data:
- self.fill(0)
- self._ascall_bitmap(self._chardata(char), (_LEDS_W - _FONT_W) // 2)
- self.show()
- time.sleep_ms(delay)
-
- def scroll(self, data, space=0, speed=100):
- """Scrolling characters"""
- if data is not None:
- data = str(data)
- uincode = False
- for char in data:
- if ord(char) >= 0xff:
- uincode =True
- break
- if uincode:
- font_buffer = []
- str_len = 0
- for c in data:
- _buffer = self._uincode(c)
- font_buffer.append(_buffer)
- str_len = str_len + _buffer[1] + space
- for i in range(str_len + _LEDS_H - space):
- x = _LEDS_H - i
- self.fill(0)
- for buffer in font_buffer:
- self._uincode_bitmap(buffer, x)
- x = buffer[1] + x + space
- self.show()
- time.sleep_ms(speed)
- else:
- str_len = len(data) * (_FONT_W + space) - space
- for i in range(str_len + _LEDS_W + 1):
- x = _LEDS_W -i
- self.fill(0)
- for char in data:
- self._ascall_bitmap(self._chardata(char), x)
- x = _FONT_W + x + space
- self.show()
- time.sleep_ms(speed)
-
- def _wreg(self, reg, val):
- '''Write memory address'''
- self._i2c.writeto_mem(_BOT035_ADDRESS, reg, val.to_bytes(1, 'little'))
-
- def _rreg(self, reg, nbytes=1):
- '''Read memory address'''
- self._i2c.writeto(_BOT035_ADDRESS, reg.to_bytes(1, 'little'))
- return self._i2c.readfrom(_BOT035_ADDRESS, nbytes)[0]
-
- def reset(self):
- """Reset SPK, PWM registers to default state"""
- self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_SPK, b'\x0A\x00\x00\x00\x20\x4E\x64\x64')
-
- def get_brightness(self):
- return self._brightness
-
- def set_brightness(self, brightness):
- if not 0.0 <= brightness <= 1.0:
- raise ValueError("Brightness must be a decimal number in the range: 0.0-1.0")
- self._brightness = brightness
- self._wreg(_BOT035_FLAG, _BOT035_PGA | round(10 * brightness))
-
- def show(self):
- self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_LEDS, self._buffer)
-
- def buzzer(self, duty=None, freq=None):
- if duty is not None:
- duty = max(min(duty, 100), 0)
- self._wreg(_BOT035_SPK + 2, int(duty))
- if freq is not None:
- freq = max(min(freq, 65535), 10)
- self._wreg(_BOT035_SPK, freq & 0xFF)
- self._wreg(_BOT035_SPK + 1, freq >> 8)
- if freq is None and duty is None:
- return self._rreg(_BOT035_SPK + 2), self._rreg(_BOT035_SPK) | self._rreg(_BOT035_SPK + 1) << 8
-
- def usben(self, index=1, duty=None, freq=None):
- index = max(min(index, 2), 1) - 1
- if duty is not None:
- duty = max(min(duty, 100), 0)
- self._wreg(_BOT035_PWM + index + 2, int(duty))
- if freq is not None:
- freq = max(min(freq, 65535), 10)
- self._wreg(_BOT035_PWM, freq & 0xFF)
- self._wreg(_BOT035_PWM + 1, freq >> 8)
- if freq is None and duty is None:
- return self._rreg(_BOT035_PWM + index + 2), self._rreg(_BOT035_PWM) | self._rreg(_BOT035_PWM + 1) << 8
-
- def touch(self, index, value=None):
- index = max(min(index, 1), 0)
- touch = 4095 - (self._rreg(_BOT5_TOUCH + index * 2) | self._rreg(_BOT5_TOUCH + index * 2 + 1) << 8)
- return touch > value if value else touch
-
- def touched(self, index, value=600):
- return self.touch(index, value)
-
- def touch_slide(self):
- values = []
- for i in range(30):
- values.append((self.touch(1) - self._touchs[1]) - (self.touch(0) - self._touchs[0]))
- return round(sorted(values)[15] / 10)
-
- def soundlevel(self):
- values = []
- for i in range(50):
- values.append(self._rreg(_BOT035_MIC) | self._rreg(_BOT035_MIC + 1) << 8)
- values = sorted(values)
- return values[-10] - values[10]
-
- """Graph module"""
- HEART=b'\x00\x0c\x1e?~\xfc~?\x1e\x0c\x00\x00'
- HEART_SMALL=b'\x00\x00\x0c\x1e\x08\x08\x00\x80p0\x00\x08\x08\x08\x08\x08\x00\x00``\x00 \x10\x08\x04\x02>QIE>\x00B\x7f@\x00rIIIF!AIM3\x18\x14\x12\x7f\x10\'EEE9A]YN|\x12\x11\x12|\x7fIII6>AAA"\x7fAAA>\x7fIIIA\x7f\t\t\t\x01>AAQs\x7f\x08\x08\x08\x7f\x00A\x7fA\x00 @A?\x01\x7f\x08\x14"A\x7f@@@@\x7f\x02\x1c\x02\x7f\x7f\x04\x08\x10\x7f>AAA>\x7f\t\t\t\x06>AQ!^\x7f\t\x19)F&III2\x03\x01\x7f\x01\x03?@@@?\x1f @ \x1f?@8@?c\x14\x08\x14c\x03\x04x\x04\x03aYIMC\x00\x7fAAA\x02\x04\x08\x10 \x00AAA\x7f\x04\x02\x01\x02\x04@@@@@\x00\x03\x07\x08\x00 TTx@\x7f(DD88DDD(8DD(\x7f8TTT\x18\x00\x08~\t\x02\x18\xa4\xa4\x9cx\x7f\x08\x04\x04x\x00D}@\x00 @@=\x00\x7f\x10(D\x00\x00A\x7f@\x00|\x04x\x04x|\x08\x04\x04x8DDD8\xfc\x18$$\x18\x18$$\x18\xfc|\x08\x04\x04\x08HTTT$\x04\x04?D$<@@ |\x1c @ \x1c<@0@> 26
+ buffer = bytearray( 12 * (font_width // 8 + 1))
+ flash_read(_Uincode_ADDR + font_address, buffer)
+ return buffer, font_width
+
+ def shift(self, x, y, rotate=False):
+ """Shift pixels by x and y"""
+ if x > 0: # Shift Right
+ for _ in range(x):
+ for row in range(0, _LEDS_H):
+ last_pixel = self.pixel(_LEDS_W - 1, row) if rotate else 0
+ for col in range(_LEDS_W - 1, 0, -1):
+ self.pixel(col, row, self.pixel(col - 1, row))
+ self.pixel(0, row, last_pixel)
+ elif x < 0: # Shift Left
+ for _ in range(-x):
+ for row in range(0, _LEDS_H):
+ last_pixel = self.pixel(0, row) if rotate else 0
+ for col in range(0, _LEDS_W - 1):
+ self.pixel(col, row, self.pixel(col + 1, row))
+ self.pixel(_LEDS_W - 1, row, last_pixel)
+ if y > 0: # Shift Up
+ for _ in range(y):
+ for col in range(0, _LEDS_W):
+ last_pixel = self.pixel(col, _LEDS_H - 1) if rotate else 0
+ for row in range(_LEDS_H - 1, 0, -1):
+ self.pixel(col, row, self.pixel(col, row - 1))
+ self.pixel(col, 0, last_pixel)
+ elif y < 0: # Shift Down
+ for _ in range(-y):
+ for col in range(0, _LEDS_W):
+ last_pixel = self.pixel(col, 0) if rotate else 0
+ for row in range(0, _LEDS_H - 1):
+ self.pixel(col, row, self.pixel(col, row + 1))
+ self.pixel(col, _LEDS_H - 1, last_pixel)
+ self.show()
+
+ def shift_right(self, num, rotate=False):
+ """Shift all pixels right"""
+ self.shift(num, 0, rotate)
+
+ def shift_left(self, num, rotate=False):
+ """Shift all pixels left"""
+ self.shift(-num, 0, rotate)
+
+ def shift_up(self, num, rotate=False):
+ """Shift all pixels up"""
+ self.shift(0, -num, rotate)
+
+ def shift_down(self, num, rotate=False):
+ """Shift all pixels down"""
+ self.shift(0, num, rotate)
+
+ def map_invert(self, own):
+ """Graph invert operation"""
+ result = bytearray()
+ for i in range(len(own)):
+ result.append(~ own[i])
+ return result
+
+ def map_add(self, own, other):
+ """Graph union operation"""
+ result = bytearray()
+ for i in range(min(len(own), len(other))):
+ result.append(own[i] | other[i])
+ return result
+
+ def map_sub(self, own, other):
+ """Graphic subtraction operation"""
+ result = bytearray()
+ for i in range(min(len(own), len(other))):
+ result.append((own[i] ^ other[i]) & own[i])
+ return result
+
+ def set_buffer(self, buffer):
+ for i in range(len(buffer)):
+ self._buffer[i] = self._buffer[i] | buffer[i]
+
+ def _ascall_bitmap(self, buffer, x=0):
+ if -_FONT_W <= x <= _LEDS_W and buffer is not None:
+ for _x in range(_FONT_W):
+ for _y in range(_FONT_H):
+ if (buffer[_x] >> _y) & 0x1:
+ self.pixel(x + _x, _y, 1)
+
+ def _uincode_bitmap(self, buffer, x=0):
+ _buffer, width = buffer
+ if -width < x < _LEDS_H and _buffer is not None:
+ for _y in range(12):
+ for _x in range(width):
+ if _buffer[_y * ((width + 7) // 8) + _x // 8] & (0x80 >> (_x & 7)):
+ self.pixel(_y, _LEDS_H - (x + _x), 1)
+
+ def shows(self, data, space=1, center=True):
+ """Display character"""
+ if data is not None:
+ self.fill(0)
+ if type(data) in [bytes, bytearray]:
+ self.set_buffer(data)
+ self.show()
+ else:
+ data = str(data)
+ x = (_LEDS_W - len(data) * (_FONT_W + space) + space) // 2 if center else 0
+ for char in data:
+ self._ascall_bitmap(self._chardata(char), x)
+ x = _FONT_W + x + space
+ self.show()
+
+ def frame(self, data, delay=500):
+ """Display one frame per character"""
+ if data is not None:
+ data = str(data)
+ for char in data:
+ self.fill(0)
+ self._ascall_bitmap(self._chardata(char), (_LEDS_W - _FONT_W) // 2)
+ self.show()
+ time.sleep_ms(delay)
+
+ def scroll(self, data, space=0, speed=100):
+ """Scrolling characters"""
+ if data is not None:
+ data = str(data)
+ uincode = False
+ for char in data:
+ if ord(char) >= 0xff:
+ uincode =True
+ break
+ if uincode:
+ font_buffer = []
+ str_len = 0
+ for c in data:
+ _buffer = self._uincode(c)
+ font_buffer.append(_buffer)
+ str_len = str_len + _buffer[1] + space
+ for i in range(str_len + _LEDS_H - space):
+ x = _LEDS_H - i
+ self.fill(0)
+ for buffer in font_buffer:
+ self._uincode_bitmap(buffer, x)
+ x = buffer[1] + x + space
+ self.show()
+ time.sleep_ms(speed)
+ else:
+ str_len = len(data) * (_FONT_W + space) - space
+ for i in range(str_len + _LEDS_W + 1):
+ x = _LEDS_W -i
+ self.fill(0)
+ for char in data:
+ self._ascall_bitmap(self._chardata(char), x)
+ x = _FONT_W + x + space
+ self.show()
+ time.sleep_ms(speed)
+
+ def _wreg(self, reg, val):
+ '''Write memory address'''
+ self._i2c.writeto_mem(_BOT035_ADDRESS, reg, val.to_bytes(1, 'little'))
+
+ def _rreg(self, reg, nbytes=1):
+ '''Read memory address'''
+ self._i2c.writeto(_BOT035_ADDRESS, reg.to_bytes(1, 'little'))
+ return self._i2c.readfrom(_BOT035_ADDRESS, nbytes)[0]
+
+ def reset(self):
+ """Reset SPK, PWM registers to default state"""
+ self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_SPK, b'\x0A\x00\x00\x00\x20\x4E\x64\x64')
+ self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_KB, bytes(9))
+
+ def get_brightness(self):
+ return self._brightness
+
+ def set_brightness(self, brightness):
+ if not 0.0 <= brightness <= 1.0:
+ raise ValueError("Brightness must be a decimal number in the range: 0.0-1.0")
+ self._brightness = brightness
+ self._wreg(_BOT035_FLAG, _BOT035_PGA | round(10 * brightness))
+
+ def show(self):
+ self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_LEDS, self._buffer)
+
+ def buzzer(self, duty=None, freq=None):
+ if duty is not None:
+ duty = max(min(duty, 100), 0)
+ self._wreg(_BOT035_SPK + 2, int(duty))
+ if freq is not None:
+ freq = max(min(freq, 65535), 10)
+ self._wreg(_BOT035_SPK, freq & 0xFF)
+ self._wreg(_BOT035_SPK + 1, freq >> 8)
+ if freq is None and duty is None:
+ return self._rreg(_BOT035_SPK + 2), self._rreg(_BOT035_SPK) | self._rreg(_BOT035_SPK + 1) << 8
+
+ def usben(self, index=1, duty=None, freq=None):
+ index = max(min(index, 2), 1) - 1
+ if duty is not None:
+ duty = max(min(duty, 100), 0)
+ self._wreg(_BOT035_PWM + index + 2, int(duty))
+ if freq is not None:
+ freq = max(min(freq, 65535), 10)
+ self._wreg(_BOT035_PWM, freq & 0xFF)
+ self._wreg(_BOT035_PWM + 1, freq >> 8)
+ if freq is None and duty is None:
+ return self._rreg(_BOT035_PWM + index + 2), self._rreg(_BOT035_PWM) | self._rreg(_BOT035_PWM + 1) << 8
+
+ def touch(self, index, value=None):
+ index = max(min(index, 1), 0)
+ touch = 4095 - (self._rreg(_BOT5_TOUCH + index * 2) | self._rreg(_BOT5_TOUCH + index * 2 + 1) << 8)
+ return touch > value if value else touch
+
+ def touched(self, index, value=600):
+ return self.touch(index, value)
+
+ def touch_slide(self):
+ values = []
+ for i in range(30):
+ values.append((self.touch(1) - self._touchs[1]) - (self.touch(0) - self._touchs[0]))
+ return round(sorted(values)[15] / 10)
+
+ def soundlevel(self):
+ values = []
+ for i in range(50):
+ values.append(self._rreg(_BOT035_MIC) | self._rreg(_BOT035_MIC + 1) << 8)
+ values = sorted(values)
+ return values[-10] - values[10]
+
+ def hid_keyboard(self, special=0, general=0, release=True):
+ self._buf = bytearray(4)
+ self._buf[0] = special
+ if type(general) is int:
+ self._buf[1] = general
+ elif type(general) is tuple:
+ for i in range(len(general)):
+ self._buf[i + 1] = general[i]
+ self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_KB, self._buf)
+ if release:
+ time.sleep_ms(10)
+ self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_KB, bytes(4))
+
+ def hid_keyboard_str(self, string, delay=0):
+ for char in str(string):
+ self._wreg(_BOT035_STR, ord(char))
+ time.sleep_ms(20 + delay)
+
+ def hid_mouse(self, keys=0, move=(0, 0), wheel=0, release=True):
+ self._buf = bytearray(4)
+ self._buf[0] = keys
+ self._buf[1] = move[0]
+ self._buf[2] = move[1]
+ self._buf[3] = wheel
+ self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_MS, self._buf)
+ if release:
+ time.sleep_ms(10)
+ self._i2c.writeto_mem(_BOT035_ADDRESS, _BOT035_MS, bytes(4))
+
+
+ """Graph module"""
+ HEART=b'\x00\x0c\x1e?~\xfc~?\x1e\x0c\x00\x00'
+ HEART_SMALL=b'\x00\x00\x0c\x1e
+
@@ -1700,6 +1701,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ;
+
+
+ Hello, Mixly!
+
+
+
+
+
+
+
diff --git a/boards/default_src/micropython_esp32c3/template.xml b/boards/default_src/micropython_esp32c3/template.xml
index 19b84f23..11d24a4f 100644
--- a/boards/default_src/micropython_esp32c3/template.xml
+++ b/boards/default_src/micropython_esp32c3/template.xml
@@ -281,6 +281,7 @@
+
@@ -6449,6 +6450,18 @@
+
+
+
+
+
+ url
+
+
+
+
+
+
diff --git a/boards/default_src/micropython_esp32s2/template.xml b/boards/default_src/micropython_esp32s2/template.xml
index d60ca037..f9a1895b 100644
--- a/boards/default_src/micropython_esp32s2/template.xml
+++ b/boards/default_src/micropython_esp32s2/template.xml
@@ -306,6 +306,7 @@
+
@@ -6305,6 +6306,18 @@
+
+
+
+
+
+ url
+
+
+
+
+
+
diff --git a/boards/default_src/micropython_esp32s3/template.xml b/boards/default_src/micropython_esp32s3/template.xml
index 20e0fe88..5a2640b3 100644
--- a/boards/default_src/micropython_esp32s3/template.xml
+++ b/boards/default_src/micropython_esp32s3/template.xml
@@ -306,6 +306,7 @@
+
@@ -6929,6 +6930,18 @@
+
+
+
+
+
+ url
+
+
+
+
+
+
diff --git a/boards/default_src/micropython_k210_mixgoai/template.xml b/boards/default_src/micropython_k210_mixgoai/template.xml
index 9c542e9a..21bf2641 100644
--- a/boards/default_src/micropython_k210_mixgoai/template.xml
+++ b/boards/default_src/micropython_k210_mixgoai/template.xml
@@ -272,7 +272,7 @@
-
+
@@ -1981,6 +1981,18 @@
+
+
+
+
+
+ url
+
+
+
+
+
+
diff --git a/boards/default_src/micropython_robot/template.xml b/boards/default_src/micropython_robot/template.xml
index bd5f42c4..51a9de9a 100644
--- a/boards/default_src/micropython_robot/template.xml
+++ b/boards/default_src/micropython_robot/template.xml
@@ -293,6 +293,7 @@
+
@@ -5622,6 +5623,18 @@
+
+
+
+
+
+ url
+
+
+
+
+
+
diff --git a/boards/default_src/python/blocks/control.js b/boards/default_src/python/blocks/control.js
index a2a6a4a8..968daea7 100644
--- a/boards/default_src/python/blocks/control.js
+++ b/boards/default_src/python/blocks/control.js
@@ -1018,5 +1018,16 @@ export const get_mem_free = {
}
};
+export const get_unique_identifier = {
+ init: function () {
+ this.setColour(LOOPS_HUE);
+ this.appendDummyInput()
+ .appendField(Blockly.Msg.MIXLY_GET + Blockly.Msg.MIXLY_DEVICE +'ID');
+ this.setInputsInline(true);
+ this.setOutput(true);
+ this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN + Blockly.Msg.MIXLY_GET_UNIQUE_IDEN);
+ }
+};
+
// export const base_type = controls_type;
// export const controls_TypeLists = controls_typeLists;
\ No newline at end of file
diff --git a/boards/default_src/python/generators/control.js b/boards/default_src/python/generators/control.js
index fc0baf98..d7e94f13 100644
--- a/boards/default_src/python/generators/control.js
+++ b/boards/default_src/python/generators/control.js
@@ -271,5 +271,11 @@ export const get_mem_free = function (_, generator) {
return [code, generator.ORDER_ATOMIC]
}
+export const get_unique_identifier = function (_, generator) {
+ generator.definitions_['import_machine'] = 'import machine';
+ var code = 'machine.unique_id()';
+ return [code, generator.ORDER_ATOMIC];
+}
+
// ok
export const controls_repeat = controls_repeat_ext;
\ No newline at end of file
diff --git a/common/msg/blockly/en.js b/common/msg/blockly/en.js
index 6fa717cc..ce561781 100644
--- a/common/msg/blockly/en.js
+++ b/common/msg/blockly/en.js
@@ -3636,4 +3636,27 @@ En.MIXLY_ESP32_CONNECT_URL_TOOLTIP = "initiate a network request";
En.MIXLY_ESP32_UREQUESTS_URL_TOOLTIP = "initiate a network request through the API URL";
En.MIXLY_ESP32_URL_REPONSE = "API return data";
En.MIXLY_ESP32_URL_REPONSE_TOOLTIP = "get the data returned by the API";
+En.MIXLY_GET_UNIQUE_IDEN = "Obtain the unique identifier of the main control board";
+En.MIXLY_KEYBOARD_INPUT = "keyboard input";
+En.MIXLY_SPECIAL_KEY = "special key";
+En.MIXLY_GENERAL_KEY = "general key";
+En.MIXLY_RELEASE = "automatic release";
+En.MIXLY_SPECIAL_KEY0 = "no operation (release)";
+En.MIXLY_SPECIAL_KEY1 = "Left Control key";
+En.MIXLY_SPECIAL_KEY2 = "Left Shift key";
+En.MIXLY_SPECIAL_KEY4 = "Left Alt key";
+En.MIXLY_SPECIAL_KEY8 = "Left Windows key";
+En.MIXLY_SPECIAL_KEY16 = "Right Control key";
+En.MIXLY_SPECIAL_KEY32 = "Right Shift key";
+En.MIXLY_SPECIAL_KEY64 = "Right Alt key";
+En.MIXLY_SPECIAL_KEY128 = "Right Windows key";
+En.MIXLY_MOUSE_INPUT = "mouse input";
+En.MIXLY_MOUSE_KEYS = "mouse button";
+En.MIXLY_X_Y_CHANGES = "change in the x and y axes ";
+En.MIXLY_MOUSE_LEFT_KEY = "left key";
+En.MIXLY_MOUSE_RIGHT_KEY = "right key";
+En.MIXLY_MOUSE_MID_KEY = "middle key";
+En.MIXLY_WHEEL_CHANGES = "roller change amount";
+En.MIXLY_STR_PRINT = "character input";
+En.MIXLY_STR_PRINT_TIME_DELAY = "per character interval";
})();
\ No newline at end of file
diff --git a/common/msg/blockly/zh-hans.js b/common/msg/blockly/zh-hans.js
index 86713c96..c945bd14 100644
--- a/common/msg/blockly/zh-hans.js
+++ b/common/msg/blockly/zh-hans.js
@@ -3784,4 +3784,27 @@ ZhHans.MIXLY_ESP32_CONNECT_URL_TOOLTIP = "发起网络请求";
ZhHans.MIXLY_ESP32_UREQUESTS_URL_TOOLTIP = "通过API的URL发起网络请求";
ZhHans.MIXLY_ESP32_URL_REPONSE = "API返回数据";
ZhHans.MIXLY_ESP32_URL_REPONSE_TOOLTIP = "获得API返回的数据";
+ZhHans.MIXLY_GET_UNIQUE_IDEN = "获取主控板的唯一标识";
+ZhHans.MIXLY_KEYBOARD_INPUT = "键盘输入";
+ZhHans.MIXLY_SPECIAL_KEY = "特殊按键";
+ZhHans.MIXLY_GENERAL_KEY = "普通按键";
+ZhHans.MIXLY_RELEASE = "自动释放";
+ZhHans.MIXLY_SPECIAL_KEY0 = "无操作(释放)";
+ZhHans.MIXLY_SPECIAL_KEY1 = "左Control键";
+ZhHans.MIXLY_SPECIAL_KEY2 = "左Shift键";
+ZhHans.MIXLY_SPECIAL_KEY4 = "左Alt键";
+ZhHans.MIXLY_SPECIAL_KEY8 = "左Windows键";
+ZhHans.MIXLY_SPECIAL_KEY16 = "右Control键";
+ZhHans.MIXLY_SPECIAL_KEY32 = "右Shift键";
+ZhHans.MIXLY_SPECIAL_KEY64 = "右Alt键";
+ZhHans.MIXLY_SPECIAL_KEY128 = "右Windows键";
+ZhHans.MIXLY_MOUSE_INPUT = "鼠标输入";
+ZhHans.MIXLY_MOUSE_KEYS = "鼠标按键";
+ZhHans.MIXLY_X_Y_CHANGES = "x、y轴改变量 ";
+ZhHans.MIXLY_MOUSE_LEFT_KEY = "左键";
+ZhHans.MIXLY_MOUSE_RIGHT_KEY = "右键";
+ZhHans.MIXLY_MOUSE_MID_KEY = "中键";
+ZhHans.MIXLY_WHEEL_CHANGES = "滚轮改变量";
+ZhHans.MIXLY_STR_PRINT = "字符输入";
+ZhHans.MIXLY_STR_PRINT_TIME_DELAY = "每个字符间隔";
})();
\ No newline at end of file
diff --git a/common/msg/blockly/zh-hant.js b/common/msg/blockly/zh-hant.js
index bceac503..f2e775cb 100644
--- a/common/msg/blockly/zh-hant.js
+++ b/common/msg/blockly/zh-hant.js
@@ -3639,4 +3639,27 @@ ZhHant.MIXLY_ESP32_CONNECT_URL_TOOLTIP = "發起網絡請求";
ZhHant.MIXLY_ESP32_UREQUESTS_URL_TOOLTIP = "通過API的URL發起網絡請求";
ZhHant.MIXLY_ESP32_URL_REPONSE = "API返回數據";
ZhHant.MIXLY_ESP32_URL_REPONSE_TOOLTIP = "獲得API返回的數據";
+ZhHant.MIXLY_GET_UNIQUE_IDEN = "獲取主控板的唯一標識";
+ZhHant.MIXLY_KEYBOARD_INPUT = "鍵盤輸入";
+ZhHant.MIXLY_SPECIAL_KEY = "特殊按鍵";
+ZhHant.MIXLY_GENERAL_KEY = "普通按鍵";
+ZhHant.MIXLY_RELEASE = "自動釋放";
+ZhHant.MIXLY_SPECIAL_KEY0 = "無操作(釋放)";
+ZhHant.MIXLY_SPECIAL_KEY1 = "左Control鍵";
+ZhHant.MIXLY_SPECIAL_KEY2 = "左Shift鍵";
+ZhHant.MIXLY_SPECIAL_KEY4 = "左Alt鍵";
+ZhHant.MIXLY_SPECIAL_KEY8 = "左Windows鍵";
+ZhHant.MIXLY_SPECIAL_KEY16 = "右Control鍵";
+ZhHant.MIXLY_SPECIAL_KEY32 = "右Shift鍵";
+ZhHant.MIXLY_SPECIAL_KEY64 = "右Alt鍵";
+ZhHant.MIXLY_SPECIAL_KEY128 = "右Windows鍵";
+ZhHant.MIXLY_MOUSE_INPUT = "鼠標輸入";
+ZhHant.MIXLY_MOUSE_KEYS = "鼠標按鍵";
+ZhHant.MIXLY_X_Y_CHANGES = "x、y軸改變量 ";
+ZhHant.MIXLY_MOUSE_LEFT_KEY = "左鍵";
+ZhHant.MIXLY_MOUSE_RIGHT_KEY = "右鍵";
+ZhHant.MIXLY_MOUSE_MID_KEY = "中鍵";
+ZhHant.MIXLY_WHEEL_CHANGES = "滾輪改變量";
+ZhHant.MIXLY_STR_PRINT = "字符輸入";
+ZhHant.MIXLY_STR_PRINT_TIME_DELAY = "每個字符間隔";
})();
\ No newline at end of file