From 8c89a72e1a38a7f17f460772c42fecb8c1809853 Mon Sep 17 00:00:00 2001 From: kevin Date: Sat, 25 Feb 2023 15:31:20 +0900 Subject: [PATCH 1/9] =?UTF-8?q?=EC=BD=94=EC=95=8C=EB=9D=BC=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extern/lang/code.js | 51 +- extern/lang/ebs.js | 51 +- extern/lang/en.js | 44 +- extern/lang/jp.js | 42 +- extern/lang/ko.js | 74 +- extern/lang/vn.js | 13 +- images/coalaboard.png | Bin 0 -> 23366 bytes images/hw/coalaboard.png | Bin 0 -> 23366 bytes .../blocks/hardware/block_bitbrick.js | 197 ++- .../blocks/hardware/block_coalaboard.js | 1149 +++++++++++++++++ 10 files changed, 1515 insertions(+), 106 deletions(-) create mode 100644 images/coalaboard.png create mode 100644 images/hw/coalaboard.png create mode 100644 src/playground/blocks/hardware/block_coalaboard.js diff --git a/extern/lang/code.js b/extern/lang/code.js index 3543a1976a..ad6986e852 100644 --- a/extern/lang/code.js +++ b/extern/lang/code.js @@ -584,6 +584,15 @@ Lang.Blocks = { "BITBRICK_UserInput": "UserInput", "BITBRICK_dc_direction_ccw": "CCW", "BITBRICK_dc_direction_cw": "CW", + "COALABOARD_light": "light", + "COALABOARD_IR": "IR", + "COALABOARD_touch": "touch", + "COALABOARD_potentiometer": "potentiometer", + "COALABOARD_MIC": "MIC", + "COALABOARD_UserSensor": "UserSensor", + "COALABOARD_UserInput": "UserInput", + "COALABOARD_dc_direction_ccw": "CCW", + "COALABOARD_dc_direction_cw": "CW", "chocopi_control_event_pressed": "누를 때", "chocopi_control_event_released": "뗄 때", "chocopi_joystick_X": "조이스틱 좌우", @@ -3021,6 +3030,7 @@ Lang.Menus = { "arduinoCompatible": "아두이노 호환보드", "bitBlock": "비트블록", "bitbrick": "비트브릭", + "coalaboard": "코알라보드", "creamo": "크리모", "playcode": "플레이코드", "funboard": "펀보드", @@ -5720,6 +5730,7 @@ Lang.Device = { "trueRobot": "뚜루뚜루", "CODEino": "코드이노", "bitbrick": "비트브릭", + "coalaboard": "코알라보드", "creamo": "크리모", "playcode": "플레이코드", "funboard": "펀보드", @@ -5980,18 +5991,36 @@ Lang.template = { "iboard_rgb_led": "RGB LED의 %1 LED %2 %3", "iboard_set_tone": "디지털 %1 번 핀의 버저를 %2 %3 음으로 %4 초 연주하기 %5", "iboard_toggle_led": "디지털 %1 번 핀 %2 %3", - "bitbrick_sensor_value": "%1 값", - "bitbrick_is_touch_pressed": "touch %1 이(가) 눌렸는가?", - "bitbrick_turn_off_color_led": "컬러 LED 끄기 %1", - "bitbrick_turn_on_color_led_by_rgb": "컬러 LED 켜기 R %1 G %2 B %3 %4", - "bitbrick_turn_on_color_led_by_picker": "컬러 LED 색 %1 로 정하기 %2", - "bitbrick_turn_on_color_led_by_value": "컬러 LED 켜기 색 %1 로 정하기 %2", - "bitbrick_buzzer": "버저음 %1 내기 %2", - "bitbrick_turn_off_all_motors": "모든 모터 끄기 %1", - "bitbrick_dc_speed": "DC 모터 %1 속도 %2 %3", - "bitbrick_dc_direction_speed": "DC 모터 %1 %2 방향 속력 %3 %4", - "bitbrick_servomotor_angle": "서보 모터 %1 각도 %2 %3", + "bitbrick_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", + "bitbrick_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", + "bitbrick_is_touch_pressed": "버튼 %1 이(가) %2 눌렸는가?", + "bitbrick_is_sensor_value_compare": '%1 값 %2 %3 인가?', + "bitbrick_sensor_value": "%1 값", "bitbrick_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", + "bitbrick_turn_on_color_led_by_rgb": "엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기", + "bitbrick_turn_on_color_led_by_picker": "엘이디를 %1 (으)로 켜기 %2", + "bitbrick_turn_on_color_led_by_value": "엘이디를 %1 (으)로 켜기 %2", + "bitbrick_turn_off_color_led": "엘이디 끄기 %1", + "bitbrick_buzzer": "버저음 %1 내기 %2", + "bitbrick_servomotor_angle": "서보모터 %1 각도 %2 %3", + "bitbrick_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", + "bitbrick_dc_speed": "디씨모터 %1 속도 %2 %3", + "bitbrick_turn_off_all_motors": "모든 모터 멈추기 %1", + "coalaboard_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", + "coalaboard_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", + "coalaboard_is_touch_pressed": "버튼 %1 이(가) %2 눌렸는가?", + "coalaboard_is_sensor_value_compare": '%1 값 %2 %3 인가?', + "coalaboard_sensor_value": "%1 값", + "coalaboard_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", + "coalaboard_turn_on_color_led_by_rgb": "엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기", + "coalaboard_turn_on_color_led_by_picker": "엘이디를 %1 (으)로 켜기 %2", + "coalaboard_turn_on_color_led_by_value": "엘이디를 %1 (으)로 켜기 %2", + "coalaboard_turn_off_color_led": "엘이디 끄기 %1", + "coalaboard_buzzer": "버저음 %1 내기 %2", + "coalaboard_servomotor_angle": "서보모터 %1 각도 %2 %3", + "coalaboard_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", + "coalaboard_dc_speed": "디씨모터 %1 속도 %2 %3", + "coalaboard_turn_off_all_motors": "모든 모터 멈추기 %1", "start_drawing": "this.startDraw() %1", "stop_drawing": "this.stopDraw() %1", "set_color": "this.brush.color = %1 %2", diff --git a/extern/lang/ebs.js b/extern/lang/ebs.js index 54bf2b465d..e9281f801d 100644 --- a/extern/lang/ebs.js +++ b/extern/lang/ebs.js @@ -584,6 +584,15 @@ Lang.Blocks = { "BITBRICK_UserInput": "사용자입력", "BITBRICK_dc_direction_ccw": "반시계", "BITBRICK_dc_direction_cw": "시계", + "COALABOARD_light": "밝기센서", + "COALABOARD_IR": "거리센서", + "COALABOARD_touch": "버튼", + "COALABOARD_potentiometer": "가변저항", + "COALABOARD_MIC": "소리감지센서", + "COALABOARD_UserSensor": "사용자입력", + "COALABOARD_UserInput": "사용자입력", + "COALABOARD_dc_direction_ccw": "반시계", + "COALABOARD_dc_direction_cw": "시계", "chocopi_control_event_pressed": "누를 때", "chocopi_control_event_released": "뗄 때", "chocopi_joystick_X": "조이스틱 좌우", @@ -3021,6 +3030,7 @@ Lang.Menus = { "arduinoCompatible": "아두이노 호환보드", "bitBlock": "비트블록", "bitbrick": "비트브릭", + "coalaboard": "코알라보드", "creamo": "크리모", "playcode": "플레이코드", "funboard": "펀보드", @@ -5720,6 +5730,7 @@ Lang.Device = { "trueRobot": "뚜루뚜루", "CODEino": "코드이노", "bitbrick": "비트브릭", + "coalaboard": "코알라보드", "creamo": "크리모", "playcode": "플레이코드", "funboard": "펀보드", @@ -5980,18 +5991,36 @@ Lang.template = { "iboard_rgb_led": "RGB LED의 %1 LED %2 %3", "iboard_set_tone": "디지털 %1 번 핀의 버저를 %2 %3 음으로 %4 초 연주하기 %5", "iboard_toggle_led": "디지털 %1 번 핀 %2 %3", - "bitbrick_sensor_value": "%1 값", - "bitbrick_is_touch_pressed": "버튼 %1 이(가) 눌렸는가?", - "bitbrick_turn_off_color_led": "컬러 LED 끄기 %1", - "bitbrick_turn_on_color_led_by_rgb": "컬러 LED 켜기 R %1 G %2 B %3 %4", - "bitbrick_turn_on_color_led_by_picker": "컬러 LED 색 %1 로 정하기 %2", - "bitbrick_turn_on_color_led_by_value": "컬러 LED 켜기 색 %1 로 정하기 %2", - "bitbrick_buzzer": "버저음 %1 내기 %2", - "bitbrick_turn_off_all_motors": "모든 모터 끄기 %1", - "bitbrick_dc_speed": "DC 모터 %1 속도 %2 %3", - "bitbrick_dc_direction_speed": "DC 모터 %1 %2 방향 속력 %3 %4", - "bitbrick_servomotor_angle": "서보 모터 %1 각도 %2 %3", + "bitbrick_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", + "bitbrick_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", + "bitbrick_is_touch_pressed": "버튼 %1 이(가) %2 눌렸는가?", + "bitbrick_is_sensor_value_compare": '%1 값 %2 %3 인가?', + "bitbrick_sensor_value": "%1 값", "bitbrick_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", + "bitbrick_turn_on_color_led_by_rgb": "엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기", + "bitbrick_turn_on_color_led_by_picker": "엘이디를 %1 (으)로 켜기 %2", + "bitbrick_turn_on_color_led_by_value": "엘이디를 %1 (으)로 켜기 %2", + "bitbrick_turn_off_color_led": "엘이디 끄기 %1", + "bitbrick_buzzer": "버저음 %1 내기 %2", + "bitbrick_servomotor_angle": "서보모터 %1 각도 %2 %3", + "bitbrick_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", + "bitbrick_dc_speed": "디씨모터 %1 속도 %2 %3", + "bitbrick_turn_off_all_motors": "모든 모터 멈추기 %1", + "coalaboard_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", + "coalaboard_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", + "coalaboard_is_touch_pressed": "버튼 %1 이(가) %2 눌렸는가?", + "coalaboard_is_sensor_value_compare": '%1 값 %2 %3 인가?', + "coalaboard_sensor_value": "%1 값", + "coalaboard_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", + "coalaboard_turn_on_color_led_by_rgb": "엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기", + "coalaboard_turn_on_color_led_by_picker": "엘이디를 %1 (으)로 켜기 %2", + "coalaboard_turn_on_color_led_by_value": "엘이디를 %1 (으)로 켜기 %2", + "coalaboard_turn_off_color_led": "엘이디 끄기 %1", + "coalaboard_buzzer": "버저음 %1 내기 %2", + "coalaboard_servomotor_angle": "서보모터 %1 각도 %2 %3", + "coalaboard_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", + "coalaboard_dc_speed": "디씨모터 %1 속도 %2 %3", + "coalaboard_turn_off_all_motors": "모든 모터 멈추기 %1", "start_drawing": "그리기 시작하기 %1", "stop_drawing": "그리기 멈추기 %1", "set_color": "붓의 색을 %1 (으)로 정하기 %2", diff --git a/extern/lang/en.js b/extern/lang/en.js index 4cd8e21f76..859614bbb1 100644 --- a/extern/lang/en.js +++ b/extern/lang/en.js @@ -2227,6 +2227,7 @@ Lang.Menus = { "arduinoCompatible": "non-certified", "bitBlock": "BitBlock", "bitbrick": "Bitbrick", + "coalaboard": "Coala Board", "creamo": "creamo", "playcode": "playcode", "funboard": "funboard", @@ -4928,6 +4929,7 @@ Lang.Device = { "trueRobot": "TrueTrueRobot", "CODEino": "CODEino", "bitbrick": "bitbrick", + "coalaboard": "Coala Board", "creamo": "creamo", "playcode": "playcode", "funboard": "funboard", @@ -5188,18 +5190,36 @@ Lang.template = { "iboard_rgb_led": " %1 LED %2 %3", "iboard_set_tone": "Play tone pin %1 on note %2 octave %3 beat %4 %5", "iboard_toggle_led": "Digital %1 Pin %2 %3", - "bitbrick_sensor_value": "Value %1", - "bitbrick_is_touch_pressed": "Pressed %1 button? ", - "bitbrick_turn_off_color_led": "Turn off color LED %1", - "bitbrick_turn_on_color_led_by_rgb": "Turn on color LED R %1 G %2 B %3 %4", - "bitbrick_turn_on_color_led_by_picker": "Select %1 for color LED %2", - "bitbrick_turn_on_color_led_by_value": "Turn on color LED, select %1 %2", - "bitbrick_buzzer": "Buzz for %1 secs %2", - "bitbrick_turn_off_all_motors": "Turn off all motors %1", - "bitbrick_dc_speed": "DC motor %1 speed %2 %3", - "bitbrick_dc_direction_speed": "DC motor %1 %2 direction speed %3 %4", - "bitbrick_servomotor_angle": "Servo motor %1 angle %2 %3", - "bitbrick_convert_scale": "Convert %1 value from %2~%3 to %4~%4", + "bitbrick_when_button_pressed": "%1 when button %2 %3", + "bitbrick_when_sensor_get_value": "%1 when %2 value %3 %4", + "bitbrick_is_touch_pressed": "button %1 %2?", + "bitbrick_is_sensor_value_compare": "%1 %2 %3?", + "bitbrick_sensor_value": "%1 value", + "bitbrick_convert_scale": "map %1 value from %2 ~ %3 to %4 ~ %5", + "bitbrick_turn_on_color_led_by_rgb": "set LED color to Red %1 Green %2 Blue %3 %4", + "bitbrick_turn_on_color_led_by_picker": "set LED color to %1 %2", + "bitbrick_turn_on_color_led_by_value": "set LED color %1 %2", + "bitbrick_turn_off_color_led": "turn off LED %1", + "bitbrick_buzzer": "buzz note %1 %2", + "bitbrick_servomotor_angle": "servo motor %1 degree %2 %3", + "bitbrick_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", + "bitbrick_dc_speed": "dc motor %1 velocity %2 %3", + "bitbrick_turn_off_all_motors": "stop all motors %1", + "coalaboard_when_button_pressed": "%1 when button %2 %3", + "coalaboard_when_sensor_get_value": "%1 when %2 value %3 %4", + "coalaboard_is_touch_pressed": "button %1 %2?", + "coalaboard_is_sensor_value_compare": "%1 %2 %3?", + "coalaboard_sensor_value": "%1 value", + "coalaboard_convert_scale": "map %1 value from %2 ~ %3 to %4 ~ %5", + "coalaboard_turn_on_color_led_by_rgb": "set LED color to Red %1 Green %2 Blue %3 %4", + "coalaboard_turn_on_color_led_by_picker": "set LED color to %1 %2", + "coalaboard_turn_on_color_led_by_value": "set LED color %1 %2", + "coalaboard_turn_off_color_led": "turn off LED %1", + "coalaboard_buzzer": "buzz note %1 %2", + "coalaboard_servomotor_angle": "servo motor %1 degree %2 %3", + "coalaboard_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", + "coalaboard_dc_speed": "dc motor %1 velocity %2 %3", + "coalaboard_turn_off_all_motors": "stop all motors %1", "start_drawing": "Start drawing %1", "stop_drawing": "Stop drawing %1", "set_color": "Set brush color to %1 %2", diff --git a/extern/lang/jp.js b/extern/lang/jp.js index 81a1f08a42..c10ba47b35 100644 --- a/extern/lang/jp.js +++ b/extern/lang/jp.js @@ -5984,18 +5984,36 @@ Lang.template = { "iboard_rgb_led": " %1 LED %2 %3", "iboard_set_tone": "Play tone pin %1 on note %2 octave %3 beat %4 %5", "iboard_toggle_led": "Digital %1 Pin %2 %3", - "bitbrick_sensor_value": "Value %1", - "bitbrick_is_touch_pressed": "Pressed %1 button? ", - "bitbrick_turn_off_color_led": "Turn off color LED %1", - "bitbrick_turn_on_color_led_by_rgb": "Turn on color LED R %1 G %2 B %3 %4", - "bitbrick_turn_on_color_led_by_picker": "Select %1 for color LED %2", - "bitbrick_turn_on_color_led_by_value": "Turn on color LED, select %1 %2", - "bitbrick_buzzer": "Buzz for %1 secs %2", - "bitbrick_turn_off_all_motors": "Turn off all motors %1", - "bitbrick_dc_speed": "DC motor %1 speed %2 %3", - "bitbrick_dc_direction_speed": "DC motor %1 %2 direction speed %3 %4", - "bitbrick_servomotor_angle": "Servo motor %1 angle %2 %3", - "bitbrick_convert_scale": "Convert %1 value from %2~%3 to %4~%4", + "bitbrick_when_button_pressed": "%1 when button %2 %3", + "bitbrick_when_sensor_get_value": "%1 when %2 value %3 %4", + "bitbrick_is_touch_pressed": "button %1 %2?", + "bitbrick_is_sensor_value_compare": "%1 %2 %3?", + "bitbrick_sensor_value": "%1 value", + "bitbrick_convert_scale": "map %1 value from %2 ~ %3 to %4 ~ %5", + "bitbrick_turn_on_color_led_by_rgb": "set LED color to Red %1 Green %2 Blue %3 %4", + "bitbrick_turn_on_color_led_by_picker": "set LED color to %1 %2", + "bitbrick_turn_on_color_led_by_value": "set LED color %1 %2", + "bitbrick_turn_off_color_led": "turn off LED %1", + "bitbrick_buzzer": "buzz note %1 %2", + "bitbrick_servomotor_angle": "servo motor %1 degree %2 %3", + "bitbrick_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", + "bitbrick_dc_speed": "dc motor %1 velocity %2 %3", + "bitbrick_turn_off_all_motors": "stop all motors %1", + "coalaboard_when_button_pressed": "%1 when button %2 %3", + "coalaboard_when_sensor_get_value": "%1 when %2 value %3 %4", + "coalaboard_is_touch_pressed": "button %1 %2?", + "coalaboard_is_sensor_value_compare": "%1 %2 %3?", + "coalaboard_sensor_value": "%1 value", + "coalaboard_convert_scale": "map %1 value from %2 ~ %3 to %4 ~ %5", + "coalaboard_turn_on_color_led_by_rgb": "set LED color to Red %1 Green %2 Blue %3 %4", + "coalaboard_turn_on_color_led_by_picker": "set LED color to %1 %2", + "coalaboard_turn_on_color_led_by_value": "set LED color %1 %2", + "coalaboard_turn_off_color_led": "turn off LED %1", + "coalaboard_buzzer": "buzz note %1 %2", + "coalaboard_servomotor_angle": "servo motor %1 degree %2 %3", + "coalaboard_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", + "coalaboard_dc_speed": "dc motor %1 velocity %2 %3", + "coalaboard_turn_off_all_motors": "stop all motors %1", "start_drawing": "描きはじめる %1", "stop_drawing": "描きおえる %1", "set_color": "筆の色を%1にする %2", diff --git a/extern/lang/ko.js b/extern/lang/ko.js index 971ebb4699..55066932e9 100644 --- a/extern/lang/ko.js +++ b/extern/lang/ko.js @@ -599,6 +599,15 @@ Lang.Blocks = { BITBRICK_UserInput: '사용자입력', BITBRICK_dc_direction_ccw: '반시계', BITBRICK_dc_direction_cw: '시계', + COALABOARD_light: '밝기센서', + COALABOARD_IR: '거리센서', + COALABOARD_touch: '버튼', + COALABOARD_potentiometer: '가변저항', + COALABOARD_MIC: '소리감지센서', + COALABOARD_UserSensor: '사용자입력', + COALABOARD_UserInput: '사용자입력', + COALABOARD_dc_direction_ccw: '반시계', + COALABOARD_dc_direction_cw: '시계', chocopi_control_event_pressed: '누를 때', chocopi_control_event_released: '뗄 때', chocopi_joystick_X: '조이스틱 좌우', @@ -3143,6 +3152,7 @@ Lang.Menus = { arduinoCompatible: '아두이노 호환보드', bitBlock: '비트블록', bitbrick: '비트브릭', + coalaboard: '코알라보드', creamo: '크리모', playcode: '플레이코드', funboard: '펀보드', @@ -6490,6 +6500,7 @@ Lang.Helper = { '비트브릭 센서를 사용할 수 있는 블록입니다. 센서값의 범위는 0 ~1023입니다. 메인보드에 연결된 센서의 종류와 포트번호를 자동으로 인식합니다. 블록 안의 화살표를 눌러 사용하려고 하는 센서를 선택하세요.', bitbrick_convert_scale: '비트브릭 센서의 값의 범위를 바꿀 수 있습니다.', bitbrick_is_touch_pressed: '비트브릭 센서 중 버튼을 눌렀을 경우 ‘참’으로 판단합니다.', + bitbrick_is_sensor_value_compare: '비트브릭 센서 중 버튼을 눌렀을 경우 ‘참’으로 판단합니다.', bitbrick_turn_off_color_led: '비트브릭 엘이디를 끕니다.', bitbrick_turn_on_color_led_by_rgb: '비트브릭 엘이디를 빛의 삼원색인 빨강,초록,파랑을 혼합하여 켭니다. 값의 범위는 0 ~ 255입니다.', @@ -6566,6 +6577,28 @@ Lang.Helper = { diaboard_buzzer_speed_bpm_change: '입력한 BPM만큼 연주 속도를 바꿉니다.', diaboard_buzzer_sleep_rhythm: '선택한 박자만큼 쉽니다.', diaboard_buzzer_stop: '버저음을 멈춥니다.', + coalaboard_when_button_pressed: '비트브릭 버튼을 누르면 아래에 연결된 블록들을 실행합니다.', + coalaboard_when_sensor_get_value: + '비트브릭 센서의 값과 오른쪽에 입력한 값을 비교합니다.\n< : 센서 값이 오른쪽에 위치한 값보다 작은 경우 ‘참’으로 판단합니다.\n> : 센서 값이 오른쪽에 위치한 값보다 큰 경우 ‘참으로 판단합니다.\n= : 센서 값이 오른쪽에 위치한 값과 같은 경우 ‘참으로 판단합니다.', + coalaboard_sensor_value: + '비트브릭 센서를 사용할 수 있는 블록입니다. 센서값의 범위는 0 ~1023입니다. 메인보드에 연결된 센서의 종류와 포트번호를 자동으로 인식합니다. 블록 안의 화살표를 눌러 사용하려고 하는 센서를 선택하세요.', + coalaboard_convert_scale: '비트브릭 센서의 값의 범위를 바꿀 수 있습니다.', + coalaboard_is_touch_pressed: '비트브릭 센서 중 버튼을 눌렀을 경우 ‘참’으로 판단합니다.', + coalaboard_turn_off_color_led: '비트브릭 엘이디를 끕니다.', + coalaboard_turn_on_color_led_by_rgb: + '비트브릭 엘이디를 빛의 삼원색인 빨강,초록,파랑을 혼합하여 켭니다. 값의 범위는 0 ~ 255입니다.', + coalaboard_turn_on_color_led_by_picker: '비트브릭 엘이디를 색상 창을 사용해 켭니다.', + coalaboard_turn_on_color_led_by_value: + '비트브릭 엘이디를 색상 값으로 켭니다. 값의 범위는 0 ~ 199입니다.', + coalaboard_buzzer: + '비트브릭 버저를 사용하여 소리를 냅니다. 값의 범위는 0 ~ 96입니다. 값이 0일 때는 버저 소리를 끕니다.', + coalaboard_turn_off_all_motors: '비트브릭 모터를 모두 끕니다.', + coalaboard_dc_speed: + '비트브릭 디씨모터의 속도를 제어합니다. 속도 값의 범위는 –100 ~ 100입니다. 음수(-)일 때는 반시계방향으로 회전합니다. 양수(+)일 때는 시계방향으로 회전합니다. 속도가 0일 때는 회전을 멈춥니다.', + coalaboard_dc_direction_speed: + '비트브릭 디씨모터의 방향과 속력을 제어합니다. 방향은 시계방향과 반시계방향을 선택할 수 있습니다. 속력 값의 범위는 0 ~ 100입니다. 속력이 0일 때는 회전을 멈춥니다.', + coalaboard_servomotor_angle: + '비트브릭 서보모터의 각도를 제어합니다. 각도 값의 범위는 0 ~ 180입니다.' }; Lang.Category = { entrybot_friends: '엔트리봇 친구들', @@ -6625,6 +6658,7 @@ Lang.Device = { trueRobot: '뚜루뚜루', CODEino: '코드이노', bitbrick: '비트브릭', + coalaboard: '코알라보드', creamo: '크리모', playcode: '플레이코드', funboard: '펀보드', @@ -6889,18 +6923,36 @@ Lang.template = { iboard_rgb_led: 'RGB LED의 %1 LED %2 %3', iboard_set_tone: '디지털 %1 번 핀의 버저를 %2 %3 음으로 %4 초 연주하기 %5', iboard_toggle_led: '디지털 %1 번 핀 %2 %3', - bitbrick_sensor_value: '%1 값', - bitbrick_is_touch_pressed: '버튼 %1 이(가) 눌렸는가?', - bitbrick_turn_off_color_led: '컬러 LED 끄기 %1', - bitbrick_turn_on_color_led_by_rgb: '컬러 LED 켜기 R %1 G %2 B %3 %4', - bitbrick_turn_on_color_led_by_picker: '컬러 LED 색 %1 로 정하기 %2', - bitbrick_turn_on_color_led_by_value: '컬러 LED 켜기 색 %1 로 정하기 %2', - bitbrick_buzzer: '버저음 %1 내기 %2', - bitbrick_turn_off_all_motors: '모든 모터 끄기 %1', - bitbrick_dc_speed: 'DC 모터 %1 속도 %2 %3', - bitbrick_dc_direction_speed: 'DC 모터 %1 %2 방향 속력 %3 %4', - bitbrick_servomotor_angle: '서보 모터 %1 각도 %2 %3', + bitbrick_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', + bitbrick_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', + bitbrick_is_touch_pressed: '버튼 %1 이(가) %2 눌렸는가?', + bitbrick_is_sensor_value_compare: '%1 값 %2 %3 인가?', + bitbrick_sensor_value: '%1 값', bitbrick_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', + bitbrick_turn_on_color_led_by_rgb: '엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기', + bitbrick_turn_on_color_led_by_picker: '엘이디를 %1 (으)로 켜기 %2', + bitbrick_turn_on_color_led_by_value: '엘이디를 %1 (으)로 켜기 %2', + bitbrick_turn_off_color_led: '엘이디 끄기 %1', + bitbrick_buzzer: '버저음 %1 내기 %2', + bitbrick_servomotor_angle: '서보모터 %1 각도 %2 %3', + bitbrick_dc_direction_speed: '디씨모터 %1 방향 %2 속력 %3 %4', + bitbrick_dc_speed: '디씨모터 %1 속도 %2 %3', + bitbrick_turn_off_all_motors: "모든 모터 멈추기 %1", + coalaboard_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', + coalaboard_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', + coalaboard_is_touch_pressed: '버튼 %1 이(가) %2 눌렸는가?', + coalaboard_is_sensor_value_compare: '%1 값 %2 %3 인가?', + coalaboard_sensor_value: '%1 값', + coalaboard_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', + coalaboard_turn_on_color_led_by_rgb: '엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기', + coalaboard_turn_on_color_led_by_picker: '엘이디를 %1 (으)로 켜기 %2', + coalaboard_turn_on_color_led_by_value: '엘이디를 %1 (으)로 켜기 %2', + coalaboard_turn_off_color_led: '엘이디 끄기 %1', + coalaboard_buzzer: '버저음 %1 내기 %2', + coalaboard_servomotor_angle: '서보모터 %1 각도 %2 %3', + coalaboard_dc_direction_speed: '디씨모터 %1 방향 %2 속력 %3 %4', + coalaboard_dc_speed: '디씨모터 %1 속도 %2 %3', + coalaboard_turn_off_all_motors: "모든 모터 멈추기 %1", start_drawing: '그리기 시작하기 %1', stop_drawing: '그리기 멈추기 %1', set_color: '붓의 색을 %1 (으)로 정하기 %2', diff --git a/extern/lang/vn.js b/extern/lang/vn.js index 5b2a5d32bc..20ac08ab2f 100644 --- a/extern/lang/vn.js +++ b/extern/lang/vn.js @@ -5983,18 +5983,19 @@ Lang.template = { "iboard_rgb_led": " %1 LED %2 %3", "iboard_set_tone": "Play tone pin %1 on note %2 octave %3 beat %4 %5", "iboard_toggle_led": "Digital %1 Pin %2 %3", + "bitbrick_is_touch_pressed": "nhấn nút %1 %2?", + "bitbrick_is_sensor_value_compare": "nhấn nút %1 %2 %3?", "bitbrick_sensor_value": "giá trị %1", - "bitbrick_is_touch_pressed": "nhấn nút %1?", - "bitbrick_turn_off_color_led": "tắt màu LED %1", + "bitbrick_convert_scale": "đổi giá trị %1 từ %2~%3 đến %4~%5", "bitbrick_turn_on_color_led_by_rgb": "mở màu LED R%1 G %2 B %3 %4", "bitbrick_turn_on_color_led_by_picker": "chọn %1 cho màu LED %2", "bitbrick_turn_on_color_led_by_value": "mở màu LED, chọn %1 %2", + "bitbrick_turn_off_color_led": "tắt màu LED %1", "bitbrick_buzzer": "âm buzz %1 giây %2", - "bitbrick_turn_off_all_motors": "tắt tất cả các động cơ %1", - "bitbrick_dc_speed": "động cơ DC %1 tốc độ %2 %3", - "bitbrick_dc_direction_speed": "động cơ DC %1 %2 tốc độ phương hướng %3 %4", "bitbrick_servomotor_angle": "động cơ servo %1 góc độ %2 %3", - "bitbrick_convert_scale": "đổi giá trị %1 từ %2~%3 đến %4~%4", + "bitbrick_dc_direction_speed": "động cơ DC %1 %2 tốc độ phương hướng %3 %4", + "bitbrick_dc_speed": "động cơ DC %1 tốc độ %2 %3", + "bitbrick_turn_off_all_motors": "tắt tất cả các động cơ %1", "start_drawing": "bắt đầu vẽ %1", "stop_drawing": "ngừng vẽ %1", "set_color": "thiết lập màu cọ bằng %1 %2", diff --git a/images/coalaboard.png b/images/coalaboard.png new file mode 100644 index 0000000000000000000000000000000000000000..3226195095400670baa20c6c5672088bae96056a GIT binary patch literal 23366 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
@33~I{aCzhRYW%@!882A*=Eb1^V*O z!#FGIUtK;VD2|$mO7ye8u9|npFv$dpw=M0=kRf{1ROp1h>>r2pxtV@*p!a2FG|q*< z5OtQ3@MHGYRd*dlg76ZDJ}mq!CfAQ3X84_%aMStomQt{^HamTFo0x2-$;XAYhAM%c zp8t4&A~)9%4!WRK%7Np;+SlhSl72+zJg(dZ&Wx&Nvz=fY-Q^z| zM|5ugZm__}n5X`9b9~_RPSzG5h4t}PJD(JDwx6J*kG6Rf81Yfh;??#0bRvV<1pteL znF_4mG_&(z)Y9toT;AKJ&2)O_glzxm!4#=@^iLb{*gM}o$yFilcs2{SZ-|+7qO_ki z2BaO~8O9o+wZ&8N3?zw%<{^$5Fh8e#j?$8U5Am(3A{Yy~8()Ir2U|U^jK#rk!n=oi z{r~U}yOP^{S>@xHnkTEG2auS$GZgPu1?(7AUFTUICSJ+j&pn1vEp2MY@u$Cw&~ zC2^qXYv#3eI9N@3L>i+@-AJLAH(T`Jrf>&jYtmOn?HI#GelhKHdp6&F%;@kIx%VC4 zc9C|U*s%X@U8#QAqxCiBmnlc{ZAJ659EN|uJ;kDov&qKcq1`M7p@!crg@|u+Eq5in zGZ&#RBHA)frC5>#e+qKE6egt%Yxkm?;h5bPgt>DjV7Oxj$WaGqSZXGs~eoDk!-uT zdAV9z&uk_(P?vb;f8$6dV!Tfb)G9%uO>m34(T!$U%Lu#&B^oHQvsrhC=n8WsEF|LlP~CO* zRy5%sM+&6(^Y(%sx2&&7uyEm1*;31>C*0Lpu$(!Ht=N-jM_TE>&G0;xoCWe>XQfcR zzCG@MY|ojXG9X#X#lA9sUy{vd;8Rj5Rm}b_xC70#@y4e?RdFcoz*1k1fBnx@`}ACD zbOrcD0*RHKr40iAJODYmFNZ+FOU@~JMOw-v$*fs;rNMoe!>+{)OlPr$1kxqvtj>O` z3cZgz$Me;(4#=GOJ2*0p1naQHsQGvKK(0kXi4pePbwSZbv22S zwBuZX9N2uCNUZO~v-$@NeOX4dF?DKDiW1ks^dHgSN3

R@x`tM9Yg1qCVkU|zrSeS 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 literal 0 HcmV?d00001 diff --git a/images/hw/coalaboard.png b/images/hw/coalaboard.png new file mode 100644 index 0000000000000000000000000000000000000000..3226195095400670baa20c6c5672088bae96056a GIT binary patch literal 23366 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
@33~I{aCzhRYW%@!882A*=Eb1^V*O z!#FGIUtK;VD2|$mO7ye8u9|npFv$dpw=M0=kRf{1ROp1h>>r2pxtV@*p!a2FG|q*< z5OtQ3@MHGYRd*dlg76ZDJ}mq!CfAQ3X84_%aMStomQt{^HamTFo0x2-$;XAYhAM%c zp8t4&A~)9%4!WRK%7Np;+SlhSl72+zJg(dZ&Wx&Nvz=fY-Q^z| zM|5ugZm__}n5X`9b9~_RPSzG5h4t}PJD(JDwx6J*kG6Rf81Yfh;??#0bRvV<1pteL znF_4mG_&(z)Y9toT;AKJ&2)O_glzxm!4#=@^iLb{*gM}o$yFilcs2{SZ-|+7qO_ki z2BaO~8O9o+wZ&8N3?zw%<{^$5Fh8e#j?$8U5Am(3A{Yy~8()Ir2U|U^jK#rk!n=oi z{r~U}yOP^{S>@xHnkTEG2auS$GZgPu1?(7AUFTUICSJ+j&pn1vEp2MY@u$Cw&~ zC2^qXYv#3eI9N@3L>i+@-AJLAH(T`Jrf>&jYtmOn?HI#GelhKHdp6&F%;@kIx%VC4 zc9C|U*s%X@U8#QAqxCiBmnlc{ZAJ659EN|uJ;kDov&qKcq1`M7p@!crg@|u+Eq5in zGZ&#RBHA)frC5>#e+qKE6egt%Yxkm?;h5bPgt>DjV7Oxj$WaGqSZXGs~eoDk!-uT zdAV9z&uk_(P?vb;f8$6dV!Tfb)G9%uO>m34(T!$U%Lu#&B^oHQvsrhC=n8WsEF|LlP~CO* zRy5%sM+&6(^Y(%sx2&&7uyEm1*;31>C*0Lpu$(!Ht=N-jM_TE>&G0;xoCWe>XQfcR zzCG@MY|ojXG9X#X#lA9sUy{vd;8Rj5Rm}b_xC70#@y4e?RdFcoz*1k1fBnx@`}ACD zbOrcD0*RHKr40iAJODYmFNZ+FOU@~JMOw-v$*fs;rNMoe!>+{)OlPr$1kxqvtj>O` z3cZgz$Me;(4#=GOJ2*0p1naQHsQGvKK(0kXi4pePbwSZbv22S zwBuZX9N2uCNUZO~v-$@NeOX4dF?DKDiW1ks^dHgSN3

R@x`tM9Yg1qCVkU|zrSeS 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 literal 0 HcmV?d00001 diff --git a/src/playground/blocks/hardware/block_bitbrick.js b/src/playground/blocks/hardware/block_bitbrick.js index f4391d5f2c..7c0cdb188a 100644 --- a/src/playground/blocks/hardware/block_bitbrick.js +++ b/src/playground/blocks/hardware/block_bitbrick.js @@ -206,21 +206,27 @@ Entry.Bitbrick = { Entry.Bitbrick.blockMenuBlocks = [ 'bitbrick_when_button_pressed', 'bitbrick_when_sensor_get_value', + 'bitbrick_is_touch_pressed', + 'bitbrick_is_sensor_value_compare', 'bitbrick_sensor_value', 'bitbrick_convert_scale', - 'bitbrick_is_touch_pressed', - 'bitbrick_turn_off_color_led', 'bitbrick_turn_on_color_led_by_rgb', 'bitbrick_turn_on_color_led_by_picker', 'bitbrick_turn_on_color_led_by_value', - 'bitbrick_buzzer', - 'bitbrick_turn_off_all_motors', - 'bitbrick_dc_speed', - 'bitbrick_dc_direction_speed', + 'bitbrick_turn_off_color_led', + 'bitbrick_buzzer', 'bitbrick_servomotor_angle', + 'bitbrick_dc_direction_speed', + 'bitbrick_dc_speed', + 'bitbrick_turn_off_all_motors', ]; Entry.Bitbrick.getBlocks = function() { + let options_BITBRICK_button2 = + [ + [Lang.Blocks.BITBRICK_button_pressed, 'pressed'], + [Lang.Blocks.BITBRICK_button_released, 'released'], + ]; return { //region bitbrick 비트브릭 bitbrick_when_button_pressed: { @@ -256,15 +262,24 @@ Entry.Bitbrick.getBlocks = function() { arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, menuName: Entry.Bitbrick.touchList, }, + { + type: 'Dropdown', + options: options_BITBRICK_button2, + value: 'pressed', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, ], events: {}, def: { - params: [null, null], + params: [null, null, null], type: 'bitbrick_when_button_pressed', }, paramsKeyMap: { DUMMY: 0, PORT: 1, + PRESSED: 2, }, class: 'event', isNotFor: ['bitbrick'], @@ -274,9 +289,16 @@ Entry.Bitbrick.getBlocks = function() { let selectedSensor = script.values[ 1 ]; let port = script.getStringField('PORT'); let type = Entry.hw.portData[port].type; - let val = Entry.hw.portData[port].value; - if( selectedSensor == port && val == 0 ) { - return script.callReturn(); + let val = Entry.hw.portData[port].value; // 0이면 누름, 1023이면 누르지 않음 + let pressed = script.getStringField('PRESSED'); + if( selectedSensor == port ) { + if ((pressed == 'pressed') && (val == 0)) { + return script.callReturn(); + } else if ((pressed == 'released') && (val == 1023)) { + return script.callReturn(); + } else { + return this.die(); + } } else { return this.die(); } @@ -284,7 +306,7 @@ Entry.Bitbrick.getBlocks = function() { return this.die(); } }, - syntax: { js: [], py: ['Bitbrick.when_button_pressed(%2)'] }, + syntax: { js: [], py: ['Bitbrick.when_button_pressed(%2, %3)'] }, }, bitbrick_when_sensor_get_value: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -316,7 +338,7 @@ Entry.Bitbrick.getBlocks = function() { bgColor: EntryStatic.colorSet.block.darken.HARDWARE, arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, options: Entry.Bitbrick.INEQ_SIGN, - value: '<', + value: '>', }, { type: 'Block', @@ -331,7 +353,7 @@ Entry.Bitbrick.getBlocks = function() { null, { type: 'text', - params: ['50'], + params: ['100'], } ], type: 'bitbrick_when_sensor_get_value', @@ -441,7 +463,7 @@ Entry.Bitbrick.getBlocks = function() { }, { type: 'number', - params: ['-100'], + params: ['0'], }, { type: 'number', @@ -501,21 +523,104 @@ Entry.Bitbrick.getBlocks = function() { bgColor: EntryStatic.colorSet.block.darken.HARDWARE, arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, }, + { + type: 'Dropdown', + options: options_BITBRICK_button2, + value: 'pressed', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, ], events: {}, def: { - params: [null], + params: [null, null], type: 'bitbrick_is_touch_pressed', }, paramsKeyMap: { PORT: 0, + PRESSED: 1 + }, + class: 'button', + isNotFor: ['bitbrick'], + func: function(sprite, script) { + let port = script.getStringField('PORT'); + let val = Entry.hw.portData[port].value; + let pressed = script.getStringField('PRESSED'); + if ((pressed == Lang.Blocks.BITBRICK_button_pressed) && (val == 0)) { + return treu; + } else if ((pressed == Lang.Blocks.BITBRICK_button_released) && (val == 1023)) { + return treu; + } else { + return false; + } + }, + syntax: { js: [], py: ['Bitbrick.is_touch_pressed(%1, %2)'] }, + }, + bitbrick_is_sensor_value_compare: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + menuName: Entry.Bitbrick.sensorList, + }, + { + type: 'Dropdown', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + options: Entry.Bitbrick.INEQ_SIGN, + value: '>', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + null, + null, + { + type: 'text', + params: ['100'], + } + ], + type: 'bitbrick_is_sensor_value_compare', + }, + paramsKeyMap: { + PORT: 0, + INEQ_SIGN: 1, + VALUE: 2 }, class: 'button', isNotFor: ['bitbrick'], func: function(sprite, script) { - return Entry.hw.portData[script.getStringField('PORT')].value === 0; + let selectedPort = script.values[ 0 ]; + let ineqSign = script.values[ 1 ]; + let value = script.values[ 2 ]; + let port = script.getStringField('PORT'); + let val = Entry.hw.portData[port].value; + if( selectedPort == port && ineqSign == '<' && val < value ) { + return true; + } else if( selectedPort == port && ineqSign == '>' && val > value ) { + return true; + } else if( selectedPort == port && ineqSign == '=' && val == value ) { + return true; + } else { + return false; + } }, - syntax: { js: [], py: ['Bitbrick.is_touch_pressed(%1)'] }, + syntax: { js: [], py: ['Bitbrick.is_sensor_value_compare(%1,%2,%3)'] }, }, bitbrick_turn_off_color_led: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -962,22 +1067,25 @@ Entry.Bitbrick.setLanguage = function() { ko: { // ko.js에 작성하던 내용 template: { - bitbrick_when_button_pressed: '%1 버튼 %2 눌러졌을 때', + bitbrick_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', bitbrick_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', - bitbrick_sensor_value: '%1 값', - bitbrick_is_touch_pressed: '버튼 %1 이(가) 눌렸는가?', - bitbrick_turn_off_color_led: '엘이디 끄기 %1', - bitbrick_turn_on_color_led_by_rgb: '엘이디 빨강 %1 초록 %2 파랑 %3 %4', - bitbrick_turn_on_color_led_by_picker: '엘이디 색 %1 로 정하기 %2', - bitbrick_turn_on_color_led_by_value: '엘이디 색 %1 로 정하기 %2', - bitbrick_buzzer: '버저음 %1 내기 %2', - bitbrick_turn_off_all_motors: '모든 모터 끄기 %1', - bitbrick_dc_speed: '디씨모터 %1 속도 %2 %3', - bitbrick_dc_direction_speed: '디씨모터 %1 %2 방향 속력 %3 %4', - bitbrick_servomotor_angle: '서보모터 %1 각도 %2 %3', + bitbrick_is_touch_pressed: '버튼 %1 이(가) %2 눌렸는가?', + bitbrick_is_sensor_value_compare: '%1 값 %2 %3 인가?', + bitbrick_sensor_value: '%1 값', bitbrick_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', + bitbrick_turn_on_color_led_by_rgb: '엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기', + bitbrick_turn_on_color_led_by_picker: '엘이디를 %1 (으)로 켜기 %2', + bitbrick_turn_on_color_led_by_value: '엘이디를 %1 (으)로 켜기 %2', + bitbrick_turn_off_color_led: '엘이디 끄기 %1', + bitbrick_buzzer: '버저음 %1 내기 %2', + bitbrick_servomotor_angle: '서보모터 %1 각도 %2 %3', + bitbrick_dc_direction_speed: '디씨모터 %1 방향 %2 속력 %3 %4', + bitbrick_dc_speed: '디씨모터 %1 속도 %2 %3', + bitbrick_turn_off_all_motors: '모든 모터 멈추기 %1', }, Blocks: { + BITBRICK_button_pressed: '누름', + BITBRICK_button_released: '누르지 않음', BITBRICK_light: '밝기센서', BITBRICK_IR: '거리센서', BITBRICK_touch: '버튼', @@ -1000,22 +1108,25 @@ Entry.Bitbrick.setLanguage = function() { en: { // en.js에 작성하던 내용 template: { - bitbrick_when_button_pressed: '%1 When button %2 pressed', - bitbrick_when_sensor_get_value: '%1 When %2 value %3 %4', - bitbrick_sensor_value: 'Value %1', - bitbrick_is_touch_pressed: 'Pressed %1 button? ', - bitbrick_turn_off_color_led: 'Turn off color LED %1', - bitbrick_turn_on_color_led_by_rgb: 'Color LED R %1 G %2 B %3 %4', - bitbrick_turn_on_color_led_by_picker: 'Select %1 for color LED %2', - bitbrick_turn_on_color_led_by_value: 'Color LED, select %1 %2', - bitbrick_buzzer: 'Buzz for %1 secs %2', - bitbrick_turn_off_all_motors: 'Turn off all motors %1', - bitbrick_dc_speed: 'DC motor %1 speed %2 %3', - bitbrick_dc_direction_speed: 'DC motor %1 %2 direction speed %3 %4', - bitbrick_servomotor_angle: 'Servo motor %1 angle %2 %3', - bitbrick_convert_scale: 'Convert %1 value from %2~%3 to %4~%4', + bitbrick_when_button_pressed: '%1 when button %2 %3', + bitbrick_when_sensor_get_value: '%1 when %2 value %3 %4', + bitbrick_is_touch_pressed: 'button %1 %2?', + bitbrick_is_sensor_value_compare: '%1 %2 %3? ', + bitbrick_sensor_value: '%1 value', + bitbrick_convert_scale: 'map %1 value from %2 ~ %3 to %4 ~ %5', + bitbrick_turn_on_color_led_by_rgb: 'set LED color to Red %1 Green %2 Blue %3 %4', + bitbrick_turn_on_color_led_by_picker: 'set LED color to %1 %2', + bitbrick_turn_on_color_led_by_value: 'set LED color %1 %2', + bitbrick_turn_off_color_led: 'turn off LED %1', + bitbrick_buzzer: 'buzz note %1 %2', + bitbrick_servomotor_angle: 'servo motor %1 degree %2 %3', + bitbrick_dc_direction_speed: 'dc motor %1 direction %2 speed %3 %4', + bitbrick_dc_speed: 'dc motor %1 velocity %2 %3', + bitbrick_turn_off_all_motors: 'stop all motors %1', }, Blocks: { + BITBRICK_button_pressed: 'pressed', + BITBRICK_button_released: 'released', BITBRICK_light: 'light', BITBRICK_IR: 'IR', BITBRICK_touch: 'touch', diff --git a/src/playground/blocks/hardware/block_coalaboard.js b/src/playground/blocks/hardware/block_coalaboard.js new file mode 100644 index 0000000000..d5a4149b22 --- /dev/null +++ b/src/playground/blocks/hardware/block_coalaboard.js @@ -0,0 +1,1149 @@ +'use strict'; + +Entry.Coalaboard = { + SENSOR_MAP: { + 1: 'light', + 2: 'IR', + 3: 'touch', + 4: 'potentiometer', + 5: 'MIC', + 6: 'ultrasonicSensor', + 10: 'vibrationSensor', + 21: 'UserSensor', + 11: 'UserInput', + 20: 'LED', + 19: 'SERVO', + 18: 'DC', + }, + PORT_MAP: { + buzzer: 2, + '5': 4, + '6': 6, + '7': 8, + '8': 10, + LEDR: 12, + LEDG: 14, + LEDB: 16, + }, + INEQ_SIGN: [ + ["<", "<"], + [">", ">"], + ["=", "="] + ], + sensorList: function() { + var list = []; + var portData = Entry.hw.portData; + for (var i = 1; i < 5; i++) { + var data = portData[i]; + if (data && (data.value || data.value === 0)) { + list.push([i + ' - ' + Lang.Blocks['COALABOARD_' + data.type], i.toString()]); + } + } + + if (list.length == 0) return [[Lang.Blocks.no_target, 'null']]; + return list; + }, + touchList: function() { + var list = []; + var portData = Entry.hw.portData; + for (var i = 1; i < 5; i++) { + var data = portData[i]; + if (data && data.type === 'touch') list.push([i.toString(), i.toString()]); + } + if (list.length == 0) return [[Lang.Blocks.no_target, 'null']]; + return list; + }, + servoList: function() { + var list = []; + var portData = Entry.hw.portData; + for (var i = 5; i < 9; i++) { + var data = portData[i]; + if (data && data.type === 'SERVO') list.push(['ABCD'[i - 5], i.toString()]); + } + if (list.length == 0) return [[Lang.Blocks.no_target, 'null']]; + return list; + }, + dcList: function() { + var list = []; + var portData = Entry.hw.portData; + for (var i = 5; i < 9; i++) { + var data = portData[i]; + if (data && data.type === 'DC') list.push(['ABCD'[i - 5], i.toString()]); + } + if (list.length == 0) return [[Lang.Blocks.no_target, 'null']]; + return list; + }, + /** + * 엔트리가 중지 되면 호출된다. + */ + setZero: function() { + let sq = Entry.hw.sendQueue; + for (let port in Entry.Coalaboard.PORT_MAP) { + let portData = Entry.hw.portData[port]; + if( portData != null ) { + if( portData.type == Entry.Coalaboard.SENSOR_MAP[18] ) { // DC모터 인 경우, 129로 세팅하여 바로 멈추기 + sq[port] = 129; + } else { + sq[port] = 0; + } + } else { + sq[port] = 0; + } + } + Entry.hw.update(); + }, + id: '3.3', + name: 'coalaboard', + url: 'http://www.bitbrick.cc/', + imageName: 'coalaboard.png', + title: { + ko: '코알라보드', + en: 'coalaboard', + }, + servoMaxValue: 181, + servoMinValue: 1, + dcMaxValue: 100, + dcMinValue: -100, + monitorTemplate: { + keys: ['value'], + imgPath: 'hw/coalaboard.png', + width: 400, + height: 400, + listPorts: { + '1': { + name: Lang.Hw.port_en + ' 1 ' + Lang.Hw.port_ko, + type: 'input', + pos: { x: 0, y: 0 }, + }, + '2': { + name: Lang.Hw.port_en + ' 2 ' + Lang.Hw.port_ko, + type: 'input', + pos: { x: 0, y: 0 }, + }, + '3': { + name: Lang.Hw.port_en + ' 3 ' + Lang.Hw.port_ko, + type: 'input', + pos: { x: 0, y: 0 }, + }, + '4': { + name: Lang.Hw.port_en + ' 4 ' + Lang.Hw.port_ko, + type: 'input', + pos: { x: 0, y: 0 }, + }, + A: { + name: Lang.Hw.port_en + ' A ' + Lang.Hw.port_ko, + type: 'input', + pos: { x: 0, y: 0 }, + }, + B: { + name: Lang.Hw.port_en + ' B ' + Lang.Hw.port_ko, + type: 'input', + pos: { x: 0, y: 0 }, + }, + C: { + name: Lang.Hw.port_en + ' C ' + Lang.Hw.port_ko, + type: 'input', + pos: { x: 0, y: 0 }, + }, + D: { + name: Lang.Hw.port_en + ' D ' + Lang.Hw.port_ko, + type: 'input', + pos: { x: 0, y: 0 }, + }, + }, + // }, + // ports : { + // "1":{name: "light", type: "input", pos: {x: 0, y: 0}}, + // "2":{name: "IR", type: "input", pos: {x : 0, y: 0}}, + // "3":{name: "touch", type: "input", pos: {x: 0, y: 0}}, + // "4":{name: "potentiometer", type: "input", pos: {x: 0, y: 0}}, + // "5":{name: "MIC", type: "input", pos: {x: 0, y: 0}}, + // "21":{name: "UserSensor", type: "input", pos: {x: 0, y: 0}}, + // "11":{name: "USER INPUT", type: "input", pos: {x: 0, y: 0}}, + // "20":{name: "LED", type: "input", pos: {x: 0, y: 0}}, + // "19":{name: "SERVO", type: "input", pos: {x: 0, y: 0}}, + // "18":{name: "DC", type: "input", pos: {x: 0, y: 0}}, + // "buzzer":{name: "부저", type: "input", pos: {x: 0, y: 0}}, + // "LEDR":{name: "LEDR", type: "output", pos: {x: 0, y: 0}}, + // "LEDG":{name: "LEDG", type: "output", pos: {x: 0, y: 0}}, + // "LEDB":{name: "LEDG", type: "output", pos: {x: 0, y: 0}} + // }, + mode: 'both', + }, + /** + * 콜백 함수. 계속해서 센서 데이터를 받는다. + * @param {*} pd + */ + afterReceive(pd) { + for( let i = 1; i < 5; i++ ) { // 오직 센서만 받기 + let obj = pd[ i ]; // ex) null or { type: "touch", value: 1023 } + if( obj != null ) { + if( obj.type == 'touch' && obj.value == 0 ) { + Entry.engine.fireEvent('coalaboardButtonEventReceive'); + } + Entry.engine.fireEvent('coalaboardSensorGetValueEventReceive'); + } + } + }, + calculateDCMotorValue: function( value ) { + let val = 0; + if ( value > 0 ) { + val = Math.floor( ( value * 0.8 ) + 16 ); + } else if ( value < 0 ) { + val = Math.ceil( ( value * 0.8 ) - 19 ); + } else { + val = 0; + } + // DC_MOTOR_ADJUSTMENT 128 + val = 128 + val; + if ( val == 128 ) { + val = 129; + } + return val; + } +}; + +Entry.Coalaboard.blockMenuBlocks = [ + 'coalaboard_when_button_pressed', + 'coalaboard_when_sensor_get_value', + 'coalaboard_is_touch_pressed', + 'coalaboard_is_sensor_value_compare', + 'coalaboard_sensor_value', + 'coalaboard_convert_scale', + 'coalaboard_turn_on_color_led_by_rgb', + 'coalaboard_turn_on_color_led_by_picker', + 'coalaboard_turn_on_color_led_by_value', + 'coalaboard_turn_off_color_led', + 'coalaboard_buzzer', + 'coalaboard_servomotor_angle', + 'coalaboard_dc_direction_speed', + 'coalaboard_dc_speed', + 'coalaboard_turn_off_all_motors', +]; + +Entry.Coalaboard.getBlocks = function() { + let options_COALABOARD_button2 = + [ + [Lang.Blocks.COALABOARD_button_pressed, 'pressed'], + [Lang.Blocks.COALABOARD_button_released, 'released'], + ]; + return { + //region coalaboard 코알라보드 + coalaboard_when_button_pressed: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_event', + statements: [], + params: [ + // { + // type: 'Indicator', + // img: 'block_icon/start_icon_play.svg', + // size: 14, + // position: { + // x: 0, + // y: -2, + // }, + // }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + position: { + x: 0, + y: 0 + } + }, + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + menuName: Entry.Coalaboard.touchList, + }, + { + type: 'Dropdown', + options: options_COALABOARD_button2, + value: 'pressed', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null, null, null], + type: 'coalaboard_when_button_pressed', + }, + paramsKeyMap: { + DUMMY: 0, + PORT: 1, + PRESSED: 2, + }, + class: 'event', + isNotFor: ['coalaboard'], + event: 'coalaboardButtonEventReceive', + func: function(sprite, script) { + if( script.values.length > 0 ) { + let selectedSensor = script.values[ 1 ]; + let port = script.getStringField('PORT'); + let type = Entry.hw.portData[port].type; + let val = Entry.hw.portData[port].value; // 0이면 누름, 1023이면 누르지 않음 + let pressed = script.getStringField('PRESSED'); + if( selectedSensor == port ) { + if ((pressed == 'pressed') && (val == 0)) { + return script.callReturn(); + } else if ((pressed == 'released') && (val == 1023)) { + return script.callReturn(); + } else { + return this.die(); + } + } else { + return this.die(); + } + } else { + return this.die(); + } + }, + syntax: { js: [], py: ['Coalaboard.when_button_pressed(%2, %3)'] }, + }, + coalaboard_when_sensor_get_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_event', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + position: { + x: 0, + y: 0 + } + }, + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + menuName: Entry.Coalaboard.sensorList, + }, + { + type: 'Dropdown', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + options: Entry.Coalaboard.INEQ_SIGN, + value: '>', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + null, + null, + null, + { + type: 'text', + params: ['100'], + } + ], + type: 'coalaboard_when_sensor_get_value', + }, + paramsKeyMap: { + DUMMY: 0, + PORT: 1, + INEQ_SIGN: 2, + VALUE: 3 + }, + class: 'event', + isNotFor: ['coalaboard'], + event: 'coalaboardSensorGetValueEventReceive', + func: function(sprite, script) { + let selectedPort = script.values[ 1 ]; + let ineqSign = script.values[ 2 ]; + let value = script.values[ 3 ]; + let port = script.getStringField('PORT'); + let val = Entry.hw.portData[port].value; + if( selectedPort == port && ineqSign == '<' && val < value ) { + return script.callReturn(); + } else if( selectedPort == port && ineqSign == '>' && val > value ) { + return script.callReturn(); + } else if( selectedPort == port && ineqSign == '=' && val == value ) { + return script.callReturn(); + } else { + return this.die(); + } + }, + syntax: { js: [], py: ['Coalaboard.when_sensor_get_value(%2,%3,%4)'] }, + }, + coalaboard_sensor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + menuName: Entry.Coalaboard.sensorList, + }, + ], + events: {}, + def: { + params: [null], + type: 'coalaboard_sensor_value', + }, + paramsKeyMap: { + PORT: 0, + }, + class: 'button', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + var port = script.getStringField('PORT'); + return Entry.hw.portData[port].value; + }, + syntax: { js: [], py: ['Coalaboard.sensor_value(%1)'] }, + }, + coalaboard_convert_scale: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + menuName: Entry.Coalaboard.sensorList, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['1023'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['100'], + }, + ], + type: 'coalaboard_convert_scale', + }, + paramsKeyMap: { + PORT: 0, + VALUE2: 1, + VALUE3: 2, + VALUE4: 3, + VALUE5: 4, + }, + class: 'button', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + var port = script.getNumberField('PORT'); + var value1 = Entry.hw.portData[port].value; + var value2 = script.getNumberValue('VALUE2', script); + var value3 = script.getNumberValue('VALUE3', script); + var value4 = script.getNumberValue('VALUE4', script); + var value5 = script.getNumberValue('VALUE5', script); + var result = value1; + + if (value4 > value5) { + var swap = value4; + value4 = value5; + value5 = swap; + } + + result -= value2; + result = result * ((value5 - value4) / (value3 - value2)); + result += value4; + result = Math.min(value5, result); + result = Math.max(value4, result); + return Math.round(result); + }, + syntax: { + js: [], + py: ['Coalaboard.convert_scale(%1, %2, %3, %4, %5)'], + }, + }, + coalaboard_is_touch_pressed: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + menuName: Entry.Coalaboard.touchList, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: options_COALABOARD_button2, + value: 'pressed', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'coalaboard_is_touch_pressed', + }, + paramsKeyMap: { + PORT: 0, + PRESSED: 1 + }, + class: 'button', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + let port = script.getStringField('PORT'); + let val = Entry.hw.portData[port].value; + let pressed = script.getStringField('PRESSED'); + if ((pressed == 'pressed') && (val == 0)) { + return treu; + } else if ((pressed == 'released') && (val == 1023)) { + return treu; + } else { + return false; + } + }, + syntax: { js: [], py: ['Coalaboard.is_touch_pressed(%1, %2)'] }, + }, + coalaboard_is_sensor_value_compare: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + menuName: Entry.Coalaboard.sensorList, + }, + { + type: 'Dropdown', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + options: Entry.Coalaboard.INEQ_SIGN, + value: '>', + }, + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + null, + null, + { + type: 'text', + params: ['100'], + } + ], + type: 'coalaboard_is_sensor_value_compare', + }, + paramsKeyMap: { + PORT: 0, + INEQ_SIGN: 1, + VALUE: 2 + }, + class: 'button', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + let selectedPort = script.values[ 0 ]; + let ineqSign = script.values[ 1 ]; + let value = script.values[ 2 ]; + let port = script.getStringField('PORT'); + let val = Entry.hw.portData[port].value; + if( selectedPort == port && ineqSign == '<' && val < value ) { + return true; + } else if( selectedPort == port && ineqSign == '>' && val > value ) { + return true; + } else if( selectedPort == port && ineqSign == '=' && val == value ) { + return true; + } else { + return false; + } + }, + syntax: { js: [], py: ['Bitbrick.is_sensor_value_compare(%1,%2,%3)'] }, + }, + coalaboard_turn_off_color_led: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'coalaboard_turn_off_color_led', + id: 'i3je', + }, + class: 'led', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + Entry.hw.sendQueue['LEDR'] = 0; + Entry.hw.sendQueue['LEDG'] = 0; + Entry.hw.sendQueue['LEDB'] = 0; + return script.callReturn(); + }, + syntax: { js: [], py: ['Coalaboard.turn_off_color_led()'] }, + }, + coalaboard_turn_on_color_led_by_rgb: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'text', + params: ['255'], + }, + { + type: 'text', + params: ['255'], + }, + { + type: 'text', + params: ['255'], + }, + null, + ], + type: 'coalaboard_turn_on_color_led_by_rgb', + }, + paramsKeyMap: { + rValue: 0, + gValue: 1, + bValue: 2, + }, + class: 'led', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + var red = script.getNumberValue('rValue'), + green = script.getNumberValue('gValue'), + blue = script.getNumberValue('bValue'), + min = 0, + max = 255, + adjustor = Entry.adjustValueWithMaxMin, + sq = Entry.hw.sendQueue; + + sq['LEDR'] = adjustor(red, min, max); + sq['LEDG'] = adjustor(green, min, max); + sq['LEDB'] = adjustor(blue, min, max); + return script.callReturn(); + }, + syntax: { js: [], py: ['Coalaboard.color_led_by_rgb(%1, %2, %3)'] }, + }, + coalaboard_turn_on_color_led_by_picker: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Color', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'coalaboard_turn_on_color_led_by_picker', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'led', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + var port = script.getStringField('VALUE'); + Entry.hw.sendQueue['LEDR'] = parseInt(port.substr(1, 2), 16); + Entry.hw.sendQueue['LEDG'] = parseInt(port.substr(3, 2), 16); + Entry.hw.sendQueue['LEDB'] = parseInt(port.substr(5, 2), 16); + return script.callReturn(); + }, + syntax: { js: [], py: ['Coalaboard.color_led_by_picker(%1)'] }, + }, + coalaboard_turn_on_color_led_by_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'text', + params: ['0'], + }, + null, + ], + type: 'coalaboard_turn_on_color_led_by_value', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'led', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + var value = script.getNumberValue('VALUE'); + var red, green, blue; + value = value % 200; + if (value < 67) { + red = 200 - value * 3; + green = value * 3; + blue = 0; + } else if (value < 134) { + value = value - 67; + red = 0; + green = 200 - value * 3; + blue = value * 3; + } else if (value < 201) { + value = value - 134; + red = value * 3; + green = 0; + blue = 200 - value * 3; + } + Entry.hw.sendQueue['LEDR'] = red; + Entry.hw.sendQueue['LEDG'] = green; + Entry.hw.sendQueue['LEDB'] = blue; + return script.callReturn(); + }, + syntax: { js: [], py: ['Coalaboard.color_led_by_value(%1)'] }, + }, + coalaboard_buzzer: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'text', + params: ['60'], + }, + null, + ], + type: 'coalaboard_buzzer', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'buzzer', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + if (!script.isStart) { + var value = script.getNumberValue('VALUE'); + Entry.hw.sendQueue['buzzer'] = value; + script.isStart = true; + return script; + } else { + Entry.hw.sendQueue['buzzer'] = 0; + delete script.isStart; + return script.callReturn(); + } + }, + syntax: { js: [], py: ['Coalaboard.buzzer(%1)'] }, + }, + coalaboard_turn_off_all_motors: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'coalaboard_turn_off_all_motors', + }, + class: 'motor', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + var sq = Entry.hw.sendQueue; + var coalaboard = Entry.Coalaboard; + coalaboard.servoList().map(function(servo) { + sq[servo[1]] = 0; + }); + coalaboard.dcList().map(function(dc) { + sq[dc[1]] = 129; + }); + return script.callReturn(); + }, + syntax: { js: [], py: ['Coalaboard.turn_off_all_motors()'] }, + }, + coalaboard_dc_speed: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + menuName: Entry.Coalaboard.dcList, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'text', + params: ['100'], + }, + null, + ], + type: 'coalaboard_dc_speed', + }, + paramsKeyMap: { + PORT: 0, + VALUE: 1, + }, + class: 'motor', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + var value = script.getNumberValue('VALUE'); + value = Math.min(value, Entry.Coalaboard.dcMaxValue); + value = Math.max(value, Entry.Coalaboard.dcMinValue); + let val = Entry.Coalaboard.calculateDCMotorValue( value ); + Entry.hw.sendQueue[script.getStringField('PORT')] = val; + return script.callReturn(); + }, + syntax: { js: [], py: ['Coalaboard.dc_speed(%1, %2)'] }, + }, + coalaboard_dc_direction_speed: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + menuName: Entry.Coalaboard.dcList, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.COALABOARD_dc_direction_cw, 'CW'], + [Lang.Blocks.COALABOARD_dc_direction_ccw, 'CCW'], + ], + value: 'CW', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + null, + { + type: 'text', + params: ['100'], + }, + null, + ], + type: 'coalaboard_dc_direction_speed', + }, + paramsKeyMap: { + PORT: 0, + DIRECTION: 1, + VALUE: 2, + }, + class: 'motor', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + let isFront = script.getStringField('DIRECTION') === 'CW'; + let value = script.getNumberValue('VALUE'); + value = Math.min(value, Entry.Coalaboard.dcMaxValue); + value = Math.max(value, 0); + if ( !isFront ) { + value = -1 * value; + } + let val = Entry.Coalaboard.calculateDCMotorValue( value ); + Entry.hw.sendQueue[script.getStringField('PORT')] = val; + return script.callReturn(); + }, + syntax: { js: [], py: ['Coalaboard.dc_direction_speed(%1, %2, %3)'] }, + }, + coalaboard_servomotor_angle: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'DropdownDynamic', + value: null, + fontSize: 11, + menuName: Entry.Coalaboard.servoList, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'text', + params: ['0'], + }, + null, + ], + type: 'coalaboard_servomotor_angle', + }, + paramsKeyMap: { + PORT: 0, + VALUE: 1, + }, + class: 'motor', + isNotFor: ['coalaboard'], + func: function(sprite, script) { + var value = Entry.Coalaboard.servoMaxValue - (script.getNumberValue('VALUE') + 1); + value = Math.min(value, Entry.Coalaboard.servoMaxValue); + value = Math.max(value, Entry.Coalaboard.servoMinValue); + Entry.hw.sendQueue[script.getStringField('PORT')] = value; + return script.callReturn(); + }, + syntax: { js: [], py: ['Coalaboard.servomotor_angle(%1, %2)'] }, + }, + //endregion coalaboard 코알라보드 + }; +}; +// 언어 적용 +Entry.Coalaboard.setLanguage = function() { + return { + ko: { + // ko.js에 작성하던 내용 + template: { + coalaboard_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', + coalaboard_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', + coalaboard_is_touch_pressed: '버튼 %1 이(가) %2 눌렸는가?', + coalaboard_is_sensor_value_compare: '%1 값 %2 %3 인가?', + coalaboard_sensor_value: '%1 값', + coalaboard_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', + coalaboard_turn_on_color_led_by_rgb: '엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기', + coalaboard_turn_on_color_led_by_picker: '엘이디를 %1 (으)로 켜기 %2', + coalaboard_turn_on_color_led_by_value: '엘이디를 %1 (으)로 켜기 %2', + coalaboard_turn_off_color_led: '엘이디 끄기 %1', + coalaboard_buzzer: '버저음 %1 내기 %2', + coalaboard_servomotor_angle: '서보모터 %1 각도 %2 %3', + coalaboard_dc_direction_speed: '디씨모터 %1 방향 %2 속력 %3 %4', + coalaboard_dc_speed: '디씨모터 %1 속도 %2 %3', + coalaboard_turn_off_all_motors: '모든 모터 멈추기 %1', + }, + Blocks: { + COALABOARD_button_pressed: '누름', + COALABOARD_button_released: '누르지 않음', + COALABOARD_light: '밝기센서', + COALABOARD_IR: '거리센서', + COALABOARD_touch: '버튼', + COALABOARD_ultrasonicSensor: '초음파센서', + COALABOARD_vibrationSensor: '진동센서', + COALABOARD_potentiometer: '가변저항', + COALABOARD_MIC: '소리센서', + COALABOARD_UserSensor: '사용자입력', + COALABOARD_UserInput: '사용자입력', + COALABOARD_dc_direction_ccw: '반시계', + COALABOARD_dc_direction_cw: '시계', + }, + Menus: { + coalaboard: '코알라보드', + }, + Device: { + coalaboard: '코알라보드', + }, + }, + en: { + // en.js에 작성하던 내용 + template: { + coalaboard_when_button_pressed: '%1 when button %2 %3', + coalaboard_when_sensor_get_value: '%1 when %2 value %3 %4', + coalaboard_is_touch_pressed: 'button %1 %2?', + coalaboard_is_sensor_value_compare: '%1 %2 %3? ', + coalaboard_sensor_value: '%1 value', + coalaboard_convert_scale: 'map %1 value from %2 ~ %3 to %4 ~ %5', + coalaboard_turn_on_color_led_by_rgb: 'set LED color to Red %1 Green %2 Blue %3 %4', + coalaboard_turn_on_color_led_by_picker: 'set LED color to %1 %2', + coalaboard_turn_on_color_led_by_value: 'set LED color %1 %2', + coalaboard_turn_off_color_led: 'turn off LED %1', + coalaboard_buzzer: 'buzz note %1 %2', + coalaboard_servomotor_angle: 'servo motor %1 degree %2 %3', + coalaboard_dc_direction_speed: 'dc motor %1 direction %2 speed %3 %4', + coalaboard_dc_speed: 'dc motor %1 velocity %2 %3', + coalaboard_turn_off_all_motors: 'stop all motors %1', + }, + Blocks: { + COALABOARD_button_pressed: 'pressed', + COALABOARD_button_released: 'released', + COALABOARD_light: 'light', + COALABOARD_IR: 'IR', + COALABOARD_touch: 'touch', + COALABOARD_ultrasonicSensor: 'ultrasonicSenso', + COALABOARD_vibrationSensor: 'vibrationSensor', + COALABOARD_potentiometer: 'potentiometer', + COALABOARD_MIC: 'MIC', + COALABOARD_UserSensor: 'UserSensor', + COALABOARD_UserInput: 'UserInput', + COALABOARD_dc_direction_ccw: 'CCW', + COALABOARD_dc_direction_cw: 'CW', + }, + Menus: { + coalaboard: 'coalaboard', + }, + }, + }; +}; + +module.exports = Entry.Coalaboard; From 2374696626d11fe3ebb08ff48029ce8b147cf0f7 Mon Sep 17 00:00:00 2001 From: Tnks2U Date: Tue, 14 Mar 2023 10:40:48 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20web=20serial=EC=97=90=EC=84=9C?= =?UTF-8?q?=EB=8F=84=20=EB=A7=88=EB=B9=97=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B8=94=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이벤트블럭 하위에 하드웨어 블록 붙일떄, 최적화 필요 --- src/class/hw_lite.ts | 2 + .../hardwareLite/block_microbit2_lite.js | 106 +++++++++++++++++- 2 files changed, 103 insertions(+), 5 deletions(-) diff --git a/src/class/hw_lite.ts b/src/class/hw_lite.ts index 1cb9946a72..f7681e8b89 100644 --- a/src/class/hw_lite.ts +++ b/src/class/hw_lite.ts @@ -434,11 +434,13 @@ export default class HardwareLite { throw new Error('HARDWARE LITE NOT CONNECTED'); } await this.writer.write(encodedData); + console.log("sendAsync writer: ", encodedData); if (isResetReq) { this.isSendAsyncRun = false; return; } const { value, done } = await this.reader.read(); + console.log("sendAsync reader: ", value); if (callback) { return callback(value); } diff --git a/src/playground/blocks/hardwareLite/block_microbit2_lite.js b/src/playground/blocks/hardwareLite/block_microbit2_lite.js index e92e1435eb..c342ec8047 100644 --- a/src/playground/blocks/hardwareLite/block_microbit2_lite.js +++ b/src/playground/blocks/hardwareLite/block_microbit2_lite.js @@ -1,9 +1,10 @@ 'use strict'; -(function() { +(function () { Entry.Microbit2lite = new (class Microbit2Lite { constructor() { this.commandStatus = {}; + this.btnEventIntervalId = -1; this.retryLimitCnt = 5; this.portData = { baudRate: 115200, @@ -13,7 +14,7 @@ bufferSize: 512, connectionType: 'ascii', }; - this.duration = 32; + this.duration = 200; this.functionKeys = { LOCALDATA: 'localdata', GET_ANALOG: 'get-analog', @@ -258,6 +259,7 @@ 'microbit2lite_set_pwm', 'microbit2lite_v2_title', 'microbit2lite_get_logo', + 'microbit2lite_btn_event', 'microbit2lite_speaker_toggle', 'microbit2lite_play_sound_effect', 'microbit2lite_get_sound_level', @@ -277,6 +279,50 @@ return Entry.hwLite.sendAsyncWithThrottle(this.functionKeys.RESET); } + async initialHandshake() { + const defaultCMD = `${this.functionKeys.LOCALDATA}`; + const response = await Entry.hwLite.sendAsync(defaultCMD); + if (response && response.indexOf('localdata') > -1) { + const version = response.split(';')[1]; + if (!version) { + return; + } + const major = version[0]; + if (this.version !== major) { + this.version = major; + } + } + + if (this.version === '2') { + Entry.addEventListener('run', this.handleBtnEventInterval.bind(this)); + Entry.addEventListener('beforeStop', () => { clearInterval(this.btnEventIntervalId) }); + } + + return response; + } + + handleBtnEventInterval() { + this.btnEventIntervalId = setInterval(this.listenBtnPressedEvent.bind(this), this.duration); + } + + async listenBtnPressedEvent() { + console.log(this.commandStatus); + + if (Object.keys(this.commandStatus).length > 0) { + return; + } + + const defaultCMD = `${this.functionKeys.LOCALDATA};`; + const response = await Entry.hwLite.sendAsyncWithThrottle(defaultCMD); + // const response = await this.getResponseWithSync(defaultCMD); + + // INFO: A,B 버튼이벤트 관련 로직 + const pressedBtn = response.split(':btn:')[1]; + if (pressedBtn) { + Entry.engine.fireEventWithValue('microbit2lite_btn_pressed', pressedBtn); + } + } + waitMilliSec(milli) { this.blockReq = true; setTimeout(() => { @@ -316,9 +362,15 @@ if (!Entry.engine.isState('run')) { return; } + console.log("cmd : ", command); const result = await Entry.hwLite.sendAsyncWithThrottle(command); + console.log('getResponseWithSync : ', result); - if (!result || this.getCommandType(command) !== this.getCommandType(result)) { + if (!result || + this.getCommandType(command) !== this.getCommandType(result) || + // INFO : localdata 명령어는 우선순위가 낮으므로 반복하지 않음 + command !== `${this.functionKeys.LOCALDATA};` + ) { if (!this.commandStatus[command]) { this.commandStatus[command] = 1; throw new Entry.Utils.AsyncError(); @@ -332,6 +384,7 @@ console.error('UnExpected Microbit command'); } } else { + console.log("delete : ", command); delete this.commandStatus[command]; } @@ -367,6 +420,7 @@ microbit2lite_get_logo: '로고를 터치했는가?', microbit2lite_get_gesture: '움직임이 %1 인가?', microbit2lite_get_acc: '%1 의 가속도 값', + microbit2lite_btn_event: '%1 %2 버튼을 눌렀을 때', microbit2lite_get_direction: '나침반 방향', microbit2lite_get_field_strength_axis: '%1 의 자기장 세기 값', microbit2lite_get_light_level: '빛 센서 값', @@ -522,7 +576,8 @@ microbit2lite_get_btn: "선택한 버튼이 눌렸다면 '참'으로 판단합니다.", microbit2lite_get_logo: "로고를 터치했다면 '참'으로 판단합니다.", microbit2lite_get_gesture: "선택한 움직임이 감지되면 '참'으로 판단합니다.", - microbit2lite_get_acc: '선택한 축의 가속도 값입니다.', + microbit2lite_get_acc: '선택한 버튼이 눌리면 아래에 연결된 블록들을 실행합니다.', + microbit2lite_btn_event: '%1 %2 버튼을 눌렀을 때', microbit2lite_get_direction: '나침반 방향 값입니다. (0~360) ', microbit2lite_get_field_strength_axis: '선택한 축의 자기장 세기 값입니다.', microbit2lite_get_light_level: '빛 센서의 값입니다.', @@ -565,6 +620,7 @@ microbit2lite_get_logo: 'logo touched?', microbit2lite_get_gesture: 'Is the movement %1?', microbit2lite_get_acc: 'acceleration value of %1', + microbit2lite_btn_event: '%1 When %2 button pressed', microbit2lite_get_direction: 'compass direction', microbit2lite_get_field_strength_axis: 'magnetic field strength value of %1 ', @@ -731,6 +787,7 @@ microbit2lite_get_gesture: "When the selected movement is detected, it is judged as 'True'.", microbit2lite_get_acc: 'The acceleration value of the selected axis.', + microbit2lite_btn_event: 'When the selected button is pressed, the connected blocks below will run', microbit2lite_get_direction: 'The compass direction value. (0~360)', microbit2lite_get_field_strength_axis: 'The magnetic field strength value of the selected axis.', @@ -949,7 +1006,7 @@ }; } - getBlocks = function() { + getBlocks = function () { return { microbit2lite_common_title: { skeleton: 'basic_text', @@ -1862,6 +1919,45 @@ } }, }, + microbit2lite_btn_event: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_event', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/start_icon_hardware.svg', + size: 14, + position: { x: 0, y: -2 }, + }, + { + type: 'Dropdown', + options: [ + ['A', '1'], + ['B', '2'], + ['A+B', '3'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + def: { + type: 'microbit2lite_btn_event' + }, + paramsKeyMap: { + VALUE: 1, + }, + class: 'microbit2litev2', + isNotFor: ['Microbit2lite'], + event: 'microbit2lite_btn_pressed', + func: (sprite, script) => { + return script.callReturn(); + }, + }, microbit2lite_get_acc: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, From 592bf55fc2e1560398612ffca268179fa75a5a69 Mon Sep 17 00:00:00 2001 From: Roborobo Date: Wed, 15 Mar 2023 15:14:15 +0900 Subject: [PATCH 3/9] =?UTF-8?q?RobokitRS=20=EC=B6=94=EA=B0=80=20=EB=B0=8F?= =?UTF-8?q?=20=EA=B8=B0=EC=A1=B4=20=ED=95=98=EB=93=9C=EC=9B=A8=EC=96=B4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blocks/hardware/block_roborobo.js | 4654 ----------------- .../blocks/hardware/block_roborobo_base.js | 422 ++ .../hardware/block_roborobo_robokit_rs.js | 2152 ++++++++ .../blocks/hardware/block_roborobo_roduino.js | 1340 +++++ .../blocks/hardware/block_roborobo_roe.js | 1146 ++++ .../hardware/block_roborobo_schoolkit.js | 1946 +++++++ 6 files changed, 7006 insertions(+), 4654 deletions(-) delete mode 100644 src/playground/blocks/hardware/block_roborobo.js create mode 100644 src/playground/blocks/hardware/block_roborobo_base.js create mode 100644 src/playground/blocks/hardware/block_roborobo_robokit_rs.js create mode 100644 src/playground/blocks/hardware/block_roborobo_roduino.js create mode 100644 src/playground/blocks/hardware/block_roborobo_roe.js create mode 100644 src/playground/blocks/hardware/block_roborobo_schoolkit.js diff --git a/src/playground/blocks/hardware/block_roborobo.js b/src/playground/blocks/hardware/block_roborobo.js deleted file mode 100644 index c86c6a69c7..0000000000 --- a/src/playground/blocks/hardware/block_roborobo.js +++ /dev/null @@ -1,4654 +0,0 @@ -'use strict'; - -Entry.Roborobo_Roduino = { - id: '10.1', - name: 'roborobo_roduino', - url: 'http://www.roborobo.co.kr', - imageName: 'roborobo_roduino.png', - title: { - ko: '로두이노', - en: 'Roduino', - }, - INSTRUCTION: { - INPUT: 0, - OUTPUT: 1, - ANALOG: 2, - PWM: 3, - SERVO: 4, - SONAR: 11, - }, - setZero: function() { - Entry.hw.sendQueue.colorPin = 0; - Entry.hw.sendQueue.digitalPinMode = []; - Entry.hw.sendQueue.preDigitalPinMode = []; - Entry.hw.sendQueue.stopSend = false; - - for (var port = 0; port < 14; port++) { - Entry.hw.sendQueue[port] = 0; - Entry.hw.sendQueue.preDigitalPinMode[port] = -2; - Entry.hw.sendQueue.digitalPinMode[port] = -1; - } - this.ColorPin = [0, 0, 0]; - Entry.hw.update(); - }, - ColorPin: [0, 0, 0], - - monitorTemplate: { - imgPath: 'hw/roborobo_roduino.png', - keys: ['value'], - width: 256, - height: 256, - listPorts: { - a0: { - name: 'A0', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - a1: { - name: 'A1', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - a2: { - name: 'A2', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - a3: { - name: 'A3', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - a4: { - name: 'A4', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - a5: { - name: 'A5', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 2: { - name: 'D2', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 3: { - name: 'D3', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 4: { - name: 'D4', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 5: { - name: 'D5', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 6: { - name: 'D6', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 7: { - name: 'D7', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 8: { - name: 'D8', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 9: { - name: 'D9', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - 10: { - name: 'D10', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - }, - mode: 'both', - }, -}; - -Entry.Roborobo_Roduino.setLanguage = function() { - return { - ko: { - template: { - roduino_get_analog_number: '%1 ', - roduino_get_port_number: '%1 ', - roduino_get_analog_value: '아날로그 %1 번 센서값 ', - roduino_get_digital_value: '디지털 %1 번 센서값 ', - roduino_set_digital: '디지털 %1 번 핀 %2 %3', - roduino_motor: '%1 %2 %3', - roduino_set_color_pin: '컬러센서 R : %1, G : %2, B : %3 %4', - roduino_get_color: '컬러센서 %1 감지', - roduino_on_block: ' On ', - roduino_off_block: ' Off ', - roduino_set_servo_value: '서보모터 %1 번 핀 %2˚ %3', - roduino_set_pwm_value: 'PWM %1 번 핀 %2으로 전류조절 %3', - roduino_get_sensor_analog_value: '아날로그 %1 %2 번 핀 값', - roduino_get_sensor_digital_value: '디지털 %1 %2 번 핀 값', - }, - Blocks: { - roborobo_get_temperutre: '온도센서', - roborobo_get_joystick_x: '조이스틱X', - roborobo_get_joystick_y: '조이스틱Y', - roborobo_get_light: '빛센서', - roborobo_get_dial: '다이얼', - roborobo_get_keypad_a: 'A키패트(키번호)', - roborobo_get_ultrasonic: '초음파센서[cm]', - roborobo_num_analog_value_1: '아날로그', - roborobo_num_analog_value_2: '번 센서값', - roborobo_get_digital_value_1: '디지털', - roborobo_num_pin_1: '디지털', - roborobo_num_pin_2: '번 핀', - roborobo_on: '켜기', - roborobo_off: '끄기', - roborobo_motor1: '모터1', - roborobo_motor2: '모터2', - roborobo_motor_CW: '정회전', - roborobo_motor_CCW: '역회전', - roborobo_motor_stop: '정지', - roborobo_input_mode: '입력', - roborobo_output_mode: '출력', - roborobo_pwm_mode: '전류조절(pwm)', - roborobo_servo_mode: '서보모터', - roborobo_color: '컬러센서', - roborobo_color_red: ' 빨간색 ', - roborobo_color_green: ' 녹색 ', - roborobo_color_blue: ' 파란색 ', - roborobo_color_yellow: ' 노란색 ', - roborobo_color_detected: ' 감지 ', - roborobo_degree: ' ˚', - }, - }, - en: { - template: { - roduino_get_analog_number: '%1 ', - roduino_get_port_number: '%1 ', - roduino_get_analog_value: 'Analog %1 Sensor value ', - roduino_get_digital_value: 'Digital %1 Sensor value ', - roduino_set_digital: 'Digital %1 Pin %2 %3', - roduino_motor: '%1 %2 %3', - roduino_set_color_pin: 'Color Sensor R : %1, G : %2, B : %3 %4', - roduino_get_color: 'Color Sensor %1 Detected ', - roduino_on_block: ' On ', - roduino_off_block: ' Off ', - roduino_set_servo_value: 'Servo %1 Pin %2˚ %3', - roduino_set_pwm_value: 'PWM Set pin %1 to %2', - roduino_get_sensor_analog_value: 'analog %1 Pin %2 value', - roduino_get_sensor_digital_value: 'digital %1 %2 번 핀 값', - }, - Blocks: { - roborobo_num_analog_value_1: 'Analog', - roborobo_num_analog_value_2: 'Sensor Value', - roborobo_get_digital_value_1: 'Digital', - roborobo_num_pin_1: 'Digital', - roborobo_num_pin_2: 'Pin', - roborobo_on: 'On', - roborobo_off: 'Off', - roborobo_motor1: 'motor1', - roborobo_motor2: 'motor2', - roborobo_motor_CW: 'ClockWise', - roborobo_motor_CCW: 'CounterClockWise', - roborobo_motor_stop: 'Stop', - roborobo_input_mode: 'Input', - roborobo_output_mode: 'Output', - roborobo_pwm_mode: 'PWM', - roborobo_servo_mode: 'Servo', - roborobo_color: 'Color Sensor ', - roborobo_color_red: ' Red ', - roborobo_color_green: ' Green ', - roborobo_color_blue: ' Blue ', - roborobo_color_yellow: ' Yellow ', - roborobo_color_detected: ' Detected ', - roborobo_degree: ' ˚', - roborobo_get_temperutre: 'Temperature Sensor', - roborobo_get_joystick_x: 'JoystickX', - roborobo_get_joystick_y: 'JoystickY', - roborobo_get_light: 'Light Sensor', - roborobo_get_dial: 'Dial', - roborobo_get_keypad_a: 'A Keypad(key number)', - roborobo_get_ultrasonic: 'Ultrasonic Sensor[cm]', - }, - }, - }; -}; - -Entry.Roborobo_SchoolKit = { - hasPracticalCourse: true, - id: '10.2', - name: 'roborobo_schoolkit', - url: 'http://www.roborobo.co.kr', - imageName: 'roborobo_schoolkit.png', - title: { - ko: '스쿨키트', - en: 'School Kit', - }, - pinMode: { - INPUT: 0, - OUTPUT: 1, - ANALOG: 2, - PWM: 3, - SERVO: 4, - }, - inputPort: { - ir: 7, - sound: 8, - contact: 9, - cds: 10, - }, - setZero: function() { - Entry.hw.sendQueue.digitalPinMode = []; - Entry.hw.sendQueue.previousValue = []; - - for (var port = 0; port < 14; port++) { - Entry.hw.sendQueue[port] = 0; - Entry.hw.sendQueue.digitalPinMode[port] = 0; - Entry.hw.sendQueue.previousValue[port] = -1; - } - Entry.hw.update(); - }, - monitorTemplate: { - imgPath: 'hw/roborobo_schoolkit.png', - keys: ['value'], - width: 256, - height: 256, - listPorts: { - '0': { - name: 'D1', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - '1': { - name: 'D2', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - '2': { - name: 'D3', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - '3': { - name: 'D4', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - '4': { - name: 'D5', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - '5': { - name: 'D6', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - '6': { - name: 'D7', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - }, - mode: 'both', - }, -}; - -Entry.Roborobo_RoE = { - id: '48.1', - name: 'roborobo_roe', - url: 'http://www.roborobo.co.kr', - imageName: 'roborobo_roe.png', - title: { - ko: '로이', - en: 'Ro-E', - }, - setZero: function() { - Entry.hw.sendQueue['LED'] = 0; - Entry.hw.sendQueue['Melody'] = [0, 0, 0]; //[octave, note, duration] - Entry.hw.sendQueue['LeftMotor'] = [0, 0]; //[direction, value] - Entry.hw.sendQueue['RightMotor'] = [0, 0]; //[direction, value] - Entry.hw.update(); - }, - motorDiretion: { - STOP: 0, - CW: 1, - CCW: 2 - }, - monitorTemplate: { - imgPath: 'hw/roborobo_roe.png', - keys: ['value'], - width: 256, - height: 256, - listPorts: { - lColor: { - name: 'Color Sensor(Left)', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - rColor: { - name: 'Color Sensor(Right)', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - ir: { - name: 'IR Sensor', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - switch: { - name: 'Switch Sensor', - type: 'input', - pos: { - x: 0, - y: 0, - }, - }, - }, - mode: 'both', - }, -}; - -Entry.Roborobo_Roduino.blockMenuBlocks = [ - 'roduino_on_block', - 'roduino_off_block', - 'roduino_get_sensor_analog_value', - 'roduino_get_sensor_digital_value', - 'roduino_get_analog_value', - 'roduino_get_digital_value', - 'roduino_get_color', - 'roduino_set_digital', - 'roduino_motor', - 'roduino_set_color_pin', - 'roduino_set_servo_value', - 'roduino_set_pwm_value', -]; - -Entry.Roborobo_Roduino.getBlocks = function() { - return { - //region roduino 로두이노 - roduino_on_block: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [null], - type: 'roduino_on_block', - }, - paramsKeyMap: {}, - class: 'roduino_value', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - return '1'; - }, - syntax: { - js: [], - py: ['Roborobo_roduino.roduino_on_block()'], - }, - }, - roduino_off_block: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [null], - type: 'roduino_off_block', - }, - paramsKeyMap: {}, - class: 'roduino_value', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - return '0'; - }, - syntax: { - js: [], - py: ['Roborobo_roduino.roduino_off_block()'], - }, - }, - roduino_get_analog_number: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ], - value: '0', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - PORT: 0, - }, - func: function(sprite, script) { - return script.getStringField('PORT'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ], - value: '0', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - keyOption: 'roduino_get_analog_number', - }, - ], - }, - }, - roduino_get_port_number: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], - ['8', '8'], - ], - value: '2', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - PORT: 0, - }, - func: function(sprite, script) { - return script.getStringField('PORT'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], - ['8', '8'], - ], - value: '2', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - keyOption: 'roduino_get_port_number', - }, - ], - }, - }, - roduino_get_analog_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [ - { - type: 'roduino_get_analog_number', - }, - ], - type: 'roduino_get_analog_value', - }, - paramsKeyMap: { - VALUE: 0, - }, - class: 'roduino_value', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var signal = script.getValue('VALUE', script); - return Entry.hw.getAnalogPortValue(signal); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.read_analog(%1)', - blockType: 'param', - textParams: [ - { - type: 'Block', - accept: 'string', - }, - ], - }, - ], - }, - }, - roduino_get_digital_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [ - { - type: 'roduino_get_port_number', - }, - ], - type: 'roduino_get_digital_value', - }, - paramsKeyMap: { - VALUE: 0, - }, - class: 'roduino_value', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var signal = script.getNumberValue('VALUE', script); - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = [ - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - ]; - } - Entry.hw.sendQueue.digitalPinMode[signal] = - Entry.Roborobo_Roduino.INSTRUCTION.INPUT; - Entry.hw.update(); - return Entry.hw.getDigitalPortValue(signal); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.read_digital(%1)', - blockType: 'param', - textParams: [ - { - type: 'Block', - accept: 'string', - }, - ], - }, - ], - }, - }, - roduino_get_color: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_color_red, 'red'], - [Lang.Blocks.roborobo_color_green, 'green'], - [Lang.Blocks.roborobo_color_blue, 'blue'], - [Lang.Blocks.roborobo_color_yellow, 'yellow'], - ], - value: 'red', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - type: 'roduino_get_color', - }, - paramsKeyMap: { - VALUE: 0, - }, - class: 'roduino_value', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var flag = 0; - var signal = script.getField('VALUE', script); - var value = [ - Entry.hw.portData[Entry.Roborobo_Roduino.ColorPin[0]], - Entry.hw.portData[Entry.Roborobo_Roduino.ColorPin[1]], - Entry.hw.portData[Entry.Roborobo_Roduino.ColorPin[2]], - ]; - - switch (signal) { - case 'red': - if (value[0] == 1 && value[1] == 0 && value[2] == 0) { - flag = 1; - } - break; - case 'green': - if (value[0] == 0 && value[1] == 1 && value[2] == 0) { - flag = 1; - } - break; - case 'blue': - if (value[0] == 0 && value[1] == 0 && value[2] == 1) { - flag = 1; - } - break; - case 'yellow': - if (value[0] == 1 && value[1] == 1 && value[2] == 1) { - flag = 1; - } - break; - } - return flag; - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.read_color(%1)', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_color_red, 'red'], - [Lang.Blocks.roborobo_color_green, 'green'], - [Lang.Blocks.roborobo_color_blue, 'blue'], - [Lang.Blocks.roborobo_color_yellow, 'yellow'], - ], - value: 'red', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - }, - ], - }, - }, - roduino_get_sensor_analog_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_get_temperutre, 'temperature'], - [Lang.Blocks.roborobo_get_joystick_x, 'joystickX'], - [Lang.Blocks.roborobo_get_joystick_y, 'joystickY'], - [Lang.Blocks.roborobo_get_light, 'light'], - [Lang.Blocks.roborobo_get_dial, 'dial'], - [Lang.Blocks.roborobo_get_keypad_a, 'keypad'], - ], - value: 'temperature', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [ - null, - { - type: 'roduino_get_analog_number', - }, - ], - type: 'roduino_get_sensor_analog_value', - }, - paramsKeyMap: { - SENSOR: 0, - VALUE: 1, - }, - class: 'roduino_value', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var sensor = script.getField('SENSOR'); - var signal = script.getNumberValue('VALUE'); - var readData = Entry.hw.getAnalogPortValue(signal); - var data = 0; - switch (sensor) { - case 'temperature': - // var data = 5 / 51.0 * readData - 22; - data = readData; - break; - case 'joystickX': - readData = readData >> 6; - if (readData > 14) data = 2; - else if (readData > 9) data = 1; - else if (readData > 5) data = 0; - else if (readData > 1) data = -1; - else data = -2; - break; - case 'joystickY': - readData = readData >> 6; - if (readData > 14) data = 2; - else if (readData > 9) data = 1; - else if (readData > 5) data = 0; - else if (readData > 1) data = -1; - else data = -2; - break; - case 'light': - data = Math.round(readData / 10) * 10; - break; - case 'dial': - data = Math.round(readData / 10); - break; - case 'keypad': - if (readData >= 450) data = 1; - else if (readData >= 390) data = 2; - else if (readData >= 310) data = 3; - else if (readData >= 200) data = 4; - else if (readData >= 100) data = 5; - else data = 0; - break; - } - return data; - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.read_analog_sensor(%1, %2)', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_get_temperutre, 'temperature'], - [Lang.Blocks.roborobo_get_joystick_x, 'joystickX'], - [Lang.Blocks.roborobo_get_joystick_y, 'joystickY'], - [Lang.Blocks.roborobo_get_light, 'light'], - [Lang.Blocks.roborobo_get_dial, 'dial'], - [Lang.Blocks.roborobo_get_keypad_a, 'keypad'], - ], - value: 'temperature', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - { - type: 'Block', - accept: 'string', - }, - ], - }, - ], - }, - }, - roduino_get_sensor_digital_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [[Lang.Blocks.roborobo_get_ultrasonic, 'ultrasonic']], - value: 'ultrasonic', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [ - null, - { - type: 'roduino_get_port_number', - }, - ], - type: 'roduino_get_sensor_digital_value', - }, - paramsKeyMap: { - SENSOR: 0, - VALUE: 1, - }, - class: 'roduino_value', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var sensor = script.getField('SENSOR'); - var signal = script.getNumberValue('VALUE', script); - switch (sensor) { - case 'ultrasonic': - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = [ - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - ]; - } - Entry.hw.sendQueue.digitalPinMode[signal] = - Entry.Roborobo_Roduino.INSTRUCTION.SONAR; - Entry.hw.update(); - break; - } - return Entry.hw.getDigitalPortValue(signal); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.read_digital_sensor(%1, %2)', - textParams: [ - { - type: 'Dropdown', - options: [[Lang.Blocks.roborobo_get_ultrasonic, 'ultrasonic']], - value: 'ultrasonic', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - { - type: 'Block', - accept: 'string', - }, - ], - }, - ], - }, - }, - roduino_set_digital: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_on, 'on'], - [Lang.Blocks.roborobo_off, 'off'], - ], - value: 'on', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12, - }, - ], - events: {}, - def: { - params: [ - { - type: 'roduino_get_port_number', - }, - null, - null, - ], - type: 'roduino_set_digital', - }, - paramsKeyMap: { - VALUE: 0, - OPERATOR: 1, - }, - class: 'roduino_set', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var pin = script.getNumberValue('VALUE', script); - var operator = script.getField('OPERATOR'); - var value = operator == 'on' ? 1 : 0; - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = [ - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - ]; - } - Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_Roduino.INSTRUCTION.OUTPUT; - - Entry.hw.setDigitalPortValue(pin, value); - return script.callReturn(); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.wirte_digital(%1, %2)', - textParams: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_on, 'on'], - [Lang.Blocks.roborobo_off, 'off'], - ], - value: 'on', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - }, - ], - }, - }, - roduino_get_pwm_port_number: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - template: '%1', - params: [ - { - type: 'Dropdown', - options: [ - ['3', 3], - ['5', 5], - ['6', 6], - ], - value: 3, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - PORT: 0, - }, - func: function(sprite, script) { - return script.getNumberField('PORT'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - ['3', 3], - ['5', 5], - ['6', 6], - ], - value: 3, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - keyOption: 'roduino_get_pwm_port_number', - }, - ], - }, - }, - roduino_get_pwm_output_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - template: '%1', - params: [ - { - type: 'Dropdown', - options: [ - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], - ['8', '8'], - ['9', '9'], - ['10', '10'], - ['11', '11'], - ['12', '12'], - ['13', '13'], - ['14', '14'], - ['15', '15'], - ], - value: '0', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: '0', - }, - func: function(sprite, script) { - return script.getNumberField('VALUE'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], - ['8', '8'], - ['9', '9'], - ['10', '10'], - ['11', '11'], - ['12', '12'], - ['13', '13'], - ['14', '14'], - ['15', '15'], - ], - value: '0', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - keyOption: 'roduino_get_pwm_output_value', - }, - ], - }, - }, - roduino_set_pwm_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12, - }, - ], - events: {}, - def: { - params: [ - { - type: 'roduino_get_pwm_port_number', - }, - { - type: 'roduino_get_pwm_output_value', - }, - null, - ], - type: 'roduino_set_pwm_value', - }, - paramsKeyMap: { - PIN: 0, - VALUE: 1, - }, - class: 'roduino_set', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var pin = script.getNumberValue('PIN', script); - var value = script.getNumberValue('VALUE'); - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = [ - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - ]; - } - - Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_Roduino.INSTRUCTION.PWM; - - Entry.hw.setDigitalPortValue(pin, value); - return script.callReturn(); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.write_analog(%1, %2)', - textParams: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - ], - }, - ], - }, - }, - roduino_get_servo_port_number: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - template: '%1', - params: [ - { - type: 'Dropdown', - options: [ - ['3', 3], - ['5', 5], - ['6', 6], - ], - value: 3, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - PORT: 0, - }, - func: function(sprite, script) { - return script.getNumberField('PORT'); - }, - - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - ['3', 3], - ['5', 5], - ['6', 6], - ], - value: 3, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - keyOption: 'roduino_get_servo_port_number', - }, - ], - }, - }, - roduino_set_servo_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12, - }, - ], - events: {}, - def: { - params: [ - { - type: 'roduino_get_servo_port_number', - }, - { - type: 'number', - params: ['90'], - }, - null, - ], - type: 'roduino_set_servo_value', - }, - paramsKeyMap: { - PIN: 0, - VALUE: 1, - }, - class: 'roduino_set', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var pin = script.getNumberValue('PIN', script); - var value = script.getNumberValue('VALUE'); - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = [ - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - ]; - } - - Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_Roduino.INSTRUCTION.SERVO; - - if (value < 0) { - value = 0; - } else if (value > 180) { - value = 180; - } - - Entry.hw.setDigitalPortValue(pin, value); - return script.callReturn(); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.move_servo(%1, %2)', - textParams: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - ], - }, - ], - }, - }, - roduino_motor: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_motor1, 'motor1'], - [Lang.Blocks.roborobo_motor2, 'motor2'], - ], - value: 'motor1', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_motor_CW, 'cw'], - [Lang.Blocks.roborobo_motor_CCW, 'ccw'], - [Lang.Blocks.roborobo_motor_stop, 'stop'], - ], - value: 'cw', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12, - }, - ], - events: {}, - def: { - params: [null, null, null], - type: 'roduino_motor', - }, - paramsKeyMap: { - MODE: 0, - OPERATOR: 1, - }, - class: 'roduino_set', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var pin1 = 0; - var pin2 = 0; - var value1 = 0; - var value2 = 0; - var mode = script.getField('MODE'); - var operator = script.getField('OPERATOR'); - - if (mode == 'motor1') { - pin1 = 9; - pin2 = 10; - } else { - pin1 = 11; - pin2 = 12; - } - - if (operator == 'cw') { - value1 = 1; - value2 = 0; - } else if (operator == 'ccw') { - value1 = 0; - value2 = 1; - } else { - value1 = 0; - value2 = 0; - } - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = [ - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - ]; - } - Entry.hw.sendQueue.digitalPinMode[pin1] = Entry.Roborobo_Roduino.INSTRUCTION.OUTPUT; - Entry.hw.sendQueue.digitalPinMode[pin2] = Entry.Roborobo_Roduino.INSTRUCTION.OUTPUT; - - Entry.hw.setDigitalPortValue(pin1, value1); - Entry.hw.setDigitalPortValue(pin2, value2); - Entry.hw.update(); - return script.callReturn(); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roduino.move_motor(%1, %2)', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_motor1, 'motor1'], - [Lang.Blocks.roborobo_motor2, 'motor2'], - ], - value: 'motor1', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_motor_CW, 'cw'], - [Lang.Blocks.roborobo_motor_CCW, 'ccw'], - [Lang.Blocks.roborobo_motor_stop, 'stop'], - ], - value: 'cw', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - }, - ], - }, - }, - roduino_set_color_pin: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12, - }, - ], - events: {}, - def: { - params: [ - { - type: 'number', - params: ['2'], - }, - { - type: 'number', - params: ['3'], - }, - { - type: 'number', - params: ['4'], - }, - null, - ], - type: 'roduino_set_color_pin', - }, - paramsKeyMap: { - RED: 0, - GREEN: 1, - BLUE: 2, - }, - class: 'roduino_set', - isNotFor: ['roborobo_roduino'], - func: function(sprite, script) { - var redPin = script.getNumberValue('RED', script); - var greenPin = script.getNumberValue('GREEN', script); - var bluePin = script.getNumberValue('BLUE', script); - - Entry.Roborobo_Roduino.ColorPin = [redPin, greenPin, bluePin]; - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = [ - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - -1, - ]; - } - Entry.hw.sendQueue.digitalPinMode[redPin] = - Entry.Roborobo_Roduino.INSTRUCTION.INPUT; - Entry.hw.sendQueue.digitalPinMode[greenPin] = - Entry.Roborobo_Roduino.INSTRUCTION.INPUT; - Entry.hw.sendQueue.digitalPinMode[bluePin] = - Entry.Roborobo_Roduino.INSTRUCTION.INPUT; - Entry.hw.update(); - return script.callReturn(); - }, - syntax: { - js: [], - py: ['Roborobo_roduino.set_color_pin_mode(%1, %2, %3)'], - }, - }, - //endregion roduino 로두이노 - }; -}; - -Entry.Roborobo_SchoolKit.setLanguage = function() { - return { - ko: { - template: { - schoolkit_get_in_port_number: '%1 ', - schoolkit_get_out_port_number: '%1 ', - schoolkit_get_servo_port_number: '%1 ', - schoolkit_get_input_value: '디지털 %1 번 센서값 ', - schoolkit_set_output: '디지털 %1 번 핀 %2 %3', - schoolkit_motor: '%1 속도 %2(으)로 %3 %4', - schoolkit_set_servo_value: '서보모터 %1 번 핀 %2˚ %3', - schoolkit_on_block: ' On ', - schoolkit_off_block: ' Off ', - }, - }, - en: { - template: { - schoolkit_get_in_port_number: '%1 ', - schoolkit_get_out_port_number: '%1 ', - schoolkit_get_servo_port_number: '%1 ', - schoolkit_get_input_value: 'Digital %1 Sensor value ', - schoolkit_set_output: 'Digital %1 Pin %2 %3', - schoolkit_motor: '%1 Speed %2 %3 %4', - schoolkit_set_servo_value: 'Servo %1 Pin %2˚ %3', - schoolkit_on_block: ' On ', - schoolkit_off_block: ' Off ', - }, - }, - }; -}; - -Entry.Roborobo_SchoolKit.blockMenuBlocks = [ - 'schoolkit_on_block', - 'schoolkit_off_block', - 'schoolkit_get_input_value', - 'schoolkit_set_output', - 'schoolkit_motor', - 'schoolkit_set_servo_value', -]; - -Entry.Roborobo_SchoolKit.practicalBlockMenuBlocks = { - hw_motor: [ - // 'roborobo_motor_speed', - 'roborobo_move_for_secs', - 'roborobo_move_for', - 'roborobo_turn_for', - 'roborobo_stop_for', - ], - hw_melody: [ - - ], - hw_sensor: [ - 'roborobo_touch_value', - 'roborobo_touch_value_boolean', - 'roborobo_light_value', - 'roborobo_light_value_boolean', - 'roborobo_sound_value', - 'roborobo_sound_value_boolean', - 'roborobo_irs_value', - 'roborobo_irs_value_boolean', - ], - hw_led: [ - 'roborobo_diode_secs_toggle', - 'roborobo_diode_toggle', - 'roborobo_diode_inout_toggle', - 'roborobo_diode_set_output', - 'roborobo_diode_input_value', - ], -} - -Entry.Roborobo_SchoolKit.getBlocks = function() { - return { - //region schoolkit 스쿨키트 - schoolkit_on_block: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [null], - type: 'schoolkit_on_block', - }, - paramsKeyMap: {}, - class: 'schoolkit_value', - isNotFor: ['roborobo_schoolkit'], - func: function(sprite, script) { - return '1'; - }, - syntax: { - js: [], - py: ['Roborobo_SchoolKit.schoolkit_on_block()'], - }, - }, - schoolkit_off_block: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [null], - type: 'schoolkit_off_block', - }, - paramsKeyMap: {}, - class: 'schoolkit_value', - isNotFor: ['roborobo_schoolkit'], - func: function(sprite, script) { - return '0'; - }, - syntax: { - js: [], - py: ['Roborobo_SchoolKit.schoolkit_off_block()'], - }, - }, - schoolkit_get_out_port_number: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - ['OUT1', 2], - ['OUT2', 3], - ['OUT3', 4], - ['OUT4', 5], - ['OUT5', 6], - ], - value: 2, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - PORT: 0, - }, - func: function(sprite, script) { - return script.getNumberField('PORT'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - ['OUT1', 2], - ['OUT2', 3], - ['OUT3', 4], - ['OUT4', 5], - ['OUT5', 6], - ], - value: 2, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'schoolkit_get_out_port_number', - }, - ], - }, - }, - schoolkit_get_servo_port_number: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - ['OUT1', 2], - ['OUT2', 3], - ['OUT3', 4], - ], - value: 2, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - PORT: 0, - }, - func: function(sprite, script) { - return script.getNumberField('PORT'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - ['OUT1', 2], - ['OUT2', 3], - ['OUT3', 4], - ], - value: 2, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'schoolkit_get_servo_port_number', - }, - ], - }, - }, - schoolkit_get_in_port_number: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - ['IN1', 7], - ['IN2', 8], - ['IN3', 9], - ['IN4', 10], - ['IN5', 11], - ['IN6', 12], - ['IN7', 13], - ], - value: 7, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - PORT: 0, - }, - func: function(sprite, script) { - return script.getNumberField('PORT'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - ['IN1', 7], - ['IN2', 8], - ['IN3', 9], - ['IN4', 10], - ['IN5', 11], - ['IN6', 12], - ['IN7', 13], - ], - value: 7, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'schoolkit_get_in_port_number', - }, - ], - }, - }, - schoolkit_set_output: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_on, 'on'], - [Lang.Blocks.roborobo_off, 'off'], - ], - value: 'on', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12, - }, - ], - events: {}, - def: { - params: [ - { - type: 'schoolkit_get_out_port_number', - }, - null, - null, - ], - type: 'schoolkit_set_output', - }, - paramsKeyMap: { - VALUE: 0, - OPERATOR: 1, - }, - class: 'schoolkit_set', - isNotFor: ['roborobo_schoolkit'], - func: function(sprite, script) { - var pin = script.getNumberValue('VALUE', script); - var operator = script.getField('OPERATOR'); - var value = operator == 'on' ? 1 : 0; - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - - Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_SchoolKit.pinMode.OUTPUT; - Entry.hw.sendQueue[pin] = value; - return script.callReturn(); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_schoolkit.wirte_digital(%1, %2)', - textParams: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_on, 'on'], - [Lang.Blocks.roborobo_off, 'off'], - ], - value: 'on', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - }, - ], - }, - }, - schoolkit_get_input_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [ - { - type: 'schoolkit_get_in_port_number', - }, - ], - type: 'schoolkit_get_input_value', - }, - paramsKeyMap: { - VALUE: 0, - }, - class: 'schoolkit_value', - isNotFor: ['roborobo_schoolkit'], - func: function(sprite, script) { - var signal = script.getNumberValue('VALUE', script); - return Entry.hw.portData[signal - 7]; - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_schoolkit.read_digital(%1)', - textParams: [ - { - type: 'Block', - accept: 'string', - }, - ], - }, - ], - }, - }, - schoolkit_motor: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_motor1, 'motor1'], - [Lang.Blocks.roborobo_motor2, 'motor2'], - ], - value: 'motor1', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Dropdown', - options: [ - ['0', '45'], - ['1', '59'], - ['2', '73'], - ['3', '87'], - ['4', '101'], - ['5', '115'], - ['6', '129'], - ['7', '143'], - ['8', '157'], - ['9', '171'], - ['10', '185'], - ['11', '199'], - ['12', '213'], - ['13', '227'], - ['14', '241'], - ['15', '255'], - ], - value: '45', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_motor_CW, 'cw'], - [Lang.Blocks.roborobo_motor_CCW, 'ccw'], - [Lang.Blocks.roborobo_motor_stop, 'stop'], - ], - value: 'cw', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12, - }, - ], - events: {}, - def: { - params: [null, null, null, null], - type: 'schoolkit_motor', - }, - paramsKeyMap: { - MODE: 0, - VALUE: 1, - OPERATOR: 2, - }, - class: 'schoolkit_set', - isNotFor: ['roborobo_schoolkit'], - func: function(sprite, script) { - var mode = script.getField('MODE'); - var pin = 0; - var operator = script.getField('OPERATOR'); - var value = script.getField('VALUE'); - - if (mode == 'motor1') { - pin = 0; - } else { - pin = 1; - } - - if (value > 255) { - value = 255; - } else if (value < 0) { - value = 0; - } - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - - Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[pin + 7] = Entry.Roborobo_SchoolKit.pinMode.PWM; - if (operator == 'cw') { - Entry.hw.sendQueue[pin] = value; - } else if (operator == 'ccw') { - Entry.hw.sendQueue[pin] = -value; - } else if (operator == 'stop') { - Entry.hw.sendQueue[pin] = 0x00; - } - return script.callReturn(); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_schoolkit.move_motor_speed(%1, %2, %3)', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_motor1, 'motor1'], - [Lang.Blocks.roborobo_motor2, 'motor2'], - ], - value: 'motor1', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - { - type: 'Dropdown', - options: [ - ['0', '45'], - ['1', '59'], - ['2', '73'], - ['3', '87'], - ['4', '101'], - ['5', '115'], - ['6', '129'], - ['7', '143'], - ['8', '157'], - ['9', '171'], - ['10', '185'], - ['11', '199'], - ['12', '213'], - ['13', '227'], - ['14', '241'], - ['15', '255'], - ], - value: '45', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roborobo_motor_CW, 'cw'], - [Lang.Blocks.roborobo_motor_CCW, 'ccw'], - [Lang.Blocks.roborobo_motor_stop, 'stop'], - ], - value: 'cw', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - }, - ], - }, - }, - schoolkit_set_servo_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12, - }, - ], - events: {}, - def: { - params: [ - { - type: 'schoolkit_get_servo_port_number', - }, - { - type: 'number', - params: ['0'], - }, - null, - ], - type: 'schoolkit_set_servo_value', - }, - paramsKeyMap: { - PIN: 0, - VALUE: 1, - }, - class: 'schoolkit_set', - isNotFor: ['roborobo_schoolkit'], - func: function(sprite, script) { - var pin = script.getNumberValue('PIN', script); - var value = script.getNumberValue('VALUE'); - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_SchoolKit.pinMode.SERVO; - - if (value < 0) { - value = 0; - } else if (value > 180) { - value = 180; - } - Entry.hw.sendQueue[pin] = value; - return script.callReturn(); - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_schoolkit.move_servo(%1, %2)', - textParams: [ - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - ], - }, - ], - }, - }, - //endregion schoolkit 스쿨키트 - }; -}; - -Entry.Roborobo_SchoolKit.getPracticalBlocks = function() { - return { - // roborobo_mini - roborobo_motor_speed: { - color: '#00B200', - outerLine: '#019101', - skeleton: 'basic_string_field', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1', - params: [ - { - type: 'Dropdown', - options: [ - ['1', '52'], - ['2', '66'], - ['3', '80'], - ['4', '94'], - ['5', '107'], - ['6', '120'], - ['7', '134'], - ['8', '148'], - ['9', '162'], - ['10', '176'], - ['11', '190'], - ['12', '204'], - ['13', '218'], - ['14', '232'], - ['15', '255'], - ], - value: '255', - fontSize: 11, - bgColor: '#019101', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: 0, - }, - func(sprite, script) { - return script.getStringField('VALUE'); - }, - }, - roborobo_move_for_secs: { - color: '#00B200', - outerLine: '#019101', - skeleton: 'basic', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1모터를 %2 %3의 속도로 %4초 동안 회전 %5', - params: [ - { - type: 'Dropdown', - options: [ - ['양쪽', '1'], - ['오른쪽', '2'], - ['왼쪽', '3'], - ], - value: '1', - fontSize: 11, - bgColor: '#019101', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Dropdown', - options: [ - ['앞으로', '1'], - ['뒤로', '2'], - ], - value: '1', - fontSize: 11, - bgColor: '#019101', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/practical_course/dcmotor.png', - size: 12, - }, - ], - events: {}, - def: { - params: [ - null, - null, - { - type: 'roborobo_motor_speed', - }, - { - type: 'number', - params: ['2'], - }, - null, - ], - type: 'roborobo_move_for_secs', - }, - paramsKeyMap: { - WHEEL: 0, - DIRECTION: 1, - SPEED: 2, - DURATION: 3, - }, - class: 'roborobo_motor', - func(sprite, script) { - const motor1 = 0; - const motor2 = 1; - const wheel = script.getNumberField('WHEEL'); - const speed = script.getNumberValue('SPEED'); - const direction = script.getNumberField('DIRECTION'); - const duration = script.getNumberValue('DURATION'); - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - - if (!script.isStart) { - if (wheel == 1) { - Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - if (direction == 1) { - Entry.hw.sendQueue[motor1] = speed; - Entry.hw.sendQueue[motor2] = speed; - } else if (direction == 2) { - Entry.hw.sendQueue[motor1] = -speed; - Entry.hw.sendQueue[motor2] = -speed; - } - } else if (wheel == 2) { - Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - if (direction == 1) { - Entry.hw.sendQueue[motor1] = 0x00; - Entry.hw.sendQueue[motor2] = speed; - } else if (direction == 2) { - Entry.hw.sendQueue[motor1] = 0x00; - Entry.hw.sendQueue[motor2] = -speed; - } - } else if (wheel == 3) { - Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - if (direction == 1) { - Entry.hw.sendQueue[motor1] = speed; - Entry.hw.sendQueue[motor2] = 0x00; - } else if (direction == 2) { - Entry.hw.sendQueue[motor1] = -speed; - Entry.hw.sendQueue[motor2] = 0x00; - } - } - - script.wheelMode = wheel; - script.isStart = true; - script.timeFlag = 1; - setTimeout(() => { - script.timeFlag = 0; - }, duration * 1000); - return script; - } else if (script.timeFlag == 1) { - return script; - } else { - Entry.hw.sendQueue[motor1] = 0x00; - Entry.hw.sendQueue[motor2] = 0x00; - - delete script.timeFlag; - delete script.isStart; - delete script.wheelMode; - Entry.engine.isContinue = false; - return script.callReturn(); - } - }, - }, - roborobo_move_for: { - color: '#00B200', - outerLine: '#019101', - skeleton: 'basic', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1모터를 %2 %3의 속도로 계속 회전 %4', - params: [ - { - type: 'Dropdown', - options: [ - ['양쪽', '1'], - ['오른쪽', '2'], - ['왼쪽', '3'], - ], - value: '1', - fontSize: 11, - bgColor: '#019101', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Dropdown', - options: [ - ['앞으로', '1'], - ['뒤로', '2'], - ], - value: '1', - fontSize: 11, - bgColor: '#019101', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/practical_course/dcmotor.png', - size: 12, - }, - ], - events: {}, - def: { - params: [ - null, - null, - { - type: 'roborobo_motor_speed', - }, - null, - ], - type: 'roborobo_move_for', - }, - paramsKeyMap: { - WHEEL: 0, - DIRECTION: 1, - SPEED: 2, - }, - class: 'roborobo_motor', - //'isNotFor': ['mini'], - func(sprite, script) { - const motor1 = 0; - const motor2 = 1; - const wheel = script.getNumberField('WHEEL'); - const speed = script.getNumberValue('SPEED'); - const direction = script.getNumberField('DIRECTION'); - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - - if (wheel == 1) { - Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - if (direction == 1) { - Entry.hw.sendQueue[motor1] = speed; - Entry.hw.sendQueue[motor2] = speed; - } else if (direction == 2) { - Entry.hw.sendQueue[motor1] = -speed; - Entry.hw.sendQueue[motor2] = -speed; - } - } else if (wheel == 2) { - Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - if (direction == 1) { - Entry.hw.sendQueue[motor1] = 0x00; - Entry.hw.sendQueue[motor2] = speed; - } else if (direction == 2) { - Entry.hw.sendQueue[motor1] = 0x00; - Entry.hw.sendQueue[motor2] = -speed; - } - } else if (wheel == 3) { - Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - if (direction == 1) { - Entry.hw.sendQueue[motor1] = speed; - Entry.hw.sendQueue[motor2] = 0x00; - } else if (direction == 2) { - Entry.hw.sendQueue[motor1] = -speed; - //Entry.hw.sendQueue[motor2] = 0x00; - } - } - - return script.callReturn(); - }, - }, - roborobo_turn_for: { - color: '#00B200', - outerLine: '#019101', - skeleton: 'basic', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '오른쪽 모터를 %1 %2, 왼쪽 모터를 %3 %4의 속도로 계속 회전 %5', - params: [ - { - type: 'Dropdown', - options: [ - ['앞으로', '1'], - ['뒤로', '2'], - ], - value: '1', - fontSize: 11, - bgColor: '#019101', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Dropdown', - options: [ - ['앞으로', '1'], - ['뒤로', '2'], - ], - value: '1', - fontSize: 11, - bgColor: '#019101', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/practical_course/dcmotor.png', - size: 12, - }, - ], - events: {}, - def: { - params: [ - null, - { type: 'roborobo_motor_speed' }, - null, - { type: 'roborobo_motor_speed' }, - null, - ], - type: 'roborobo_turn_for', - }, - paramsKeyMap: { - RDIR: 0, - RSPEED: 1, - LDIR: 2, - LSPEED: 3, - }, - class: 'roborobo_motor', - //'isNotFor': ['mini'], - func(sprite, script) { - const motor1 = 0; - const motor2 = 1; - - const rightDir = script.getNumberField('RDIR'); - const rightSpeed = script.getNumberValue('RSPEED'); - const leftDir = script.getNumberField('LDIR'); - const leftSpeed = script.getNumberValue('LSPEED'); - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - - Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - if (leftDir == 1) { - Entry.hw.sendQueue[motor1] = leftSpeed; - } else { - Entry.hw.sendQueue[motor1] = -leftSpeed; - } - - if (rightDir == 1) { - Entry.hw.sendQueue[motor2] = rightSpeed; - } else { - Entry.hw.sendQueue[motor2] = -rightSpeed; - } - - return script.callReturn(); - }, - }, - roborobo_stop_for: { - color: '#00B200', - outerLine: '#019101', - skeleton: 'basic', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1모터를 정지 %2', - params: [ - { - type: 'Dropdown', - options: [ - ['양쪽', '1'], - ['오른쪽', '2'], - ['왼쪽', '3'], - ], - value: '1', - fontSize: 11, - bgColor: '#019101', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Indicator', - img: 'block_icon/practical_course/dcmotor.png', - size: 12, - }, - ], - events: {}, - def: { - params: [null, null], - type: 'roborobo_stop_for', - }, - paramsKeyMap: { - WHEEL: 0, - }, - class: 'roborobo_motor', - func(sprite, script) { - const motor1 = 0; - const motor2 = 1; - const wheel = script.getNumberField('WHEEL'); - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - - if (wheel == 1) { - Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - Entry.hw.sendQueue[motor1] = 0x00; - Entry.hw.sendQueue[motor2] = 0x00; - } else if (wheel == 2) { - Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - Entry.hw.sendQueue[motor2] = 0x00; - } else if (wheel == 3) { - Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - Entry.hw.sendQueue[motor1] = 0x00; - } - - return script.callReturn(); - }, - }, - roborobo_touch_value: { - color: '#2AB4D3', - outerLine: '#0e93b1', - skeleton: 'basic_string_field', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '접촉 센서 값', - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [null], - type: 'roborobo_touch_value', - }, - paramsKeyMap: {}, - class: 'roborobo_touch', - func(sprite, script) { - const port = Entry.Roborobo_SchoolKit.inputPort.contact; - Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.INPUT; - Entry.hw.update(); - return Entry.hw.portData[port - 7]; - }, - }, - roborobo_touch_value_boolean: { - color: '#2AB4D3', - outerLine: '#0e93b1', - skeleton: 'basic_boolean_field', - fontColor: '#fff', - isNotFor: ['roborobo_schoolkit'], - template: '접촉 센서가 %1', - params: [ - { - type: 'Dropdown', - options: [ - ['접촉 되면', '1'], - ['접촉 안되면', '0'], - ], - value: '1', - fontSize: 11, - bgColor: '#0e93b1', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - ], - def: { - params: [null], - type: 'roborobo_touch_value_boolean', - }, - paramsKeyMap: { - TOUCH: 0, - }, - class: 'roborobo_touch', - func(sprite, script) { - const port = Entry.Roborobo_SchoolKit.inputPort.contact; - const touch = script.getNumberField('TOUCH', script); - - Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.INPUT; - Entry.hw.update(); - - const value = Entry.hw.portData[port - 7]; - const isTouch = touch == value; - - return isTouch; - }, - }, - roborobo_light_value: { - color: '#ff8d0f', - outerLine: '#e37100', - skeleton: 'basic_string_field', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: 'CDS 센서 값', - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [null], - type: 'roborobo_light_value', - }, - paramsKeyMap: {}, - class: 'roborobo_light', - func(sprite, script) { - const port = Entry.Roborobo_SchoolKit.inputPort.cds; - return Entry.hw.portData[port - 7]; - }, - }, - roborobo_light_value_boolean: { - color: '#ff8d0f', - outerLine: '#e37100', - skeleton: 'basic_boolean_field', - fontColor: '#fff', - isNotFor: ['roborobo_schoolkit'], - template: 'CDS 센서 값 %1 %2', - params: [ - { - type: 'Dropdown', - options: [ - ['=', 'EQUAL'], - ['>', 'GREATER'], - ['<', 'LESS'], - ['≥', 'GREATER_OR_EQUAL'], - ['≤', 'LESS_OR_EQUAL'], - ], - value: 'LESS', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - noaRrow: true, - }, - { - type: 'Block', - accept: 'string', - }, - ], - def: { - params: [ - null, - { - type: 'number', - params: ['512'], - }, - ], - type: 'roborobo_light_value_boolean', - }, - paramsKeyMap: { - OPERATOR: 0, - RIGHTVALUE: 1, - }, - class: 'roborobo_light', - func(sprite, script) { - const port = Entry.Roborobo_SchoolKit.inputPort.cds; - const operator = script.getField('OPERATOR', script); - let rightValue = script.getNumberValue('RIGHTVALUE', script); - const leftValue = Entry.hw.portData[port - 7]; - let isCheck = false; - - if (rightValue < 0) { - rightValue = 0; - } else if (rightValue > 1023) { - rightValue = 1023; - } - switch (operator) { - case 'EQUAL': - isCheck = leftValue == rightValue; - break; - case 'GREATER': - isCheck = Number(leftValue) > Number(rightValue); - break; - case 'LESS': - isCheck = Number(leftValue) < Number(rightValue); - break; - case 'GREATER_OR_EQUAL': - isCheck = Number(leftValue) >= Number(rightValue); - break; - case 'LESS_OR_EQUAL': - isCheck = Number(leftValue) <= Number(rightValue); - break; - } - return isCheck; - }, - }, - roborobo_sound_value: { - color: '#01d67f', - outerLine: '#00b36a', - skeleton: 'basic_string_field', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '소리 센서에 감지되는 소리 값', - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [null], - type: 'roborobo_sound_value', - }, - paramsKeyMap: {}, - class: 'roborobo_sound', - func(sprite, script) { - const port = Entry.Roborobo_SchoolKit.inputPort.sound; - return Entry.hw.portData[port - 7]; - }, - }, - roborobo_sound_value_boolean: { - color: '#01d67f', - outerLine: '#00b36a', - skeleton: 'basic_boolean_field', - fontColor: '#fff', - isNotFor: ['roborobo_schoolkit'], - template: '소리 센서에 감지되는 소리 값 %1 %2', - params: [ - { - type: 'Dropdown', - options: [ - ['=', 'EQUAL'], - ['>', 'GREATER'], - ['<', 'LESS'], - ['≥', 'GREATER_OR_EQUAL'], - ['≤', 'LESS_OR_EQUAL'], - ], - value: 'LESS', - fontSize: 11, - bgColor: '#00b36a', - arrowColor: EntryStatic.colorSet.common.WHITE, - noaRrow: true, - }, - { - type: 'Block', - accept: 'string', - }, - ], - def: { - params: [ - null, - { - type: 'number', - params: ['512'], - }, - ], - type: 'roborobo_sound_value_boolean', - }, - paramsKeyMap: { - OPERATOR: 0, - RIGHTVALUE: 1, - }, - class: 'roborobo_sound', - func(sprite, script) { - const port = Entry.Roborobo_SchoolKit.inputPort.sound; - const operator = script.getField('OPERATOR', script); - let rightValue = script.getNumberValue('RIGHTVALUE', script); - const leftValue = Entry.hw.portData[port - 7]; - let isCheck = false; - - if (rightValue < 0) { - rightValue = 0; - } else if (rightValue > 1023) { - rightValue = 1023; - } - - switch (operator) { - case 'EQUAL': - isCheck = leftValue == rightValue; - break; - case 'GREATER': - isCheck = Number(leftValue) > Number(rightValue); - break; - case 'LESS': - isCheck = Number(leftValue) < Number(rightValue); - break; - case 'GREATER_OR_EQUAL': - isCheck = Number(leftValue) >= Number(rightValue); - break; - case 'LESS_OR_EQUAL': - isCheck = Number(leftValue) <= Number(rightValue); - break; - } - - return isCheck; - }, - }, - roborobo_irs_value: { - color: '#C4065C', - outerLine: '#9a0045', - skeleton: 'basic_string_field', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '적외선 센서 값', - params: [ - { - type: 'Block', - accept: 'string', - }, - ], - events: {}, - def: { - params: [null], - type: 'roborobo_irs_value', - }, - paramsKeyMap: {}, - class: 'roborobo_irs', - //'isNotFor': ['mini'], - func(sprite, script) { - const port = Entry.Roborobo_SchoolKit.inputPort.ir; - const value = - Entry.hw.portData[port - 7] == undefined ? 0 : Entry.hw.portData[port - 7]; - return value; - }, - }, - roborobo_irs_value_boolean: { - color: '#C4065C', - outerLine: '#9a0045', - skeleton: 'basic_boolean_field', - fontColor: '#fff', - isNotFor: ['roborobo_schoolkit'], - template: '적외선 센서가 %1', - params: [ - { - type: 'Dropdown', - options: [ - ['감지 되면', '1'], - ['감지 안되면', '0'], - ], - value: '1', - fontSize: 11, - bgColor: '#9a0045', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - ], - def: { - params: [null], - type: 'roborobo_irs_value_boolean', - }, - paramsKeyMap: { - DETECT: 0, - }, - class: 'roborobo_irs', - //'isNotFor': ['mini'], - func(sprite, script) { - const port = Entry.Roborobo_SchoolKit.inputPort.ir; - const detect = script.getNumberField('DETECT', script); - - Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.INPUT; - Entry.hw.update(); - - const value = Entry.hw.portData[port - 7]; - const isDetect = detect == value; - - return isDetect; - }, - }, - roborobo_diode_secs_toggle: { - color: '#ff8d0f', - outerLine: '#e37100', - skeleton: 'basic', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1번 포트의 발광다이오드를 %2초 동안 %3 %4', - params: [ - { - type: 'Dropdown', - options: [ - ['LED 1', '5'], - ['LED 2', '4'], - ['R - A', '3'], - ['R - B', '2'], - ], - value: '5', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Dropdown', - options: [ - ['켜기', '255'], - ['끄기', '0'], - ], - value: '255', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Indicator', - img: 'block_icon/practical_course/diode.png', - size: 12, - }, - ], - events: {}, - def: { - params: [ - null, - { - type: 'number', - params: ['2'], - }, - null, - null, - ], - type: 'roborobo_diode_secs_toggle', - }, - paramsKeyMap: { - PORT: 0, - DURATION: 1, - VALUE: 2, - }, - class: 'roborobo_diode', - func(sprite, script) { - const port = script.getNumberField('PORT'); - const duration = script.getNumberValue('DURATION'); - const value = script.getNumberField('VALUE'); - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.PWM; - - if (!script.isStart) { - script.isStart = true; - script.timeFlag = 1; - Entry.hw.sendQueue[port] = value; - - setTimeout(() => { - script.timeFlag = 0; - }, duration * 1000); - return script; - } else if (script.timeFlag == 1) { - return script; - } else { - Entry.hw.sendQueue[port] = 0; - delete script.timeFlag; - delete script.isStart; - Entry.engine.isContinue = false; - return script.callReturn(); - } - }, - }, - roborobo_diode_toggle: { - color: '#ff8d0f', - outerLine: '#e37100', - skeleton: 'basic', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1번 포트의 발광다이오드를 %2 %3', - params: [ - { - type: 'Dropdown', - options: [ - ['LED 1', '5'], - ['LED 2', '4'], - ['R - A', '3'], - ['R - B', '2'], - ], - value: '5', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Dropdown', - options: [ - ['켜기', '255'], - ['끄기', '0'], - ], - value: '255', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Indicator', - img: 'block_icon/practical_course/diode.png', - size: 12, - }, - ], - events: {}, - def: { - params: [null, null, null], - type: 'roborobo_diode_toggle', - }, - paramsKeyMap: { - PORT: 0, - VALUE: 1, - }, - class: 'roborobo_diode', - //'isNotFor': ['mini'], - func(sprite, script) { - const port = script.getNumberField('PORT'); - const value = script.getNumberField('VALUE'); - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - - Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue[port] = value; - - return script.callReturn(); - }, - }, - roborobo_diode_inout_toggle: { - color: '#ff8d0f', - outerLine: '#e37100', - skeleton: 'basic', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1번 포트의 발광다이오드를 %2번 포트의 %3~%4의 범위로 켜기%5', - params: [ - { - type: 'Dropdown', - options: [ - ['LED 1', '5'], - ['LED 2', '4'], - ['R - A', '3'], - ['R - B', '2'], - ], - value: '5', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Dropdown', - options: [ - ['소 리', '8'], - ['CDS', '10'], - ], - value: '8', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/practical_course/diode.png', - size: 12, - }, - ], - events: {}, - def: { - params: [ - null, - null, - { type: 'number', params: ['0'] }, - { type: 'number', params: ['255'] }, - null, - ], - type: 'roborobo_diode_inout_toggle', - }, - paramsKeyMap: { - OUTPUT: 0, - INPUT: 1, - MIN: 2, - MAX: 3, - }, - class: 'roborobo_diode', - //'isNotFor': ['mini'], - func(sprite, script) { - const outputPort = script.getNumberField('OUTPUT'); - const inputPort = script.getNumberField('INPUT'); - - const oMin = script.getNumberValue('MIN'); - const oMax = script.getNumberValue('MAX'); - const nMin = 0; - const nMax = 255; - const x = Entry.hw.portData[inputPort - 7] / 4; - const percent = (x - oMin) / (oMax - oMin); - let result = percent * (nMax - nMin) + nMin; - if (result > nMax) { - result = nMax; - } - if (result < nMin) { - result = nMin; - } - - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - - Entry.hw.sendQueue.digitalPinMode[outputPort] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue[outputPort] = result; - - return script.callReturn(); - }, - }, - roborobo_diode_set_output: { - color: '#ff8d0f', - outerLine: '#e37100', - skeleton: 'basic', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1번 포트의 발광다이오드를 %2의 밝기로 켜기 %3', - params: [ - { - type: 'Dropdown', - options: [ - ['LED 1', '5'], - ['LED 2', '4'], - ['R - A', '3'], - ['R - B', '2'], - ], - value: '5', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - { - type: 'Block', - accept: 'string', - }, - { - type: 'Indicator', - img: 'block_icon/practical_course/diode.png', - size: 12, - }, - ], - events: {}, - def: { - params: [ - null, - { - type: 'number', - params: ['255'], - }, - null, - ], - type: 'roborobo_diode_set_output', - }, - paramsKeyMap: { - PORT: 0, - VALUE: 1, - }, - class: 'roborobo_diode', - //'isNotFor': ['mini'], - func(sprite, script) { - const port = script.getStringField('PORT', script); - let value = script.getNumberValue('VALUE', script); - - if (value < 0) { - value = 0; - } else if (value > 255) { - value = 255; - } - if (!Entry.hw.sendQueue.digitalPinMode) { - Entry.hw.sendQueue.digitalPinMode = {}; - } - Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.PWM; - Entry.hw.sendQueue[port] = value; - - return script.callReturn(); - }, - }, - roborobo_diode_input_value: { - color: '#ff8d0f', - outerLine: '#e37100', - skeleton: 'basic_string_field', - fontColor: '#fff', - statements: [], - isNotFor: ['roborobo_schoolkit'], - template: '%1 포트의 값', - params: [ - { - type: 'Dropdown', - options: [ - ['적외선', '7'], - ['소 리', '8'], - ['접 촉', '9'], - ['CDS', '10'], - ], - value: '8', - fontSize: 11, - bgColor: '#e37100', - arrowColor: EntryStatic.colorSet.common.WHITE, - }, - ], - events: {}, - def: { - params: [null], - type: 'roborobo_diode_input_value', - }, - paramsKeyMap: { - PORT: 0, - }, - class: 'roborobo_diode', - func(sprite, script) { - const port = script.getNumberField('PORT'); - return Entry.hw.portData[port - 7]; - }, - }, - } -} - -Entry.Roborobo_RoE.setLanguage = function() { - return { - ko: { - template: { - roe_set_led: '%1 LED 켜기 %2', - roe_set_led_off: 'LED 끄기 %1', - roe_set_motor: '로이 %1 %2', - roe_set_motor_value: '%1 모터 : %2 만큼 %3 %4', - roe_set_melody: '%1 옥타브 %2 을(를) %3 초 연주 %4', - roe_get_input_switch: '접촉센서가 %1 ?', - roe_get_input_ir: '적외선 센서가 %1 ?', - roe_get_input_color: '%1 컬러센서 값이 %2 인가?', - roe_led_color_dropdown: '%1', - roe_melody_dropdown: '%1', - roe_motor_dropdown: '%1', - roe_movement_dropdown: '%1', - roe_detect_dropdown: '%1', - roe_color_select_dropdown: '%1', - roe_color_color_dropdown: '%1', - }, - Blocks: { - roe_color_sensor_left: '왼쪽', - roe_color_sensor_right: '오른쪽', - roe_color_sensor_both: '양쪽', - roe_color_red: '빨간색', - roe_color_orange: '주황색', - roe_color_yellow: '노란색', - roe_color_yellowgreen: '연두색', - roe_color_green: '초록색', - roe_color_skyblue: '하늘색', - roe_color_blue: '파란색', - roe_color_purple: '보라색', - roe_color_pink: '분홍색', - roe_color_white: '흰색', - roe_color_black: '검정색', - roe_color_random: '무작위 색', - roe_color_none: '미감지', - roe_motor_both: '양쪽', - roe_motor_left: '왼쪽', - roe_motor_right: '오른쪽', - roe_move_forward: '전진', - roe_move_backward: '후진', - roe_move_turnleft: '좌회전', - roe_move_turnright: '우회전', - roe_move_stop: '정지', - roe_detected: '감지되었는가', - roe_undetected: '감지되지 않았는가', - roe_melody_do: '도', - roe_melody_doS: '도#', - roe_melody_re: '레', - roe_melody_miF: '미b', - roe_melody_mi: '미', - roe_melody_pa: '파', - roe_melody_paS: '파#', - roe_melody_sol: '솔', - roe_melody_solS: '솔#', - roe_melody_la: '라', - roe_melody_siF: '시b', - roe_melody_si: '시', - } - }, - en: { - template: { - roe_set_led: 'Turn on %1 LED %2', - roe_set_led_off: 'Turn off LED %1', - roe_set_motor: 'Ro-E %1 %2', - roe_set_motor_value: '%1 motor(s) : Move %3 by %2 %4', - roe_set_melody: 'Play %1 octave %2 tone for %3 second(s) %4', - roe_get_input_switch: 'Is the switch sensor %1 ?', - roe_get_input_ir: 'Is the IR sensor %1 ?', - roe_get_input_color: 'Is %1 color sensor value %2 ?', - roe_led_color_dropdown: '%1', - roe_melody_dropdown: '%1', - roe_motor_dropdown: '%1', - roe_movement_dropdown: '%1', - roe_detect_dropdown: '%1', - roe_color_select_dropdown: '%1', - roe_color_color_dropdown: '%1', - }, - Blocks: { - roe_color_sensor_left: 'left', - roe_color_sensor_right: 'right', - roe_color_sensor_both: 'both', - roe_color_red: 'Red', - roe_color_orange: 'Orange', - roe_color_yellow: 'Yellow', - roe_color_yellowgreen: 'Yellow Green', - roe_color_green: 'Green', - roe_color_skyblue: 'Sky Blue', - roe_color_blue: 'Blue', - roe_color_purple: 'Purple', - roe_color_pink: 'Pink', - roe_color_white: 'White', - roe_color_black: 'Black', - roe_color_random: 'Random', - roe_color_none: 'Undetected', - roe_motor_both: 'Both', - roe_motor_left: 'Left', - roe_motor_right: 'Right', - roe_move_forward: 'forward', - roe_move_backward: 'backward', - roe_move_turnleft: 'turn left', - roe_move_turnright: 'turn right', - roe_move_stop: 'stop', - roe_detected: 'detected', - roe_undetected: 'undetected', - roe_melody_do: 'C', - roe_melody_doS: 'C#', - roe_melody_re: 'D', - roe_melody_miF: 'Eb', - roe_melody_mi: 'E', - roe_melody_pa: 'F', - roe_melody_paS: 'F#', - roe_melody_sol: 'G', - roe_melody_solS: 'G#', - roe_melody_la: 'A', - roe_melody_siF: 'Bb', - roe_melody_si: 'B', - }, - }, - }; -}; - -Entry.Roborobo_RoE.blockMenuBlocks = [ - 'roe_set_led', - 'roe_set_led_off', - 'roe_set_motor', - 'roe_set_motor_value', - 'roe_set_melody', - 'roe_get_input_switch', - 'roe_get_input_ir', - 'roe_get_input_color', -]; - -Entry.Roborobo_RoE.getBlocks = function() { - return { - //region roe 로이 - roe_led_color_dropdown: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_color_red, 1], - [Lang.Blocks.roe_color_orange, 2], - [Lang.Blocks.roe_color_yellow, 3], - [Lang.Blocks.roe_color_yellowgreen, 4], - [Lang.Blocks.roe_color_green, 5], - [Lang.Blocks.roe_color_skyblue, 6], - [Lang.Blocks.roe_color_blue, 7], - [Lang.Blocks.roe_color_purple, 8], - [Lang.Blocks.roe_color_pink, 9], - [Lang.Blocks.roe_color_white, 10] - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: 0, - }, - func: function(sprite, script) { - return script.getNumberField('VALUE'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_color_red, 1], - [Lang.Blocks.roe_color_orange, 2], - [Lang.Blocks.roe_color_yellow, 3], - [Lang.Blocks.roe_color_yellowgreen, 4], - [Lang.Blocks.roe_color_green, 5], - [Lang.Blocks.roe_color_skyblue, 6], - [Lang.Blocks.roe_color_blue, 7], - [Lang.Blocks.roe_color_purple, 8], - [Lang.Blocks.roe_color_pink, 9], - [Lang.Blocks.roe_color_white, 10] - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'roe_led_color_dropdown', - }, - ], - }, - }, - roe_melody_dropdown: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_melody_do, 1], - [Lang.Blocks.roe_melody_re, 2], - [Lang.Blocks.roe_melody_mi, 3], - [Lang.Blocks.roe_melody_pa, 4], - [Lang.Blocks.roe_melody_sol, 5], - [Lang.Blocks.roe_melody_la, 6], - [Lang.Blocks.roe_melody_si, 7], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: 0, - }, - func: function(sprite, script) { - return script.getNumberField('VALUE', script); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_melody_do, 1], - [Lang.Blocks.roe_melody_re, 2], - [Lang.Blocks.roe_melody_mi, 3], - [Lang.Blocks.roe_melody_pa, 4], - [Lang.Blocks.roe_melody_sol, 5], - [Lang.Blocks.roe_melody_la, 6], - [Lang.Blocks.roe_melody_si, 7], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - keyOption: 'roe_melody_dropdown', - }, - ], - }, - }, - roe_motor_dropdown: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_motor_both, 1], - [Lang.Blocks.roe_motor_left, 2], - [Lang.Blocks.roe_motor_right, 3], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: 0, - }, - func: function(sprite, script) { - return script.getNumberField('VALUE'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_motor_both, 1], - [Lang.Blocks.roe_motor_left, 2], - [Lang.Blocks.roe_motor_right, 3], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'roe_motor_dropdown', - }, - ], - }, - }, - roe_movement_dropdown: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_move_forward, 1], - [Lang.Blocks.roe_move_backward, 2], - [Lang.Blocks.roe_move_turnleft, 3], - [Lang.Blocks.roe_move_turnright, 4], - [Lang.Blocks.roe_move_stop, 5], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: 0, - }, - func: function(sprite, script) { - return script.getNumberField('VALUE'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_move_forward, 1], - [Lang.Blocks.roe_move_backward, 2], - [Lang.Blocks.roe_move_turnleft, 3], - [Lang.Blocks.roe_move_turnright, 4], - [Lang.Blocks.roe_move_stop, 5], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'roe_movement_dropdown', - }, - ], - }, - }, - roe_detect_dropdown: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_detected, 1], - [Lang.Blocks.roe_undetected, 0], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: 0, - }, - func: function(sprite, script) { - return script.getNumberField('VALUE'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_detected, 1], - [Lang.Blocks.roe_undetected, 2], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'roe_detect_dropdown', - }, - ], - }, - }, - roe_color_select_dropdown: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_color_sensor_both, 1], - [Lang.Blocks.roe_color_sensor_left, 2], - [Lang.Blocks.roe_color_sensor_right, 3], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: 0, - }, - func: function(sprite, script) { - return script.getNumberField('VALUE'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_color_sensor_both, 1], - [Lang.Blocks.roe_color_sensor_left, 2], - [Lang.Blocks.roe_color_sensor_right, 3], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'roe_color_select_dropdown', - }, - ], - }, - }, - roe_color_color_dropdown: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic_string_field', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_color_red, 1], - [Lang.Blocks.roe_color_orange, 2], - [Lang.Blocks.roe_color_yellow, 3], - [Lang.Blocks.roe_color_yellowgreen, 7], - [Lang.Blocks.roe_color_green, 4], - [Lang.Blocks.roe_color_skyblue, 8], - [Lang.Blocks.roe_color_blue, 5], - [Lang.Blocks.roe_color_purple, 6], - [Lang.Blocks.roe_color_pink, 9], - [Lang.Blocks.roe_color_black, 10], - [Lang.Blocks.roe_color_white, 11], - [Lang.Blocks.roe_color_none, 127], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - ], - events: {}, - def: { - params: [null], - }, - paramsKeyMap: { - VALUE: 0, - }, - func: function(sprite, script) { - return script.getNumberField('VALUE'); - }, - syntax: { - js: [], - py: [ - { - syntax: '%1', - textParams: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.roe_color_red, 1], - [Lang.Blocks.roe_color_orange, 2], - [Lang.Blocks.roe_color_yellow, 3], - [Lang.Blocks.roe_color_yellowgreen, 7], - [Lang.Blocks.roe_color_green, 4], - [Lang.Blocks.roe_color_skyblue, 8], - [Lang.Blocks.roe_color_blue, 5], - [Lang.Blocks.roe_color_purple, 6], - [Lang.Blocks.roe_color_pink, 9], - [Lang.Blocks.roe_color_black, 10], - [Lang.Blocks.roe_color_white, 11], - [Lang.Blocks.roe_color_none, 127], - ], - value: 1, - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - converter: Entry.block.converters.returnStringValue, - }, - ], - keyOption: 'roe_color_color_dropdown', - }, - ], - }, - }, - roe_set_led: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Block', - accept: 'string' - }, - { - type: 'Indicator', - img: 'block_icon/hardware_icon.svg', - size: 12 - } - ], - events: {}, - def: { - params: [ - { - type: 'roe_led_color_dropdown', - }, - null - ], - type: 'roe_set_led', - }, - paramsKeyMap: { - VALUE: 0, - }, - class: 'roe_set', - isNotFor: ['roborobo_roe'], - func: function(sprite, script) { - var color = script.getNumberValue('VALUE', script); - Entry.hw.sendQueue['LED'] = color; - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roe.roe_set_led(%1)', - textParams: [ - { - type: "Block", - accept: "string" - }, - { - type: 'roe_led_color_dropdown' - } - ], - }, - ], - }, - }, - roe_set_led_off: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic', - statements: [], - params: [ - { - type: "Indicator", - img: "block_icon/hardware_icon.svg", - size: 12 - } - ], - events: {}, - def: { - params: [ - null - ], - type: 'roe_set_led_off' - }, - paramsKeyMap: {}, - class: 'roe_set', - isNotFor: ['roborobo_roe'], - func: function(sprite, script) { - Entry.hw.sendQueue['LED'] = 0; - }, - syntax: { - js: [], - py: ['Roborobo_roe.roe_set_led_off()'], - }, - }, - roe_set_melody: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic', - statements: [], - params: [ - { - type: 'Dropdown', - options: [ - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], - ], - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Block', - accept: 'string' - }, - { - type: 'Block', - accept: 'string' - }, - { - type: "Indicator", - img: "block_icon/hardware_icon.svg", - size: 12 - } - ], - events: {}, - def: { - params: [ - '4', - { - type: 'roe_melody_dropdown', - }, - '1', - null - ], - type: 'roe_set_melody', - }, - paramsKeyMap: { - OCTAVE: 0, - NOTE: 1, - DURATION: 2 - }, - class: 'roe_set', - isNotFor: ['roborobo_roe'], - func: function(sprite, script) { - if (!script.isStart) { - var octave = script.getNumberValue('OCTAVE', script); - var note = script.getNumberValue('NOTE', script); - var duration = script.getNumberValue('DURATION', script); - - if(octave < 4) { - octave = 4; - } else if (octave > 7) { - octave = 7; - } - - if(note < 1) { - note = 1; - } else if (note > 7) { - note = 7; - } - duration = duration < 0 ? 0 : duration; - duration = duration * 1000; - - script.isStart = true; - script.timeFlag = 1; - - Entry.hw.sendQueue['Melody'] = [octave, note, duration]; - - setTimeout(function() { - script.timeFlag = 0; - }, duration); - return script; - } else if (script.timeFlag == 1) { - return script; - } else { - delete script.timeFlag; - delete script.isStart; - } - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roe.roe_set_melody(%1 %2 %3)', - textParams: [ - '4', - { - type: 'roe_melody_dropdown', - }, - '1', - ], - }, - ], - }, - }, - roe_set_motor: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: "Block", - accept: "string" - }, - { - type: "Indicator", - img: "block_icon/hardware_icon.svg", - size: 12 - } - ], - events: {}, - def: { - params: [ - { - type: 'roe_movement_dropdown' - }, - null - ], - type: 'roe_set_motor' - }, - paramsKeyMap: { - OPERATOR: 0, - }, - class: 'roe_set', - isNotFor: ['roborobo_roe'], - func: function(sprite, script) { - var op = script.getNumberValue('OPERATOR', script); - if(op == 1) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, 0 ]; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, 0 ]; - } else if (op == 2) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, 0] ; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, 0 ]; - } else if (op == 3) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, 0 ]; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, 0 ]; - } else if (op == 4) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, 0 ]; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, 0 ]; - } else if (op == 5) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.STOP, 0 ]; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.STOP,0 ]; - } - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roe.roe_set_motor(%1)', - textParams: [ - { - type: 'roe_movement_dropdown' - }, - ], - }, - ], - }, - }, - roe_set_motor_value: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - skeleton: 'basic', - statements: [], - params: [ - { - type: "Block", - accept: "string" - }, - { - type: "Block", - accept: "string" - }, - { - type: "Block", - accept: "string" - }, - { - type: "Indicator", - img: "block_icon/hardware_icon.svg", - size: 12 - } - ], - events: {}, - def: { - params: [ - { - type: 'roe_motor_dropdown' - }, - '100', - { - type: 'roe_movement_dropdown' - }, - null - ], - type: 'roe_set_motor_value' - }, - paramsKeyMap: { - MOTOR: 0, - VALUE: 1, - OPERATOR: 2, - }, - class: 'roe_set', - isNotFor: ['roborobo_roe'], - func: function(sprite, script) { - var motor = script.getNumberValue('MOTOR', script); - var value = script.getNumberValue('VALUE', script); - var op = script.getNumberValue('OPERATOR', script); - - if(value < 0) { - value = 0; - } else if(value > 100) { - value = 100; - } - - if(motor == 1) { - if(op == 1) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, value ]; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, value ]; - } else if (op == 2) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, value ] ; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, value ]; - } else if (op == 3) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, value ]; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, value ]; - } else if (op == 4) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, value ]; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, value ]; - } else if (op == 5) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.STOP, value ]; - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.STOP, value ]; - } - } else if (motor == 2) { - if(op == 1) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, value ]; - } else if (op == 2) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, value ] ; - } else if (op == 3) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, value ]; - } else if (op == 4) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, value ]; - } else if (op == 5) { - Entry.hw.sendQueue['LeftMotor'] = [ Entry.Roborobo_RoE.motorDiretion.STOP, value ]; - } - } else if (motor == 3) { - if(op == 1) { - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, value ]; - } else if (op == 2) { - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, value ]; - } else if (op == 3) { - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CW, value ]; - } else if (op == 4) { - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.CCW, value ]; - } else if (op == 5) { - Entry.hw.sendQueue['RightMotor'] = [ Entry.Roborobo_RoE.motorDiretion.STOP, value ]; - } - } - }, - syntax: { - js: [], - py: [ - { - syntax: 'Roborobo_roe.roe_set_motor_value(%1 %2 %3)', - textParams: [ - { - type: 'roe_motor_dropdown' - }, - '100', - { - type: 'roe_movement_dropdown' - }, - ], - }, - ], - }, - }, - roe_get_input_switch: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_boolean_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string' - }, - { - type: "Indicator", - img: "block_icon/hardware_icon.svg", - size: 12 - } - ], - events: {}, - def: { - params: [ - { - type: 'roe_detect_dropdown', - }, - null - ], - type: 'roe_get_input_switch' - }, - paramsKeyMap: { - DETECT: 0 - }, - class: 'roe_get', - isNotFor: ['roborobo_roe'], - func: function(sprite, script) { - var detect = script.getNumberValue('DETECT', script); - var value = Entry.hw.portData['Switch']; - // console.log('Switch Value : ' + value); - return detect == value ? true : false; - }, - syntax: { - js: [], - py: ['Roborobo_roe.roe_get_input_switch()'], - }, - }, - roe_get_input_ir: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_boolean_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string' - }, - { - type: "Indicator", - img: "block_icon/hardware_icon.svg", - size: 12 - } - ], - events: {}, - def: { - params: [ - { - type: 'roe_detect_dropdown', - }, - null - ], - type: 'roe_get_input_ir' - }, - paramsKeyMap: { - DETECT: 0 - }, - class: 'roe_get', - isNotFor: ['roborobo_roe'], - func: function(sprite, script) { - var detect = script.getNumberValue('DETECT', script); - var value = Entry.hw.portData['IR']; - // console.log('IR Value : ' + value); - return detect == value ? true : false; - }, - syntax: { - js: [], - py: ['Roborobo_roe.roe_get_input_ir()'], - }, - }, - roe_get_input_color: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#fff', - skeleton: 'basic_boolean_field', - statements: [], - params: [ - { - type: 'Block', - accept: 'string' - }, - { - type: 'Block', - accept: 'string' - }, - { - type: "Indicator", - img: "block_icon/hardware_icon.svg", - size: 12 - } - ], - events: {}, - def: { - params: [ - { - type: 'roe_color_select_dropdown', - }, - { - type: 'roe_color_color_dropdown', - }, - null - ], - type: 'roe_get_input_color' - }, - paramsKeyMap: { - SENSOR: 0, - COLOR: 1 - }, - class: 'roe_get', - isNotFor: ['roborobo_roe'], - func: function(sprite, script) { - var result = false; - var sensor = script.getNumberValue('SENSOR', script); - var color = script.getNumberValue('COLOR', script); - var left = Entry.hw.portData['LeftColor']; - var right = Entry.hw.portData['RightColor']; - - if(sensor == 1) { - if(left == color && right == color) { - result = true; - } - } else if (sensor == 2) { - result = left == color ? true : false; - } else if (sensor == 3) { - result = right == color ? true : false; - } - return result; - }, - syntax: { - js: [], - py: ['Roborobo_roe.roe_get_input_color()'], - }, - }, - //endregion roe 로이 - }; -}; - -module.exports = [Entry.Roborobo_Roduino, Entry.Roborobo_SchoolKit, Entry.Roborobo_RoE]; diff --git a/src/playground/blocks/hardware/block_roborobo_base.js b/src/playground/blocks/hardware/block_roborobo_base.js new file mode 100644 index 0000000000..620d6843e2 --- /dev/null +++ b/src/playground/blocks/hardware/block_roborobo_base.js @@ -0,0 +1,422 @@ +'use strict'; + +const PinMode = { + INPUT: 0x00, + OUTPUT: 0x01, + ANALOG: 0x02, + I2C: 0x06, +} + +class ArduinoBase { + constructor () { + this.resetState(); + } + + setLanguage () {throw new Error('재정의 필요');} + getBlocks () {throw new Error('재정의 필요');} + + setZero () { + this.resetState(); + this.request('reset', null, null, true); + } + + afterReceive = function (data) { + const keys = data.state ? Object.keys(data.state) : []; + keys.forEach(key => this.state[key] = data.state[key]); + } + + afterSend = function () { + Entry.hw.sendQueue = {}; + } + + request (func, subkey, value, updateNow = false) { + if (!Entry.hw.sendQueue[func]) Entry.hw.sendQueue[func] = {}; + + if (subkey) { + Entry.hw.sendQueue[func][subkey.toString()] = value; + } else { + Entry.hw.sendQueue[func] = value; + } + + if (updateNow) Entry.hw.update(); + } + + resetState () { + this.state = { + pin: [], + rx: {} + }; + } + + pinToNumber (pin) { + if (pin === undefined || pin === null) return 0; + if (typeof pin === 'number') { + if (Number.isNaN(pin)) return 0; + return pin; + } + + const pinStr = pin.toString().toLowerCase(); + switch (pinStr) { + case 'd2': return 2; + case 'd3': return 3; + case 'd4': return 4; + case 'd5': return 5; + case 'd6': return 6; + case 'd7': return 7; + case 'd8': return 8; + case 'd9': return 9; + case 'd10': return 10; + case 'd11': return 11; + case 'd12': return 12; + case 'd13': return 13; + case 'a0': return 14; + case 'a1': return 15; + case 'a2': return 16; + case 'a3': return 17; + case 'a4': return 18; + case 'a5': return 19; + default: { + const n = Number(pin); + if (Number.isNaN(n)) return 0; + return n; + } + } + } + + isEqualsPinMode (pin, mode) { + return typeof pin === 'number' && this.state.pin[pin] && this.state.pin[pin].mode == mode; + } + + isDigitalPin (pin) { + return typeof pin === 'number' && 2 <= pin && pin <= 15; + } + + isAnalogPin (pin) { + return typeof pin === 'number' && 14 <= pin && pin <= 19; + } + + measureAnalogPin (pin) { + const analogPin = pin - 14; + return Math.min(5, Math.max(0, analogPin)); + } + + getDigitalValue (pin) { + if (!this.isDigitalPin(pin)) return 0; + + if (!this.isEqualsPinMode(pin, PinMode.INPUT)) { + this.request('enableDigitalInput', pin, {pin}, true); + } + + return this.state.rx.digital && typeof this.state.rx.digital[pin] === 'number' + ? this.state.rx.digital[pin] + : 0; + } + + getAnalogValue (pin, defValue = 0) { + if (!this.isAnalogPin(pin)) return defValue; + + if (!this.isEqualsPinMode(pin, PinMode.ANALOG)) { + this.request('enableAnalogInput', pin, {pin}, true); + } + + const analogPin = this.measureAnalogPin(pin); + return this.state.rx.analog && typeof this.state.rx.analog[analogPin] === 'number' + ? this.state.rx.analog[analogPin] + : defValue; + } + + set_digital (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + const value = script.getNumberValue('VALUE'); + + this.request('setDigital', pin, {pin, value}); + return script.callReturn(); + } + + set_motor (sprite, script) { + const motor = script.getNumberValue('MOTOR'); + const speed = script.getNumberValue('SPEED'); + const state = script.getStringValue('STATE'); + + let stateNum = 0; + if (state == 'cw') stateNum = 1; + else if (state == 'ccw') stateNum = 2; + + this.request('setMotor', motor, {motor, speed, state: stateNum}); + return script.callReturn(); + } + + set_motors (sprite, script) { + const motors = script.getNumberValue('MOTORS'); + const speed1 = script.getNumberValue('SPEED1'); + const speed2 = script.getNumberValue('SPEED2'); + const state = script.getStringValue('STATE'); + + const speed = [speed1, speed2]; + let motor = [] + if (motors == 12) { + motor = [1, 2]; + } else if (motors == 34) { + motor = [3, 4]; + } + + let stateNum = [0, 0]; + switch (state) { + case 'forward': + stateNum = [2, 1]; + break; + case 'turn-left': + stateNum = [1, 1]; + break; + case 'backward': + stateNum = [1, 2]; + break; + case 'turn-right': + stateNum = [2, 2]; + break; + } + + for (let i = 0; i < 2; i++) { + this.request('setMotor', i + 1, {motor: motor[i], speed: speed[i], state: stateNum[i]}); + } + return script.callReturn(); + } + + set_servo_angle (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + const angle = script.getNumberValue('ANGLE'); + + this.request('setServo', pin, {pin, angle}); + return script.callReturn(); + } + + set_rgbled_color (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + let colorString = script.getStringValue('COLOR'); + + let color; + if (typeof colorString === 'string' && colorString.substring(0, 1) === '#') { + const shorThandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; + colorString = colorString.replace(shorThandRegex, (m, r, g, b) => r + r + g + g + b + b); + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(colorString); + color = result ? { + r: parseInt(result[1], 16), + g: parseInt(result[2], 16), + b: parseInt(result[3], 16) + } : null; + } + if (!color) color = {r: 0, g: 0, b: 0}; + + this.request('setRgbLedColor', pin, {pin, color}); + return script.callReturn(); + + } + + change_rgbled_brightness_by (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + const brightness = script.getNumberValue('BRIGHTNESS'); + + this.request('changeRgbLedBrightnessBy', pin, {pin, brightness}); + return script.callReturn(); + } + + set_rgbled_brightness_to (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + const brightness = script.getNumberValue('BRIGHTNESS'); + + this.request('setRgbLedBrightnessTo', pin, {pin, brightness}); + return script.callReturn(); + } + + play_piezobuzzer (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + const octave = script.getNumberValue('OCTAVE'); + const duration = script.getNumberValue('DURATION'); + let note = script.getNumberValue('NOTE'); + note = (octave - 1) * 12 + note; + + this.request('setPiezoBuzzer', pin, {pin, note, duration}); + return script.callReturn(); + } + + play_piezobuzzer_until_done (sprite, script) { + const duration = script.getNumberValue('DURATION'); + this.play_piezobuzzer(sprite, script); + return new Promise(resolve => setTimeout(() => resolve(), duration * 1000)); + } + + get_digital_value (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + return this.getDigitalValue(pin); + } + + is_digital_detected (sprite, script) { + return this.get_digital_value(sprite, script) == 1; + } + + get_analog_value (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + return this.getAnalogValue(pin); + } + + compare_analog_value (sprite, script) { + const value1 = this.get_analog_value(sprite, script); + const symbol = script.getStringValue('SYMBOL'); + const value2 = script.getStringValue('VALUE'); + + return this._compare(value1, value2, symbol); + } + + _compare (v1, v2, symbol) { + switch (symbol) { + case 'greater-than': + return v1 > v2; + case 'equal': + return v1 == v2; + case 'less-than': + return v1 < v2; + default: return false; + } + } + + get_sensor_value (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + const sensor = script.getStringValue('SENSOR'); + + if (sensor == 'ultrasonic') { + if (!this.isEqualsPinMode(pin, PinMode.INPUT)) { + this.request('enableSonarSensor', pin, {pin}, true); + } + return this.state.rx.digital[pin]; + } + + if (!this.isEqualsPinMode(pin, PinMode.ANALOG)) { + this.request('enableAnalogInput', pin, {pin}, true); + } + const analogPin = this.measureAnalogPin(pin); + switch (sensor) { + case "joystickx": + case "joysticky": { + const analogValue = this.getAnalogValue(pin, 512); + const value = analogValue >> 6; + + if (value > 14) return 2; + else if (value > 9) return 1; + else if (value > 5) return 0; + else if (value > 1) return -1; + else return -2; + } + case "light": { + const analogValue = this.getAnalogValue(pin); + return parseInt(Math.round(analogValue * 0.1)); + } + case "dial": { + const analogValue = this.getAnalogValue(pin); + return Math.round(analogValue * 0.1); + } + case "akeypad": { + const analogValue = this.getAnalogValue(pin); + if (analogValue >= 450) return 1; + else if (analogValue >= 390) return 2; + else if (analogValue >= 310) return 3; + else if (analogValue >= 200) return 4; + else if (analogValue >= 100) return 5; + else return 0; + } + case 'temperature': { + if (!this.state.rx.temperature[analogPin] || !this.state.rx.temperature[analogPin].enable) { + this.request('enableTemperatureSensor', pin, {pin}, true); + } + + if (this.state.rx.temperature[analogPin] && this.state.rx.temperature[analogPin].value) { + return this.state.rx.temperature[analogPin].value; + } + } break; + case 'magnetic': { + const analogValue = this.getAnalogValue(pin, 512); + + const zero = 512; + const zeroGap = 32; + const startS = zero + zeroGap; + const startN = zero - zeroGap; + const maxArea = 64; + + let value = 0; + if (analogValue > startS) { + value = (analogValue > 1024 - maxArea) ? 1024 - maxArea : analogValue; + value = Math.min(10, parseInt(Math.round((value - startS) / 32))); + } else if (analogValue < startN) { + value = (analogValue < maxArea) ? maxArea : analogValue; + value = Math.min(10, parseInt(Math.round((startN - value) / 32))) * -1; + } + return value; + } + case 'rotaryposition': { + if (!this.state.rx.rotaryPosition[analogPin] || !this.state.rx.rotaryPosition[analogPin].enable) { + this.request('enableRotaryPositionSensor', pin, {pin}, true); + } + + if (this.state.rx.rotaryPosition[analogPin] && this.state.rx.rotaryPosition[analogPin].rotation) { + return this.state.rx.rotaryPosition[analogPin].originAngle; + } + } break; + } + return 0; + } + + compare_sensor_value (sprite, script) { + const value1 = this.get_sensor_value(sprite, script); + const symbol = script.getStringValue('SYMBOL'); + const value2 = script.getStringValue('VALUE'); + + return this._compare(value1, value2, symbol); + } + + get_rotary_position_sensor_value (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + const analogPin = this.measureAnalogPin(pin); + const type = script.getStringValue('PROPERTY'); + + if (!this.state.rx.rotaryPosition[analogPin] || !this.state.rx.rotaryPosition[analogPin].enable) { + this.request('enableRotaryPositionSensor', pin, {pin}, true); + } + + if (!this.state.rx.rotaryPosition[analogPin] || !this.state.rx.rotaryPosition[analogPin].rotation) return 0; + + const obj = this.state.rx.rotaryPosition[analogPin]; + let value = 0; + switch (type) { + case 'rotation': { + if (obj.isIntegerRotation) { + value = parseInt(obj.rotation); + } else { + value = obj.rotation; + } + } break; + case 'position': { + if (obj.isIntegerPosition) { + value = parseInt(Math.round(obj.position)); + } else { + value = obj.position; + } + } break; + case 'angle': { + value = obj.angle; + } break; + case 'angle-origin': { + value = obj.originAngle; + } break; + } + return value; + } + + reset_rotary_position_sensor (sprite, script) { + const pin = this.pinToNumber(script.getStringValue('PIN')); + const type = script.getStringValue('PROPERTY'); + const value = script.getNumberValue('VALUE'); + + this.request('resetRotaryPositionSensor', pin, {pin, type, value}); + } +} + +module.exports = {ArduinoBase, PinMode}; diff --git a/src/playground/blocks/hardware/block_roborobo_robokit_rs.js b/src/playground/blocks/hardware/block_roborobo_robokit_rs.js new file mode 100644 index 0000000000..5366dad99a --- /dev/null +++ b/src/playground/blocks/hardware/block_roborobo_robokit_rs.js @@ -0,0 +1,2152 @@ +'use strict'; +const {ArduinoBase, PinMode} = require('./block_roborobo_base.js'); + +class RobokitRS extends ArduinoBase { + constructor () { + super(); + + this.id = '10.3'; + this.name = 'roborobo_robokit_rs'; + this.url = 'http://www.roborobo.co.kr'; + this.imageName = 'roborobo_robokit_rs.png'; + this.title = { + ko: '로보키트 RS', + en: 'Robokit RS', + } + this.blockMenuBlocks = this.getBlockMenuBlocks(); + } + + /** + * 언어 번역 사용을 위해 함수 형태로 유지 + */ + monitorTemplate () { + return { + //imgPath: 'hw/~~.png', + //width: 256, + //height: 256, + // 모니터 화면 상단에 차례대로 나열하는 값 + listPorts: { + digital_2: {name: (Lang.Blocks.monitor_digital + ': 2'), type: 'input', pos: {x: 0, y: 0, }}, + digital_3: {name: (Lang.Blocks.monitor_digital + ': 3'), type: 'input', pos: {x: 0, y: 0, }}, + digital_4: {name: (Lang.Blocks.monitor_digital + ': 4'), type: 'input', pos: {x: 0, y: 0, }}, + digital_5: {name: (Lang.Blocks.monitor_digital + ': 5'), type: 'input', pos: {x: 0, y: 0, }}, + digital_6: {name: (Lang.Blocks.monitor_digital + ': 6'), type: 'input', pos: {x: 0, y: 0, }}, + digital_7: {name: (Lang.Blocks.monitor_digital + ': 7'), type: 'input', pos: {x: 0, y: 0, }}, + digital_8: {name: (Lang.Blocks.monitor_digital + ': 8'), type: 'input', pos: {x: 0, y: 0, }}, + digital_9: {name: (Lang.Blocks.monitor_digital + ': 9'), type: 'input', pos: {x: 0, y: 0, }}, + digital_10: {name: (Lang.Blocks.monitor_digital + ': 10'), type: 'input', pos: {x: 0, y: 0, }}, + digital_11: {name: (Lang.Blocks.monitor_digital + ': 11'), type: 'input', pos: {x: 0, y: 0, }}, + digital_12: {name: (Lang.Blocks.monitor_digital + ': 12'), type: 'input', pos: {x: 0, y: 0, }}, + digital_13: {name: (Lang.Blocks.monitor_digital + ': 13'), type: 'input', pos: {x: 0, y: 0, }}, + analog_0: {name: (Lang.Blocks.monitor_analog + ': A0'), type: 'input', pos: {x: 0, y: 0, }}, + analog_1: {name: (Lang.Blocks.monitor_analog + ': A1'), type: 'input', pos: {x: 0, y: 0, }}, + analog_2: {name: (Lang.Blocks.monitor_analog + ': A2'), type: 'input', pos: {x: 0, y: 0, }}, + analog_3: {name: (Lang.Blocks.monitor_analog + ': A3'), type: 'input', pos: {x: 0, y: 0, }}, + analog_4: {name: (Lang.Blocks.monitor_analog + ': A4'), type: 'input', pos: {x: 0, y: 0, }}, + analog_5: {name: (Lang.Blocks.monitor_analog + ': A5'), type: 'input', pos: {x: 0, y: 0, }}, + sensor_gyroscope_angle_x: {name: Lang.Blocks.monitor_gyroscope_angle_x, type: 'input', pos: {x: 0, y: 0, }}, + sensor_gyroscope_angle_y: {name: Lang.Blocks.monitor_gyroscope_angle_y, type: 'input', pos: {x: 0, y: 0, }}, + sensor_gyroscope_angle_z: {name: Lang.Blocks.monitor_gyroscope_angle_z, type: 'input', pos: {x: 0, y: 0, }}, + sensor_gyroscope_gyro_x: {name: Lang.Blocks.monitor_gyroscope_x, type: 'input', pos: {x: 0, y: 0, }}, + sensor_gyroscope_gyro_y: {name: Lang.Blocks.monitor_gyroscope_y, type: 'input', pos: {x: 0, y: 0, }}, + sensor_gyroscope_gyro_z: {name: Lang.Blocks.monitor_gyroscope_z, type: 'input', pos: {x: 0, y: 0, }}, + sensor_gyroscope_shake: {name: Lang.Blocks.monitor_gyroscope_shake, type: 'input', pos: {x: 0, y: 0, }}, + }, + // 모니터 화면 지정 위치와 선으로 연결하여 표시하는 값 + ports: {}, + mode: 'both', + } + } + + getBlockMenuBlocks () { + return [ + 'robokit_rs_menu_digital_pin', + 'robokit_rs_menu_analog_pin', + 'robokit_rs_menu_pin', + 'robokit_rs_menu_digital_value', + 'robokit_rs_menu_motor_number', + + 'robokit_rs_set_digital', + 'robokit_rs_set_motor', + 'robokit_rs_set_motors', + 'robokit_rs_set_mecanumwheels', + 'robokit_rs_set_servo_angle', + 'robokit_rs_set_rgbled_color', + 'robokit_rs_change_rgbled_brightness_by', + 'robokit_rs_set_rgbled_brightness_to', + 'robokit_rs_set_dot_state_of_dotmatrix', + 'robokit_rs_set_dotmatrix_row', + 'robokit_rs_set_dotmatrix', + 'robokit_rs_clear_dotmatrix', + 'robokit_rs_play_piezobuzzer', + 'robokit_rs_play_piezobuzzer_until_done', + 'robokit_rs_get_digital_value', + 'robokit_rs_get_analog_value', + 'robokit_rs_get_sensor_value', + 'robokit_rs_is_digital_detected', + 'robokit_rs_compare_analog_value', + 'robokit_rs_compare_sensor_value', + 'robokit_rs_get_gyro_sensor_value', + 'robokit_rs_is_shaken_gyro_sensor', + 'robokit_rs_reset_gyro_sensor', + 'robokit_rs_get_rotary_position_sensor_value', + 'robokit_rs_reset_rotary_position_sensor', + ]; + } + + setLanguage () { + return { + ko: { + template: { + robokit_rs_menu_digital_pin: '%1', + robokit_rs_menu_analog_pin: '%1', + robokit_rs_menu_pin: '%1', + robokit_rs_menu_digital_value: '%1', + robokit_rs_menu_motor_number: '%1', + + robokit_rs_set_digital: '%1 번 핀 디지털 값을 %2 (으)로 정하기 %3', + robokit_rs_set_motor: '%1 번 모터를 속도 %2 (으)로 %3 %4', + robokit_rs_set_motors: '%1 번 모터, 속도 %2, %3 (으)로 로봇을 %4 %5', + robokit_rs_set_mecanumwheels: '메카넘 휠 로봇을 속도 %1 (으)로 %2 %3', + robokit_rs_set_servo_angle: '%1 번 핀 서보 모터를 %2 도로 회전하기 %3', + robokit_rs_set_rgbled_color: '%1 번 핀 RGB LED 색상을 %2 색으로 정하기 %3', + robokit_rs_change_rgbled_brightness_by: '%1 번 핀 RGB LED 밝기를 %2 만큼 바꾸기 %3', + robokit_rs_set_rgbled_brightness_to: '%1 번 핀 RGB LED 밝기를 %2 %로 정하기 %3', + robokit_rs_set_dot_state_of_dotmatrix: '도트 매트릭스 x: %1 y: %2 좌표를 %3 (으)로 정하기 %4', + robokit_rs_set_dotmatrix_row: '도트 매트릭스 y: %1 행에 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 그리기 %17', + robokit_rs_set_dotmatrix: '도트 매트릭스에 %1 그리기 %2', + robokit_rs_clear_dotmatrix: '도트 매트릭스 모두 지우기 %1', + robokit_rs_play_piezobuzzer: '%1 번 핀 피에조 버저로 %2 옥타브 %3 음을 %4 초 소리내기 %5', + robokit_rs_play_piezobuzzer_until_done: '%1 번 핀 피에조 버저로 %2 옥타브 %3 음을 %4 초 소리내며 기다리기 %5', + robokit_rs_get_digital_value: '%1 번 핀 디지털 값', + robokit_rs_get_analog_value: '%1 번 핀 아날로그 값', + robokit_rs_get_sensor_value: '%1 번 핀 %2 값', + robokit_rs_is_digital_detected: '%1 번 핀이 감지되었는가?', + robokit_rs_compare_analog_value: '%1 번 핀 아날로그 값 %2 %3', + robokit_rs_compare_sensor_value: '%1 번 핀 %2 값 %3 %4', + robokit_rs_get_gyro_sensor_value: '자이로 센서 %1 값', + robokit_rs_is_shaken_gyro_sensor: '자이로 센서를 흔들었는가?', + robokit_rs_reset_gyro_sensor: '자이로 센서 기본 자세의 방향을 %1 정하기 %2', + robokit_rs_get_rotary_position_sensor_value: '%1 번 핀 회전 위치 센서 %2 값', + robokit_rs_reset_rotary_position_sensor: '%1 번 핀 회전 위치 센서 %2 값을 %3 (으)로 정하기 %4' + }, + Blocks: { + monitor_digital: '디지털', + monitor_analog: '아날로그', + monitor_gyroscope_angle_x: '자이로 센서 : 기울기 x', + monitor_gyroscope_angle_y: '자이로 센서 : 기울기 y', + monitor_gyroscope_angle_z: '자이로 센서 : 기울기 z', + monitor_gyroscope_x: '자이로 센서 : 각속도 x', + monitor_gyroscope_y: '자이로 센서 : 각속도 y', + monitor_gyroscope_z: '자이로 센서 : 각속도 z', + monitor_gyroscope_shake: '자이로 센서 : 흔들림', + + robokit_rs_motor_state_cw: '시계 방향 회전', + robokit_rs_motor_state_ccw: '시계 반대 방향 회전', + robokit_rs_motor_state_stop: '정지', + + robokit_rs_motors_state_forward: '앞으로 이동', + robokit_rs_motors_state_backward: '뒤로 이동', + robokit_rs_motors_state_turn_left: '왼쪽으로 회전', + robokit_rs_motors_state_turn_right: '오른쪽으로 회전', + robokit_rs_motors_state_stop: '정지', + + robokit_rs_mecanumwheels_state_0: '앞으로 이동', + robokit_rs_mecanumwheels_state_180: '뒤로 이동', + robokit_rs_mecanumwheels_state_270: '왼쪽으로 이동', + robokit_rs_mecanumwheels_state_90: '오른쪽으로 이동', + robokit_rs_mecanumwheels_state_45: '45도 방향으로 이동', + robokit_rs_mecanumwheels_state_135: '135도 방향으로 이동', + robokit_rs_mecanumwheels_state_315: '-45도 방향으로 이동', + robokit_rs_mecanumwheels_state_225: '-135도 방향으로 이동', + robokit_rs_mecanumwheels_state_cw: '시계 방향 회전', + robokit_rs_mecanumwheels_state_ccw: '시계 반대 방향 회전', + robokit_rs_mecanumwheels_state_stop: '정지', + + robokit_rs_dotmatrix_example_eighth_note: '8분 음표', + robokit_rs_dotmatrix_example_sixteenth_note: '16분 음표', + robokit_rs_dotmatrix_example_square: '네모', + robokit_rs_dotmatrix_example_triangle: '세모', + robokit_rs_dotmatrix_example_circle: '동그라미', + robokit_rs_dotmatrix_example_heart: '하트', + robokit_rs_dotmatrix_example_ga: '가', + robokit_rs_dotmatrix_example_na: '나', + robokit_rs_dotmatrix_example_speech_bubble: '말풍선', + robokit_rs_dotmatrix_example_looking_at_top_right: '오른쪽 위 보기', + robokit_rs_dotmatrix_example_looking_at_bottom_right: '오른쪽 아래 보기', + robokit_rs_dotmatrix_example_looking_at_top_left: '왼쪽 위 보기', + robokit_rs_dotmatrix_example_looking_at_bottom_left: '왼쪽 아래 보기', + robokit_rs_dotmatrix_example_square_basic: '네모 기본', + robokit_rs_dotmatrix_example_square_basic_2: '네모 기본2', + robokit_rs_dotmatrix_example_square_square_eyes: '네모 네모 눈', + robokit_rs_dotmatrix_example_square_surprised_mouth: '네모 놀란 입', + robokit_rs_dotmatrix_example_big_round_eyes: '크고 둥근 눈', + robokit_rs_dotmatrix_example_small_round_eyes: '작고 둥근 눈', + robokit_rs_dotmatrix_example_wink_right_eye: '오른쪽 윙크', + robokit_rs_dotmatrix_example_wink_left_eye: '왼쪽 윙크', + robokit_rs_dotmatrix_example_eyebrow_eye_right: '오른쪽 눈썹 눈', + robokit_rs_dotmatrix_example_eyebrow_eye_left: '왼쪽 눈썹 눈', + robokit_rs_dotmatrix_example_expressionless: '무표정', + robokit_rs_dotmatrix_example_cutie: '귀요미', + robokit_rs_dotmatrix_example_cute: '깜찍이', + robokit_rs_dotmatrix_example_small_eyes_smile: '작은 눈 웃는 표정', + robokit_rs_dotmatrix_example_half_moon_shape_eyes: '반달 눈', + robokit_rs_dotmatrix_example_half_moon_shape_eyes_smiling: '반달 눈 웃기', + robokit_rs_dotmatrix_example_half_moon_shape_eyes_closed: '반달 눈 감기', + robokit_rs_dotmatrix_example_sad_expression: '슬픈 표정', + robokit_rs_dotmatrix_example_sullen: '시무룩', + robokit_rs_dotmatrix_example_crying_eyes: '우는 눈', + robokit_rs_dotmatrix_example_melancholy_look: '우울한 표정', + robokit_rs_dotmatrix_example_angry_eyes: '화난 눈', + robokit_rs_dotmatrix_example_o_shape_mouth: '오모양 입', + robokit_rs_dotmatrix_example_yo_shape_mouth: '요모양 입', + + robokit_rs_piezobuzzer_tone_c: '도', + robokit_rs_piezobuzzer_tone_c_sharp: '도♯(레♭)', + robokit_rs_piezobuzzer_tone_d: '레', + robokit_rs_piezobuzzer_tone_d_sharp: '레♯(미♭)', + robokit_rs_piezobuzzer_tone_e: '미', + robokit_rs_piezobuzzer_tone_f: '파', + robokit_rs_piezobuzzer_tone_f_sharp: '파♯(솔♭)', + robokit_rs_piezobuzzer_tone_g: '솔', + robokit_rs_piezobuzzer_tone_g_sharp: '솔♯(라♭)', + robokit_rs_piezobuzzer_tone_a: '라', + robokit_rs_piezobuzzer_tone_a_sharp: '라♯(시♭)', + robokit_rs_piezobuzzer_tone_b: '시', + + robokit_rs_sensor_temperutre: '온도 센서', + robokit_rs_sensor_joystick_x: '조이스틱 x', + robokit_rs_sensor_joystick_y: '조이스틱 y', + robokit_rs_sensor_light: '빛 센서', + robokit_rs_sensor_dial: '다이얼', + robokit_rs_sensor_a_keypad: 'A 키패드', + robokit_rs_sensor_rotaryposition: '회전 위치 센서', + robokit_rs_sensor_magnetic: '자기 센서', + robokit_rs_sensor_ultrasonic: '초음파 센서', + + robokit_rs_sensor_gyroscope_angle_x: '기울기 x', + robokit_rs_sensor_gyroscope_angle_y: '기울기 y', + robokit_rs_sensor_gyroscope_angle_z: '기울기 z', + robokit_rs_sensor_gyroscope_x: '각속도 x', + robokit_rs_sensor_gyroscope_y: '각속도 y', + robokit_rs_sensor_gyroscope_z: '각속도 z', + robokit_rs_sensor_gyroscope_shake: '흔들림', + + robokit_rs_sensor_gyroscope_direction_up: '위로', + robokit_rs_sensor_gyroscope_direction_forward: '앞으로', + robokit_rs_sensor_gyroscope_direction_right: '오른쪽으로', + robokit_rs_sensor_gyroscope_direction_backward: '뒤로', + robokit_rs_sensor_gyroscope_direction_left: '왼쪽으로', + + robokit_rs_sensor_rotaryposition_rotation: '회전', + robokit_rs_sensor_rotaryposition_position: '위치', + robokit_rs_sensor_rotaryposition_angle: '각도', + }, + }, + en: { + template: { + robokit_rs_menu_digital_pin: '%1', + robokit_rs_menu_analog_pin: '%1', + robokit_rs_menu_pin: '%1', + robokit_rs_menu_digital_value: '%1', + robokit_rs_menu_motor_number: '%1', + + robokit_rs_set_digital: 'set pin %1 digital value to %2 %3', + robokit_rs_set_motor: 'set motor %1 speed to %2 %3 %4', + robokit_rs_set_motors: '%4 a robot with motor %1 at speed %2 %3 %5', + robokit_rs_set_mecanumwheels: 'mecanum wheel robot %1 at speed %2 %3', + robokit_rs_set_servo_angle: 'rotate pin %1 servo motor to %2 degree %3', + robokit_rs_set_rgbled_color: 'set %1 pin RGB LED color to the %2 color %3', + robokit_rs_change_rgbled_brightness_by: 'change pin %1 RGB LED brightness by %2 %3', + robokit_rs_set_rgbled_brightness_to: 'set pin %1 RGB LED brightness to %2 % %3', + robokit_rs_set_dot_state_of_dotmatrix: 'Set dot matrix X: %1 Y: %2 to %3 %4', + robokit_rs_set_dotmatrix_row: 'Draw %2 %3 %4 %5 %6 %7 %8 %9 %10 %11 %12 %13 %14 %15 %16 on dot matrix y:%1 column %17', + robokit_rs_set_dotmatrix: 'draw %1 on dotmatrix %2', + robokit_rs_clear_dotmatrix: 'Clear all dot matrix %1', + robokit_rs_play_piezobuzzer: 'Play pin %1 peizo buzzer with %2 otave %3 note for %4 sec %5', + robokit_rs_play_piezobuzzer_until_done: 'Play pin %1 peizo buzzer with %2 otave %3 note for %4 sec and wait %5', + robokit_rs_get_digital_value: 'pin %1 digital value', + robokit_rs_get_analog_value: 'pin %1 analog value', + robokit_rs_get_sensor_value: 'pin %1 %2 value', + robokit_rs_is_digital_detected: 'pin %1 detected?', + robokit_rs_compare_analog_value: 'pin %1 analog value %2 %3', + robokit_rs_compare_sensor_value: 'pin %1 %2 value %3 %4', + robokit_rs_get_gyro_sensor_value: '%1 value of gyrosensor', + robokit_rs_is_shaken_gyro_sensor: 'is gyrosensor shaken?', + robokit_rs_reset_gyro_sensor: 'set basic position of gyrosensor %1 %2', + robokit_rs_get_rotary_position_sensor_value: 'rotary position sensor of pin %1 %2 value', + robokit_rs_reset_rotary_position_sensor: 'rotary position sensor of pin %1 set %2 value to %3 %4' + }, + Blocks: { + monitor_digital: 'Digital', + monitor_analog: 'Analog', + monitor_gyroscope_angle_x: 'Gyroscope sensor : angle x', + monitor_gyroscope_angle_y: 'Gyroscope sensor : angle y', + monitor_gyroscope_angle_z: 'Gyroscope sensor : angle z', + monitor_gyroscope_x: 'Gyroscope sensor : angular velocity x', + monitor_gyroscope_y: 'Gyroscope sensor : angular velocity y', + monitor_gyroscope_z: 'Gyroscope sensor : angular velocity z', + monitor_gyroscope_shake: 'Gyroscope sensor : shake', + + robokit_rs_motor_state_cw: 'rotate clockwise', + robokit_rs_motor_state_ccw: 'rotate counterclockwise', + robokit_rs_motor_state_stop: 'stop', + + robokit_rs_motors_state_forward: 'move forward', + robokit_rs_motors_state_backward: 'move backword', + robokit_rs_motors_state_turn_left: 'turn left', + robokit_rs_motors_state_turn_right: 'turn right', + robokit_rs_motors_state_stop: 'stop', + + robokit_rs_mecanumwheels_state_0: 'move forward', + robokit_rs_mecanumwheels_state_180: 'move backward', + robokit_rs_mecanumwheels_state_270: 'move left', + robokit_rs_mecanumwheels_state_90: 'move right', + robokit_rs_mecanumwheels_state_45: 'move 45 degree', + robokit_rs_mecanumwheels_state_135: 'move 135 degree', + robokit_rs_mecanumwheels_state_315: 'move -45 degree', + robokit_rs_mecanumwheels_state_225: 'move -135 degree', + robokit_rs_mecanumwheels_state_cw: 'rotate clockwise', + robokit_rs_mecanumwheels_state_ccw: 'rotate counterclockwise', + robokit_rs_mecanumwheels_state_stop: 'stop', + + robokit_rs_dotmatrix_example_eighth_note: 'eighth note', + robokit_rs_dotmatrix_example_sixteenth_note: 'sixteenth note', + robokit_rs_dotmatrix_example_square: 'square', + robokit_rs_dotmatrix_example_triangle: 'triangle', + robokit_rs_dotmatrix_example_circle: 'circle', + robokit_rs_dotmatrix_example_heart: 'heart', + robokit_rs_dotmatrix_example_ga: 'ga', + robokit_rs_dotmatrix_example_ga: 'na', + robokit_rs_dotmatrix_example_speech_bubble: 'speech bubble', + robokit_rs_dotmatrix_example_looking_at_top_right: 'looking at top right', + robokit_rs_dotmatrix_example_looking_at_bottom_right: 'looking at bottom right', + robokit_rs_dotmatrix_example_looking_at_top_left: 'looking at top left', + robokit_rs_dotmatrix_example_looking_at_bottom_left: 'looking at bottom left', + robokit_rs_dotmatrix_example_square_basic: 'square basic', + robokit_rs_dotmatrix_example_square_basic_2: 'square basic2', + robokit_rs_dotmatrix_example_square_square_eyes: 'square square eyes', + robokit_rs_dotmatrix_example_square_surprised_mouth: 'square surprised mouth', + robokit_rs_dotmatrix_example_big_round_eyes: 'big round eyes', + robokit_rs_dotmatrix_example_small_round_eyes: 'small round eyes', + robokit_rs_dotmatrix_example_wink_right_eye: 'wink right eye', + robokit_rs_dotmatrix_example_wink_left_eye: 'wink left eye', + robokit_rs_dotmatrix_example_eyebrow_eye_right: 'eyebrow eye to the right', + robokit_rs_dotmatrix_example_eyebrow_eye_left: 'eyebrow eye to the left', + robokit_rs_dotmatrix_example_expressionless: 'expressionless', + robokit_rs_dotmatrix_example_cutie: 'cutie', + robokit_rs_dotmatrix_example_cute: 'cute', + robokit_rs_dotmatrix_example_small_eyes_smile: 'small eyes smile', + robokit_rs_dotmatrix_example_half_moon_shape_eyes: 'half moon shape eyes', + robokit_rs_dotmatrix_example_half_moon_shape_eyes_smiling: 'half moon shape eyes smiling', + robokit_rs_dotmatrix_example_half_moon_shape_eyes_closed: 'half moon shape eyes closed', + robokit_rs_dotmatrix_example_sad_expression: 'sad expression', + robokit_rs_dotmatrix_example_sullen: 'sullen', + robokit_rs_dotmatrix_example_crying_eyes: 'crying eyes', + robokit_rs_dotmatrix_example_melancholy_look: 'melancholy look', + robokit_rs_dotmatrix_example_angry_eyes: 'angry eyes', + robokit_rs_dotmatrix_example_o_shape_mouth: 'o shape mouth', + robokit_rs_dotmatrix_example_yo_shape_mouth: 'yo shape mouth', + + robokit_rs_piezobuzzer_tone_c: 'C', + robokit_rs_piezobuzzer_tone_c_sharp: 'C♯(D♭)', + robokit_rs_piezobuzzer_tone_d: 'D', + robokit_rs_piezobuzzer_tone_d_sharp: 'D♯(E♭)', + robokit_rs_piezobuzzer_tone_e: 'E', + robokit_rs_piezobuzzer_tone_f: 'F', + robokit_rs_piezobuzzer_tone_f_sharp: 'F♯(G♭)', + robokit_rs_piezobuzzer_tone_g: 'G', + robokit_rs_piezobuzzer_tone_g_sharp: 'G♯(A♭)', + robokit_rs_piezobuzzer_tone_a: 'A', + robokit_rs_piezobuzzer_tone_a_sharp: 'A♯(B♭)', + robokit_rs_piezobuzzer_tone_b: 'B', + + robokit_rs_sensor_temperutre: 'temperature sensor', + robokit_rs_sensor_joystick_x: 'joystick x', + robokit_rs_sensor_joystick_y: 'joystick y', + robokit_rs_sensor_light: 'light sensor', + robokit_rs_sensor_dial: 'dial', + robokit_rs_sensor_a_keypad: 'A keypad', + robokit_rs_sensor_rotaryposition: 'rotary position sensor', + robokit_rs_sensor_magnetic: 'magnetic sensor', + robokit_rs_sensor_ultrasonic: 'ultrasonic sensor', + + robokit_rs_sensor_gyroscope_angle_x: 'angle x', + robokit_rs_sensor_gyroscope_angle_y: 'angle y', + robokit_rs_sensor_gyroscope_angle_z: 'angle z', + robokit_rs_sensor_gyroscope_x: 'angular velocity x', + robokit_rs_sensor_gyroscope_y: 'angular velocity y', + robokit_rs_sensor_gyroscope_z: 'angular velocity z', + robokit_rs_sensor_gyroscope_shake: 'shake', + + robokit_rs_sensor_gyroscope_direction_up: 'up', + robokit_rs_sensor_gyroscope_direction_forward: 'forward', + robokit_rs_sensor_gyroscope_direction_right: 'right', + robokit_rs_sensor_gyroscope_direction_backward: 'backward', + robokit_rs_sensor_gyroscope_direction_left: 'left', + + robokit_rs_sensor_rotaryposition_rotation: 'rotation', + robokit_rs_sensor_rotaryposition_position: 'position', + robokit_rs_sensor_rotaryposition_angle: 'angle', + }, + }, + }; + }; + + getBlocks () { + return { + robokit_rs_menu_digital_pin: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ['8', '8'], + ['9', '9'], + ['10', '10'], + ['11', '11'], + ['12', '12'], + ['13', '13'] + ], + value: '2', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PIN: 0, + }, + func: (sprite, script) => { + return script.getStringField('PIN'); + }, + }, + robokit_rs_menu_analog_pin: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['A0', '14'], + ['A1', '15'], + ['A2', '16'], + ['A3', '17'], + ['A4', '18'], + ['A5', '19'], + ], + value: '14', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PIN: 0, + }, + func: (sprite, script) => { + return script.getStringField('PIN'); + }, + }, + robokit_rs_menu_pin: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['A0', '14'], + ['A1', '15'], + ['A2', '16'], + ['A3', '17'], + ['A4', '18'], + ['A5', '19'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ['8', '8'], + ['9', '9'], + ['10', '10'], + ['11', '11'], + ['12', '12'], + ['13', '13'], + ], + value: '14', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PIN: 0, + }, + func: (sprite, script) => { + return script.getStringField('PIN'); + }, + }, + robokit_rs_menu_digital_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['0', '0'], + ['1', '1'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + NUM: 0, + }, + func: (sprite, script) => { + return script.getStringField('NUM'); + }, + }, + robokit_rs_menu_motor_number: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + NUM: 0, + }, + func: (sprite, script) => { + return script.getStringField('NUM'); + }, + }, + robokit_rs_set_digital: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + } + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin', + }, + { + type: 'robokit_rs_menu_digital_value', + }, + null, + ], + type: 'robokit_rs_set_digital', + }, + paramsKeyMap: { + PIN: 0, + VALUE: 1, + }, + class: 'motion', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_digital(sprite, script), + }, + robokit_rs_set_motor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_motor_state_cw, 'cw'], + [Lang.Blocks.robokit_rs_motor_state_ccw, 'ccw'], + [Lang.Blocks.robokit_rs_motor_state_stop, 'stop'], + ], + value: 'cw', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_motor_number' + }, + { + type: 'number', + params: ['15'], + }, + null, + null, + + ], + type: 'robokit_rs_set_motor', + }, + paramsKeyMap: { + MOTOR: 0, + SPEED: 1, + STATE: 2, + }, + class: 'motion', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_motor(sprite, script) + }, + robokit_rs_set_motors: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1, 2', '12'], + ['3, 4', '34'] + ], + value: '12', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_motors_state_forward, 'forward'], + [Lang.Blocks.robokit_rs_motors_state_backward, 'backward'], + [Lang.Blocks.robokit_rs_motors_state_turn_left, 'turn-left'], + [Lang.Blocks.robokit_rs_motors_state_turn_right, 'turn-right'], + [Lang.Blocks.robokit_rs_motors_state_stop, 'stop'], + ], + value: 'forward', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['15'], + }, + { + type: 'number', + params: ['15'], + }, + null, + null, + + ], + type: 'robokit_rs_set_motors', + }, + paramsKeyMap: { + MOTORS: 0, + SPEED1: 1, + SPEED2: 2, + STATE: 3, + }, + class: 'motion', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_motors(sprite, script) + }, + robokit_rs_set_mecanumwheels: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_mecanumwheels_state_0, '0'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_180, '180'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_270, '270'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_90, '90'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_45, '45'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_135, '135'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_315, '315'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_225, '225'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_cw, 'cw'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_ccw, 'ccw'], + [Lang.Blocks.robokit_rs_mecanumwheels_state_stop, 'stop'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['15'], + }, + null, + null, + + ], + type: 'robokit_rs_set_mecanumwheels', + }, + paramsKeyMap: { + SPEED: 0, + STATE: 1, + }, + class: 'motion', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_mecanumwheels(sprite, script) + }, + robokit_rs_set_servo_angle: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin' + }, + { + type: 'number', + params: ['0'], + }, + null, + + ], + type: 'robokit_rs_set_servo_angle', + }, + paramsKeyMap: { + PIN: 0, + ANGLE: 1, + }, + class: 'motion', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_servo_angle(sprite, script) + }, + robokit_rs_set_rgbled_color: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Color', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin' + }, + null, + null, + + ], + type: 'robokit_rs_set_rgbled_color', + }, + paramsKeyMap: { + PIN: 0, + COLOR: 1, + }, + class: 'looks', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_rgbled_color(sprite, script) + }, + robokit_rs_change_rgbled_brightness_by: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin' + }, + { + type: 'number', + params: ['10'], + }, + null, + + ], + type: 'robokit_rs_change_rgbled_brightness_by', + }, + paramsKeyMap: { + PIN: 0, + BRIGHTNESS: 1, + }, + class: 'looks', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.change_rgbled_brightness_by(sprite, script) + }, + robokit_rs_set_rgbled_brightness_to: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin' + }, + { + type: 'number', + params: ['100'], + }, + null, + + ], + type: 'robokit_rs_set_rgbled_brightness_to', + }, + paramsKeyMap: { + PIN: 0, + BRIGHTNESS: 1, + }, + class: 'looks', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_rgbled_brightness_to(sprite, script) + }, + robokit_rs_set_dot_state_of_dotmatrix: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'robokit_rs_menu_digital_value', + }, + null, + ], + type: 'robokit_rs_set_dot_state_of_dotmatrix', + }, + paramsKeyMap: { + X: 0, + Y: 1, + STATE: 2, + }, + class: 'looks_dot_matrix', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_dot_state_of_dotmatrix(sprite, script) + }, + robokit_rs_set_dotmatrix_row: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['0', '0'], + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + null, + + ], + type: 'robokit_rs_set_dotmatrix_row', + }, + paramsKeyMap: { + Y: 0, + X0: 1, X1: 2, X2: 3, X3: 4, X4: 5, X5: 6, X6: 7, X7: 8, X8: 9, X9: 10, X10: 11, X11: 12, X12: 13, X13: 14, X14: 15, X15: 16, + }, + class: 'looks_dot_matrix', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_dotmatrix_row(sprite, script) + }, + robokit_rs_set_dotmatrix: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_dotmatrix_example_eighth_note, '000000000000000000000011000000000000010100000000000010100000000001110100000000011110000000000001100000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_sixteenth_note, '000000001111000000000011001000000000010001000000000010011000000001110111000000011110111000000001100000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_square, '000111111111000000111111111000000110000011000000110000011000000110000011000000111111111000000111111111000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_triangle, '000000010000000000000111000000000001101100000000011000110000000110000011000001100000001100001111111111100'], + [Lang.Blocks.robokit_rs_dotmatrix_example_circle, '000001111100000000011000110000000110000011000000100000001000000110000011000000011000110000000001111100000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_heart, '000011000110000000111101111000001111111111100001111111111100000111111111000000001111100000000000010000000'], + ['X', '000110000011000000011000110000000001111100000000000111000000000001111100000000011000110000000110000011000'], + ['A', '000000111000000000001000100000000001000100000000001111100000000001000100000000001000100000000001000100000'], + ['B', '000001111000000000001000100000000001000100000000001111100000000001000100000000001000100000000001111000000'], + ['C', '000000111000000000001000100000000001000000000000001000000000000001000000000000001000100000000000111000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_ga, '000000000000000000011101000000000000101000000000000101100000000001001000000000000001000000000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_na, '000000000000000000010001000000000010001000000000010001100000000011101000000000000001000000000000000000000'], + ['!', '000000010000000000000010000000000000010000000000000010000000000000010000000000000000000000000000010000000'], + ['?', '000000111000000000001000100000000000000100000000000001000000000000010000000000000000000000000000010000000'], + ['0', '000001111100000000001000100000000001000100000000001000100000000001000100000000001000100000000001111100000'], + ['1', '000000010000000000000110000000000001010000000000000010000000000000010000000000000010000000000001111100000'], + ['2', '000001111100000000000000100000000000000100000000001111100000000001000000000000001000000000000001111100000'], + ['3', '000001111100000000000000100000000000000100000000001111100000000000000100000000000000100000000001111100000'], + ['4', '000001000100000000001000100000000001000100000000001000100000000001111110000000000000100000000000000100000'], + ['5', '000001111100000000001000000000000001000000000000001111100000000000000100000000000000100000000001111100000'], + ['6', '000001111100000000001000000000000001000000000000001111100000000001000100000000001000100000000001111100000'], + ['7', '000001111100000000001000100000000001000100000000000000100000000000000100000000000000100000000000000100000'], + ['8', '000001111100000000001000100000000001000100000000001111100000000001000100000000001000100000000001111100000'], + ['9', '000001111100000000001000100000000001000100000000001111100000000000000100000000000000100000000001111100000'], + ['10', '000010001111100000110001000100001010001000100000010001000100000010001000100000010001000100001111101111100'], + [Lang.Blocks.robokit_rs_dotmatrix_example_speech_bubble, '111111111111111100000000000001100111111111001100000000000001111110011111111000010100000000000011000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_looking_at_top_right, '011111000111110111100101111001111100101111001111111101111111111111101111111111111101111111011111000111110'], + [Lang.Blocks.robokit_rs_dotmatrix_example_looking_at_bottom_right, '011111000111110111111101111111111111101111111111111101111111111100101111001111100101111001011111000111110'], + [Lang.Blocks.robokit_rs_dotmatrix_example_looking_at_top_left, '011111000111110100111101001111100111101001111111111101111111111111101111111111111101111111011111000111110'], + [Lang.Blocks.robokit_rs_dotmatrix_example_looking_at_bottom_left, '011111000111110111111101111111111111101111111111111101111111100111101001111100111101001111011111000111110'], + [Lang.Blocks.robokit_rs_dotmatrix_example_square_basic, '111111111111111100000000000001100100000001001100000000000001100111111111001100000000000001111111111111111'], + [Lang.Blocks.robokit_rs_dotmatrix_example_square_basic_2, '111111111111111100000000000001101111000111101100110000011001100110010011001100000000000001111111111111111'], + [Lang.Blocks.robokit_rs_dotmatrix_example_square_square_eyes, '111111111111111100000000000001101111000111101101001000100101101111010111101100000000000001111111111111111'], + [Lang.Blocks.robokit_rs_dotmatrix_example_square_surprised_mouth, '111111111111111100000000000001100100111001001100000101000001100000101000001100000111000001111111111111111'], + [Lang.Blocks.robokit_rs_dotmatrix_example_big_round_eyes, '001111000111100011111101111110011111101111110011111101111110011111101111110011111101111110001111000111100'], + [Lang.Blocks.robokit_rs_dotmatrix_example_small_round_eyes, '000000000000000001111000111100011111101111110011111101111110011111101111110001111000111100000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_wink_right_eye, '000000000000000001111000000000011111100000000011111100111100011111101111110001111000111100000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_wink_left_eye, '000000000000000000000000111100000000001111110001111001111110011111101111110001111000111100000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_eyebrow_eye_right, '111111000111111000000000000000111111000111111011101000111010011111000111110011110000011110000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_eyebrow_eye_left, '111111000111111000000000000000111111000111111010111000101110011111000111110011110000011110000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_expressionless, '000000000000000011111000111110000000000000000000111000111000000111000111000000111000111000000111000111000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_cutie, '000000000000000001110000011100001110000011100001010010010100001110010011100000000101000000000011000110000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_cute, '001000000000100000100000001000000010000010000000100000001000001000010000100000000000000000000111111111000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_small_eyes_smile, '000000000000000000100000001000000100000001000000000000000000001111111111100001111111111100000111111111000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_half_moon_shape_eyes, '000000000000000001111000111100011111101111110010000101000010000000000000000000000000000000000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_half_moon_shape_eyes_smiling, '001111000111100011111101111110010000101000010000000000000000001100000001100000110000011000000011111110000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_half_moon_shape_eyes_closed, '000000000000000000000000000000000000000000000010000101000010011111101111110001111000111100000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_sad_expression, '000000000000000000010000010000000100000001000001000000000100010110000011010000110000011000000110000011000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_sullen, '000000000000000001100000001100011110000011110011110000011110001100111001100000001111100000000011000110000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_crying_eyes, '000000000000000000000000000000011111000111110001010000010100001010000010100001010000010100000000000000000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_melancholy_look, '011111000111110001100000001100001100000001100000001111100000000011000110000000110000011000000100000001000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_angry_eyes, '100000000000001010000000000010001000000000100000100000001000011010000010110011001000100110011000000000110'], + [Lang.Blocks.robokit_rs_dotmatrix_example_o_shape_mouth, '000000000000000001100000001100011010000011010011110000011110001100010001100000000010000000000001111100000'], + [Lang.Blocks.robokit_rs_dotmatrix_example_yo_shape_mouth, '000000000000000010001000100010010001000100010001110000011100000000000000000000000101000000000000111000000'], + ['↑', '000000010000000000000111000000000001010100000000000010000000000000010000000000000010000000000000010000000'], + ['↗', '000000011110000000000000110000000000001010000000000010010000000000100000000000001000000000000010000000000'], + ['→', '000000000000000000000001000000000000000100000000011111110000000000000100000000000001000000000000000000000'], + ['↘', '000010000000000000001000000000000000100000000000000010010000000000001010000000000000110000000000011110000'], + ['↓', '000000010000000000000010000000000000010000000000000010000000000001010100000000000111000000000000010000000'], + ['↙', '000000000010000000000000100000000000001000000000010010000000000010100000000000011000000000000011110000000'], + ['←', '000000000000000000000100000000000001000000000000011111110000000001000000000000000100000000000000000000000'], + ['↖', '000011110000000000011000000000000010100000000000010010000000000000001000000000000000100000000000000010000'], + ], + value: '000000000000000000000011000000000000010100000000000010100000000001110100000000011110000000000001100000000', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + null, + ], + type: 'robokit_rs_set_dotmatrix', + }, + paramsKeyMap: { + MATRIX: 0 + }, + class: 'looks_dot_matrix', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.set_dotmatrix(sprite, script) + }, + robokit_rs_clear_dotmatrix: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + ], + type: 'robokit_rs_clear_dotmatrix', + }, + paramsKeyMap: {}, + class: 'looks_dot_matrix', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.clear_dotmatrix(sprite, script) + }, + robokit_rs_play_piezobuzzer: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ['8', '8'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_piezobuzzer_tone_c, '0'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_c_sharp, '1'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_d, '2'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_d_sharp, '3'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_e, '4'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_f, '5'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_f_sharp, '6'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_g, '7'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_g_sharp, '8'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_a, '9'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_a_sharp, '10'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_b, '11'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin' + }, + null, + null, + { + type: 'number', + params: ['0.5'], + }, + null, + + ], + type: 'robokit_rs_play_piezobuzzer', + }, + paramsKeyMap: { + PIN: 0, + OCTAVE: 1, + NOTE: 2, + DURATION: 3, + }, + class: 'sound', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.play_piezobuzzer(sprite, script) + }, + robokit_rs_play_piezobuzzer_until_done: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ['8', '8'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_piezobuzzer_tone_c, '0'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_c_sharp, '1'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_d, '2'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_d_sharp, '3'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_e, '4'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_f, '5'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_f_sharp, '6'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_g, '7'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_g_sharp, '8'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_a, '9'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_a_sharp, '10'], + [Lang.Blocks.robokit_rs_piezobuzzer_tone_b, '11'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin' + }, + null, + null, + { + type: 'number', + params: ['0.5'], + }, + null, + + ], + type: 'robokit_rs_play_piezobuzzer_until_done', + }, + paramsKeyMap: { + PIN: 0, + OCTAVE: 1, + NOTE: 2, + DURATION: 3, + }, + class: 'sound', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.play_piezobuzzer_until_done(sprite, script) + }, + robokit_rs_get_digital_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin', + }, + ], + type: 'robokit_rs_get_digital_value', + }, + paramsKeyMap: { + PIN: 0, + }, + class: 'sensing', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.get_digital_value(sprite, script), + }, + robokit_rs_get_analog_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_analog_pin', + }, + ], + type: 'robokit_rs_get_analog_value', + }, + paramsKeyMap: { + PIN: 0, + }, + class: 'sensing', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.get_analog_value(sprite, script), + }, + robokit_rs_get_sensor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_sensor_temperutre, 'temperature'], + [Lang.Blocks.robokit_rs_sensor_joystick_x, 'joystickx'], + [Lang.Blocks.robokit_rs_sensor_joystick_y, 'joysticky'], + [Lang.Blocks.robokit_rs_sensor_light, 'light'], + [Lang.Blocks.robokit_rs_sensor_dial, 'dial'], + [Lang.Blocks.robokit_rs_sensor_a_keypad, 'akeypad'], + [Lang.Blocks.robokit_rs_sensor_rotaryposition, 'rotaryposition'], + [Lang.Blocks.robokit_rs_sensor_magnetic, 'magnetic'], + [Lang.Blocks.robokit_rs_sensor_ultrasonic, 'ultrasonic'], + ], + value: 'temperature', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_pin', + }, + null, + ], + type: 'robokit_rs_get_sensor_value', + }, + paramsKeyMap: { + PIN: 0, + SENSOR: 1, + }, + class: 'sensing', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.get_sensor_value(sprite, script) + }, + robokit_rs_is_digital_detected: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_digital_pin', + }, + ], + type: 'robokit_rs_is_digital_detected', + }, + paramsKeyMap: { + PIN: 0, + }, + class: 'sensing', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.is_digital_detected(sprite, script), + }, + robokit_rs_compare_analog_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + ['>', 'greater-than'], + ['=', 'equal'], + ['<', 'less-than'], + ], + value: 'greater-than', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_analog_pin', + }, + null, + { + type: 'number', + params: ['512'], + }, + ], + type: 'robokit_rs_compare_analog_value', + }, + paramsKeyMap: { + PIN: 0, + SYMBOL: 1, + VALUE: 2, + }, + class: 'sensing', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.compare_analog_value(sprite, script), + }, + robokit_rs_compare_sensor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_sensor_temperutre, 'temperature'], + [Lang.Blocks.robokit_rs_sensor_joystick_x, 'joystickx'], + [Lang.Blocks.robokit_rs_sensor_joystick_y, 'joysticky'], + [Lang.Blocks.robokit_rs_sensor_light, 'light'], + [Lang.Blocks.robokit_rs_sensor_dial, 'dial'], + [Lang.Blocks.robokit_rs_sensor_a_keypad, 'akeypad'], + [Lang.Blocks.robokit_rs_sensor_rotaryposition, 'rotaryposition'], + [Lang.Blocks.robokit_rs_sensor_magnetic, 'magnetic'], + [Lang.Blocks.robokit_rs_sensor_ultrasonic, 'ultrasonic'], + ], + value: 'temperature', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['>', 'greater-than'], + ['=', 'equal'], + ['<', 'less-than'], + ], + value: 'greater-than', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_pin', + }, + null, + null, + { + type: 'number', + params: ['0'], + }, + ], + type: 'robokit_rs_compare_sensor_value', + }, + paramsKeyMap: { + PIN: 0, + SENSOR: 1, + SYMBOL: 2, + VALUE: 3, + }, + class: 'sensing', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.compare_sensor_value(sprite, script), + }, + robokit_rs_get_gyro_sensor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_sensor_gyroscope_angle_x, "anglex"], + [Lang.Blocks.robokit_rs_sensor_gyroscope_angle_y, "angley"], + [Lang.Blocks.robokit_rs_sensor_gyroscope_angle_z, "anglez"], + [Lang.Blocks.robokit_rs_sensor_gyroscope_x, "gyrox"], + [Lang.Blocks.robokit_rs_sensor_gyroscope_y, "gyroy"], + [Lang.Blocks.robokit_rs_sensor_gyroscope_z, "gyroz"], + [Lang.Blocks.robokit_rs_sensor_gyroscope_shake, "shake"] + ], + value: 'anglex', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null, + null, + ], + type: 'robokit_rs_get_gyro_sensor_value', + }, + paramsKeyMap: { + PROPERTY: 0, + }, + class: 'sensing_gyro_sensor', + isNotFor: ['roborobo_robokit_rs'], + + func: (sprite, script) => this.get_gyro_sensor_value(sprite, script), + }, + robokit_rs_is_shaken_gyro_sensor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_boolean_field', + statements: [], + params: [], + events: {}, + def: { + params: [], + type: 'robokit_rs_is_shaken_gyro_sensor', + }, + paramsKeyMap: {}, + class: 'sensing_gyro_sensor', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.is_shaken_gyro_sensor(sprite, script) + }, + robokit_rs_reset_gyro_sensor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_sensor_gyroscope_direction_up, 'up'], + [Lang.Blocks.robokit_rs_sensor_gyroscope_direction_forward, 'forward'], + [Lang.Blocks.robokit_rs_sensor_gyroscope_direction_right, 'right'], + [Lang.Blocks.robokit_rs_sensor_gyroscope_direction_backward, 'backward'], + [Lang.Blocks.robokit_rs_sensor_gyroscope_direction_left, 'left'] + ], + value: 'up', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + null, + ], + type: 'robokit_rs_reset_gyro_sensor', + }, + paramsKeyMap: { + DIRECTION: 0, + }, + class: 'sensing_gyro_sensor', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.reset_gyro_sensor(sprite, script) + }, + + robokit_rs_get_rotary_position_sensor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_sensor_rotaryposition_rotation, 'rotation'], + [Lang.Blocks.robokit_rs_sensor_rotaryposition_position, 'position'], + [Lang.Blocks.robokit_rs_sensor_rotaryposition_angle, 'angle'] + ], + value: 'rotation', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_analog_pin', + }, + null, + ], + type: 'robokit_rs_get_rotary_position_sensor_value', + }, + paramsKeyMap: { + PIN: 0, + PROPERTY: 1, + }, + class: 'sensing_rotary_position_sensor', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.get_rotary_position_sensor_value(sprite, script) + }, + + robokit_rs_reset_rotary_position_sensor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robokit_rs_sensor_rotaryposition_rotation, 'rotation'], + [Lang.Blocks.robokit_rs_sensor_rotaryposition_position, 'position'], + [Lang.Blocks.robokit_rs_sensor_rotaryposition_angle, 'angle'] + ], + value: 'rotation', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'robokit_rs_menu_analog_pin', + }, + null, + { + type: 'number', + params: ['0'], + }, + null, + ], + type: 'robokit_rs_reset_rotary_position_sensor', + }, + paramsKeyMap: { + PIN: 0, + PROPERTY: 1, + VALUE: 2, + }, + class: 'sensing_rotary_position_sensor', + isNotFor: ['roborobo_robokit_rs'], + func: (sprite, script) => this.reset_rotary_position_sensor(sprite, script) + }, + }; + }; + + setZero () { + super.setZero(); + } + + afterReceive (data) { + super.afterReceive(data); + } + + afterSend () { + super.afterSend(); + } + + request (func, subkey, value, updateNow = false) { + super.request(func, subkey, value, updateNow); + } + + /** + * -----------------------------------block execute----------------------------------- + * 공통 사용 함수를 제외한 나머지 블록 동작을 작성 + * ----------------------------------------------------------------------------------- + */ + + set_mecanumwheels (sprite, script) { + const speed = script.getNumberValue('SPEED'); + const state = script.getStringValue('STATE'); + + let data = [] + for (let i = 0; i < 4; i++) { + data[i] = {motor: i + 1, speed: speed, state: 0} + } + + switch (state) { + case '0': { + data[0].state = 2; + data[1].state = 1; + data[2].state = 2; + data[3].state = 1; + } + break; + case '45': { + data[0].state = 2; + data[3].state = 1; + } + break; + case '90': { + data[0].state = 2; + data[1].state = 2; + data[2].state = 1; + data[3].state = 1; + } + break; + case '135': { + data[1].state = 2; + data[2].state = 1; + } + break; + case '180': { + data[0].state = 1; + data[1].state = 2; + data[2].state = 1; + data[3].state = 2; + } + break; + case '225': { + data[0].state = 1; + data[3].state = 2; + } + break; + case '270': { + data[0].state = 1; + data[1].state = 1; + data[2].state = 2; + data[3].state = 2; + } + break; + case '315': { + data[1].state = 1; + data[2].state = 2; + } + break; + case 'cw': { + data[0].state = 2; + data[1].state = 2; + data[2].state = 2; + data[3].state = 2; + } + break; + case 'ccw': { + data[0].state = 1; + data[1].state = 1; + data[2].state = 1; + data[3].state = 1; + } + break; + case 'stop': + break; + } + + for (let i = 0; i < 4; i++) { + this.request('setMotor', i + 1, data[i]); + } + return script.callReturn(); + } + + set_dot_state_of_dotmatrix (sprite, script) { + const x = script.getNumberValue('X'); + const y = script.getNumberValue('Y'); + const state = script.getNumberValue('STATE'); + if (x < 0 || x > 14 || y < 0 || y > 6) return script.callReturn(); + + this.request('setDotMatrix', null, {type: 'dot', x, y, dot: Math.min(1, Math.max(0, state)).toString()}, true); + return script.callReturn(); + } + + set_dotmatrix_row (sprite, script) { + const y = script.getNumberValue('Y'); + let dots = ''; + for (let i = 0; i < 16; i++) { + const value = script.getNumberValue('X' + i); + dots += Math.max(0, Math.min(1, value)).toString(); + } + + this.request('setDotMatrix', null, {type: 'row', y, dots}, true); + return script.callReturn(); + } + + set_dotmatrix (sprite, script) { + const example = script.getStringValue('MATRIX') + this.request('setDotMatrix', null, {type: 'all', dots: example}, true); + return script.callReturn(); + } + + clear_dotmatrix (sprite, script) { + const length = 15 * 7; + let dots = ''; + for (let i = 0; i < length; i++) {dots += 0;} + + this.request('setDotMatrix', null, {type: 'all', dots}); + return script.callReturn(); + } + + get_gyro_sensor_value (sprite, script) { + const type = script.getStringValue('PROPERTY'); + + const obj = this.state.rx.gyro; + if (!this.isEqualsPinMode(18, PinMode.I2C) || !this.isEqualsPinMode(19, PinMode.I2C) || !obj || !obj.enable) { + this.request('enableGyroSensor', null, null, true); + } + + if (!obj) return 0; + switch (type) { + case 'anglex': return obj.angle.x; + case 'angley': return obj.angle.y; + case 'anglez': return obj.angle.z; + case 'gyrox': return obj.gyro.x; + case 'gyroy': return obj.gyro.y; + case 'gyroz': return obj.gyro.z; + case 'shake': return obj.shake; + default: return 0; + } + } + + is_shaken_gyro_sensor (sprite, script) { + const obj = this.state.rx.gyro; + + if (!this.isEqualsPinMode(18, PinMode.I2C) || !this.isEqualsPinMode(19, PinMode.I2C) || !obj || !obj.enable) { + this.request('enableGyroSensor', null, null, true); + } + + return obj ? obj.shake == 1 : false; + } + + reset_gyro_sensor (sprite, script) { + const dir = script.getStringValue('DIRECTION'); + let dirNum = 0; + switch (dir) { + case 'up': + dirNum = 0; + break; + case 'forward': + dirNum = 1; + break; + case 'right': + dirNum = 2; + break; + case 'backward': + dirNum = 3; + break; + case 'left': + dirNum = 4; + break; + } + this.request('resetGyroSensor', null, {direction: dirNum}, true); + return new Promise(resolve => setTimeout(() => resolve(), 500)); + } +} + +module.exports = new RobokitRS(); \ No newline at end of file diff --git a/src/playground/blocks/hardware/block_roborobo_roduino.js b/src/playground/blocks/hardware/block_roborobo_roduino.js new file mode 100644 index 0000000000..034c6e2bad --- /dev/null +++ b/src/playground/blocks/hardware/block_roborobo_roduino.js @@ -0,0 +1,1340 @@ +'use strict'; +const {ArduinoBase} = require('./block_roborobo_base.js'); + +class Roduino extends ArduinoBase { + constructor () { + super(); + + this.id = '10.1'; + this.name = 'roborobo_roduino'; + this.url = 'http://www.roborobo.co.kr'; + this.imageName = 'roborobo_roduino.png'; + this.title = { + ko: '로두이노', + en: 'Roduino', + } + this.blockMenuBlocks = this.getBlockMenuBlocks(); + } + + /** + * 언어 번역 사용을 위해 함수 형태로 유지 + */ + monitorTemplate () { + return { + //imgPath: 'hw/~~.png', + //width: 256, + //height: 256, + // 모니터 화면 상단에 차례대로 나열하는 값 + listPorts: { + digital_2: {name: (Lang.Blocks.monitor_digital + ': 2'), type: 'input', pos: {x: 0, y: 0, }}, + digital_3: {name: (Lang.Blocks.monitor_digital + ': 3'), type: 'input', pos: {x: 0, y: 0, }}, + digital_4: {name: (Lang.Blocks.monitor_digital + ': 4'), type: 'input', pos: {x: 0, y: 0, }}, + digital_5: {name: (Lang.Blocks.monitor_digital + ': 5'), type: 'input', pos: {x: 0, y: 0, }}, + digital_6: {name: (Lang.Blocks.monitor_digital + ': 6'), type: 'input', pos: {x: 0, y: 0, }}, + digital_7: {name: (Lang.Blocks.monitor_digital + ': 7'), type: 'input', pos: {x: 0, y: 0, }}, + digital_8: {name: (Lang.Blocks.monitor_digital + ': 8'), type: 'input', pos: {x: 0, y: 0, }}, + analog_0: {name: (Lang.Blocks.monitor_analog + ': A0'), type: 'input', pos: {x: 0, y: 0, }}, + analog_1: {name: (Lang.Blocks.monitor_analog + ': A1'), type: 'input', pos: {x: 0, y: 0, }}, + analog_2: {name: (Lang.Blocks.monitor_analog + ': A2'), type: 'input', pos: {x: 0, y: 0, }}, + analog_3: {name: (Lang.Blocks.monitor_analog + ': A3'), type: 'input', pos: {x: 0, y: 0, }}, + analog_4: {name: (Lang.Blocks.monitor_analog + ': A4'), type: 'input', pos: {x: 0, y: 0, }}, + analog_5: {name: (Lang.Blocks.monitor_analog + ': A5'), type: 'input', pos: {x: 0, y: 0, }}, + }, + // 모니터 화면 지정 위치와 선으로 연결하여 표시하는 값 + ports: {}, + mode: 'both', + } + } + + getBlockMenuBlocks () { + return [ + 'roduino_menu_digital_pin', + 'roduino_menu_analog_pin', + 'roduino_menu_pin', + 'roduino_menu_digital_value', + 'roduino_menu_motor_number', + + 'roduino_set_digital', + 'roduino_set_motor_rotation', + 'roduino_set_rgbled_color', + 'roduino_change_rgbled_brightness_by', + 'roduino_set_rgbled_brightness_to', + 'roduino_play_piezobuzzer', + 'roduino_play_piezobuzzer_until_done', + 'roduino_get_digital_value', + 'roduino_get_analog_value', + 'roduino_get_sensor_value', + 'roduino_is_digital_detected', + 'roduino_compare_analog_value', + 'roduino_compare_sensor_value', + 'roduino_get_rotary_position_sensor_value', + 'roduino_reset_rotary_position_sensor', + 'roduino_get_color_sensor_detected_value', + 'roduino_is_color_sensor_detected', + 'roduino_set_color_sensor_pins', + ]; + } + + setLanguage () { + return { + ko: { + template: { + roduino_menu_digital_pin: '%1', + roduino_menu_analog_pin: '%1', + roduino_menu_pin: '%1', + roduino_menu_digital_value: '%1', + roduino_menu_motor_number: '%1', + + roduino_set_digital: '%1 번 핀 디지털 값을 %2 (으)로 정하기 %3', + roduino_set_motor_rotation: '%1 번 모터를 %2 하기 %3', + roduino_set_rgbled_color: '%1 번 핀 RGB LED 색상을 %2 색으로 정하기 %3', + roduino_change_rgbled_brightness_by: '%1 번 핀 RGB LED 밝기를 %2 만큼 바꾸기 %3', + roduino_set_rgbled_brightness_to: '%1 번 핀 RGB LED 밝기를 %2 %로 정하기 %3', + roduino_play_piezobuzzer: '%1 번 핀 피에조 버저로 %2 옥타브 %3 음을 %4 초 소리내기 %5', + roduino_play_piezobuzzer_until_done: '%1 번 핀 피에조 버저로 %2 옥타브 %3 음을 %4 초 소리내며 기다리기 %5', + roduino_get_digital_value: '%1 번 핀 디지털 값', + roduino_get_analog_value: '%1 번 핀 아날로그 값', + roduino_get_sensor_value: '%1 번 핀 %2 값', + roduino_is_digital_detected: '%1 번 핀이 감지되었는가?', + roduino_compare_analog_value: '%1 번 핀 아날로그 값 %2 %3', + roduino_compare_sensor_value: '%1 번 핀 %2 값 %3 %4', + roduino_get_rotary_position_sensor_value: '%1 번 핀 회전 위치 센서 %2 값', + roduino_reset_rotary_position_sensor: '%1 번 핀 회전 위치 센서 %2 값을 %3 (으)로 정하기 %4', + roduino_get_color_sensor_detected_value: '%1 감지 값', + roduino_is_color_sensor_detected: '%1 이 감지되었는가?', + roduino_set_color_sensor_pins: '컬러 센서 핀을 R: %1 G: %2 B: %3 번으로 정하기 %4', + }, + Blocks: { + monitor_digital: '디지털', + monitor_analog: '아날로그', + + roduino_motor_state_cw: '시계 방향 회전', + roduino_motor_state_ccw: '시계 반대 방향 회전', + roduino_motor_state_stop: '정지', + + roduino_piezobuzzer_tone_c: '도', + roduino_piezobuzzer_tone_c_sharp: '도♯(레♭)', + roduino_piezobuzzer_tone_d: '레', + roduino_piezobuzzer_tone_d_sharp: '레♯(미♭)', + roduino_piezobuzzer_tone_e: '미', + roduino_piezobuzzer_tone_f: '파', + roduino_piezobuzzer_tone_f_sharp: '파♯(솔♭)', + roduino_piezobuzzer_tone_g: '솔', + roduino_piezobuzzer_tone_g_sharp: '솔♯(라♭)', + roduino_piezobuzzer_tone_a: '라', + roduino_piezobuzzer_tone_a_sharp: '라♯(시♭)', + roduino_piezobuzzer_tone_b: '시', + + roduino_sensor_temperutre: '온도 센서', + roduino_sensor_joystick_x: '조이스틱 x', + roduino_sensor_joystick_y: '조이스틱 y', + roduino_sensor_light: '빛 센서', + roduino_sensor_dial: '다이얼', + roduino_sensor_a_keypad: 'A 키패드', + roduino_sensor_rotaryposition: '회전 위치 센서', + roduino_sensor_magnetic: '자기 센서', + roduino_sensor_ultrasonic: '초음파 센서', + + roduino_sensor_rotaryposition_rotation: '회전', + roduino_sensor_rotaryposition_position: '위치', + roduino_sensor_rotaryposition_angle: '각도', + + roduino_sensor_color_red: '빨간색', + roduino_sensor_color_yellow: '노란색', + roduino_sensor_color_green: '초록색', + roduino_sensor_color_blue: '파란색', + }, + }, + en: { + template: { + roduino_menu_digital_pin: '%1', + roduino_menu_analog_pin: '%1', + roduino_menu_pin: '%1', + roduino_menu_digital_value: '%1', + roduino_menu_motor_number: '%1', + + roduino_set_digital: 'set pin %1 digital value to %2 %3', + roduino_set_motor_rotation: 'set %1 the %2 motor %3', + roduino_set_rgbled_color: 'set %1 pin RGB LED color to the %2 color %3', + roduino_change_rgbled_brightness_by: 'change pin %1 RGB LED brightness by %2 %3', + roduino_set_rgbled_brightness_to: 'set pin %1 RGB LED brightness to %2 % %3', + roduino_play_piezobuzzer: 'Play pin %1 peizo buzzer with %2 otave %3 note for %4 sec %5', + roduino_play_piezobuzzer_until_done: 'Play pin %1 peizo buzzer with %2 otave %3 note for %4 sec and wait %5', + roduino_get_digital_value: 'pin %1 digital value', + roduino_get_analog_value: 'pin %1 analog value', + roduino_get_sensor_value: 'pin %1 %2 value', + roduino_is_digital_detected: 'pin %1 detected?', + roduino_compare_analog_value: 'pin %1 analog value %2 %3', + roduino_compare_sensor_value: 'pin %1 %2 value %3 %4', + roduino_get_rotary_position_sensor_value: 'rotary position sensor of pin %1 %2 value', + roduino_reset_rotary_position_sensor: 'rotary position sensor of pin %1 set %2 value to %3 %4', + roduino_get_color_sensor_detected_value: '%1 detection value', + roduino_is_color_sensor_detected: 'is %1 detected?', + roduino_set_color_sensor_pins: 'set color sensor pins to R: %1 G: %2 B: %3 %4', + }, + Blocks: { + monitor_digital: 'Digital', + monitor_analog: 'Analog', + + roduino_motor_state_cw: 'rotate clockwise', + roduino_motor_state_ccw: 'rotate counterclockwise', + roduino_motor_state_stop: 'stop', + + roduino_piezobuzzer_tone_c: 'C', + roduino_piezobuzzer_tone_c_sharp: 'C♯(D♭)', + roduino_piezobuzzer_tone_d: 'D', + roduino_piezobuzzer_tone_d_sharp: 'D♯(E♭)', + roduino_piezobuzzer_tone_e: 'E', + roduino_piezobuzzer_tone_f: 'F', + roduino_piezobuzzer_tone_f_sharp: 'F♯(G♭)', + roduino_piezobuzzer_tone_g: 'G', + roduino_piezobuzzer_tone_g_sharp: 'G♯(A♭)', + roduino_piezobuzzer_tone_a: 'A', + roduino_piezobuzzer_tone_a_sharp: 'A♯(B♭)', + roduino_piezobuzzer_tone_b: 'B', + + roduino_sensor_temperutre: 'temperature sensor', + roduino_sensor_joystick_x: 'joystick x', + roduino_sensor_joystick_y: 'joystick y', + roduino_sensor_light: 'light sensor', + roduino_sensor_dial: 'dial', + roduino_sensor_a_keypad: 'A keypad', + roduino_sensor_rotaryposition: 'rotary position sensor', + roduino_sensor_magnetic: 'magnetic sensor', + roduino_sensor_ultrasonic: 'ultrasonic sensor', + + roduino_sensor_rotaryposition_rotation: 'rotation', + roduino_sensor_rotaryposition_position: 'position', + roduino_sensor_rotaryposition_angle: 'angle', + + roduino_sensor_color_red: 'red', + roduino_sensor_color_yellow: 'yellow', + roduino_sensor_color_green: 'green', + roduino_sensor_color_blue: 'blue', + }, + }, + }; + }; + + getBlocks () { + return { + roduino_menu_digital_pin: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ['8', '8'], + ], + value: '2', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PIN: 0, + }, + func: (sprite, script) => { + return script.getStringField('PIN'); + }, + }, + roduino_menu_analog_pin: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['A0', '14'], + ['A1', '15'], + ['A2', '16'], + ['A3', '17'], + ['A4', '18'], + ['A5', '19'], + ], + value: '14', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PIN: 0, + }, + func: (sprite, script) => { + return script.getStringField('PIN'); + }, + }, + roduino_menu_pin: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['A0', '14'], + ['A1', '15'], + ['A2', '16'], + ['A3', '17'], + ['A4', '18'], + ['A5', '19'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ['8', '8'], + ], + value: '14', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PIN: 0, + }, + func: (sprite, script) => { + return script.getStringField('PIN'); + }, + }, + roduino_menu_digital_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['0', '0'], + ['1', '1'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + NUM: 0, + }, + func: (sprite, script) => { + return script.getStringField('NUM'); + }, + }, + roduino_menu_motor_number: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'] + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + NUM: 0, + }, + func: (sprite, script) => { + return script.getStringField('NUM'); + }, + }, + roduino_set_digital: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + } + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin', + }, + { + type: 'roduino_menu_digital_value', + }, + null, + ], + type: 'roduino_set_digital', + }, + paramsKeyMap: { + PIN: 0, + VALUE: 1, + }, + class: 'motion', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.set_digital(sprite, script), + }, + roduino_set_motor_rotation: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_motor_state_cw, 'cw'], + [Lang.Blocks.roduino_motor_state_ccw, 'ccw'], + [Lang.Blocks.roduino_motor_state_stop, 'stop'], + ], + value: 'cw', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_motor_number' + }, + null, + null, + + ], + type: 'roduino_set_motor_rotation', + }, + paramsKeyMap: { + MOTOR: 0, + STATE: 1, + }, + class: 'motion', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.set_motor_rotation(sprite, script) + }, + roduino_set_rgbled_color: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Color', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin' + }, + null, + null, + + ], + type: 'roduino_set_rgbled_color', + }, + paramsKeyMap: { + PIN: 0, + COLOR: 1, + }, + class: 'looks', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.set_rgbled_color(sprite, script) + }, + roduino_change_rgbled_brightness_by: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin' + }, + { + type: 'number', + params: ['10'], + }, + null, + + ], + type: 'roduino_change_rgbled_brightness_by', + }, + paramsKeyMap: { + PIN: 0, + BRIGHTNESS: 1, + }, + class: 'looks', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.change_rgbled_brightness_by(sprite, script) + }, + roduino_set_rgbled_brightness_to: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin' + }, + { + type: 'number', + params: ['100'], + }, + null, + + ], + type: 'roduino_set_rgbled_brightness_to', + }, + paramsKeyMap: { + PIN: 0, + BRIGHTNESS: 1, + }, + class: 'looks', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.set_rgbled_brightness_to(sprite, script) + }, + roduino_play_piezobuzzer: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ['8', '8'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_piezobuzzer_tone_c, '0'], + [Lang.Blocks.roduino_piezobuzzer_tone_c_sharp, '1'], + [Lang.Blocks.roduino_piezobuzzer_tone_d, '2'], + [Lang.Blocks.roduino_piezobuzzer_tone_d_sharp, '3'], + [Lang.Blocks.roduino_piezobuzzer_tone_e, '4'], + [Lang.Blocks.roduino_piezobuzzer_tone_f, '5'], + [Lang.Blocks.roduino_piezobuzzer_tone_f_sharp, '6'], + [Lang.Blocks.roduino_piezobuzzer_tone_g, '7'], + [Lang.Blocks.roduino_piezobuzzer_tone_g_sharp, '8'], + [Lang.Blocks.roduino_piezobuzzer_tone_a, '9'], + [Lang.Blocks.roduino_piezobuzzer_tone_a_sharp, '10'], + [Lang.Blocks.roduino_piezobuzzer_tone_b, '11'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin' + }, + null, + null, + { + type: 'number', + params: ['0.5'], + }, + null, + + ], + type: 'roduino_play_piezobuzzer', + }, + paramsKeyMap: { + PIN: 0, + OCTAVE: 1, + NOTE: 2, + DURATION: 3, + }, + class: 'sound', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.play_piezobuzzer(sprite, script) + }, + roduino_play_piezobuzzer_until_done: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + ['1', '1'], + ['2', '2'], + ['3', '3'], + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ['8', '8'], + ], + value: '4', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_piezobuzzer_tone_c, '0'], + [Lang.Blocks.roduino_piezobuzzer_tone_c_sharp, '1'], + [Lang.Blocks.roduino_piezobuzzer_tone_d, '2'], + [Lang.Blocks.roduino_piezobuzzer_tone_d_sharp, '3'], + [Lang.Blocks.roduino_piezobuzzer_tone_e, '4'], + [Lang.Blocks.roduino_piezobuzzer_tone_f, '5'], + [Lang.Blocks.roduino_piezobuzzer_tone_f_sharp, '6'], + [Lang.Blocks.roduino_piezobuzzer_tone_g, '7'], + [Lang.Blocks.roduino_piezobuzzer_tone_g_sharp, '8'], + [Lang.Blocks.roduino_piezobuzzer_tone_a, '9'], + [Lang.Blocks.roduino_piezobuzzer_tone_a_sharp, '10'], + [Lang.Blocks.roduino_piezobuzzer_tone_b, '11'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin' + }, + null, + null, + { + type: 'number', + params: ['0.5'], + }, + null, + + ], + type: 'roduino_play_piezobuzzer_until_done', + }, + paramsKeyMap: { + PIN: 0, + OCTAVE: 1, + NOTE: 2, + DURATION: 3, + }, + class: 'sound', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.play_piezobuzzer_until_done(sprite, script) + }, + roduino_get_digital_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin', + }, + ], + type: 'roduino_get_digital_value', + }, + paramsKeyMap: { + PIN: 0, + }, + class: 'sensing', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.get_digital_value(sprite, script), + }, + roduino_get_analog_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_analog_pin', + }, + ], + type: 'roduino_get_analog_value', + }, + paramsKeyMap: { + PIN: 0, + }, + class: 'sensing', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.get_analog_value(sprite, script), + }, + roduino_get_sensor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_sensor_temperutre, 'temperature'], + [Lang.Blocks.roduino_sensor_joystick_x, 'joystickx'], + [Lang.Blocks.roduino_sensor_joystick_y, 'joysticky'], + [Lang.Blocks.roduino_sensor_light, 'light'], + [Lang.Blocks.roduino_sensor_dial, 'dial'], + [Lang.Blocks.roduino_sensor_a_keypad, 'akeypad'], + [Lang.Blocks.roduino_sensor_rotaryposition, 'rotaryposition'], + [Lang.Blocks.roduino_sensor_magnetic, 'magnetic'], + [Lang.Blocks.roduino_sensor_ultrasonic, 'ultrasonic'], + ], + value: 'temperature', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_pin', + }, + null, + ], + type: 'roduino_get_sensor_value', + }, + paramsKeyMap: { + PIN: 0, + SENSOR: 1, + }, + class: 'sensing', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.get_sensor_value(sprite, script) + }, + roduino_is_digital_detected: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin', + }, + ], + type: 'roduino_is_digital_detected', + }, + paramsKeyMap: { + PIN: 0, + }, + class: 'sensing', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.is_digital_detected(sprite, script), + }, + roduino_compare_analog_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + ['>', 'greater-than'], + ['=', 'equal'], + ['<', 'less-than'], + ], + value: 'greater-than', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_analog_pin', + }, + null, + { + type: 'number', + params: ['512'], + }, + ], + type: 'roduino_compare_analog_value', + }, + paramsKeyMap: { + PIN: 0, + SYMBOL: 1, + VALUE: 2, + }, + class: 'sensing', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.compare_analog_value(sprite, script), + }, + roduino_compare_sensor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_sensor_temperutre, 'temperature'], + [Lang.Blocks.roduino_sensor_joystick_x, 'joystickx'], + [Lang.Blocks.roduino_sensor_joystick_y, 'joysticky'], + [Lang.Blocks.roduino_sensor_light, 'light'], + [Lang.Blocks.roduino_sensor_dial, 'dial'], + [Lang.Blocks.roduino_sensor_a_keypad, 'akeypad'], + [Lang.Blocks.roduino_sensor_rotaryposition, 'rotaryposition'], + [Lang.Blocks.roduino_sensor_magnetic, 'magnetic'], + [Lang.Blocks.roduino_sensor_ultrasonic, 'ultrasonic'], + ], + value: 'temperature', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['>', 'greater-than'], + ['=', 'equal'], + ['<', 'less-than'], + ], + value: 'greater-than', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_pin', + }, + null, + null, + { + type: 'number', + params: ['0'], + }, + ], + type: 'roduino_compare_sensor_value', + }, + paramsKeyMap: { + PIN: 0, + SENSOR: 1, + SYMBOL: 2, + VALUE: 3, + }, + class: 'sensing', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.compare_sensor_value(sprite, script), + }, + + roduino_get_rotary_position_sensor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_sensor_rotaryposition_rotation, 'rotation'], + [Lang.Blocks.roduino_sensor_rotaryposition_position, 'position'], + [Lang.Blocks.roduino_sensor_rotaryposition_angle, 'angle'] + ], + value: 'rotation', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_analog_pin', + }, + null, + ], + type: 'roduino_get_rotary_position_sensor_value', + }, + paramsKeyMap: { + PIN: 0, + PROPERTY: 1, + }, + class: 'sensing_rotary_position_sensor', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.get_rotary_position_sensor_value(sprite, script) + }, + + roduino_reset_rotary_position_sensor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_sensor_rotaryposition_rotation, 'rotation'], + [Lang.Blocks.roduino_sensor_rotaryposition_position, 'position'], + [Lang.Blocks.roduino_sensor_rotaryposition_angle, 'angle'] + ], + value: 'rotation', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defualtType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_analog_pin', + }, + null, + { + type: 'number', + params: ['0'], + }, + null, + ], + type: 'roduino_reset_rotary_position_sensor', + }, + paramsKeyMap: { + PIN: 0, + PROPERTY: 1, + VALUE: 2, + }, + class: 'sensing_rotary_position_sensor', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.reset_rotary_position_sensor(sprite, script) + }, + roduino_get_color_sensor_detected_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_sensor_color_red, '#FF0000'], + [Lang.Blocks.roduino_sensor_color_yellow, '#FFEE00'], + [Lang.Blocks.roduino_sensor_color_green, '#00AA00'], + [Lang.Blocks.roduino_sensor_color_blue, '#0055FF'], + ], + value: '#FF0000', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null, + ], + type: 'roduino_get_color_sensor_detected_value', + }, + paramsKeyMap: { + COLOR: 0, + }, + class: 'sensing_color_sensor', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.get_color_sensor_detected_value(sprite, script) + }, + roduino_is_color_sensor_detected: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roduino_sensor_color_red, '#FF0000'], + [Lang.Blocks.roduino_sensor_color_yellow, '#FFEE00'], + [Lang.Blocks.roduino_sensor_color_green, '#00AA00'], + [Lang.Blocks.roduino_sensor_color_blue, '#0055FF'], + ], + value: '#FF0000', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + null, + ], + type: 'roduino_is_color_sensor_detected', + }, + paramsKeyMap: { + COLOR: 0, + }, + class: 'sensing_color_sensor', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.is_color_sensor_detected(sprite, script) + }, + roduino_set_color_sensor_pins: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'roduino_menu_digital_pin', + params: ['6'], + }, + { + type: 'roduino_menu_digital_pin', + params: ['7'], + }, + { + type: 'roduino_menu_digital_pin', + params: ['8'], + }, + null, + ], + type: 'roduino_set_color_sensor_pins', + }, + paramsKeyMap: { + RED: 0, + GREEN: 1, + BLUE: 2, + }, + class: 'sensing_color_sensor', + isNotFor: ['roborobo_roduino'], + func: (sprite, script) => this.set_color_sensor_pins(sprite, script) + }, + }; + }; + + setZero () { + super.setZero(); + } + + afterReceive (data) { + super.afterReceive(data); + } + + afterSend () { + super.afterSend(); + } + + request (func, subkey, value, updateNow = false) { + super.request(func, subkey, value, updateNow); + } + + resetState () { + super.resetState(); + this.state.tx = {color: {pins: {r: -1, g: -1, b: -1}}}; + } + + /** + * -----------------------------------block execute----------------------------------- + * 공통 사용 함수를 제외한 나머지 블록 동작을 작성 + * ----------------------------------------------------------------------------------- + */ + + set_motor_rotation (sprite, script) { + const motor = script.getNumberValue('MOTOR'); + const state = script.getStringValue('STATE'); + + let stateNum = 0; + if (state == 'cw') stateNum = 1; + else if (state == 'ccw') stateNum = 2; + + this.request('setMotor', motor, {motor, speed: 0, state: stateNum}); + return script.callReturn(); + } + + get_color_sensor_detected_value (sprite, script) { + const color = script.getStringValue('COLOR'); + return this._isColorSensorDetected(color) ? 1 : 0; + } + + is_color_sensor_detected (sprite, script) { + const color = script.getStringValue('COLOR'); + return this._isColorSensorDetected(color); + } + + _isColorSensorDetected (color) { + const pins = this.state.tx.color.pins; + if (!pins || !this.isDigitalPin(pins.r) || !this.isDigitalPin(pins.g) || !this.isDigitalPin(pins.b)) return false; + + const r = this.getDigitalValue(pins.r); + const g = this.getDigitalValue(pins.g); + const b = this.getDigitalValue(pins.b); + + switch (color) { + case '#FF0000': + return r == 1 && g == 0 && b == 0; + case '#00AA00': + return r == 0 && g == 1 && b == 0; + case '#0055FF': + return r == 0 && g == 0 && b == 1; + case '#FFEE00': + return r == 1 && g == 1 && b == 1; + } + return false; + } + + set_color_sensor_pins (sprite, script) { + const r = this.pinToNumber(script.getStringValue('RED')); + const g = this.pinToNumber(script.getStringValue('GREEN')); + const b = this.pinToNumber(script.getStringValue('BLUE')); + + const colorPins = this.state.tx.color.pins; + if (!colorPins) return; + + if (colorPins.r != r) { + this.request('enableDigitalInput', r, {pin: r}); + colorPins.r = r; + } + if (colorPins.g != g) { + this.request('enableDigitalInput', g, {pin: g}); + colorPins.g = g; + } + if (colorPins.b != b) { + this.request('enableDigitalInput', b, {pin: b}, true); + colorPins.b = b; + } + } +} + +module.exports = new Roduino(); \ No newline at end of file diff --git a/src/playground/blocks/hardware/block_roborobo_roe.js b/src/playground/blocks/hardware/block_roborobo_roe.js new file mode 100644 index 0000000000..4ec189e542 --- /dev/null +++ b/src/playground/blocks/hardware/block_roborobo_roe.js @@ -0,0 +1,1146 @@ +'use strict'; + +Entry.Roborobo_RoE = { + id: '48.1', + name: 'roborobo_roe', + url: 'http://www.roborobo.co.kr', + imageName: 'roborobo_roe.png', + title: { + ko: '로이', + en: 'Ro-E', + }, + setZero: function () { + Entry.hw.sendQueue['LED'] = 0; + Entry.hw.sendQueue['Melody'] = [0, 0, 0]; //[octave, note, duration] + Entry.hw.sendQueue['LeftMotor'] = [0, 0]; //[direction, value] + Entry.hw.sendQueue['RightMotor'] = [0, 0]; //[direction, value] + Entry.hw.update(); + }, + motorDiretion: { + STOP: 0, + CW: 1, + CCW: 2 + }, + monitorTemplate: { + imgPath: 'hw/roborobo_roe.png', + keys: ['value'], + width: 256, + height: 256, + listPorts: { + lColor: { + name: 'Color Sensor(Left)', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + rColor: { + name: 'Color Sensor(Right)', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + ir: { + name: 'IR Sensor', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + switch: { + name: 'Switch Sensor', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + }, + mode: 'both', + }, +}; + +Entry.Roborobo_RoE.setLanguage = function () { + return { + ko: { + template: { + roe_set_led: '%1 LED 켜기 %2', + roe_set_led_off: 'LED 끄기 %1', + roe_set_motor: '로이 %1 %2', + roe_set_motor_value: '%1 모터 : %2 만큼 %3 %4', + roe_set_melody: '%1 옥타브 %2 을(를) %3 초 연주 %4', + roe_get_input_switch: '접촉센서가 %1 ?', + roe_get_input_ir: '적외선 센서가 %1 ?', + roe_get_input_color: '%1 컬러센서 값이 %2 인가?', + roe_led_color_dropdown: '%1', + roe_melody_dropdown: '%1', + roe_motor_dropdown: '%1', + roe_movement_dropdown: '%1', + roe_detect_dropdown: '%1', + roe_color_select_dropdown: '%1', + roe_color_color_dropdown: '%1', + }, + Blocks: { + roe_color_sensor_left: '왼쪽', + roe_color_sensor_right: '오른쪽', + roe_color_sensor_both: '양쪽', + roe_color_red: '빨간색', + roe_color_orange: '주황색', + roe_color_yellow: '노란색', + roe_color_yellowgreen: '연두색', + roe_color_green: '초록색', + roe_color_skyblue: '하늘색', + roe_color_blue: '파란색', + roe_color_purple: '보라색', + roe_color_pink: '분홍색', + roe_color_white: '흰색', + roe_color_black: '검정색', + roe_color_random: '무작위 색', + roe_color_none: '미감지', + roe_motor_both: '양쪽', + roe_motor_left: '왼쪽', + roe_motor_right: '오른쪽', + roe_move_forward: '전진', + roe_move_backward: '후진', + roe_move_turnleft: '좌회전', + roe_move_turnright: '우회전', + roe_move_stop: '정지', + roe_detected: '감지되었는가', + roe_undetected: '감지되지 않았는가', + roe_melody_do: '도', + roe_melody_doS: '도#', + roe_melody_re: '레', + roe_melody_miF: '미b', + roe_melody_mi: '미', + roe_melody_pa: '파', + roe_melody_paS: '파#', + roe_melody_sol: '솔', + roe_melody_solS: '솔#', + roe_melody_la: '라', + roe_melody_siF: '시b', + roe_melody_si: '시', + } + }, + en: { + template: { + roe_set_led: 'Turn on %1 LED %2', + roe_set_led_off: 'Turn off LED %1', + roe_set_motor: 'Ro-E %1 %2', + roe_set_motor_value: '%1 motor(s) : Move %3 by %2 %4', + roe_set_melody: 'Play %1 octave %2 tone for %3 second(s) %4', + roe_get_input_switch: 'Is the switch sensor %1 ?', + roe_get_input_ir: 'Is the IR sensor %1 ?', + roe_get_input_color: 'Is %1 color sensor value %2 ?', + roe_led_color_dropdown: '%1', + roe_melody_dropdown: '%1', + roe_motor_dropdown: '%1', + roe_movement_dropdown: '%1', + roe_detect_dropdown: '%1', + roe_color_select_dropdown: '%1', + roe_color_color_dropdown: '%1', + }, + Blocks: { + roe_color_sensor_left: 'left', + roe_color_sensor_right: 'right', + roe_color_sensor_both: 'both', + roe_color_red: 'Red', + roe_color_orange: 'Orange', + roe_color_yellow: 'Yellow', + roe_color_yellowgreen: 'Yellow Green', + roe_color_green: 'Green', + roe_color_skyblue: 'Sky Blue', + roe_color_blue: 'Blue', + roe_color_purple: 'Purple', + roe_color_pink: 'Pink', + roe_color_white: 'White', + roe_color_black: 'Black', + roe_color_random: 'Random', + roe_color_none: 'Undetected', + roe_motor_both: 'Both', + roe_motor_left: 'Left', + roe_motor_right: 'Right', + roe_move_forward: 'forward', + roe_move_backward: 'backward', + roe_move_turnleft: 'turn left', + roe_move_turnright: 'turn right', + roe_move_stop: 'stop', + roe_detected: 'detected', + roe_undetected: 'undetected', + roe_melody_do: 'C', + roe_melody_doS: 'C#', + roe_melody_re: 'D', + roe_melody_miF: 'Eb', + roe_melody_mi: 'E', + roe_melody_pa: 'F', + roe_melody_paS: 'F#', + roe_melody_sol: 'G', + roe_melody_solS: 'G#', + roe_melody_la: 'A', + roe_melody_siF: 'Bb', + roe_melody_si: 'B', + }, + }, + }; +}; + +Entry.Roborobo_RoE.blockMenuBlocks = [ + 'roe_set_led', + 'roe_set_led_off', + 'roe_set_motor', + 'roe_set_motor_value', + 'roe_set_melody', + 'roe_get_input_switch', + 'roe_get_input_ir', + 'roe_get_input_color', +]; + +Entry.Roborobo_RoE.getBlocks = function () { + return { + //region roe 로이 + roe_led_color_dropdown: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_color_red, 1], + [Lang.Blocks.roe_color_orange, 2], + [Lang.Blocks.roe_color_yellow, 3], + [Lang.Blocks.roe_color_yellowgreen, 4], + [Lang.Blocks.roe_color_green, 5], + [Lang.Blocks.roe_color_skyblue, 6], + [Lang.Blocks.roe_color_blue, 7], + [Lang.Blocks.roe_color_purple, 8], + [Lang.Blocks.roe_color_pink, 9], + [Lang.Blocks.roe_color_white, 10] + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + VALUE: 0, + }, + func: function (sprite, script) { + return script.getNumberField('VALUE'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_color_red, 1], + [Lang.Blocks.roe_color_orange, 2], + [Lang.Blocks.roe_color_yellow, 3], + [Lang.Blocks.roe_color_yellowgreen, 4], + [Lang.Blocks.roe_color_green, 5], + [Lang.Blocks.roe_color_skyblue, 6], + [Lang.Blocks.roe_color_blue, 7], + [Lang.Blocks.roe_color_purple, 8], + [Lang.Blocks.roe_color_pink, 9], + [Lang.Blocks.roe_color_white, 10] + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'roe_led_color_dropdown', + }, + ], + }, + }, + roe_melody_dropdown: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_melody_do, 1], + [Lang.Blocks.roe_melody_re, 2], + [Lang.Blocks.roe_melody_mi, 3], + [Lang.Blocks.roe_melody_pa, 4], + [Lang.Blocks.roe_melody_sol, 5], + [Lang.Blocks.roe_melody_la, 6], + [Lang.Blocks.roe_melody_si, 7], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + VALUE: 0, + }, + func: function (sprite, script) { + return script.getNumberField('VALUE', script); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_melody_do, 1], + [Lang.Blocks.roe_melody_re, 2], + [Lang.Blocks.roe_melody_mi, 3], + [Lang.Blocks.roe_melody_pa, 4], + [Lang.Blocks.roe_melody_sol, 5], + [Lang.Blocks.roe_melody_la, 6], + [Lang.Blocks.roe_melody_si, 7], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + keyOption: 'roe_melody_dropdown', + }, + ], + }, + }, + roe_motor_dropdown: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_motor_both, 1], + [Lang.Blocks.roe_motor_left, 2], + [Lang.Blocks.roe_motor_right, 3], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + VALUE: 0, + }, + func: function (sprite, script) { + return script.getNumberField('VALUE'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_motor_both, 1], + [Lang.Blocks.roe_motor_left, 2], + [Lang.Blocks.roe_motor_right, 3], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'roe_motor_dropdown', + }, + ], + }, + }, + roe_movement_dropdown: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_move_forward, 1], + [Lang.Blocks.roe_move_backward, 2], + [Lang.Blocks.roe_move_turnleft, 3], + [Lang.Blocks.roe_move_turnright, 4], + [Lang.Blocks.roe_move_stop, 5], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + VALUE: 0, + }, + func: function (sprite, script) { + return script.getNumberField('VALUE'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_move_forward, 1], + [Lang.Blocks.roe_move_backward, 2], + [Lang.Blocks.roe_move_turnleft, 3], + [Lang.Blocks.roe_move_turnright, 4], + [Lang.Blocks.roe_move_stop, 5], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'roe_movement_dropdown', + }, + ], + }, + }, + roe_detect_dropdown: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_detected, 1], + [Lang.Blocks.roe_undetected, 0], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + VALUE: 0, + }, + func: function (sprite, script) { + return script.getNumberField('VALUE'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_detected, 1], + [Lang.Blocks.roe_undetected, 2], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'roe_detect_dropdown', + }, + ], + }, + }, + roe_color_select_dropdown: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_color_sensor_both, 1], + [Lang.Blocks.roe_color_sensor_left, 2], + [Lang.Blocks.roe_color_sensor_right, 3], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + VALUE: 0, + }, + func: function (sprite, script) { + return script.getNumberField('VALUE'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_color_sensor_both, 1], + [Lang.Blocks.roe_color_sensor_left, 2], + [Lang.Blocks.roe_color_sensor_right, 3], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'roe_color_select_dropdown', + }, + ], + }, + }, + roe_color_color_dropdown: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_color_red, 1], + [Lang.Blocks.roe_color_orange, 2], + [Lang.Blocks.roe_color_yellow, 3], + [Lang.Blocks.roe_color_yellowgreen, 7], + [Lang.Blocks.roe_color_green, 4], + [Lang.Blocks.roe_color_skyblue, 8], + [Lang.Blocks.roe_color_blue, 5], + [Lang.Blocks.roe_color_purple, 6], + [Lang.Blocks.roe_color_pink, 9], + [Lang.Blocks.roe_color_black, 10], + [Lang.Blocks.roe_color_white, 11], + [Lang.Blocks.roe_color_none, 127], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + VALUE: 0, + }, + func: function (sprite, script) { + return script.getNumberField('VALUE'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roe_color_red, 1], + [Lang.Blocks.roe_color_orange, 2], + [Lang.Blocks.roe_color_yellow, 3], + [Lang.Blocks.roe_color_yellowgreen, 7], + [Lang.Blocks.roe_color_green, 4], + [Lang.Blocks.roe_color_skyblue, 8], + [Lang.Blocks.roe_color_blue, 5], + [Lang.Blocks.roe_color_purple, 6], + [Lang.Blocks.roe_color_pink, 9], + [Lang.Blocks.roe_color_black, 10], + [Lang.Blocks.roe_color_white, 11], + [Lang.Blocks.roe_color_none, 127], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'roe_color_color_dropdown', + }, + ], + }, + }, + roe_set_led: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string' + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12 + } + ], + events: {}, + def: { + params: [ + { + type: 'roe_led_color_dropdown', + }, + null + ], + type: 'roe_set_led', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'roe_set', + isNotFor: ['roborobo_roe'], + func: function (sprite, script) { + var color = script.getNumberValue('VALUE', script); + Entry.hw.sendQueue['LED'] = color; + }, + syntax: { + js: [], + py: [ + { + syntax: 'Roborobo_roe.roe_set_led(%1)', + textParams: [ + { + type: "Block", + accept: "string" + }, + { + type: 'roe_led_color_dropdown' + } + ], + }, + ], + }, + }, + roe_set_led_off: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: "Indicator", + img: "block_icon/hardware_icon.svg", + size: 12 + } + ], + events: {}, + def: { + params: [ + null + ], + type: 'roe_set_led_off' + }, + paramsKeyMap: {}, + class: 'roe_set', + isNotFor: ['roborobo_roe'], + func: function (sprite, script) { + Entry.hw.sendQueue['LED'] = 0; + }, + syntax: { + js: [], + py: ['Roborobo_roe.roe_set_led_off()'], + }, + }, + roe_set_melody: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['4', '4'], + ['5', '5'], + ['6', '6'], + ['7', '7'], + ], + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string' + }, + { + type: 'Block', + accept: 'string' + }, + { + type: "Indicator", + img: "block_icon/hardware_icon.svg", + size: 12 + } + ], + events: {}, + def: { + params: [ + '4', + { + type: 'roe_melody_dropdown', + }, + '1', + null + ], + type: 'roe_set_melody', + }, + paramsKeyMap: { + OCTAVE: 0, + NOTE: 1, + DURATION: 2 + }, + class: 'roe_set', + isNotFor: ['roborobo_roe'], + func: function (sprite, script) { + if (!script.isStart) { + var octave = script.getNumberValue('OCTAVE', script); + var note = script.getNumberValue('NOTE', script); + var duration = script.getNumberValue('DURATION', script); + + if (octave < 4) { + octave = 4; + } else if (octave > 7) { + octave = 7; + } + + if (note < 1) { + note = 1; + } else if (note > 7) { + note = 7; + } + duration = duration < 0 ? 0 : duration; + duration = duration * 1000; + + script.isStart = true; + script.timeFlag = 1; + + Entry.hw.sendQueue['Melody'] = [octave, note, duration]; + + setTimeout(function () { + script.timeFlag = 0; + }, duration); + return script; + } else if (script.timeFlag == 1) { + return script; + } else { + delete script.timeFlag; + delete script.isStart; + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'Roborobo_roe.roe_set_melody(%1 %2 %3)', + textParams: [ + '4', + { + type: 'roe_melody_dropdown', + }, + '1', + ], + }, + ], + }, + }, + roe_set_motor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: "Block", + accept: "string" + }, + { + type: "Indicator", + img: "block_icon/hardware_icon.svg", + size: 12 + } + ], + events: {}, + def: { + params: [ + { + type: 'roe_movement_dropdown' + }, + null + ], + type: 'roe_set_motor' + }, + paramsKeyMap: { + OPERATOR: 0, + }, + class: 'roe_set', + isNotFor: ['roborobo_roe'], + func: function (sprite, script) { + var op = script.getNumberValue('OPERATOR', script); + if (op == 1) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, 0]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, 0]; + } else if (op == 2) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, 0]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, 0]; + } else if (op == 3) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, 0]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, 0]; + } else if (op == 4) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, 0]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, 0]; + } else if (op == 5) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.STOP, 0]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.STOP, 0]; + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'Roborobo_roe.roe_set_motor(%1)', + textParams: [ + { + type: 'roe_movement_dropdown' + }, + ], + }, + ], + }, + }, + roe_set_motor_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: "Block", + accept: "string" + }, + { + type: "Block", + accept: "string" + }, + { + type: "Block", + accept: "string" + }, + { + type: "Indicator", + img: "block_icon/hardware_icon.svg", + size: 12 + } + ], + events: {}, + def: { + params: [ + { + type: 'roe_motor_dropdown' + }, + '100', + { + type: 'roe_movement_dropdown' + }, + null + ], + type: 'roe_set_motor_value' + }, + paramsKeyMap: { + MOTOR: 0, + VALUE: 1, + OPERATOR: 2, + }, + class: 'roe_set', + isNotFor: ['roborobo_roe'], + func: function (sprite, script) { + var motor = script.getNumberValue('MOTOR', script); + var value = script.getNumberValue('VALUE', script); + var op = script.getNumberValue('OPERATOR', script); + + if (value < 0) { + value = 0; + } else if (value > 100) { + value = 100; + } + + if (motor == 1) { + if (op == 1) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, value]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, value]; + } else if (op == 2) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, value]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, value]; + } else if (op == 3) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, value]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, value]; + } else if (op == 4) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, value]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, value]; + } else if (op == 5) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.STOP, value]; + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.STOP, value]; + } + } else if (motor == 2) { + if (op == 1) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, value]; + } else if (op == 2) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, value]; + } else if (op == 3) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, value]; + } else if (op == 4) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, value]; + } else if (op == 5) { + Entry.hw.sendQueue['LeftMotor'] = [Entry.Roborobo_RoE.motorDiretion.STOP, value]; + } + } else if (motor == 3) { + if (op == 1) { + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, value]; + } else if (op == 2) { + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, value]; + } else if (op == 3) { + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CW, value]; + } else if (op == 4) { + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.CCW, value]; + } else if (op == 5) { + Entry.hw.sendQueue['RightMotor'] = [Entry.Roborobo_RoE.motorDiretion.STOP, value]; + } + } + }, + syntax: { + js: [], + py: [ + { + syntax: 'Roborobo_roe.roe_set_motor_value(%1 %2 %3)', + textParams: [ + { + type: 'roe_motor_dropdown' + }, + '100', + { + type: 'roe_movement_dropdown' + }, + ], + }, + ], + }, + }, + roe_get_input_switch: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string' + }, + { + type: "Indicator", + img: "block_icon/hardware_icon.svg", + size: 12 + } + ], + events: {}, + def: { + params: [ + { + type: 'roe_detect_dropdown', + }, + null + ], + type: 'roe_get_input_switch' + }, + paramsKeyMap: { + DETECT: 0 + }, + class: 'roe_get', + isNotFor: ['roborobo_roe'], + func: function (sprite, script) { + var detect = script.getNumberValue('DETECT', script); + var value = Entry.hw.portData['Switch']; + // console.log('Switch Value : ' + value); + return detect == value ? true : false; + }, + syntax: { + js: [], + py: ['Roborobo_roe.roe_get_input_switch()'], + }, + }, + roe_get_input_ir: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string' + }, + { + type: "Indicator", + img: "block_icon/hardware_icon.svg", + size: 12 + } + ], + events: {}, + def: { + params: [ + { + type: 'roe_detect_dropdown', + }, + null + ], + type: 'roe_get_input_ir' + }, + paramsKeyMap: { + DETECT: 0 + }, + class: 'roe_get', + isNotFor: ['roborobo_roe'], + func: function (sprite, script) { + var detect = script.getNumberValue('DETECT', script); + var value = Entry.hw.portData['IR']; + // console.log('IR Value : ' + value); + return detect == value ? true : false; + }, + syntax: { + js: [], + py: ['Roborobo_roe.roe_get_input_ir()'], + }, + }, + roe_get_input_color: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_boolean_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string' + }, + { + type: 'Block', + accept: 'string' + }, + { + type: "Indicator", + img: "block_icon/hardware_icon.svg", + size: 12 + } + ], + events: {}, + def: { + params: [ + { + type: 'roe_color_select_dropdown', + }, + { + type: 'roe_color_color_dropdown', + }, + null + ], + type: 'roe_get_input_color' + }, + paramsKeyMap: { + SENSOR: 0, + COLOR: 1 + }, + class: 'roe_get', + isNotFor: ['roborobo_roe'], + func: function (sprite, script) { + var result = false; + var sensor = script.getNumberValue('SENSOR', script); + var color = script.getNumberValue('COLOR', script); + var left = Entry.hw.portData['LeftColor']; + var right = Entry.hw.portData['RightColor']; + + if (sensor == 1) { + if (left == color && right == color) { + result = true; + } + } else if (sensor == 2) { + result = left == color ? true : false; + } else if (sensor == 3) { + result = right == color ? true : false; + } + return result; + }, + syntax: { + js: [], + py: ['Roborobo_roe.roe_get_input_color()'], + }, + }, + //endregion roe 로이 + }; +}; + +module.exports = Entry.Roborobo_RoE; diff --git a/src/playground/blocks/hardware/block_roborobo_schoolkit.js b/src/playground/blocks/hardware/block_roborobo_schoolkit.js new file mode 100644 index 0000000000..fd91dadfda --- /dev/null +++ b/src/playground/blocks/hardware/block_roborobo_schoolkit.js @@ -0,0 +1,1946 @@ +'use strict'; + +Entry.Roborobo_SchoolKit = { + hasPracticalCourse: true, + id: '10.2', + name: 'roborobo_schoolkit', + url: 'http://www.roborobo.co.kr', + imageName: 'roborobo_schoolkit.png', + title: { + ko: '스쿨키트', + en: 'School Kit', + }, + pinMode: { + INPUT: 0, + OUTPUT: 1, + ANALOG: 2, + PWM: 3, + SERVO: 4, + }, + inputPort: { + ir: 7, + sound: 8, + contact: 9, + cds: 10, + }, + setZero: function () { + Entry.hw.sendQueue.digitalPinMode = []; + Entry.hw.sendQueue.previousValue = []; + + for (var port = 0; port < 14; port++) { + Entry.hw.sendQueue[port] = 0; + Entry.hw.sendQueue.digitalPinMode[port] = 0; + Entry.hw.sendQueue.previousValue[port] = -1; + } + Entry.hw.update(); + }, + monitorTemplate: { + imgPath: 'hw/roborobo_schoolkit.png', + keys: ['value'], + width: 256, + height: 256, + listPorts: { + '0': { + name: 'D1', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + '1': { + name: 'D2', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + '2': { + name: 'D3', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + '3': { + name: 'D4', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + '4': { + name: 'D5', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + '5': { + name: 'D6', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + '6': { + name: 'D7', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + }, + mode: 'both', + }, +}; + +Entry.Roborobo_SchoolKit.setLanguage = function () { + return { + ko: { + template: { + schoolkit_get_in_port_number: '%1 ', + schoolkit_get_out_port_number: '%1 ', + schoolkit_get_servo_port_number: '%1 ', + schoolkit_get_input_value: '디지털 %1 번 센서값 ', + schoolkit_set_output: '디지털 %1 번 핀 %2 %3', + schoolkit_motor: '%1 속도 %2(으)로 %3 %4', + schoolkit_set_servo_value: '서보모터 %1 번 핀 %2˚ %3', + schoolkit_on_block: ' On ', + schoolkit_off_block: ' Off ', + }, + }, + en: { + template: { + schoolkit_get_in_port_number: '%1 ', + schoolkit_get_out_port_number: '%1 ', + schoolkit_get_servo_port_number: '%1 ', + schoolkit_get_input_value: 'Digital %1 Sensor value ', + schoolkit_set_output: 'Digital %1 Pin %2 %3', + schoolkit_motor: '%1 Speed %2 %3 %4', + schoolkit_set_servo_value: 'Servo %1 Pin %2˚ %3', + schoolkit_on_block: ' On ', + schoolkit_off_block: ' Off ', + }, + }, + }; +}; + +Entry.Roborobo_SchoolKit.blockMenuBlocks = [ + 'schoolkit_on_block', + 'schoolkit_off_block', + 'schoolkit_get_input_value', + 'schoolkit_set_output', + 'schoolkit_motor', + 'schoolkit_set_servo_value', +]; + +Entry.Roborobo_SchoolKit.practicalBlockMenuBlocks = { + hw_motor: [ + // 'roborobo_motor_speed', + 'roborobo_move_for_secs', + 'roborobo_move_for', + 'roborobo_turn_for', + 'roborobo_stop_for', + ], + hw_melody: [ + + ], + hw_sensor: [ + 'roborobo_touch_value', + 'roborobo_touch_value_boolean', + 'roborobo_light_value', + 'roborobo_light_value_boolean', + 'roborobo_sound_value', + 'roborobo_sound_value_boolean', + 'roborobo_irs_value', + 'roborobo_irs_value_boolean', + ], + hw_led: [ + 'roborobo_diode_secs_toggle', + 'roborobo_diode_toggle', + 'roborobo_diode_inout_toggle', + 'roborobo_diode_set_output', + 'roborobo_diode_input_value', + ], +} + +Entry.Roborobo_SchoolKit.getBlocks = function () { + return { + //region schoolkit 스쿨키트 + schoolkit_on_block: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null], + type: 'schoolkit_on_block', + }, + paramsKeyMap: {}, + class: 'schoolkit_value', + isNotFor: ['roborobo_schoolkit'], + func: function (sprite, script) { + return '1'; + }, + syntax: { + js: [], + py: ['Roborobo_SchoolKit.schoolkit_on_block()'], + }, + }, + schoolkit_off_block: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null], + type: 'schoolkit_off_block', + }, + paramsKeyMap: {}, + class: 'schoolkit_value', + isNotFor: ['roborobo_schoolkit'], + func: function (sprite, script) { + return '0'; + }, + syntax: { + js: [], + py: ['Roborobo_SchoolKit.schoolkit_off_block()'], + }, + }, + schoolkit_get_out_port_number: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['OUT1', 2], + ['OUT2', 3], + ['OUT3', 4], + ['OUT4', 5], + ['OUT5', 6], + ], + value: 2, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PORT: 0, + }, + func: function (sprite, script) { + return script.getNumberField('PORT'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + ['OUT1', 2], + ['OUT2', 3], + ['OUT3', 4], + ['OUT4', 5], + ['OUT5', 6], + ], + value: 2, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'schoolkit_get_out_port_number', + }, + ], + }, + }, + schoolkit_get_servo_port_number: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['OUT1', 2], + ['OUT2', 3], + ['OUT3', 4], + ], + value: 2, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PORT: 0, + }, + func: function (sprite, script) { + return script.getNumberField('PORT'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + ['OUT1', 2], + ['OUT2', 3], + ['OUT3', 4], + ], + value: 2, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'schoolkit_get_servo_port_number', + }, + ], + }, + }, + schoolkit_get_in_port_number: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['IN1', 7], + ['IN2', 8], + ['IN3', 9], + ['IN4', 10], + ['IN5', 11], + ['IN6', 12], + ['IN7', 13], + ], + value: 7, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + PORT: 0, + }, + func: function (sprite, script) { + return script.getNumberField('PORT'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + ['IN1', 7], + ['IN2', 8], + ['IN3', 9], + ['IN4', 10], + ['IN5', 11], + ['IN6', 12], + ['IN7', 13], + ], + value: 7, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + keyOption: 'schoolkit_get_in_port_number', + }, + ], + }, + }, + schoolkit_set_output: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roborobo_on, 'on'], + [Lang.Blocks.roborobo_off, 'off'], + ], + value: 'on', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'schoolkit_get_out_port_number', + }, + null, + null, + ], + type: 'schoolkit_set_output', + }, + paramsKeyMap: { + VALUE: 0, + OPERATOR: 1, + }, + class: 'schoolkit_set', + isNotFor: ['roborobo_schoolkit'], + func: function (sprite, script) { + var pin = script.getNumberValue('VALUE', script); + var operator = script.getField('OPERATOR'); + var value = operator == 'on' ? 1 : 0; + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + + Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_SchoolKit.pinMode.OUTPUT; + Entry.hw.sendQueue[pin] = value; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'Roborobo_schoolkit.wirte_digital(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roborobo_on, 'on'], + [Lang.Blocks.roborobo_off, 'off'], + ], + value: 'on', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + }, + ], + }, + }, + schoolkit_get_input_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [ + { + type: 'schoolkit_get_in_port_number', + }, + ], + type: 'schoolkit_get_input_value', + }, + paramsKeyMap: { + VALUE: 0, + }, + class: 'schoolkit_value', + isNotFor: ['roborobo_schoolkit'], + func: function (sprite, script) { + var signal = script.getNumberValue('VALUE', script); + return Entry.hw.portData[signal - 7]; + }, + syntax: { + js: [], + py: [ + { + syntax: 'Roborobo_schoolkit.read_digital(%1)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + schoolkit_motor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roborobo_motor1, 'motor1'], + [Lang.Blocks.roborobo_motor2, 'motor2'], + ], + value: 'motor1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['0', '45'], + ['1', '59'], + ['2', '73'], + ['3', '87'], + ['4', '101'], + ['5', '115'], + ['6', '129'], + ['7', '143'], + ['8', '157'], + ['9', '171'], + ['10', '185'], + ['11', '199'], + ['12', '213'], + ['13', '227'], + ['14', '241'], + ['15', '255'], + ], + value: '45', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roborobo_motor_CW, 'cw'], + [Lang.Blocks.roborobo_motor_CCW, 'ccw'], + [Lang.Blocks.roborobo_motor_stop, 'stop'], + ], + value: 'cw', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null, null, null], + type: 'schoolkit_motor', + }, + paramsKeyMap: { + MODE: 0, + VALUE: 1, + OPERATOR: 2, + }, + class: 'schoolkit_set', + isNotFor: ['roborobo_schoolkit'], + func: function (sprite, script) { + var mode = script.getField('MODE'); + var pin = 0; + var operator = script.getField('OPERATOR'); + var value = script.getField('VALUE'); + + if (mode == 'motor1') { + pin = 0; + } else { + pin = 1; + } + + if (value > 255) { + value = 255; + } else if (value < 0) { + value = 0; + } + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + + Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[pin + 7] = Entry.Roborobo_SchoolKit.pinMode.PWM; + if (operator == 'cw') { + Entry.hw.sendQueue[pin] = value; + } else if (operator == 'ccw') { + Entry.hw.sendQueue[pin] = -value; + } else if (operator == 'stop') { + Entry.hw.sendQueue[pin] = 0x00; + } + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'Roborobo_schoolkit.move_motor_speed(%1, %2, %3)', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roborobo_motor1, 'motor1'], + [Lang.Blocks.roborobo_motor2, 'motor2'], + ], + value: 'motor1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + { + type: 'Dropdown', + options: [ + ['0', '45'], + ['1', '59'], + ['2', '73'], + ['3', '87'], + ['4', '101'], + ['5', '115'], + ['6', '129'], + ['7', '143'], + ['8', '157'], + ['9', '171'], + ['10', '185'], + ['11', '199'], + ['12', '213'], + ['13', '227'], + ['14', '241'], + ['15', '255'], + ], + value: '45', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.roborobo_motor_CW, 'cw'], + [Lang.Blocks.roborobo_motor_CCW, 'ccw'], + [Lang.Blocks.roborobo_motor_stop, 'stop'], + ], + value: 'cw', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + }, + ], + }, + }, + schoolkit_set_servo_value: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'schoolkit_get_servo_port_number', + }, + { + type: 'number', + params: ['0'], + }, + null, + ], + type: 'schoolkit_set_servo_value', + }, + paramsKeyMap: { + PIN: 0, + VALUE: 1, + }, + class: 'schoolkit_set', + isNotFor: ['roborobo_schoolkit'], + func: function (sprite, script) { + var pin = script.getNumberValue('PIN', script); + var value = script.getNumberValue('VALUE'); + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + Entry.hw.sendQueue.digitalPinMode[pin] = Entry.Roborobo_SchoolKit.pinMode.SERVO; + + if (value < 0) { + value = 0; + } else if (value > 180) { + value = 180; + } + Entry.hw.sendQueue[pin] = value; + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'Roborobo_schoolkit.move_servo(%1, %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + //endregion schoolkit 스쿨키트 + }; +}; + +Entry.Roborobo_SchoolKit.getPracticalBlocks = function () { + return { + // roborobo_mini + roborobo_motor_speed: { + color: '#00B200', + outerLine: '#019101', + skeleton: 'basic_string_field', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1', + params: [ + { + type: 'Dropdown', + options: [ + ['1', '52'], + ['2', '66'], + ['3', '80'], + ['4', '94'], + ['5', '107'], + ['6', '120'], + ['7', '134'], + ['8', '148'], + ['9', '162'], + ['10', '176'], + ['11', '190'], + ['12', '204'], + ['13', '218'], + ['14', '232'], + ['15', '255'], + ], + value: '255', + fontSize: 11, + bgColor: '#019101', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + VALUE: 0, + }, + func (sprite, script) { + return script.getStringField('VALUE'); + }, + }, + roborobo_move_for_secs: { + color: '#00B200', + outerLine: '#019101', + skeleton: 'basic', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1모터를 %2 %3의 속도로 %4초 동안 회전 %5', + params: [ + { + type: 'Dropdown', + options: [ + ['양쪽', '1'], + ['오른쪽', '2'], + ['왼쪽', '3'], + ], + value: '1', + fontSize: 11, + bgColor: '#019101', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Dropdown', + options: [ + ['앞으로', '1'], + ['뒤로', '2'], + ], + value: '1', + fontSize: 11, + bgColor: '#019101', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/practical_course/dcmotor.png', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + null, + { + type: 'roborobo_motor_speed', + }, + { + type: 'number', + params: ['2'], + }, + null, + ], + type: 'roborobo_move_for_secs', + }, + paramsKeyMap: { + WHEEL: 0, + DIRECTION: 1, + SPEED: 2, + DURATION: 3, + }, + class: 'roborobo_motor', + func (sprite, script) { + const motor1 = 0; + const motor2 = 1; + const wheel = script.getNumberField('WHEEL'); + const speed = script.getNumberValue('SPEED'); + const direction = script.getNumberField('DIRECTION'); + const duration = script.getNumberValue('DURATION'); + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + + if (!script.isStart) { + if (wheel == 1) { + Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + if (direction == 1) { + Entry.hw.sendQueue[motor1] = speed; + Entry.hw.sendQueue[motor2] = speed; + } else if (direction == 2) { + Entry.hw.sendQueue[motor1] = -speed; + Entry.hw.sendQueue[motor2] = -speed; + } + } else if (wheel == 2) { + Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + if (direction == 1) { + Entry.hw.sendQueue[motor1] = 0x00; + Entry.hw.sendQueue[motor2] = speed; + } else if (direction == 2) { + Entry.hw.sendQueue[motor1] = 0x00; + Entry.hw.sendQueue[motor2] = -speed; + } + } else if (wheel == 3) { + Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + if (direction == 1) { + Entry.hw.sendQueue[motor1] = speed; + Entry.hw.sendQueue[motor2] = 0x00; + } else if (direction == 2) { + Entry.hw.sendQueue[motor1] = -speed; + Entry.hw.sendQueue[motor2] = 0x00; + } + } + + script.wheelMode = wheel; + script.isStart = true; + script.timeFlag = 1; + setTimeout(() => { + script.timeFlag = 0; + }, duration * 1000); + return script; + } else if (script.timeFlag == 1) { + return script; + } else { + Entry.hw.sendQueue[motor1] = 0x00; + Entry.hw.sendQueue[motor2] = 0x00; + + delete script.timeFlag; + delete script.isStart; + delete script.wheelMode; + Entry.engine.isContinue = false; + return script.callReturn(); + } + }, + }, + roborobo_move_for: { + color: '#00B200', + outerLine: '#019101', + skeleton: 'basic', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1모터를 %2 %3의 속도로 계속 회전 %4', + params: [ + { + type: 'Dropdown', + options: [ + ['양쪽', '1'], + ['오른쪽', '2'], + ['왼쪽', '3'], + ], + value: '1', + fontSize: 11, + bgColor: '#019101', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Dropdown', + options: [ + ['앞으로', '1'], + ['뒤로', '2'], + ], + value: '1', + fontSize: 11, + bgColor: '#019101', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/practical_course/dcmotor.png', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + null, + { + type: 'roborobo_motor_speed', + }, + null, + ], + type: 'roborobo_move_for', + }, + paramsKeyMap: { + WHEEL: 0, + DIRECTION: 1, + SPEED: 2, + }, + class: 'roborobo_motor', + //'isNotFor': ['mini'], + func (sprite, script) { + const motor1 = 0; + const motor2 = 1; + const wheel = script.getNumberField('WHEEL'); + const speed = script.getNumberValue('SPEED'); + const direction = script.getNumberField('DIRECTION'); + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + + if (wheel == 1) { + Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + if (direction == 1) { + Entry.hw.sendQueue[motor1] = speed; + Entry.hw.sendQueue[motor2] = speed; + } else if (direction == 2) { + Entry.hw.sendQueue[motor1] = -speed; + Entry.hw.sendQueue[motor2] = -speed; + } + } else if (wheel == 2) { + Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + if (direction == 1) { + Entry.hw.sendQueue[motor1] = 0x00; + Entry.hw.sendQueue[motor2] = speed; + } else if (direction == 2) { + Entry.hw.sendQueue[motor1] = 0x00; + Entry.hw.sendQueue[motor2] = -speed; + } + } else if (wheel == 3) { + Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + if (direction == 1) { + Entry.hw.sendQueue[motor1] = speed; + Entry.hw.sendQueue[motor2] = 0x00; + } else if (direction == 2) { + Entry.hw.sendQueue[motor1] = -speed; + //Entry.hw.sendQueue[motor2] = 0x00; + } + } + + return script.callReturn(); + }, + }, + roborobo_turn_for: { + color: '#00B200', + outerLine: '#019101', + skeleton: 'basic', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '오른쪽 모터를 %1 %2, 왼쪽 모터를 %3 %4의 속도로 계속 회전 %5', + params: [ + { + type: 'Dropdown', + options: [ + ['앞으로', '1'], + ['뒤로', '2'], + ], + value: '1', + fontSize: 11, + bgColor: '#019101', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + ['앞으로', '1'], + ['뒤로', '2'], + ], + value: '1', + fontSize: 11, + bgColor: '#019101', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/practical_course/dcmotor.png', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + {type: 'roborobo_motor_speed'}, + null, + {type: 'roborobo_motor_speed'}, + null, + ], + type: 'roborobo_turn_for', + }, + paramsKeyMap: { + RDIR: 0, + RSPEED: 1, + LDIR: 2, + LSPEED: 3, + }, + class: 'roborobo_motor', + //'isNotFor': ['mini'], + func (sprite, script) { + const motor1 = 0; + const motor2 = 1; + + const rightDir = script.getNumberField('RDIR'); + const rightSpeed = script.getNumberValue('RSPEED'); + const leftDir = script.getNumberField('LDIR'); + const leftSpeed = script.getNumberValue('LSPEED'); + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + + Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + if (leftDir == 1) { + Entry.hw.sendQueue[motor1] = leftSpeed; + } else { + Entry.hw.sendQueue[motor1] = -leftSpeed; + } + + if (rightDir == 1) { + Entry.hw.sendQueue[motor2] = rightSpeed; + } else { + Entry.hw.sendQueue[motor2] = -rightSpeed; + } + + return script.callReturn(); + }, + }, + roborobo_stop_for: { + color: '#00B200', + outerLine: '#019101', + skeleton: 'basic', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1모터를 정지 %2', + params: [ + { + type: 'Dropdown', + options: [ + ['양쪽', '1'], + ['오른쪽', '2'], + ['왼쪽', '3'], + ], + value: '1', + fontSize: 11, + bgColor: '#019101', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Indicator', + img: 'block_icon/practical_course/dcmotor.png', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'roborobo_stop_for', + }, + paramsKeyMap: { + WHEEL: 0, + }, + class: 'roborobo_motor', + func (sprite, script) { + const motor1 = 0; + const motor2 = 1; + const wheel = script.getNumberField('WHEEL'); + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + + if (wheel == 1) { + Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + Entry.hw.sendQueue[motor1] = 0x00; + Entry.hw.sendQueue[motor2] = 0x00; + } else if (wheel == 2) { + Entry.hw.sendQueue.digitalPinMode[8] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[1] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + Entry.hw.sendQueue[motor2] = 0x00; + } else if (wheel == 3) { + Entry.hw.sendQueue.digitalPinMode[7] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue.digitalPinMode[0] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + Entry.hw.sendQueue[motor1] = 0x00; + } + + return script.callReturn(); + }, + }, + roborobo_touch_value: { + color: '#2AB4D3', + outerLine: '#0e93b1', + skeleton: 'basic_string_field', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '접촉 센서 값', + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null], + type: 'roborobo_touch_value', + }, + paramsKeyMap: {}, + class: 'roborobo_touch', + func (sprite, script) { + const port = Entry.Roborobo_SchoolKit.inputPort.contact; + Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.INPUT; + Entry.hw.update(); + return Entry.hw.portData[port - 7]; + }, + }, + roborobo_touch_value_boolean: { + color: '#2AB4D3', + outerLine: '#0e93b1', + skeleton: 'basic_boolean_field', + fontColor: '#fff', + isNotFor: ['roborobo_schoolkit'], + template: '접촉 센서가 %1', + params: [ + { + type: 'Dropdown', + options: [ + ['접촉 되면', '1'], + ['접촉 안되면', '0'], + ], + value: '1', + fontSize: 11, + bgColor: '#0e93b1', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + ], + def: { + params: [null], + type: 'roborobo_touch_value_boolean', + }, + paramsKeyMap: { + TOUCH: 0, + }, + class: 'roborobo_touch', + func (sprite, script) { + const port = Entry.Roborobo_SchoolKit.inputPort.contact; + const touch = script.getNumberField('TOUCH', script); + + Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.INPUT; + Entry.hw.update(); + + const value = Entry.hw.portData[port - 7]; + const isTouch = touch == value; + + return isTouch; + }, + }, + roborobo_light_value: { + color: '#ff8d0f', + outerLine: '#e37100', + skeleton: 'basic_string_field', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: 'CDS 센서 값', + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null], + type: 'roborobo_light_value', + }, + paramsKeyMap: {}, + class: 'roborobo_light', + func (sprite, script) { + const port = Entry.Roborobo_SchoolKit.inputPort.cds; + return Entry.hw.portData[port - 7]; + }, + }, + roborobo_light_value_boolean: { + color: '#ff8d0f', + outerLine: '#e37100', + skeleton: 'basic_boolean_field', + fontColor: '#fff', + isNotFor: ['roborobo_schoolkit'], + template: 'CDS 센서 값 %1 %2', + params: [ + { + type: 'Dropdown', + options: [ + ['=', 'EQUAL'], + ['>', 'GREATER'], + ['<', 'LESS'], + ['≥', 'GREATER_OR_EQUAL'], + ['≤', 'LESS_OR_EQUAL'], + ], + value: 'LESS', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + noaRrow: true, + }, + { + type: 'Block', + accept: 'string', + }, + ], + def: { + params: [ + null, + { + type: 'number', + params: ['512'], + }, + ], + type: 'roborobo_light_value_boolean', + }, + paramsKeyMap: { + OPERATOR: 0, + RIGHTVALUE: 1, + }, + class: 'roborobo_light', + func (sprite, script) { + const port = Entry.Roborobo_SchoolKit.inputPort.cds; + const operator = script.getField('OPERATOR', script); + let rightValue = script.getNumberValue('RIGHTVALUE', script); + const leftValue = Entry.hw.portData[port - 7]; + let isCheck = false; + + if (rightValue < 0) { + rightValue = 0; + } else if (rightValue > 1023) { + rightValue = 1023; + } + switch (operator) { + case 'EQUAL': + isCheck = leftValue == rightValue; + break; + case 'GREATER': + isCheck = Number(leftValue) > Number(rightValue); + break; + case 'LESS': + isCheck = Number(leftValue) < Number(rightValue); + break; + case 'GREATER_OR_EQUAL': + isCheck = Number(leftValue) >= Number(rightValue); + break; + case 'LESS_OR_EQUAL': + isCheck = Number(leftValue) <= Number(rightValue); + break; + } + return isCheck; + }, + }, + roborobo_sound_value: { + color: '#01d67f', + outerLine: '#00b36a', + skeleton: 'basic_string_field', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '소리 센서에 감지되는 소리 값', + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null], + type: 'roborobo_sound_value', + }, + paramsKeyMap: {}, + class: 'roborobo_sound', + func (sprite, script) { + const port = Entry.Roborobo_SchoolKit.inputPort.sound; + return Entry.hw.portData[port - 7]; + }, + }, + roborobo_sound_value_boolean: { + color: '#01d67f', + outerLine: '#00b36a', + skeleton: 'basic_boolean_field', + fontColor: '#fff', + isNotFor: ['roborobo_schoolkit'], + template: '소리 센서에 감지되는 소리 값 %1 %2', + params: [ + { + type: 'Dropdown', + options: [ + ['=', 'EQUAL'], + ['>', 'GREATER'], + ['<', 'LESS'], + ['≥', 'GREATER_OR_EQUAL'], + ['≤', 'LESS_OR_EQUAL'], + ], + value: 'LESS', + fontSize: 11, + bgColor: '#00b36a', + arrowColor: EntryStatic.colorSet.common.WHITE, + noaRrow: true, + }, + { + type: 'Block', + accept: 'string', + }, + ], + def: { + params: [ + null, + { + type: 'number', + params: ['512'], + }, + ], + type: 'roborobo_sound_value_boolean', + }, + paramsKeyMap: { + OPERATOR: 0, + RIGHTVALUE: 1, + }, + class: 'roborobo_sound', + func (sprite, script) { + const port = Entry.Roborobo_SchoolKit.inputPort.sound; + const operator = script.getField('OPERATOR', script); + let rightValue = script.getNumberValue('RIGHTVALUE', script); + const leftValue = Entry.hw.portData[port - 7]; + let isCheck = false; + + if (rightValue < 0) { + rightValue = 0; + } else if (rightValue > 1023) { + rightValue = 1023; + } + + switch (operator) { + case 'EQUAL': + isCheck = leftValue == rightValue; + break; + case 'GREATER': + isCheck = Number(leftValue) > Number(rightValue); + break; + case 'LESS': + isCheck = Number(leftValue) < Number(rightValue); + break; + case 'GREATER_OR_EQUAL': + isCheck = Number(leftValue) >= Number(rightValue); + break; + case 'LESS_OR_EQUAL': + isCheck = Number(leftValue) <= Number(rightValue); + break; + } + + return isCheck; + }, + }, + roborobo_irs_value: { + color: '#C4065C', + outerLine: '#9a0045', + skeleton: 'basic_string_field', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '적외선 센서 값', + params: [ + { + type: 'Block', + accept: 'string', + }, + ], + events: {}, + def: { + params: [null], + type: 'roborobo_irs_value', + }, + paramsKeyMap: {}, + class: 'roborobo_irs', + //'isNotFor': ['mini'], + func (sprite, script) { + const port = Entry.Roborobo_SchoolKit.inputPort.ir; + const value = + Entry.hw.portData[port - 7] == undefined ? 0 : Entry.hw.portData[port - 7]; + return value; + }, + }, + roborobo_irs_value_boolean: { + color: '#C4065C', + outerLine: '#9a0045', + skeleton: 'basic_boolean_field', + fontColor: '#fff', + isNotFor: ['roborobo_schoolkit'], + template: '적외선 센서가 %1', + params: [ + { + type: 'Dropdown', + options: [ + ['감지 되면', '1'], + ['감지 안되면', '0'], + ], + value: '1', + fontSize: 11, + bgColor: '#9a0045', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + ], + def: { + params: [null], + type: 'roborobo_irs_value_boolean', + }, + paramsKeyMap: { + DETECT: 0, + }, + class: 'roborobo_irs', + //'isNotFor': ['mini'], + func (sprite, script) { + const port = Entry.Roborobo_SchoolKit.inputPort.ir; + const detect = script.getNumberField('DETECT', script); + + Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.INPUT; + Entry.hw.update(); + + const value = Entry.hw.portData[port - 7]; + const isDetect = detect == value; + + return isDetect; + }, + }, + roborobo_diode_secs_toggle: { + color: '#ff8d0f', + outerLine: '#e37100', + skeleton: 'basic', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1번 포트의 발광다이오드를 %2초 동안 %3 %4', + params: [ + { + type: 'Dropdown', + options: [ + ['LED 1', '5'], + ['LED 2', '4'], + ['R - A', '3'], + ['R - B', '2'], + ], + value: '5', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + ['켜기', '255'], + ['끄기', '0'], + ], + value: '255', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Indicator', + img: 'block_icon/practical_course/diode.png', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['2'], + }, + null, + null, + ], + type: 'roborobo_diode_secs_toggle', + }, + paramsKeyMap: { + PORT: 0, + DURATION: 1, + VALUE: 2, + }, + class: 'roborobo_diode', + func (sprite, script) { + const port = script.getNumberField('PORT'); + const duration = script.getNumberValue('DURATION'); + const value = script.getNumberField('VALUE'); + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.PWM; + + if (!script.isStart) { + script.isStart = true; + script.timeFlag = 1; + Entry.hw.sendQueue[port] = value; + + setTimeout(() => { + script.timeFlag = 0; + }, duration * 1000); + return script; + } else if (script.timeFlag == 1) { + return script; + } else { + Entry.hw.sendQueue[port] = 0; + delete script.timeFlag; + delete script.isStart; + Entry.engine.isContinue = false; + return script.callReturn(); + } + }, + }, + roborobo_diode_toggle: { + color: '#ff8d0f', + outerLine: '#e37100', + skeleton: 'basic', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1번 포트의 발광다이오드를 %2 %3', + params: [ + { + type: 'Dropdown', + options: [ + ['LED 1', '5'], + ['LED 2', '4'], + ['R - A', '3'], + ['R - B', '2'], + ], + value: '5', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Dropdown', + options: [ + ['켜기', '255'], + ['끄기', '0'], + ], + value: '255', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Indicator', + img: 'block_icon/practical_course/diode.png', + size: 12, + }, + ], + events: {}, + def: { + params: [null, null, null], + type: 'roborobo_diode_toggle', + }, + paramsKeyMap: { + PORT: 0, + VALUE: 1, + }, + class: 'roborobo_diode', + //'isNotFor': ['mini'], + func (sprite, script) { + const port = script.getNumberField('PORT'); + const value = script.getNumberField('VALUE'); + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + + Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue[port] = value; + + return script.callReturn(); + }, + }, + roborobo_diode_inout_toggle: { + color: '#ff8d0f', + outerLine: '#e37100', + skeleton: 'basic', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1번 포트의 발광다이오드를 %2번 포트의 %3~%4의 범위로 켜기%5', + params: [ + { + type: 'Dropdown', + options: [ + ['LED 1', '5'], + ['LED 2', '4'], + ['R - A', '3'], + ['R - B', '2'], + ], + value: '5', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Dropdown', + options: [ + ['소 리', '8'], + ['CDS', '10'], + ], + value: '8', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/practical_course/diode.png', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + null, + {type: 'number', params: ['0']}, + {type: 'number', params: ['255']}, + null, + ], + type: 'roborobo_diode_inout_toggle', + }, + paramsKeyMap: { + OUTPUT: 0, + INPUT: 1, + MIN: 2, + MAX: 3, + }, + class: 'roborobo_diode', + //'isNotFor': ['mini'], + func (sprite, script) { + const outputPort = script.getNumberField('OUTPUT'); + const inputPort = script.getNumberField('INPUT'); + + const oMin = script.getNumberValue('MIN'); + const oMax = script.getNumberValue('MAX'); + const nMin = 0; + const nMax = 255; + const x = Entry.hw.portData[inputPort - 7] / 4; + const percent = (x - oMin) / (oMax - oMin); + let result = percent * (nMax - nMin) + nMin; + if (result > nMax) { + result = nMax; + } + if (result < nMin) { + result = nMin; + } + + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + + Entry.hw.sendQueue.digitalPinMode[outputPort] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue[outputPort] = result; + + return script.callReturn(); + }, + }, + roborobo_diode_set_output: { + color: '#ff8d0f', + outerLine: '#e37100', + skeleton: 'basic', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1번 포트의 발광다이오드를 %2의 밝기로 켜기 %3', + params: [ + { + type: 'Dropdown', + options: [ + ['LED 1', '5'], + ['LED 2', '4'], + ['R - A', '3'], + ['R - B', '2'], + ], + value: '5', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Indicator', + img: 'block_icon/practical_course/diode.png', + size: 12, + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['255'], + }, + null, + ], + type: 'roborobo_diode_set_output', + }, + paramsKeyMap: { + PORT: 0, + VALUE: 1, + }, + class: 'roborobo_diode', + //'isNotFor': ['mini'], + func (sprite, script) { + const port = script.getStringField('PORT', script); + let value = script.getNumberValue('VALUE', script); + + if (value < 0) { + value = 0; + } else if (value > 255) { + value = 255; + } + if (!Entry.hw.sendQueue.digitalPinMode) { + Entry.hw.sendQueue.digitalPinMode = {}; + } + Entry.hw.sendQueue.digitalPinMode[port] = Entry.Roborobo_SchoolKit.pinMode.PWM; + Entry.hw.sendQueue[port] = value; + + return script.callReturn(); + }, + }, + roborobo_diode_input_value: { + color: '#ff8d0f', + outerLine: '#e37100', + skeleton: 'basic_string_field', + fontColor: '#fff', + statements: [], + isNotFor: ['roborobo_schoolkit'], + template: '%1 포트의 값', + params: [ + { + type: 'Dropdown', + options: [ + ['적외선', '7'], + ['소 리', '8'], + ['접 촉', '9'], + ['CDS', '10'], + ], + value: '8', + fontSize: 11, + bgColor: '#e37100', + arrowColor: EntryStatic.colorSet.common.WHITE, + }, + ], + events: {}, + def: { + params: [null], + type: 'roborobo_diode_input_value', + }, + paramsKeyMap: { + PORT: 0, + }, + class: 'roborobo_diode', + func (sprite, script) { + const port = script.getNumberField('PORT'); + return Entry.hw.portData[port - 7]; + }, + }, + } +} + +module.exports = Entry.Roborobo_SchoolKit; From d4f5237aa56779a886ad0edd018a64c8a93f4951 Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 17 Mar 2023 00:06:24 +0900 Subject: [PATCH 4/9] =?UTF-8?q?=EC=97=94=ED=8A=B8=EB=A6=AC=EC=88=98?= =?UTF-8?q?=EC=A0=95=5F=EC=BD=94=EC=95=8C=EB=9D=BC=EB=B3=B4=EB=93=9C=5F202?= =?UTF-8?q?30304=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extern/lang/code.js | 7 +- extern/lang/ebs.js | 27 ++-- extern/lang/en.js | 2 +- extern/lang/jp.js | 2 +- extern/lang/ko.js | 27 ++-- .../blocks/hardware/block_bitbrick.js | 14 +- .../blocks/hardware/block_coalaboard.js | 120 ++++++------------ 7 files changed, 79 insertions(+), 120 deletions(-) diff --git a/extern/lang/code.js b/extern/lang/code.js index ad6986e852..d7e4e4102d 100644 --- a/extern/lang/code.js +++ b/extern/lang/code.js @@ -587,6 +587,7 @@ Lang.Blocks = { "COALABOARD_light": "light", "COALABOARD_IR": "IR", "COALABOARD_touch": "touch", + "COALABOARD_temperature": "temperature", "COALABOARD_potentiometer": "potentiometer", "COALABOARD_MIC": "MIC", "COALABOARD_UserSensor": "UserSensor", @@ -5993,7 +5994,7 @@ Lang.template = { "iboard_toggle_led": "디지털 %1 번 핀 %2 %3", "bitbrick_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", "bitbrick_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", - "bitbrick_is_touch_pressed": "버튼 %1 이(가) %2 눌렸는가?", + "bitbrick_is_touch_pressed": "버튼 %1 이(가) %2 인가?", "bitbrick_is_sensor_value_compare": '%1 값 %2 %3 인가?', "bitbrick_sensor_value": "%1 값", "bitbrick_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", @@ -6006,9 +6007,9 @@ Lang.template = { "bitbrick_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", "bitbrick_dc_speed": "디씨모터 %1 속도 %2 %3", "bitbrick_turn_off_all_motors": "모든 모터 멈추기 %1", - "coalaboard_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", + "coalaboard_when_button_pressed": "%1 버튼 %2 눌러졌을 때", "coalaboard_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", - "coalaboard_is_touch_pressed": "버튼 %1 이(가) %2 눌렸는가?", + "coalaboard_is_touch_pressed": "버튼 %1 이(가) %2 인가?", "coalaboard_is_sensor_value_compare": '%1 값 %2 %3 인가?', "coalaboard_sensor_value": "%1 값", "coalaboard_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", diff --git a/extern/lang/ebs.js b/extern/lang/ebs.js index e9281f801d..c4903ebcc3 100644 --- a/extern/lang/ebs.js +++ b/extern/lang/ebs.js @@ -575,22 +575,23 @@ Lang.Blocks = { "blacksmith_toggle_off": "끄기", "blacksmith_lcd_first_line": "첫 번째", "blacksmith_lcd_seconds_line": "두 번째", - "BITBRICK_light": "밝기센서", - "BITBRICK_IR": "거리센서", + "BITBRICK_light": "밝기 센서", + "BITBRICK_IR": "적외선 센서", "BITBRICK_touch": "버튼", "BITBRICK_potentiometer": "가변저항", - "BITBRICK_MIC": "소리감지센서", - "BITBRICK_UserSensor": "사용자입력", - "BITBRICK_UserInput": "사용자입력", + "BITBRICK_MIC": "소리 센서", + "BITBRICK_UserSensor": "사용자 입력", + "BITBRICK_UserInput": "사용자 입력", "BITBRICK_dc_direction_ccw": "반시계", "BITBRICK_dc_direction_cw": "시계", - "COALABOARD_light": "밝기센서", - "COALABOARD_IR": "거리센서", + "COALABOARD_light": "밝기 센서", + "COALABOARD_IR": "적외선 센서", "COALABOARD_touch": "버튼", + "COALABOARD_temperature": "온도 센서", "COALABOARD_potentiometer": "가변저항", - "COALABOARD_MIC": "소리감지센서", - "COALABOARD_UserSensor": "사용자입력", - "COALABOARD_UserInput": "사용자입력", + "COALABOARD_MIC": "소리 센서", + "COALABOARD_UserSensor": "사용자 입력", + "COALABOARD_UserInput": "사용자 입력", "COALABOARD_dc_direction_ccw": "반시계", "COALABOARD_dc_direction_cw": "시계", "chocopi_control_event_pressed": "누를 때", @@ -5993,7 +5994,7 @@ Lang.template = { "iboard_toggle_led": "디지털 %1 번 핀 %2 %3", "bitbrick_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", "bitbrick_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", - "bitbrick_is_touch_pressed": "버튼 %1 이(가) %2 눌렸는가?", + "bitbrick_is_touch_pressed": "버튼 %1 이(가) %2 인가?", "bitbrick_is_sensor_value_compare": '%1 값 %2 %3 인가?', "bitbrick_sensor_value": "%1 값", "bitbrick_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", @@ -6006,9 +6007,9 @@ Lang.template = { "bitbrick_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", "bitbrick_dc_speed": "디씨모터 %1 속도 %2 %3", "bitbrick_turn_off_all_motors": "모든 모터 멈추기 %1", - "coalaboard_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", + "coalaboard_when_button_pressed": "%1 버튼 %2 눌러졌을 일 때", "coalaboard_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", - "coalaboard_is_touch_pressed": "버튼 %1 이(가) %2 눌렸는가?", + "coalaboard_is_touch_pressed": "버튼 %1 이(가) %2 인가?", "coalaboard_is_sensor_value_compare": '%1 값 %2 %3 인가?', "coalaboard_sensor_value": "%1 값", "coalaboard_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", diff --git a/extern/lang/en.js b/extern/lang/en.js index 859614bbb1..7554a65f11 100644 --- a/extern/lang/en.js +++ b/extern/lang/en.js @@ -5205,7 +5205,7 @@ Lang.template = { "bitbrick_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", "bitbrick_dc_speed": "dc motor %1 velocity %2 %3", "bitbrick_turn_off_all_motors": "stop all motors %1", - "coalaboard_when_button_pressed": "%1 when button %2 %3", + "coalaboard_when_button_pressed": "%1 when button %2", "coalaboard_when_sensor_get_value": "%1 when %2 value %3 %4", "coalaboard_is_touch_pressed": "button %1 %2?", "coalaboard_is_sensor_value_compare": "%1 %2 %3?", diff --git a/extern/lang/jp.js b/extern/lang/jp.js index c10ba47b35..704d4758f5 100644 --- a/extern/lang/jp.js +++ b/extern/lang/jp.js @@ -5999,7 +5999,7 @@ Lang.template = { "bitbrick_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", "bitbrick_dc_speed": "dc motor %1 velocity %2 %3", "bitbrick_turn_off_all_motors": "stop all motors %1", - "coalaboard_when_button_pressed": "%1 when button %2 %3", + "coalaboard_when_button_pressed": "%1 when button %2", "coalaboard_when_sensor_get_value": "%1 when %2 value %3 %4", "coalaboard_is_touch_pressed": "button %1 %2?", "coalaboard_is_sensor_value_compare": "%1 %2 %3?", diff --git a/extern/lang/ko.js b/extern/lang/ko.js index 55066932e9..7f809def06 100644 --- a/extern/lang/ko.js +++ b/extern/lang/ko.js @@ -590,22 +590,23 @@ Lang.Blocks = { blacksmith_toggle_off: '끄기', blacksmith_lcd_first_line: '첫 번째', blacksmith_lcd_seconds_line: '두 번째', - BITBRICK_light: '밝기센서', - BITBRICK_IR: '거리센서', + BITBRICK_light: '밝기 센서', + BITBRICK_IR: '적외선 센서', BITBRICK_touch: '버튼', BITBRICK_potentiometer: '가변저항', - BITBRICK_MIC: '소리감지센서', - BITBRICK_UserSensor: '사용자입력', - BITBRICK_UserInput: '사용자입력', + BITBRICK_MIC: '소리 센서', + BITBRICK_UserSensor: '사용자 입력', + BITBRICK_UserInput: '사용자 입력', BITBRICK_dc_direction_ccw: '반시계', BITBRICK_dc_direction_cw: '시계', - COALABOARD_light: '밝기센서', - COALABOARD_IR: '거리센서', + COALABOARD_light: '밝기 센서', + COALABOARD_IR: '적외선 센서', COALABOARD_touch: '버튼', + COALABOARD_temperature: '온도 센서', COALABOARD_potentiometer: '가변저항', - COALABOARD_MIC: '소리감지센서', - COALABOARD_UserSensor: '사용자입력', - COALABOARD_UserInput: '사용자입력', + COALABOARD_MIC: '소리 센서', + COALABOARD_UserSensor: '사용자 입력', + COALABOARD_UserInput: '사용자 입력', COALABOARD_dc_direction_ccw: '반시계', COALABOARD_dc_direction_cw: '시계', chocopi_control_event_pressed: '누를 때', @@ -6925,7 +6926,7 @@ Lang.template = { iboard_toggle_led: '디지털 %1 번 핀 %2 %3', bitbrick_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', bitbrick_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', - bitbrick_is_touch_pressed: '버튼 %1 이(가) %2 눌렸는가?', + bitbrick_is_touch_pressed: '버튼 %1 이(가) %2 인가?', bitbrick_is_sensor_value_compare: '%1 값 %2 %3 인가?', bitbrick_sensor_value: '%1 값', bitbrick_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', @@ -6938,9 +6939,9 @@ Lang.template = { bitbrick_dc_direction_speed: '디씨모터 %1 방향 %2 속력 %3 %4', bitbrick_dc_speed: '디씨모터 %1 속도 %2 %3', bitbrick_turn_off_all_motors: "모든 모터 멈추기 %1", - coalaboard_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', + coalaboard_when_button_pressed: '%1 버튼 %2 눌러졌을 때', coalaboard_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', - coalaboard_is_touch_pressed: '버튼 %1 이(가) %2 눌렸는가?', + coalaboard_is_touch_pressed: '버튼 %1 이(가) %2 인가?', coalaboard_is_sensor_value_compare: '%1 값 %2 %3 인가?', coalaboard_sensor_value: '%1 값', coalaboard_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', diff --git a/src/playground/blocks/hardware/block_bitbrick.js b/src/playground/blocks/hardware/block_bitbrick.js index 7c0cdb188a..64e814fc31 100644 --- a/src/playground/blocks/hardware/block_bitbrick.js +++ b/src/playground/blocks/hardware/block_bitbrick.js @@ -1069,7 +1069,7 @@ Entry.Bitbrick.setLanguage = function() { template: { bitbrick_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', bitbrick_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', - bitbrick_is_touch_pressed: '버튼 %1 이(가) %2 눌렸는가?', + bitbrick_is_touch_pressed: '버튼 %1 이(가) %2 인가?', bitbrick_is_sensor_value_compare: '%1 값 %2 %3 인가?', bitbrick_sensor_value: '%1 값', bitbrick_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', @@ -1086,15 +1086,15 @@ Entry.Bitbrick.setLanguage = function() { Blocks: { BITBRICK_button_pressed: '누름', BITBRICK_button_released: '누르지 않음', - BITBRICK_light: '밝기센서', - BITBRICK_IR: '거리센서', + BITBRICK_light: '밝기 센서', + BITBRICK_IR: '적외선 센서', BITBRICK_touch: '버튼', BITBRICK_ultrasonicSensor: '초음파센서', - BITBRICK_vibrationSensor: '진동센서', + BITBRICK_vibrationSensor: '진동 센서', BITBRICK_potentiometer: '가변저항', - BITBRICK_MIC: '소리센서', - BITBRICK_UserSensor: '사용자입력', - BITBRICK_UserInput: '사용자입력', + BITBRICK_MIC: '소리 센서', + BITBRICK_UserSensor: '사용자 입력', + BITBRICK_UserInput: '사용자 입력', BITBRICK_dc_direction_ccw: '반시계', BITBRICK_dc_direction_cw: '시계', }, diff --git a/src/playground/blocks/hardware/block_coalaboard.js b/src/playground/blocks/hardware/block_coalaboard.js index d5a4149b22..8e1adf38a2 100644 --- a/src/playground/blocks/hardware/block_coalaboard.js +++ b/src/playground/blocks/hardware/block_coalaboard.js @@ -8,6 +8,7 @@ Entry.Coalaboard = { 4: 'potentiometer', 5: 'MIC', 6: 'ultrasonicSensor', + 7: 'temperature', 10: 'vibrationSensor', 21: 'UserSensor', 11: 'UserInput', @@ -110,64 +111,42 @@ Entry.Coalaboard = { width: 400, height: 400, listPorts: { - '1': { - name: Lang.Hw.port_en + ' 1 ' + Lang.Hw.port_ko, + 'UserInput': { + name: Lang.Blocks.COALABOARD_UserInput, type: 'input', pos: { x: 0, y: 0 }, }, - '2': { - name: Lang.Hw.port_en + ' 2 ' + Lang.Hw.port_ko, + 'potentiometer': { + name: Lang.Blocks.COALABOARD_potentiometer, type: 'input', pos: { x: 0, y: 0 }, }, - '3': { - name: Lang.Hw.port_en + ' 3 ' + Lang.Hw.port_ko, + 'MIC': { + name: Lang.Blocks.COALABOARD_MIC, type: 'input', pos: { x: 0, y: 0 }, }, - '4': { - name: Lang.Hw.port_en + ' 4 ' + Lang.Hw.port_ko, + 'IR': { + name: Lang.Blocks.COALABOARD_IR, type: 'input', pos: { x: 0, y: 0 }, }, - A: { - name: Lang.Hw.port_en + ' A ' + Lang.Hw.port_ko, + 'temperature': { + name: Lang.Blocks.COALABOARD_temperature, type: 'input', pos: { x: 0, y: 0 }, }, - B: { - name: Lang.Hw.port_en + ' B ' + Lang.Hw.port_ko, + 'light': { + name: Lang.Blocks.COALABOARD_light, type: 'input', pos: { x: 0, y: 0 }, }, - C: { - name: Lang.Hw.port_en + ' C ' + Lang.Hw.port_ko, - type: 'input', - pos: { x: 0, y: 0 }, - }, - D: { - name: Lang.Hw.port_en + ' D ' + Lang.Hw.port_ko, + 'touch': { + name: Lang.Blocks.COALABOARD_touch, type: 'input', pos: { x: 0, y: 0 }, }, }, - // }, - // ports : { - // "1":{name: "light", type: "input", pos: {x: 0, y: 0}}, - // "2":{name: "IR", type: "input", pos: {x : 0, y: 0}}, - // "3":{name: "touch", type: "input", pos: {x: 0, y: 0}}, - // "4":{name: "potentiometer", type: "input", pos: {x: 0, y: 0}}, - // "5":{name: "MIC", type: "input", pos: {x: 0, y: 0}}, - // "21":{name: "UserSensor", type: "input", pos: {x: 0, y: 0}}, - // "11":{name: "USER INPUT", type: "input", pos: {x: 0, y: 0}}, - // "20":{name: "LED", type: "input", pos: {x: 0, y: 0}}, - // "19":{name: "SERVO", type: "input", pos: {x: 0, y: 0}}, - // "18":{name: "DC", type: "input", pos: {x: 0, y: 0}}, - // "buzzer":{name: "부저", type: "input", pos: {x: 0, y: 0}}, - // "LEDR":{name: "LEDR", type: "output", pos: {x: 0, y: 0}}, - // "LEDG":{name: "LEDG", type: "output", pos: {x: 0, y: 0}}, - // "LEDB":{name: "LEDG", type: "output", pos: {x: 0, y: 0}} - // }, mode: 'both', }, /** @@ -236,15 +215,6 @@ Entry.Coalaboard.getBlocks = function() { skeleton: 'basic_event', statements: [], params: [ - // { - // type: 'Indicator', - // img: 'block_icon/start_icon_play.svg', - // size: 14, - // position: { - // x: 0, - // y: -2, - // }, - // }, { type: 'Indicator', img: 'block_icon/hardware_icon.svg', @@ -262,43 +232,27 @@ Entry.Coalaboard.getBlocks = function() { arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, menuName: Entry.Coalaboard.touchList, }, - { - type: 'Dropdown', - options: options_COALABOARD_button2, - value: 'pressed', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, ], events: {}, def: { - params: [null, null, null], + params: [null, null], type: 'coalaboard_when_button_pressed', }, paramsKeyMap: { DUMMY: 0, - PORT: 1, - PRESSED: 2, + PORT: 1 }, class: 'event', isNotFor: ['coalaboard'], event: 'coalaboardButtonEventReceive', func: function(sprite, script) { - if( script.values.length > 0 ) { - let selectedSensor = script.values[ 1 ]; - let port = script.getStringField('PORT'); - let type = Entry.hw.portData[port].type; - let val = Entry.hw.portData[port].value; // 0이면 누름, 1023이면 누르지 않음 - let pressed = script.getStringField('PRESSED'); - if( selectedSensor == port ) { - if ((pressed == 'pressed') && (val == 0)) { - return script.callReturn(); - } else if ((pressed == 'released') && (val == 1023)) { - return script.callReturn(); - } else { - return this.die(); - } + let selectedSensor = script.values[ 1 ]; + let port = script.getStringField('PORT'); + let type = Entry.hw.portData[port].type; + let val = Entry.hw.portData[port].value; // 0이면 누름, 1023이면 누르지 않음 + if( selectedSensor == port ) { + if (val == 0) { + return script.callReturn(); } else { return this.die(); } @@ -548,9 +502,9 @@ Entry.Coalaboard.getBlocks = function() { let val = Entry.hw.portData[port].value; let pressed = script.getStringField('PRESSED'); if ((pressed == 'pressed') && (val == 0)) { - return treu; + return true; } else if ((pressed == 'released') && (val == 1023)) { - return treu; + return true; } else { return false; } @@ -1067,9 +1021,9 @@ Entry.Coalaboard.setLanguage = function() { ko: { // ko.js에 작성하던 내용 template: { - coalaboard_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', + coalaboard_when_button_pressed: '%1 버튼 %2 눌러졌을 때', coalaboard_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', - coalaboard_is_touch_pressed: '버튼 %1 이(가) %2 눌렸는가?', + coalaboard_is_touch_pressed: '버튼 %1 이(가) %2 인가?', coalaboard_is_sensor_value_compare: '%1 값 %2 %3 인가?', coalaboard_sensor_value: '%1 값', coalaboard_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', @@ -1086,15 +1040,16 @@ Entry.Coalaboard.setLanguage = function() { Blocks: { COALABOARD_button_pressed: '누름', COALABOARD_button_released: '누르지 않음', - COALABOARD_light: '밝기센서', - COALABOARD_IR: '거리센서', + COALABOARD_light: '밝기 센서', + COALABOARD_IR: '적외선 센서', COALABOARD_touch: '버튼', - COALABOARD_ultrasonicSensor: '초음파센서', - COALABOARD_vibrationSensor: '진동센서', + COALABOARD_temperature: '온도 센서', + COALABOARD_ultrasonicSensor: '초음파 센서', + COALABOARD_vibrationSensor: '진동 센서', COALABOARD_potentiometer: '가변저항', - COALABOARD_MIC: '소리센서', - COALABOARD_UserSensor: '사용자입력', - COALABOARD_UserInput: '사용자입력', + COALABOARD_MIC: '소리 센서', + COALABOARD_UserSensor: '사용자 입력', + COALABOARD_UserInput: '사용자 입력', COALABOARD_dc_direction_ccw: '반시계', COALABOARD_dc_direction_cw: '시계', }, @@ -1108,7 +1063,7 @@ Entry.Coalaboard.setLanguage = function() { en: { // en.js에 작성하던 내용 template: { - coalaboard_when_button_pressed: '%1 when button %2 %3', + coalaboard_when_button_pressed: '%1 when button %2', coalaboard_when_sensor_get_value: '%1 when %2 value %3 %4', coalaboard_is_touch_pressed: 'button %1 %2?', coalaboard_is_sensor_value_compare: '%1 %2 %3? ', @@ -1130,6 +1085,7 @@ Entry.Coalaboard.setLanguage = function() { COALABOARD_light: 'light', COALABOARD_IR: 'IR', COALABOARD_touch: 'touch', + COALABOARD_temperature: 'temperature', COALABOARD_ultrasonicSensor: 'ultrasonicSenso', COALABOARD_vibrationSensor: 'vibrationSensor', COALABOARD_potentiometer: 'potentiometer', From 528fc5c51c18965535f75f27a9d43e642a46170e Mon Sep 17 00:00:00 2001 From: Tnks2U Date: Mon, 20 Mar 2023 16:40:40 +0900 Subject: [PATCH 5/9] =?UTF-8?q?lang:=20=EC=BD=94=EC=95=8C=EB=9D=BC?= =?UTF-8?q?=EB=B3=B4=EB=93=9C=20=EB=8B=A4=EA=B5=AD=EC=96=B4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extern/lang/code.js | 27 ---------- extern/lang/ebs.js | 27 ---------- extern/lang/en.js | 17 ------- extern/lang/jp.js | 15 ------ extern/lang/ko.js | 49 ------------------- .../blocks/hardware/block_coalaboard.js | 24 +++++++++ 6 files changed, 24 insertions(+), 135 deletions(-) diff --git a/extern/lang/code.js b/extern/lang/code.js index d7e4e4102d..06778e1bed 100644 --- a/extern/lang/code.js +++ b/extern/lang/code.js @@ -584,16 +584,6 @@ Lang.Blocks = { "BITBRICK_UserInput": "UserInput", "BITBRICK_dc_direction_ccw": "CCW", "BITBRICK_dc_direction_cw": "CW", - "COALABOARD_light": "light", - "COALABOARD_IR": "IR", - "COALABOARD_touch": "touch", - "COALABOARD_temperature": "temperature", - "COALABOARD_potentiometer": "potentiometer", - "COALABOARD_MIC": "MIC", - "COALABOARD_UserSensor": "UserSensor", - "COALABOARD_UserInput": "UserInput", - "COALABOARD_dc_direction_ccw": "CCW", - "COALABOARD_dc_direction_cw": "CW", "chocopi_control_event_pressed": "누를 때", "chocopi_control_event_released": "뗄 때", "chocopi_joystick_X": "조이스틱 좌우", @@ -3031,7 +3021,6 @@ Lang.Menus = { "arduinoCompatible": "아두이노 호환보드", "bitBlock": "비트블록", "bitbrick": "비트브릭", - "coalaboard": "코알라보드", "creamo": "크리모", "playcode": "플레이코드", "funboard": "펀보드", @@ -5731,7 +5720,6 @@ Lang.Device = { "trueRobot": "뚜루뚜루", "CODEino": "코드이노", "bitbrick": "비트브릭", - "coalaboard": "코알라보드", "creamo": "크리모", "playcode": "플레이코드", "funboard": "펀보드", @@ -6007,21 +5995,6 @@ Lang.template = { "bitbrick_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", "bitbrick_dc_speed": "디씨모터 %1 속도 %2 %3", "bitbrick_turn_off_all_motors": "모든 모터 멈추기 %1", - "coalaboard_when_button_pressed": "%1 버튼 %2 눌러졌을 때", - "coalaboard_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", - "coalaboard_is_touch_pressed": "버튼 %1 이(가) %2 인가?", - "coalaboard_is_sensor_value_compare": '%1 값 %2 %3 인가?', - "coalaboard_sensor_value": "%1 값", - "coalaboard_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", - "coalaboard_turn_on_color_led_by_rgb": "엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기", - "coalaboard_turn_on_color_led_by_picker": "엘이디를 %1 (으)로 켜기 %2", - "coalaboard_turn_on_color_led_by_value": "엘이디를 %1 (으)로 켜기 %2", - "coalaboard_turn_off_color_led": "엘이디 끄기 %1", - "coalaboard_buzzer": "버저음 %1 내기 %2", - "coalaboard_servomotor_angle": "서보모터 %1 각도 %2 %3", - "coalaboard_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", - "coalaboard_dc_speed": "디씨모터 %1 속도 %2 %3", - "coalaboard_turn_off_all_motors": "모든 모터 멈추기 %1", "start_drawing": "this.startDraw() %1", "stop_drawing": "this.stopDraw() %1", "set_color": "this.brush.color = %1 %2", diff --git a/extern/lang/ebs.js b/extern/lang/ebs.js index c4903ebcc3..c4822c9dcc 100644 --- a/extern/lang/ebs.js +++ b/extern/lang/ebs.js @@ -584,16 +584,6 @@ Lang.Blocks = { "BITBRICK_UserInput": "사용자 입력", "BITBRICK_dc_direction_ccw": "반시계", "BITBRICK_dc_direction_cw": "시계", - "COALABOARD_light": "밝기 센서", - "COALABOARD_IR": "적외선 센서", - "COALABOARD_touch": "버튼", - "COALABOARD_temperature": "온도 센서", - "COALABOARD_potentiometer": "가변저항", - "COALABOARD_MIC": "소리 센서", - "COALABOARD_UserSensor": "사용자 입력", - "COALABOARD_UserInput": "사용자 입력", - "COALABOARD_dc_direction_ccw": "반시계", - "COALABOARD_dc_direction_cw": "시계", "chocopi_control_event_pressed": "누를 때", "chocopi_control_event_released": "뗄 때", "chocopi_joystick_X": "조이스틱 좌우", @@ -3031,7 +3021,6 @@ Lang.Menus = { "arduinoCompatible": "아두이노 호환보드", "bitBlock": "비트블록", "bitbrick": "비트브릭", - "coalaboard": "코알라보드", "creamo": "크리모", "playcode": "플레이코드", "funboard": "펀보드", @@ -5731,7 +5720,6 @@ Lang.Device = { "trueRobot": "뚜루뚜루", "CODEino": "코드이노", "bitbrick": "비트브릭", - "coalaboard": "코알라보드", "creamo": "크리모", "playcode": "플레이코드", "funboard": "펀보드", @@ -6007,21 +5995,6 @@ Lang.template = { "bitbrick_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", "bitbrick_dc_speed": "디씨모터 %1 속도 %2 %3", "bitbrick_turn_off_all_motors": "모든 모터 멈추기 %1", - "coalaboard_when_button_pressed": "%1 버튼 %2 눌러졌을 일 때", - "coalaboard_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", - "coalaboard_is_touch_pressed": "버튼 %1 이(가) %2 인가?", - "coalaboard_is_sensor_value_compare": '%1 값 %2 %3 인가?', - "coalaboard_sensor_value": "%1 값", - "coalaboard_convert_scale": "변환 %1 값 %2 ~ %3 에서 %4 ~ %5", - "coalaboard_turn_on_color_led_by_rgb": "엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기", - "coalaboard_turn_on_color_led_by_picker": "엘이디를 %1 (으)로 켜기 %2", - "coalaboard_turn_on_color_led_by_value": "엘이디를 %1 (으)로 켜기 %2", - "coalaboard_turn_off_color_led": "엘이디 끄기 %1", - "coalaboard_buzzer": "버저음 %1 내기 %2", - "coalaboard_servomotor_angle": "서보모터 %1 각도 %2 %3", - "coalaboard_dc_direction_speed": "디씨모터 %1 방향 %2 속력 %3 %4", - "coalaboard_dc_speed": "디씨모터 %1 속도 %2 %3", - "coalaboard_turn_off_all_motors": "모든 모터 멈추기 %1", "start_drawing": "그리기 시작하기 %1", "stop_drawing": "그리기 멈추기 %1", "set_color": "붓의 색을 %1 (으)로 정하기 %2", diff --git a/extern/lang/en.js b/extern/lang/en.js index 7554a65f11..6c86204fe6 100644 --- a/extern/lang/en.js +++ b/extern/lang/en.js @@ -2227,7 +2227,6 @@ Lang.Menus = { "arduinoCompatible": "non-certified", "bitBlock": "BitBlock", "bitbrick": "Bitbrick", - "coalaboard": "Coala Board", "creamo": "creamo", "playcode": "playcode", "funboard": "funboard", @@ -4929,7 +4928,6 @@ Lang.Device = { "trueRobot": "TrueTrueRobot", "CODEino": "CODEino", "bitbrick": "bitbrick", - "coalaboard": "Coala Board", "creamo": "creamo", "playcode": "playcode", "funboard": "funboard", @@ -5205,21 +5203,6 @@ Lang.template = { "bitbrick_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", "bitbrick_dc_speed": "dc motor %1 velocity %2 %3", "bitbrick_turn_off_all_motors": "stop all motors %1", - "coalaboard_when_button_pressed": "%1 when button %2", - "coalaboard_when_sensor_get_value": "%1 when %2 value %3 %4", - "coalaboard_is_touch_pressed": "button %1 %2?", - "coalaboard_is_sensor_value_compare": "%1 %2 %3?", - "coalaboard_sensor_value": "%1 value", - "coalaboard_convert_scale": "map %1 value from %2 ~ %3 to %4 ~ %5", - "coalaboard_turn_on_color_led_by_rgb": "set LED color to Red %1 Green %2 Blue %3 %4", - "coalaboard_turn_on_color_led_by_picker": "set LED color to %1 %2", - "coalaboard_turn_on_color_led_by_value": "set LED color %1 %2", - "coalaboard_turn_off_color_led": "turn off LED %1", - "coalaboard_buzzer": "buzz note %1 %2", - "coalaboard_servomotor_angle": "servo motor %1 degree %2 %3", - "coalaboard_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", - "coalaboard_dc_speed": "dc motor %1 velocity %2 %3", - "coalaboard_turn_off_all_motors": "stop all motors %1", "start_drawing": "Start drawing %1", "stop_drawing": "Stop drawing %1", "set_color": "Set brush color to %1 %2", diff --git a/extern/lang/jp.js b/extern/lang/jp.js index 704d4758f5..9f5722aa67 100644 --- a/extern/lang/jp.js +++ b/extern/lang/jp.js @@ -5999,21 +5999,6 @@ Lang.template = { "bitbrick_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", "bitbrick_dc_speed": "dc motor %1 velocity %2 %3", "bitbrick_turn_off_all_motors": "stop all motors %1", - "coalaboard_when_button_pressed": "%1 when button %2", - "coalaboard_when_sensor_get_value": "%1 when %2 value %3 %4", - "coalaboard_is_touch_pressed": "button %1 %2?", - "coalaboard_is_sensor_value_compare": "%1 %2 %3?", - "coalaboard_sensor_value": "%1 value", - "coalaboard_convert_scale": "map %1 value from %2 ~ %3 to %4 ~ %5", - "coalaboard_turn_on_color_led_by_rgb": "set LED color to Red %1 Green %2 Blue %3 %4", - "coalaboard_turn_on_color_led_by_picker": "set LED color to %1 %2", - "coalaboard_turn_on_color_led_by_value": "set LED color %1 %2", - "coalaboard_turn_off_color_led": "turn off LED %1", - "coalaboard_buzzer": "buzz note %1 %2", - "coalaboard_servomotor_angle": "servo motor %1 degree %2 %3", - "coalaboard_dc_direction_speed": "dc motor %1 direction %2 speed %3 %4", - "coalaboard_dc_speed": "dc motor %1 velocity %2 %3", - "coalaboard_turn_off_all_motors": "stop all motors %1", "start_drawing": "描きはじめる %1", "stop_drawing": "描きおえる %1", "set_color": "筆の色を%1にする %2", diff --git a/extern/lang/ko.js b/extern/lang/ko.js index 7f809def06..c023eb7538 100644 --- a/extern/lang/ko.js +++ b/extern/lang/ko.js @@ -599,16 +599,6 @@ Lang.Blocks = { BITBRICK_UserInput: '사용자 입력', BITBRICK_dc_direction_ccw: '반시계', BITBRICK_dc_direction_cw: '시계', - COALABOARD_light: '밝기 센서', - COALABOARD_IR: '적외선 센서', - COALABOARD_touch: '버튼', - COALABOARD_temperature: '온도 센서', - COALABOARD_potentiometer: '가변저항', - COALABOARD_MIC: '소리 센서', - COALABOARD_UserSensor: '사용자 입력', - COALABOARD_UserInput: '사용자 입력', - COALABOARD_dc_direction_ccw: '반시계', - COALABOARD_dc_direction_cw: '시계', chocopi_control_event_pressed: '누를 때', chocopi_control_event_released: '뗄 때', chocopi_joystick_X: '조이스틱 좌우', @@ -3153,7 +3143,6 @@ Lang.Menus = { arduinoCompatible: '아두이노 호환보드', bitBlock: '비트블록', bitbrick: '비트브릭', - coalaboard: '코알라보드', creamo: '크리모', playcode: '플레이코드', funboard: '펀보드', @@ -6578,28 +6567,6 @@ Lang.Helper = { diaboard_buzzer_speed_bpm_change: '입력한 BPM만큼 연주 속도를 바꿉니다.', diaboard_buzzer_sleep_rhythm: '선택한 박자만큼 쉽니다.', diaboard_buzzer_stop: '버저음을 멈춥니다.', - coalaboard_when_button_pressed: '비트브릭 버튼을 누르면 아래에 연결된 블록들을 실행합니다.', - coalaboard_when_sensor_get_value: - '비트브릭 센서의 값과 오른쪽에 입력한 값을 비교합니다.\n< : 센서 값이 오른쪽에 위치한 값보다 작은 경우 ‘참’으로 판단합니다.\n> : 센서 값이 오른쪽에 위치한 값보다 큰 경우 ‘참으로 판단합니다.\n= : 센서 값이 오른쪽에 위치한 값과 같은 경우 ‘참으로 판단합니다.', - coalaboard_sensor_value: - '비트브릭 센서를 사용할 수 있는 블록입니다. 센서값의 범위는 0 ~1023입니다. 메인보드에 연결된 센서의 종류와 포트번호를 자동으로 인식합니다. 블록 안의 화살표를 눌러 사용하려고 하는 센서를 선택하세요.', - coalaboard_convert_scale: '비트브릭 센서의 값의 범위를 바꿀 수 있습니다.', - coalaboard_is_touch_pressed: '비트브릭 센서 중 버튼을 눌렀을 경우 ‘참’으로 판단합니다.', - coalaboard_turn_off_color_led: '비트브릭 엘이디를 끕니다.', - coalaboard_turn_on_color_led_by_rgb: - '비트브릭 엘이디를 빛의 삼원색인 빨강,초록,파랑을 혼합하여 켭니다. 값의 범위는 0 ~ 255입니다.', - coalaboard_turn_on_color_led_by_picker: '비트브릭 엘이디를 색상 창을 사용해 켭니다.', - coalaboard_turn_on_color_led_by_value: - '비트브릭 엘이디를 색상 값으로 켭니다. 값의 범위는 0 ~ 199입니다.', - coalaboard_buzzer: - '비트브릭 버저를 사용하여 소리를 냅니다. 값의 범위는 0 ~ 96입니다. 값이 0일 때는 버저 소리를 끕니다.', - coalaboard_turn_off_all_motors: '비트브릭 모터를 모두 끕니다.', - coalaboard_dc_speed: - '비트브릭 디씨모터의 속도를 제어합니다. 속도 값의 범위는 –100 ~ 100입니다. 음수(-)일 때는 반시계방향으로 회전합니다. 양수(+)일 때는 시계방향으로 회전합니다. 속도가 0일 때는 회전을 멈춥니다.', - coalaboard_dc_direction_speed: - '비트브릭 디씨모터의 방향과 속력을 제어합니다. 방향은 시계방향과 반시계방향을 선택할 수 있습니다. 속력 값의 범위는 0 ~ 100입니다. 속력이 0일 때는 회전을 멈춥니다.', - coalaboard_servomotor_angle: - '비트브릭 서보모터의 각도를 제어합니다. 각도 값의 범위는 0 ~ 180입니다.' }; Lang.Category = { entrybot_friends: '엔트리봇 친구들', @@ -6659,7 +6626,6 @@ Lang.Device = { trueRobot: '뚜루뚜루', CODEino: '코드이노', bitbrick: '비트브릭', - coalaboard: '코알라보드', creamo: '크리모', playcode: '플레이코드', funboard: '펀보드', @@ -6939,21 +6905,6 @@ Lang.template = { bitbrick_dc_direction_speed: '디씨모터 %1 방향 %2 속력 %3 %4', bitbrick_dc_speed: '디씨모터 %1 속도 %2 %3', bitbrick_turn_off_all_motors: "모든 모터 멈추기 %1", - coalaboard_when_button_pressed: '%1 버튼 %2 눌러졌을 때', - coalaboard_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', - coalaboard_is_touch_pressed: '버튼 %1 이(가) %2 인가?', - coalaboard_is_sensor_value_compare: '%1 값 %2 %3 인가?', - coalaboard_sensor_value: '%1 값', - coalaboard_convert_scale: '변환 %1 값 %2 ~ %3 에서 %4 ~ %5', - coalaboard_turn_on_color_led_by_rgb: '엘이디를 빨강 %1 초록 %2 파랑 %3 %4 (으)로 켜기', - coalaboard_turn_on_color_led_by_picker: '엘이디를 %1 (으)로 켜기 %2', - coalaboard_turn_on_color_led_by_value: '엘이디를 %1 (으)로 켜기 %2', - coalaboard_turn_off_color_led: '엘이디 끄기 %1', - coalaboard_buzzer: '버저음 %1 내기 %2', - coalaboard_servomotor_angle: '서보모터 %1 각도 %2 %3', - coalaboard_dc_direction_speed: '디씨모터 %1 방향 %2 속력 %3 %4', - coalaboard_dc_speed: '디씨모터 %1 속도 %2 %3', - coalaboard_turn_off_all_motors: "모든 모터 멈추기 %1", start_drawing: '그리기 시작하기 %1', stop_drawing: '그리기 멈추기 %1', set_color: '붓의 색을 %1 (으)로 정하기 %2', diff --git a/src/playground/blocks/hardware/block_coalaboard.js b/src/playground/blocks/hardware/block_coalaboard.js index 8e1adf38a2..b29e9ad34d 100644 --- a/src/playground/blocks/hardware/block_coalaboard.js +++ b/src/playground/blocks/hardware/block_coalaboard.js @@ -1059,6 +1059,30 @@ Entry.Coalaboard.setLanguage = function() { Device: { coalaboard: '코알라보드', }, + Helper: { + coalaboard_when_button_pressed: '비트브릭 버튼을 누르면 아래에 연결된 블록들을 실행합니다.', + coalaboard_when_sensor_get_value: + '비트브릭 센서의 값과 오른쪽에 입력한 값을 비교합니다.\n< : 센서 값이 오른쪽에 위치한 값보다 작은 경우 ‘참’으로 판단합니다.\n> : 센서 값이 오른쪽에 위치한 값보다 큰 경우 ‘참으로 판단합니다.\n= : 센서 값이 오른쪽에 위치한 값과 같은 경우 ‘참으로 판단합니다.', + coalaboard_sensor_value: + '비트브릭 센서를 사용할 수 있는 블록입니다. 센서값의 범위는 0 ~1023입니다. 메인보드에 연결된 센서의 종류와 포트번호를 자동으로 인식합니다. 블록 안의 화살표를 눌러 사용하려고 하는 센서를 선택하세요.', + coalaboard_convert_scale: '비트브릭 센서의 값의 범위를 바꿀 수 있습니다.', + coalaboard_is_touch_pressed: '비트브릭 센서 중 버튼을 눌렀을 경우 ‘참’으로 판단합니다.', + coalaboard_turn_off_color_led: '비트브릭 엘이디를 끕니다.', + coalaboard_turn_on_color_led_by_rgb: + '비트브릭 엘이디를 빛의 삼원색인 빨강,초록,파랑을 혼합하여 켭니다. 값의 범위는 0 ~ 255입니다.', + coalaboard_turn_on_color_led_by_picker: '비트브릭 엘이디를 색상 창을 사용해 켭니다.', + coalaboard_turn_on_color_led_by_value: + '비트브릭 엘이디를 색상 값으로 켭니다. 값의 범위는 0 ~ 199입니다.', + coalaboard_buzzer: + '비트브릭 버저를 사용하여 소리를 냅니다. 값의 범위는 0 ~ 96입니다. 값이 0일 때는 버저 소리를 끕니다.', + coalaboard_turn_off_all_motors: '비트브릭 모터를 모두 끕니다.', + coalaboard_dc_speed: + '비트브릭 디씨모터의 속도를 제어합니다. 속도 값의 범위는 –100 ~ 100입니다. 음수(-)일 때는 반시계방향으로 회전합니다. 양수(+)일 때는 시계방향으로 회전합니다. 속도가 0일 때는 회전을 멈춥니다.', + coalaboard_dc_direction_speed: + '비트브릭 디씨모터의 방향과 속력을 제어합니다. 방향은 시계방향과 반시계방향을 선택할 수 있습니다. 속력 값의 범위는 0 ~ 100입니다. 속력이 0일 때는 회전을 멈춥니다.', + coalaboard_servomotor_angle: + '비트브릭 서보모터의 각도를 제어합니다. 각도 값의 범위는 0 ~ 180입니다.' + } }, en: { // en.js에 작성하던 내용 From 92f224d6e1ba0d55c8522479e5292ea8b6e33f1e Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 21 Mar 2023 00:08:15 +0900 Subject: [PATCH 6/9] =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extern/lang/code.js | 2 +- extern/lang/ebs.js | 2 +- extern/lang/en.js | 2 +- extern/lang/jp.js | 2 +- extern/lang/ko.js | 2 +- images/hw/bitbrick.png | Bin 7520 -> 12827 bytes .../blocks/hardware/block_bitbrick.js | 56 +++--------------- 7 files changed, 12 insertions(+), 54 deletions(-) diff --git a/extern/lang/code.js b/extern/lang/code.js index d7e4e4102d..f908bb0b79 100644 --- a/extern/lang/code.js +++ b/extern/lang/code.js @@ -5992,7 +5992,7 @@ Lang.template = { "iboard_rgb_led": "RGB LED의 %1 LED %2 %3", "iboard_set_tone": "디지털 %1 번 핀의 버저를 %2 %3 음으로 %4 초 연주하기 %5", "iboard_toggle_led": "디지털 %1 번 핀 %2 %3", - "bitbrick_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", + "bitbrick_when_button_pressed": "%1 버튼 %2 눌러졌을 때", "bitbrick_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", "bitbrick_is_touch_pressed": "버튼 %1 이(가) %2 인가?", "bitbrick_is_sensor_value_compare": '%1 값 %2 %3 인가?', diff --git a/extern/lang/ebs.js b/extern/lang/ebs.js index c4903ebcc3..fd0a2ddad3 100644 --- a/extern/lang/ebs.js +++ b/extern/lang/ebs.js @@ -5992,7 +5992,7 @@ Lang.template = { "iboard_rgb_led": "RGB LED의 %1 LED %2 %3", "iboard_set_tone": "디지털 %1 번 핀의 버저를 %2 %3 음으로 %4 초 연주하기 %5", "iboard_toggle_led": "디지털 %1 번 핀 %2 %3", - "bitbrick_when_button_pressed": "%1 버튼 %2 이(가) %3 일 때", + "bitbrick_when_button_pressed": "%1 버튼 %2 눌러졌을 때", "bitbrick_when_sensor_get_value": "%1 %2 값 %3 %4 일 때", "bitbrick_is_touch_pressed": "버튼 %1 이(가) %2 인가?", "bitbrick_is_sensor_value_compare": '%1 값 %2 %3 인가?', diff --git a/extern/lang/en.js b/extern/lang/en.js index 7554a65f11..f4ad7242e0 100644 --- a/extern/lang/en.js +++ b/extern/lang/en.js @@ -5190,7 +5190,7 @@ Lang.template = { "iboard_rgb_led": " %1 LED %2 %3", "iboard_set_tone": "Play tone pin %1 on note %2 octave %3 beat %4 %5", "iboard_toggle_led": "Digital %1 Pin %2 %3", - "bitbrick_when_button_pressed": "%1 when button %2 %3", + "bitbrick_when_button_pressed": "%1 when button %2", "bitbrick_when_sensor_get_value": "%1 when %2 value %3 %4", "bitbrick_is_touch_pressed": "button %1 %2?", "bitbrick_is_sensor_value_compare": "%1 %2 %3?", diff --git a/extern/lang/jp.js b/extern/lang/jp.js index 704d4758f5..5fdbac1e2d 100644 --- a/extern/lang/jp.js +++ b/extern/lang/jp.js @@ -5984,7 +5984,7 @@ Lang.template = { "iboard_rgb_led": " %1 LED %2 %3", "iboard_set_tone": "Play tone pin %1 on note %2 octave %3 beat %4 %5", "iboard_toggle_led": "Digital %1 Pin %2 %3", - "bitbrick_when_button_pressed": "%1 when button %2 %3", + "bitbrick_when_button_pressed": "%1 when button %2", "bitbrick_when_sensor_get_value": "%1 when %2 value %3 %4", "bitbrick_is_touch_pressed": "button %1 %2?", "bitbrick_is_sensor_value_compare": "%1 %2 %3?", diff --git a/extern/lang/ko.js b/extern/lang/ko.js index 7f809def06..208092940f 100644 --- a/extern/lang/ko.js +++ b/extern/lang/ko.js @@ -6924,7 +6924,7 @@ Lang.template = { iboard_rgb_led: 'RGB LED의 %1 LED %2 %3', iboard_set_tone: '디지털 %1 번 핀의 버저를 %2 %3 음으로 %4 초 연주하기 %5', iboard_toggle_led: '디지털 %1 번 핀 %2 %3', - bitbrick_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', + bitbrick_when_button_pressed: '%1 버튼 %2 눌러졌을 때', bitbrick_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', bitbrick_is_touch_pressed: '버튼 %1 이(가) %2 인가?', bitbrick_is_sensor_value_compare: '%1 값 %2 %3 인가?', diff --git a/images/hw/bitbrick.png b/images/hw/bitbrick.png index 22905bae534c3436d4e3edee02f05c0f5b300c45..87bba5bd06361906881c3f2756d16cf1c7695ba0 100644 GIT binary patch literal 12827 zcmV+$GUUyPP)m((FlBy0e7E zN&%rz1qGC%ASxh&{$0>-DEbMm3<@ga2B_l>%Gmfk%K z27H;1Tk){|ZK8g&^Cx8!zO2J-;qlX_PW=Y(FBjb6M6GlAtp8_(DWfca??wHt#Vmz2 zTQ%_7XL@=+9YJ348^FIjaElPoEg#K45BUarROcu=C5Jl~b|H{QBgiE`=lw{3gVax! zzx7x{P;g00cOFu*jera!^jkUyo$KemnS?00=_cHg!yLK}pWc1HHtj`l48!^b=G@ml zOCNJ4yLS8MNq?$eU zas~TbS?h#N-`nu1=J+SKmkfmOb{=e>|KS(CN*bD-lkuXOekB+ejlHZj;1@5fNP-pr z))7#nJ?`fb1aLN*<5$U~`+`j8LM4!Ggc9gWIk)!mO!k1Y2J8yQf>W;LivDnr(Jvos7V3@&T6#eqMqg4?^dvxcCNB zMCVOOl5Sc4QhGstZw2hy-v-bBtrhwWx*Bf3XA~qPBtUz6J8Uc23ah^S8lHJj1y4PY z0#n9mXW#n=S@QR#$EU~DbS;0OKgS&`o_GS5e2h_;N(<@f%7R}r!1)Fny$lM)-H945qI0IFN(+GF z;Pv;LVcIl7= ziLiFfS_WP?X=-YOo!@;0!-nYKHwiA8>cepKXt}6k={P#R(=u68#;3w<_k9Rsue~;; z*Voq81}l~=gX>2-gQn)XcI~=1w`*5X|9iNstf}pKsr10q70QcWJ6aMzjn+S3rzi`QFwZi-Ft$-~X zm&5uG^4Pv%g*w<-$`S>qf$uL(o^s1AFl+YjMg8xcx8ISB00#vZAC@hF9+t|A3UFng zq6V3=Set%Odw~+GP$vcD2Uy$S>!uy0@c7)h@W(&>DWDTe*6zK?8f?gTJKV@vR_{D`D3E zX2RI35@)xV9Pr_)`uYF&Rnx+_CL$2X3Leb33iTMR_)iYgvbcs_S4x0VzDy(%c&KsPkhvo?Ky`Fn8txCWSZb2{Q+2T8m5ZcI`A!Kfu$%D?LF zX9m}NX@*_Y%8$!RRSR;GtQwBGF*jw{Kri zXKu)lAu#On%l!e`u>(p=OG74QNR&z?s8lLwZEa=rB8c5)gWW5Wg~UR91>1$gu!r-= zDNvS*IvRw|2E9%K)CoZy4!Kzg9_?;|c`r54sF4M6HPL>Yj9^X~7bbMVSdVKp11D_- zDFU6FtpK?~5%GUzWM>EFdjy4mq%GL*l&a7gn46meJ$m$j)2B~EWo4Cne{FSjr+~}J z5`dE{7|34Nfgn!1SlM^0V&;W~;8evUIHY6q{dOo=O#DE(!z!8bl0ZywCO|~Mo z)1byuyR_TeL6#8R<&$PQInHgu>gvv;_O_uTV+0#&u#j}*C|aN_9OsNr8%Sl~r2ChK z=kvqI?NCvdiquyDH{WtI~D*?opQ2sps}$LELLlj)=>gVv?4N@3^Fq_S@M7+H7yOyCKH@J zdzO7CAt2JS0L&Q2TTQWO5GOneK%^S zm4YYS2?oUhG&n^7*E3T@``xiVX|OIC(MO7qE298b0Zx@BVsHg8J*kKK+YjM};F3c! z{eqe3RmG>@&bs@qPUF-s;b}L-M7tdethn zg%SaH@`CkAN$!WE)nWmeTn>r|oHcqNEGCoty`fjH&^ceNHgLv{v^X`3H`!#mefc>E z&u%E;Lz@Xja(HEV8&a0T{qWQKJH{(u)KG6Ys4Yneyd#61otNkcB>DaFy*xZI^1&+^ zA}B&B_{$;%C-~o(~iP^yKfe;NfRmAOZPuz<>d)0fOB$ zg-PT!Pn(v?e#>X%WKdUI3(2XeK`+CGzqz<~7z=^?%xTdQsFHxQpG0#OSx1CGSp@Wk zE&j<1YR7)4K(R>N!X&yFYUp6`sA#_gogWGD9ECBqRw8(`mx+E3jw3=2ruf_QA?cn~ z%S?4bfKbbU*Kig!|MB}$LYz^Dmza&4j(1g+gONX)Ffc!a*WMcTdiMO}0KF#if%UH~ z`Rj!RSf8kmlUwTqsolonW$&OB!EUN!Lw`V%$U8e8a_rbK=!y>)h7LhZbRe1cPzKC= zVh{AmFZ2SLz%4&~82WU#!j$oWk}C=qumQARir%(*IFkHXyzY~f-wk@Z6H#l)Ke=zd zg+&>`yl5kuX$qGF8Fu-w3k$Hozblq4XHOS>F1~wuL?&5+z)He+rA(9C&~$51W1Jn_ zOwLv)XDwI;jI{WjMH%q)qTSGBNn`0sN>h^QzIB2cX8msupI^xEQZsN%XYWI|YBxM2 zn+KV|cF9uYTiOcy%e>wb|N1&u!JMoMZlWtIDqYT2KbHd_-h@bm#5pH&z#4h1 zmb6#=&0*6jE<$QSux(|it&IUA3Nf_T;n4Pj%^Nq;KI#`(i=oow3!17F%fDVc8;$4Q zQ;HXEh8B+@=xf)k@zP|^&?-UN3SF~<&$J<+1qUoB&qnQ3s3PWP&-SF800A3mq!KrP zbGznxaYIOs2*$IK(gJ#)o8Hz!*$J0s%J4Qc-TnAkkglkazFHYtLhx+Vd1&$cEXa|g zN6`goW0uiVllvH!l!(#ZNC0l4-VN&T_lnbSU)j+{7qFN6X)@)XiDv{S;^MAOm~&Tr zdS?h^q0^k#6f@7y6rV;tOg93ajhYk#^K-z*%$3L?x`{Nw5h=h6C*OCj=%#D6UUu&5 z@7tiNPR)4tt)(4igf3_@KCD}JwSx&C0?I=d=1ZWcuoI^v3;f(_;k|8DWJ!#ucs6RY z?aj}j;%7a!={MWAyFXK62j#DE1(=`yXxR6`hJ+%|^q^dk42j87IDF&?%RdvqEN|R) z44#~th90RMHXyj!=@Q66r6|nr{I+8`Vq-(l__7vVRdkZrFSVvNJVMcuALzou+S*UiKrnPkD{#;Cq)=!3)nlPZ|q-*TYzT&&@W}^zcz-4v-&7L|BoGI4;r^sTv<}Bf0@rN9&|K{iBHyJpUYP>F2 z_apHed9JOym~->`KlZ_m)4qgjZr=izPgoDLp5BI`U&95vyrmxUK;4@N zFgBXA)w_*>AJIV=5Efzw-9_X9`KBQ$so^!GMydf$e;IIz!=Y$s5=U|^J@qwg-!F%po&({czI~zK(o4YtJ>ijsr56O`>KY5%_8dG9(C`sJ<7$io zn!V`HH*pkcZ&E}6`wjr3F;#~=G}>(r@Ic&vazYs?|W)nYU5BC#1&v)Df#vrHcu(|*^z){iNI+t z?%1cw1GsoSz<}NSt12(>Z&M}$-i3zCw#Xg@hmgPA||MB`c4Yz8No-Eq-A!8 z&0EiO9=gc0dvr%#?7nb38!CK|ht_fx6_{}}Mb!HfQrc_$ zcy`ZW4Lo|sIhZh_3HBWEpCLkROKltqgSZ0x(I+dtK2y%wcSx(JWM`@&uUC?fbK}!s z_UZsxs4)9t9B)iQW3EC8&650lV>MKs+$OsBCopf|{Wfm^IKK@4w8P|+#uoOqAh^vi zVPxO}KEj~8P#DB3(LuE+UPTw(;5&_iyt<(m9fqMpvc&zPJPV{Lx1lB{GY#R+y$sby z{{uN)0&sBFqrAqO_W+!ki^m(|GTxYE(2ey_P*~_!3QCYOr%yw3b2HRcS2M?p1{Tmf zD8Uh<&uj_|rDoB3(0nW3&ot10K>XnO`p6R-mkGxjh_w zyio#G7){J6mcgi@v4>wYy@oP<-MV%2n%zKSvZ|}9m_`_yczg-Pe$68^+)k+rfWTW+ebb10z7%gW5)M&`*p7|CwU~T?GD#%Wc9B7(z z`=HU3}6BO%Fj>0%5}$K&q*yzOiE$BL7c0HD$gK= zf4!+?0|^$dpuq+lEPSJtjYy=yKZ^Ox=eFIq)(Ku#(F-zu}V&s6XxEhgsGErASaW*G>KZzx*(lxX4cnCLV(h?@(UXS zn}9W0xQGFcNo48#s0@j#J(4CM8Uy(}vMqiI5~2amp}#FnP0-xf_<5%Q+*n`lrNK06 zQ7Vl`hrSIttr|Bz|0{so(U=J!L2RAX75q5rtQ?lypb1;FT~Lvtuc64}JL&xrG~Ll* zxs%sq0@~3W^WRx57BDt9`)V+C_?N^T;Ii@~Uf$gU_dgIL2a~f>hg&UsA55GTCxNT& zD6IfAE-5Mb!U9XLU z^Lm0SNlpc6*Isz%N;f~Fn+u%H;^yc0@+>-eiu?|q4Fc@KSNF0AK!^(7UNoX3gC|Rh znxErQ!a-~tycM;#2tm!FAYO>cNTYY{*a`VPZGLeuB{AOr>=;zzQ_bHj@oWWdm0`8k z%RHa#DDx-l)87rQ8+7DinorDXq8p_rT(2|2=;4l#JR9C#DgD6p!bHJO8YgY$ z>{0gPM!>UlZ=|j7{CNb-oVOij+<7tHs}<%xzl#mQ(d*3&{Clccx1q1ZV|HOg0Q;6nAU@Cs0GN1|;@QH1c6`#Ukk>o9P)4He=tAR+5riCM zwkdvA>B4s-63^0@WERtgekitnU+o5&w3onJx$XqgkQIgu>=KZl?|Wjq8{~ICI>It` z^m{?78uYMqLmw#2_g4UFTi+@}fl5`xEli3uo?ZM-Ba3N^u29Ejnr(bZCa$T0Ia+?2 zUVWAgY?ox@_*h&yZb__WCTDN;9@fid74!=n&jtXBOfrE;uQ?eSrlABBnP$qqW#hj2 zj}B&l3!F@H$4z`yUeabdkKl;iduPWe7wYiW>od_AyC`n)b5sD6$Lu)>tfHcl5&xJ% z)E3D(uXuLPfi@`l&I*g?r^n{+B&WGOX|DQ=7r+F#v*LvN0RTKsYPbj_x}@Oz-0l>` zvoxG_!{)OL2+tv{r3dQa-GfJ%SuXkh9OGP14JSY+jOm72TMrZQRY<)GLcDzYO})IR zjQ)c(9n>Q_;%Di8*0#PB*r_EPd`I|^`Cu2&vJRjPpHx-H7^jcdwVu;hjUBSv#}QkyHS&~@qHmE zqc+jf>~1WZC1@>eA)PY>-tpsZX0qwG;NfsNTTRejzZV=9EhMBQW7L8nh)m(uS~9(Y zkT*(!NrBNXQ}c6?zy*gGnBp zIRM+S1*8`IFMB;+s68%DmZ&%wL!`Ax?$>p7l@y>pNfP=@Wt4I?TOc#B231ajZ6cIihf8TB`?+X>o*}xY-EY`5M+o%SqK>Dy;$Qp$4#{)=1O(!FkPi zke%NG@}w@z-z30D)5yG<5FitCh9rzinq5mUopKwh!eCeEc|D?&^rq|k>JL)5dF+A|oBN<2SSS z4ULT;IXe$hGN~@58bR*ro-0g1eS%)G5Z?-blDQSWBL_+dd&ryzOl|~fcpEyU=ATew zEdjsZdC(3IzAR@Y9G3q5UEj_IQ4`Oi@}fN*ECM%dy-0^YKZ}*-lXg&GEUQgv1-VLm zr$U=W4yJlFDz6kIGRj}v4@P4JB%S>iwBvWO#Ex((2{oh2+8y040@#Ya*iqWcfYxgj zj7P~UCI^eOm%L^&twO>>2z!V_MS<(dv*Fy23s}N|$@?FC-~}iJ;$l1exi)l;>b8SK zlgk4w75CS+)&#Is>p-QmF`#7$p*s}_SW8QXL#OH17ZNXd2&70U#?~58pDqPim!Ta7 zhT>;^Kj6$;kWzFmhr5|=`~>lIrnzLEDPcio+cVCcac5sI=PGyu*qO#k+RjD<&;=>s z5VRv8iXNP3`MK4kV4A5(Y6DGT8#+$@aSj3N2`-7M*BG~hQj1E z@A--_$KiNZjQs2+9B9;G)Dk5>6PPV^8aL3y&jh?5xU}S}s;d{@nw4GIkk*j%GTp+f-_0Q{YA=1d<9GztShpAKP5U9G?$2=I zSQ)(XMJ8HH%cAadbI=cx{GwgV&Lb1H>c|0X$pso6<^wrdW^$9~CpR);(*Y1swqb|t}ved*|Er9k)YJ>aIBZUkd<3%vQ( zTd?6D;SE~%rs<=hI{axE%8W^MOnXZYi>zuRMGsh$hg;}z zP-4Z#si1NHbC7-ZcG$7|CwO>y4_JS&H?(tFxZ;W{V9uOJpm*=y5uKB!mD1Fd#FP}b z|3N^frl+$Riwt;d6Pm|FpJ`MieWwaA$?eD)U}Y|-0$|A=|NjbykrVfdM{5$ODYt^l<+1>z+dSvgdft%WB(%7wST?gchUCYu=c)Bb&sn)(YUfX0#} zsL8V>Z1a_POdpL;Z&DE1uss>7&&yGZL*$X=>8KVxc#z{POaD&^U!Ld*Ny*7D<>u?) z$}300-P62_m0Qr99yoZwRrNh|oi7UQ`u8yM6VjY5EJQq6;XsF|WA-7LF~t7 zCs1SkEyFk4w!z0AuSCa33U^JCLa=dTUi#wnd#!`zz;f2i#3`39W5%tvUBc^nCf&y1TfiuPp^*1pVwgj3wY&|EXYo? zF%#{_v!t;iOmX6XWH26X;YVRaDFkdFaM!L~%K#aX-wHE}jzMA`h59~IVC_cWTFO|O zHI$4U+6wEwbwU@^SlRKJi)jqpYk9lxh{EBql&%?{;{6{0VTh)q_Ui(~;q92d?QLIP12D1y>Lq zn&9l59KY4nJeSJj+E1ft?-}#81T{Hiu{dEJ3{Orb3O4jq6$zxXFM9A@Y<5H-&-Q-z=|{nWQSVMz`^sgvk5^aYrtQ_FQbHmx;Ji#Q3FdwRY-HG7>ZD9V?CN^+U681 z1Fj0@DKd3XmoshHf{Oq8ICGQtf!a;p0p2-?^nHXQGu5&W(C4gxyKdPidyh}o$(u$n4M10;C zQv6Qk{w}B|>%-4@K_I~flBA@7RHx@xGt~}8zD1B*YrKB@`aks%gX`8%Y!~vP%h5}x z*k9;6b+ny_d&aiHl&d3j+=$}T{A`LKB^)Nfg)QMAewi3g51G7Yqiani@|K5qI8*eQ z94%V0g$4L?&CCIN6g4_ru@!-zIh!4U)gWtVItIVfD9_ZvAh9)o6M+VM3!97k`X{li zxR#7X-|Yw3F`utLrj$-6Euo3vO=;T4Ho#%pbYBAB{^G<`VhgMR&u>X?%#)QNF% zk0|FQ6QJr|tn{+iCH`VdID}XxhE=FTt*ovERxkBB19d^+#sDfv6pZV3-EM2;oAIu`302d5MnaY zXf`?OqQF0TWmz+NvZ)x$;*GTPT0+2(mJ;uhrjk~=pCSa0w3E1**10Fp30wl1!l=BS zQdankeoLC|tI2G-D4F93mbR;`wn2;05wb_;t)=fUOLgCjnSrz^I>D&pm6e&SX0%Rg zg*kXXz7_kZZ9NBA(0^CpKE#5ΞnUid~e00_zYZ9D-!1)*XlJtVF($iE1c6+1e$f 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 literal 7520 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 diff --git a/src/playground/blocks/hardware/block_bitbrick.js b/src/playground/blocks/hardware/block_bitbrick.js index 64e814fc31..d708e50196 100644 --- a/src/playground/blocks/hardware/block_bitbrick.js +++ b/src/playground/blocks/hardware/block_bitbrick.js @@ -130,26 +130,6 @@ Entry.Bitbrick = { type: 'input', pos: { x: 0, y: 0 }, }, - A: { - name: Lang.Hw.port_en + ' A ' + Lang.Hw.port_ko, - type: 'input', - pos: { x: 0, y: 0 }, - }, - B: { - name: Lang.Hw.port_en + ' B ' + Lang.Hw.port_ko, - type: 'input', - pos: { x: 0, y: 0 }, - }, - C: { - name: Lang.Hw.port_en + ' C ' + Lang.Hw.port_ko, - type: 'input', - pos: { x: 0, y: 0 }, - }, - D: { - name: Lang.Hw.port_en + ' D ' + Lang.Hw.port_ko, - type: 'input', - pos: { x: 0, y: 0 }, - }, }, // }, // ports : { @@ -236,15 +216,6 @@ Entry.Bitbrick.getBlocks = function() { skeleton: 'basic_event', statements: [], params: [ - // { - // type: 'Indicator', - // img: 'block_icon/start_icon_play.svg', - // size: 14, - // position: { - // x: 0, - // y: -2, - // }, - // }, { type: 'Indicator', img: 'block_icon/hardware_icon.svg', @@ -262,24 +233,15 @@ Entry.Bitbrick.getBlocks = function() { arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, menuName: Entry.Bitbrick.touchList, }, - { - type: 'Dropdown', - options: options_BITBRICK_button2, - value: 'pressed', - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, ], events: {}, def: { - params: [null, null, null], + params: [null, null], type: 'bitbrick_when_button_pressed', }, paramsKeyMap: { DUMMY: 0, PORT: 1, - PRESSED: 2, }, class: 'event', isNotFor: ['bitbrick'], @@ -288,13 +250,9 @@ Entry.Bitbrick.getBlocks = function() { if( script.values.length > 0 ) { let selectedSensor = script.values[ 1 ]; let port = script.getStringField('PORT'); - let type = Entry.hw.portData[port].type; let val = Entry.hw.portData[port].value; // 0이면 누름, 1023이면 누르지 않음 - let pressed = script.getStringField('PRESSED'); if( selectedSensor == port ) { - if ((pressed == 'pressed') && (val == 0)) { - return script.callReturn(); - } else if ((pressed == 'released') && (val == 1023)) { + if (val == 0) { return script.callReturn(); } else { return this.die(); @@ -306,7 +264,7 @@ Entry.Bitbrick.getBlocks = function() { return this.die(); } }, - syntax: { js: [], py: ['Bitbrick.when_button_pressed(%2, %3)'] }, + syntax: { js: [], py: ['Bitbrick.when_button_pressed(%2)'] }, }, bitbrick_when_sensor_get_value: { color: EntryStatic.colorSet.block.default.HARDWARE, @@ -548,9 +506,9 @@ Entry.Bitbrick.getBlocks = function() { let val = Entry.hw.portData[port].value; let pressed = script.getStringField('PRESSED'); if ((pressed == Lang.Blocks.BITBRICK_button_pressed) && (val == 0)) { - return treu; + return true; } else if ((pressed == Lang.Blocks.BITBRICK_button_released) && (val == 1023)) { - return treu; + return true; } else { return false; } @@ -1067,7 +1025,7 @@ Entry.Bitbrick.setLanguage = function() { ko: { // ko.js에 작성하던 내용 template: { - bitbrick_when_button_pressed: '%1 버튼 %2 이(가) %3 일 때', + bitbrick_when_button_pressed: '%1 버튼 %2 눌러졌을 때', bitbrick_when_sensor_get_value: '%1 %2 값 %3 %4 일 때', bitbrick_is_touch_pressed: '버튼 %1 이(가) %2 인가?', bitbrick_is_sensor_value_compare: '%1 값 %2 %3 인가?', @@ -1108,7 +1066,7 @@ Entry.Bitbrick.setLanguage = function() { en: { // en.js에 작성하던 내용 template: { - bitbrick_when_button_pressed: '%1 when button %2 %3', + bitbrick_when_button_pressed: '%1 when button %2', bitbrick_when_sensor_get_value: '%1 when %2 value %3 %4', bitbrick_is_touch_pressed: 'button %1 %2?', bitbrick_is_sensor_value_compare: '%1 %2 %3? ', From 4283770382ba6100a165a17c9ba195c7bbda556a Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 21 Mar 2023 00:44:35 +0900 Subject: [PATCH 7/9] =?UTF-8?q?=EB=B8=94=EB=A1=9D=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/playground/blocks/hardware/block_bitbrick.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/playground/blocks/hardware/block_bitbrick.js b/src/playground/blocks/hardware/block_bitbrick.js index d708e50196..61b7a12021 100644 --- a/src/playground/blocks/hardware/block_bitbrick.js +++ b/src/playground/blocks/hardware/block_bitbrick.js @@ -502,12 +502,13 @@ Entry.Bitbrick.getBlocks = function() { class: 'button', isNotFor: ['bitbrick'], func: function(sprite, script) { + console.info("bitbrick_is_touch_pressed"); let port = script.getStringField('PORT'); let val = Entry.hw.portData[port].value; let pressed = script.getStringField('PRESSED'); - if ((pressed == Lang.Blocks.BITBRICK_button_pressed) && (val == 0)) { + if ((pressed == 'pressed') && (val == 0)) { return true; - } else if ((pressed == Lang.Blocks.BITBRICK_button_released) && (val == 1023)) { + } else if ((pressed == 'released') && (val == 1023)) { return true; } else { return false; From cac04c98c871a69b29fc556ca49a02a16e190ed2 Mon Sep 17 00:00:00 2001 From: Tnks2U Date: Wed, 22 Mar 2023 16:33:45 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=EC=86=A1=EC=88=98=EC=8B=A0=20?= =?UTF-8?q?=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../blocks/hardwareLite/block_microbit2_lite.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/playground/blocks/hardwareLite/block_microbit2_lite.js b/src/playground/blocks/hardwareLite/block_microbit2_lite.js index c342ec8047..df806eb0d2 100644 --- a/src/playground/blocks/hardwareLite/block_microbit2_lite.js +++ b/src/playground/blocks/hardwareLite/block_microbit2_lite.js @@ -1,5 +1,9 @@ 'use strict'; +const _throttle = require('lodash/throttle'); + +const EVENT_INTERVAL = 150; + (function () { Entry.Microbit2lite = new (class Microbit2Lite { constructor() { @@ -14,7 +18,7 @@ bufferSize: 512, connectionType: 'ascii', }; - this.duration = 200; + this.duration = 64; this.functionKeys = { LOCALDATA: 'localdata', GET_ANALOG: 'get-analog', @@ -265,6 +269,13 @@ 'microbit2lite_get_sound_level', ]; this.version = '2'; + this.firePressedBtnEventWithThrottle = _throttle( + (pressedBtn) => { + Entry.engine.fireEventWithValue('microbit2lite_btn_pressed', pressedBtn); + }, + EVENT_INTERVAL, + { leading: true, trailing: false } + ); } _clamp(value, min, max) { if (value < min) { @@ -319,7 +330,7 @@ // INFO: A,B 버튼이벤트 관련 로직 const pressedBtn = response.split(':btn:')[1]; if (pressedBtn) { - Entry.engine.fireEventWithValue('microbit2lite_btn_pressed', pressedBtn); + this.firePressedBtnEventWithThrottle(pressedBtn); } } From a69647e1375c5487d76ad38246a85df8627b37f7 Mon Sep 17 00:00:00 2001 From: Tnks2U Date: Wed, 22 Mar 2023 16:35:28 +0900 Subject: [PATCH 9/9] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A1=9C=EA=B7=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/class/hw_lite.ts | 2 -- src/playground/blocks/hardwareLite/block_microbit2_lite.js | 5 ----- 2 files changed, 7 deletions(-) diff --git a/src/class/hw_lite.ts b/src/class/hw_lite.ts index f7681e8b89..1cb9946a72 100644 --- a/src/class/hw_lite.ts +++ b/src/class/hw_lite.ts @@ -434,13 +434,11 @@ export default class HardwareLite { throw new Error('HARDWARE LITE NOT CONNECTED'); } await this.writer.write(encodedData); - console.log("sendAsync writer: ", encodedData); if (isResetReq) { this.isSendAsyncRun = false; return; } const { value, done } = await this.reader.read(); - console.log("sendAsync reader: ", value); if (callback) { return callback(value); } diff --git a/src/playground/blocks/hardwareLite/block_microbit2_lite.js b/src/playground/blocks/hardwareLite/block_microbit2_lite.js index df806eb0d2..a74f28e860 100644 --- a/src/playground/blocks/hardwareLite/block_microbit2_lite.js +++ b/src/playground/blocks/hardwareLite/block_microbit2_lite.js @@ -317,8 +317,6 @@ const EVENT_INTERVAL = 150; } async listenBtnPressedEvent() { - console.log(this.commandStatus); - if (Object.keys(this.commandStatus).length > 0) { return; } @@ -373,9 +371,7 @@ const EVENT_INTERVAL = 150; if (!Entry.engine.isState('run')) { return; } - console.log("cmd : ", command); const result = await Entry.hwLite.sendAsyncWithThrottle(command); - console.log('getResponseWithSync : ', result); if (!result || this.getCommandType(command) !== this.getCommandType(result) || @@ -395,7 +391,6 @@ const EVENT_INTERVAL = 150; console.error('UnExpected Microbit command'); } } else { - console.log("delete : ", command); delete this.commandStatus[command]; }