diff --git a/src/playground/blocks/hardware/block_avatarbot.js b/src/playground/blocks/hardware/block_avatarbot.js index ce5ec04514..b449766cdb 100644 --- a/src/playground/blocks/hardware/block_avatarbot.js +++ b/src/playground/blocks/hardware/block_avatarbot.js @@ -76,8 +76,12 @@ Entry.avatarbot = { Entry.hw.sendQueue.CMD[index+6] = (Entry.avatarbot.Board_PCA9568.Osci>>8)&0xff; Entry.hw.sendQueue.CMD[index+7] = (Entry.avatarbot.Board_PCA9568.Osci>>16)&0xff; Entry.hw.sendQueue.CMD[index+8] = (Entry.avatarbot.Board_PCA9568.Osci>>24)&0xff; + + this.servo_on.fill(0); + this.servo_init.fill(0); + this.servo_speed.fill(3); - // servo moter + // servo moter for(var i=0; i<8; i++) { index = Entry.avatarbot.BoardFunType.Servo_M0 + (i*10); @@ -92,6 +96,8 @@ Entry.avatarbot = { Entry.hw.sendQueue.CMD[index+7] = (Entry.avatarbot.Board_Servo.us_Max)&0xff; Entry.hw.sendQueue.CMD[index+8] = (Entry.avatarbot.Board_Servo.us_Max>>8)&0xff; + + Entry.hw.sendQueue.CMD[index+9] = (Entry.avatarbot.Board_Servo.angle)&0xff; } // led @@ -205,19 +211,34 @@ Entry.avatarbot = { Freq: 50 }, + // default - sg90 + servo_on: new Array(8).fill(0), + servo_init: new Array(8).fill(0), + servo_speed: new Array(8).fill(3), Board_Servo : { Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, - + + Board_Servo_SelectType : { + // sg90 + sg90_us_min: 400, + sg90_us_max: 2100, + // mg996r + mg996r_us_min: 400, + mg996r_us_max: 2360, + }, + // Board_Servo_M0 : { En:0, Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, Board_Servo_M1 : { @@ -225,7 +246,8 @@ Entry.avatarbot = { Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, Board_Servo_M2 : { @@ -233,7 +255,8 @@ Entry.avatarbot = { Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, Board_Servo_M3 : { @@ -241,7 +264,8 @@ Entry.avatarbot = { Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, Board_Servo_M4 : { @@ -249,7 +273,8 @@ Entry.avatarbot = { Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, Board_Servo_M5 : { @@ -257,7 +282,8 @@ Entry.avatarbot = { Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, Board_Servo_M6 : { @@ -265,7 +291,8 @@ Entry.avatarbot = { Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, Board_Servo_M7 : { @@ -273,7 +300,8 @@ Entry.avatarbot = { Pulse_Min: 150, Pulse_Max: 600, us_Min: 400, - us_Max: 2100 + us_Max: 2100, + angle: 90 }, dc_m_index: new Array(4).fill(0), @@ -287,7 +315,10 @@ Entry.avatarbot = { En3:0, CCW3:0 }, - + // + dc_lineCar_index: new Array(16).fill(0), // 4(control)*4(index) + dc_lineCar_ir_index: new Array(2).fill(0), + // Board_MPU6050 : { En:0, // get value list @@ -320,6 +351,7 @@ Entry.avatarbot = { ch1_cm: 0, ch2_inch: 0 }, + /* monitorTemplate: { imgPath: 'hardware/avatarbot.png', @@ -438,6 +470,7 @@ Entry.avatarbot.setLanguage = function() { avatarbot_get_pwm_port_number: '%1 ', avatarbot_get_buzzer_tone_number: '%1 ', avatarbot_get_buzzer_time_number: '%1 ', + avatarbot_get_servo_speed_number: '%1 ', avatarbot_get_sensor_number: '%1 ', avatarbot_get_port_number: '%1 ', avatarbot_get_digital_toggle: '%1 ', @@ -453,13 +486,30 @@ Entry.avatarbot.setLanguage = function() { avatarbot_ext_get_digital: '디지털 %1 번 센서값', avatarbot_DC_CW: '정회전', avatarbot_DC_CCW: '역회전', + // + avatarbot_DC_CAR_F: ' 앞 ', + avatarbot_DC_CAR_B: ' 뒷 ', + // avatarbot_func_on: '시작', avatarbot_func_off: '정지', - + // + avatarbot_DC_LINECAR_STOP: '정지', + avatarbot_DC_LINECAR_RUN: '전진', + avatarbot_DC_LINECAR_BACK: '후진', + avatarbot_DC_LINECAR_LEFT: '왼쪽', + avatarbot_DC_LINECAR_RIGHT: '오른쪽', + // + avatarbot_DC_LINECAR_DETECTION_BOTH: '라인 둘 다 감지', + avatarbot_DC_LINECAR_DETECTION_LEFT: '라인 왼쪽 감지', + avatarbot_DC_LINECAR_DETECTION_RIGHT: '라인 오른쪽 감지', + avatarbot_DC_LINECAR_DETECTION_NONE: '라인 잃어버림', + // + avatarbot_servo_type_sg90: 'SG90', + avatarbot_servo_type_mg996r: 'MG996R', // // avatarbot_hw_test: 'AvatarBot HW Test %1 번 값 ', // - avatarbot_get_button: '버튼 값 가져오기 ', + // avatarbot_get_button: '버튼 값 가져오기 ', avatarbot_get_number_sensor_value: '아날로그 %1 번 센서값 가져오기 ', // adc avatarbot_convert_scale: '%1 값의 범위를 %2 ~ %3 에서 %4 ~ %5 (으)로 바꾼값 가져오기 ', avatarbot_get_digital_value: '디지털 %1 번 센서값 가져오기 ', @@ -467,15 +517,30 @@ Entry.avatarbot.setLanguage = function() { avatarbot_toggle_pwm: 'PWM %1 번 핀을 %2 % 로 %3 ', // // avatarbot_pca9568: '모터 컨트롤 주파수 %1 와 오실레이터 %2 (으)로 설정 ', - avatarbot_servo: '서보 모터 %1 을 시간(us) %2 ~ %3로 %4 ° %5 ', + avatarbot_servo: '서보 모터 %1 을 %2 속도, PWM 시간(us) %3 ~ %4 로 %5 ° %6 ', + avatarbot_servo_sample: '서보 모터 %1 을 %2 속도, %3 로 %4 ° %5 ', avatarbot_dc: 'DC 모터 %1 을 %2 방향으로 %3 % %4 동작 ', + avatarbot_robot_arm_on: '로봇 팔 %1(주의! 시작 전 초기 위치에 각 관절을 위치해주세요.)', + avatarbot_robot_arm_speed: '로봇 팔 몸통 %1, 팔[축1 %2, 축2 %3], 헤드[축1 %4, 축2 %5], 집게 %6 속도 설정', + avatarbot_robot_arm: '로봇 팔 몸통 %1°, 팔[축1 %2°, 축2 %3°], 헤드[축1 %4°, 축2 %5°], 집게 %6° 동작', + avatarbot_dc_car: '자동차 앞[%1 방향, 속도(좌 %2 %, 우 %3 %)], 뒷[%4 방향, 속도(좌 %5 %, 우 %6 %)] %7 동작', + // + avatarbot_line_car_ir_init: '라인트레이서 좌측 센서 %1 %, 우측 센서 %2 % 감도 설정', + avatarbot_line_car_motor_init: '라인트레이서 %1 조건일 때 앞[좌 %2 %, 우 %3 %], 뒷[좌 %4 %, 우 %5 %] 속도 설정', + avatarbot_line_car: '라인트레이서 %1', + // avatarbot_buzzer_sample: '부저 샘플 %1 %2 초 동안 시작 ', avatarbot_buzzer: '부저 %1 소리로 %2 초 동안 시작 ', - avatarbot_led_strip_sample: 'LED 스트립 샘플 %1 ', + // + avatarbot_led_strip_sample: 'LED 스트립 샘플 %1 동작', avatarbot_led_strip_set: 'LED 스트립 LED %1 개, 밝기 %2 % 설정 ', + avatarbot_led_strip_indexOn: 'LED 스트립 LED %1 번 R %2, G %3, B %4 %5', + // avatarbot_ir_remote: '리모컨 %1 (으)로 동작 ', - avatarbot_get_mpu6050: '자이로 가속도 센서 %1 값 가져오기 ', - avatarbot_ultra_sonic:'초음파 %1 번 센서 값 가져오기 ', + avatarbot_get_mpu6050: '자이로 가속도 센서 %1 정보 확인 ', + avatarbot_get_mpu6050_detail: '자이로 가속도 센서 %1 의 %2 값 가져오기 ', + avatarbot_ultra_sonic:'초음파 %1 번 센서 정보 확인 ', + avatarbot_ultra_sonic_detail:'초음파 %1 번 센서 값(%2)', // avatarbot_ir_receiver:'리모컨 %1 모드로 값 가져오기 ', @@ -514,7 +579,7 @@ Entry.avatarbot.blockMenuBlocks = [ // hw data 통신 test // 'avatarbot_hw_test', // base block - 'avatarbot_get_button', + // 'avatarbot_get_button', 'avatarbot_get_number_sensor_value', 'avatarbot_convert_scale', // @@ -524,18 +589,30 @@ Entry.avatarbot.blockMenuBlocks = [ // // 'avatarbot_pca9568', 'avatarbot_servo', + 'avatarbot_servo_sample', 'avatarbot_dc', + 'avatarbot_robot_arm_on', + 'avatarbot_robot_arm_speed', + 'avatarbot_robot_arm', + 'avatarbot_dc_car', + // + 'avatarbot_line_car_ir_init', + 'avatarbot_line_car_motor_init', + 'avatarbot_line_car', // 'avatarbot_buzzer_sample', 'avatarbot_buzzer', 'avatarbot_led_strip_sample', 'avatarbot_led_strip_set', + 'avatarbot_led_strip_indexOn', // 'avatarbot_led_strip', // 'avatarbot_ir_remote', 'avatarbot_get_mpu6050', + 'avatarbot_get_mpu6050_detail', 'avatarbot_ultra_sonic', + 'avatarbot_ultra_sonic_detail', // 'avatarbot_ir_receiver', 'avatarbot_oled_sample', @@ -940,6 +1017,70 @@ Entry.avatarbot.getBlocks = function() { }, }, //--------------------------------------------------------------- + avatarbot_get_servo_speed_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'], + ['5단계', '5'], + ['6단계', '6'], + ['7단계', '7'], + ['8단계', '8'], + ], + value: '3', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + }, + paramsKeyMap: { + SPEED: 0, + }, + func(sprite, script) { + return script.getStringField('SPEED'); + }, + syntax: { + js: [], + py: [ + { + syntax: '%1', + textParams: [ + { + type: 'Dropdown', + options: [ + ['1단계', '1'], + ['2단계', '2'], + ['3단계', '3'], + ['4단계', '4'], + ['5단계', '5'], + ['6단계', '6'], + ['7단계', '7'], + ['8단계', '8'], + ], + value: '3', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + keyOption: 'avatarbot_get_servo_speed_number', + }, + ], + }, + }, + //--------------------------------------------------------------- // get port(module, function) number // - gpio(4), pwm(3), adc(2), dac(2), servo_m(8), dc_m(4), ulrasonic(2) //--------------------------------------------------------------- @@ -952,8 +1093,8 @@ Entry.avatarbot.getBlocks = function() { { type: 'Dropdown', options: [ - ['0', '0'], - ['1', '1'], + ['1', '0'], + ['2', '1'], ], value: '0', fontSize: 11, @@ -980,8 +1121,8 @@ Entry.avatarbot.getBlocks = function() { { type: 'Dropdown', options: [ - ['0', '0'], - ['1', '1'], + ['1', '0'], + ['2', '1'], ], value: '0', fontSize: 11, @@ -1082,10 +1223,10 @@ Entry.avatarbot.getBlocks = function() { { type: 'Dropdown', options: [ - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], ], value: '0', fontSize: 11, @@ -1112,10 +1253,10 @@ Entry.avatarbot.getBlocks = function() { { type: 'Dropdown', options: [ - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], ], value: '0', fontSize: 11, @@ -1138,14 +1279,14 @@ Entry.avatarbot.getBlocks = function() { { type: 'Dropdown', options: [ - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], + ['5', '4'], + ['6', '5'], + ['7', '6'], + ['8', '7'], ], value: '0', fontSize: 11, @@ -1172,14 +1313,14 @@ Entry.avatarbot.getBlocks = function() { { type: 'Dropdown', options: [ - ['0', '0'], - ['1', '1'], - ['2', '2'], - ['3', '3'], - ['4', '4'], - ['5', '5'], - ['6', '6'], - ['7', '7'], + ['1', '0'], + ['2', '1'], + ['3', '2'], + ['4', '3'], + ['5', '4'], + ['6', '5'], + ['7', '6'], + ['8', '7'], ], value: '0', fontSize: 11, @@ -1464,6 +1605,7 @@ Entry.avatarbot.getBlocks = function() { //--------------------------------------------------------------- // base function. //--------------------------------------------------------------- + /* avatarbot_get_button: { color: EntryStatic.colorSet.block.default.HARDWARE, //블록 색상 outerLine: EntryStatic.colorSet.block.darken.HARDWARE, //경계선 색상 @@ -1505,6 +1647,7 @@ Entry.avatarbot.getBlocks = function() { ], }, }, + */ //--------------------------------------------------------------- avatarbot_get_number_sensor_value: { color: EntryStatic.colorSet.block.default.HARDWARE, //블록 색상 @@ -2120,6 +2263,11 @@ Entry.avatarbot.getBlocks = function() { accept: 'string', defaultType: 'number', }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, { type: 'Dropdown', options: [ @@ -2138,6 +2286,9 @@ Entry.avatarbot.getBlocks = function() { { type: 'avatarbot_get_serve_number', }, + { + type: 'avatarbot_get_servo_speed_number', + }, { type: 'number', params: ['400'], @@ -2148,7 +2299,7 @@ Entry.avatarbot.getBlocks = function() { }, { type: 'number', - params: ['0'], + params: ['90'], }, null, ], @@ -2156,18 +2307,19 @@ Entry.avatarbot.getBlocks = function() { }, paramsKeyMap: { VALUE1: 0, - VALUE2: 1, - VALUE3: 2, - VALUE4: 3, - RUN:4, + SPEED:1, + VALUE2: 2, + VALUE3: 3, + VALUE4: 4, + RUN:5, }, - class: 'avatarbot', + class: 'avatarbot_serbo', isNotFor: ['avatarbot'], func(sprite, script) { if (!Entry.hw.sendQueue.CMD) { Entry.avatarbot.dataTableReset(); } - + const speed = script.getNumberValue('SPEED', script); const signal = script.getNumberValue('VALUE1', script); let us_min = script.getNumberValue('VALUE2', script); let us_max = script.getNumberValue('VALUE3', script); @@ -2187,11 +2339,13 @@ Entry.avatarbot.getBlocks = function() { value = Math.max(value, 0); //150 value = Math.min(value, 180); // 600 - + + Entry.avatarbot.servo_speed[signal] = speed&0xf; + let index = (signal*10) + Entry.avatarbot.BoardFunType.Servo_M0; // base+10,20,30,...n // digital setting - Entry.hw.sendQueue.CMD[index] = on; // 1; // ch en + Entry.hw.sendQueue.CMD[index] = on + (Entry.avatarbot.servo_speed[signal]<<4); // 1; // ch en // Entry.hw.sendQueue.CMD[index+1] = 0; // pulse min low // Entry.hw.sendQueue.CMD[index+2] = 0; // pulse min high // Entry.hw.sendQueue.CMD[index+3] = 0; // pulse max low @@ -2209,7 +2363,7 @@ Entry.avatarbot.getBlocks = function() { js: [], py: [ { - syntax: 'avatarbot.servo(%1, %2, %3, %4)', + syntax: 'avatarbot.servo(%1, %2, %3, %4, %5, %6)', blockType: 'param', textParams: [ { @@ -2228,6 +2382,182 @@ Entry.avatarbot.getBlocks = function() { type: 'Block', accept: 'string', }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_func_on, '1'], + [Lang.template.avatarbot_func_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_servo_sample: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_servo_type_sg90, '0'], + [Lang.template.avatarbot_servo_type_mg996r, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_func_on, '1'], + [Lang.template.avatarbot_func_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [ + { + type: 'avatarbot_get_serve_number', + }, + { + type: 'avatarbot_get_servo_speed_number', + }, + null, + { + type: 'number', + params: ['90'], + }, + null, + ], + type: 'avatarbot_servo_sample', + }, + paramsKeyMap: { + VALUE1: 0, + SPEED:1, + VALUE2: 2, + VALUE3: 3, + RUN:4, + }, + class: 'avatarbot_serbo_sample', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + + const speed = script.getNumberValue('SPEED', script); + const signal = script.getNumberValue('VALUE1', script); + let servo_type = script.getNumberValue('VALUE2', script); + let value = script.getNumberValue('VALUE3', script); + const run = script.getField('RUN'); + const on = run == '1' ? 1 : 0; + let us_min = Entry.avatarbot.Board_Servo_SelectType.sg90_us_min; + let us_max = Entry.avatarbot.Board_Servo_SelectType.sg90_us_max; + + value = Math.round(value); + value = Math.max(value, 0); //150 + value = Math.min(value, 180); // 600 + + switch(servo_type) + { + case 0: // sg90 servo motor + us_min = Entry.avatarbot.Board_Servo_SelectType.sg90_us_min; + us_max = Entry.avatarbot.Board_Servo_SelectType.sg90_us_max; + break; + case 1: // mg996r servo motor + us_min = Entry.avatarbot.Board_Servo_SelectType.mg996r_us_min; + us_max = Entry.avatarbot.Board_Servo_SelectType.mg996r_us_max; + break; + default: + break; + } + Entry.avatarbot.servo_speed[signal] = speed&0xf; + + let index = (signal*10) + Entry.avatarbot.BoardFunType.Servo_M0; // base+10,20,30,...n + + // digital setting + // Entry.hw.sendQueue.CMD[index] = on; // 1; // ch en + Entry.hw.sendQueue.CMD[index] = on + (Entry.avatarbot.servo_speed[signal]<<4); // 1; // ch en + // Entry.hw.sendQueue.CMD[index+1] = 0; // pulse min low + // Entry.hw.sendQueue.CMD[index+2] = 0; // pulse min high + // Entry.hw.sendQueue.CMD[index+3] = 0; // pulse max low + // Entry.hw.sendQueue.CMD[index+4] = 0; // pulse max high + Entry.hw.sendQueue.CMD[index+5] = (us_min)&0xff; // us min low + Entry.hw.sendQueue.CMD[index+6] = (us_min>>8)&0xff; // us min high + Entry.hw.sendQueue.CMD[index+7] = (us_max)&0xff; // us max low + Entry.hw.sendQueue.CMD[index+8] = (us_max>>8)&0xff; // us max high + Entry.hw.sendQueue.CMD[index+9] = (value)&0xff; // angle value. 0 ~ 180 + Entry.hw.update(); + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.servo_sample(%1, %2, %3, %4, %5)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_servo_type_sg90, '0'], + [Lang.template.avatarbot_servo_type_mg996r, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + }, { type: 'Dropdown', options: [ @@ -2302,7 +2632,7 @@ Entry.avatarbot.getBlocks = function() { null, { type: 'number', - params: ['0'], + params: ['50'], }, // null, { @@ -2318,7 +2648,7 @@ Entry.avatarbot.getBlocks = function() { // RUN:3, TIME: 3, }, - class: 'avatarbot', + class: 'avatarbot_dc', isNotFor: ['avatarbot'], func(sprite, script) { if (!Entry.hw.sendQueue.CMD) { @@ -2413,13 +2743,13 @@ Entry.avatarbot.getBlocks = function() { }, }, //--------------------------------------------------------------- - avatarbot_buzzer_sample: { + avatarbot_robot_arm_on: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', skeleton: 'basic', statements: [], params: [ - /* { type: 'Dropdown', options: [ @@ -2431,11 +2761,1081 @@ Entry.avatarbot.getBlocks = function() { bgColor: EntryStatic.colorSet.block.darken.HARDWARE, arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, }, - */ - { - type: 'Block', - accept: 'string', - defaultType: 'number', + ], + events: {}, + def: { + params: [ + null, + ], + type: 'avatarbot_robot_arm_on', + }, + paramsKeyMap: { + VALUE1: 0, + }, + class: 'avatarbot_robotArm', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + const on = script.getNumberValue('VALUE1', script); + + // + let value = [90, 180, 180, 90, 0, 0]; + let us_min = [400, 400, 400, 400, 400, 400]; + let us_max = [2360, 2360, 2360, 2100, 2100, 2100]; + + for (let i = 0; i < 6; i++) { + // Entry.avatarbot.servo_on[i] = on; + Entry.avatarbot.servo_on[i] = 0; + + value[i] = Math.round(value[i]); + value[i] = Math.max(value[i], 0); //150 + value[i] = Math.min(value[i], 180); // 600 + let index = (i*10) + Entry.avatarbot.BoardFunType.Servo_M0; // base+10,20,30,...n + + // digital setting + // Entry.hw.sendQueue.CMD[index] = 1; // 1; // ch en + if(Entry.avatarbot.servo_init[i] == 0) + { + Entry.hw.sendQueue.CMD[index] = Entry.avatarbot.servo_on[i] + (1<<1) + (Entry.avatarbot.servo_speed[i]<<4); // 1; // ch en + }else{ + Entry.hw.sendQueue.CMD[index] = Entry.avatarbot.servo_on[i] + (Entry.avatarbot.servo_speed[i]<<4); // 1; // ch en + } + Entry.avatarbot.servo_init[i] = 1; + Entry.hw.sendQueue.CMD[index+5] = (us_min[i])&0xff; // us min low + Entry.hw.sendQueue.CMD[index+6] = (us_min[i]>>8)&0xff; // us min high + Entry.hw.sendQueue.CMD[index+7] = (us_max[i])&0xff; // us max low + Entry.hw.sendQueue.CMD[index+8] = (us_max[i]>>8)&0xff; // us max high + Entry.hw.sendQueue.CMD[index+9] = (value[i])&0xff; // angle value. 0 ~ 180 + } + // + Entry.hw.update(); + /* + setTimeout(() => { + for (let i = 0; i < 6; i++) { + Entry.avatarbot.servo_on[i] = on; + value[i] = Math.round(value[i]); + value[i] = Math.max(value[i], 0); //150 + value[i] = Math.min(value[i], 180); // 600 + let index = (i*10) + Entry.avatarbot.BoardFunType.Servo_M0; // base+10,20,30,...n + Entry.hw.sendQueue.CMD[index] = Entry.avatarbot.servo_on[i] + (Entry.avatarbot.servo_speed[i]<<4); // 1; // ch en + } + Entry.hw.update(); + script.callReturn(); + }, 3000); // 1000ms = 1초 + + // return script.callReturn(); + return; + */ + + if (!script.isStart) { + // 스크립트 시작 플래그 설정 + script.isStart = true; + script.timeFlag = 1; + + // 3000ms 대기 설정 + setTimeout(() => { + script.timeFlag = 0; // 대기 종료 + }, 3000); + return script; + } else if (script.timeFlag === 1) { + // 대기 중인 경우, 스크립트를 멈춤 상태로 유지 + return script; + } else { + // 대기 종료 후, 다음 블록 실행 + delete script.isStart; + delete script.timeFlag; + for (let i = 0; i < 6; i++) + { + Entry.avatarbot.servo_on[i] = on; + value[i] = Math.round(value[i]); + value[i] = Math.max(value[i], 0); + value[i] = Math.min(value[i], 180); + let index = (i * 10) + Entry.avatarbot.BoardFunType.Servo_M0; + Entry.hw.sendQueue.CMD[index] = Entry.avatarbot.servo_on[i] + (Entry.avatarbot.servo_speed[i] << 4); + } + Entry.hw.update(); + return script.callReturn(); + } + + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.robot_arm_on(%1)', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_func_on, '1'], + [Lang.template.avatarbot_func_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + ], + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_robot_arm_speed: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'avatarbot_get_servo_speed_number', + }, + { + type: 'avatarbot_get_servo_speed_number', + }, + { + type: 'avatarbot_get_servo_speed_number', + }, + { + type: 'avatarbot_get_servo_speed_number', + }, + { + type: 'avatarbot_get_servo_speed_number', + }, + { + type: 'avatarbot_get_servo_speed_number', + }, + ], + type: 'avatarbot_robot_arm_speed', + }, + paramsKeyMap: { + VALUE1: 0, + VALUE2: 1, + VALUE3: 2, + VALUE4: 3, + VALUE5: 4, + VALUE6: 5, + }, + class: 'avatarbot_robotArm', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + + for (let i = 0; i < 6; i++) { + Entry.avatarbot.servo_speed[i] = script.getNumberValue(`VALUE${i + 1}`, script); + let index = (i*10) + Entry.avatarbot.BoardFunType.Servo_M0; // base+10,20,30,...n + // digital setting + // Entry.hw.sendQueue.CMD[index] = 1; // 1; // ch en + Entry.hw.sendQueue.CMD[index] = Entry.avatarbot.servo_on[i] + (Entry.avatarbot.servo_speed[i]<<4); // 1; // ch en + } + + Entry.hw.update(); + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.robot_arm_speed(%1, %2, %3, %4, %5, %6)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_robot_arm: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['90'], + }, + { + type: 'number', + params: ['180'], + }, + { + type: 'number', + params: ['180'], + }, + { + type: 'number', + params: ['90'], + }, + { + type: 'number', + params: ['0'], + }, + { + type: 'number', + params: ['0'], + }, + ], + type: 'avatarbot_robot_arm', + }, + paramsKeyMap: { + VALUE1: 0, + VALUE2: 1, + VALUE3: 2, + VALUE4: 3, + VALUE5: 4, + VALUE6: 5, + }, + class: 'avatarbot_robotArm', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + + // const signal = script.getNumberValue('VALUE1', script); + // let us_min = script.getNumberValue('VALUE2', script); + // let us_max = script.getNumberValue('VALUE3', script); + // const int usMinTable[] = {USMIN, 400, 400}; + // const int usMaxTable[] = {USMAX, 2100, 2360}; + + let value = [0, 0, 0, 0, 0, 0]; + let us_min = [400, 400, 400, 400, 400, 400]; + let us_max = [2360, 2360, 2360, 2100, 2100, 2100]; + + for (let i = 0; i < 6; i++) { + value[i] = script.getNumberValue(`VALUE${i + 1}`, script); + value[i] = Math.round(value[i]); + value[i] = Math.max(value[i], 0); //150 + value[i] = Math.min(value[i], 180); // 600 + let index = (i*10) + Entry.avatarbot.BoardFunType.Servo_M0; // base+10,20,30,...n + // digital setting + // Entry.hw.sendQueue.CMD[index] = 1; // 1; // ch en + Entry.hw.sendQueue.CMD[index] = Entry.avatarbot.servo_on[i] + (Entry.avatarbot.servo_speed[i]<<4); // 1; // ch en + Entry.hw.sendQueue.CMD[index+5] = (us_min[i])&0xff; // us min low + Entry.hw.sendQueue.CMD[index+6] = (us_min[i]>>8)&0xff; // us min high + Entry.hw.sendQueue.CMD[index+7] = (us_max[i])&0xff; // us max low + Entry.hw.sendQueue.CMD[index+8] = (us_max[i]>>8)&0xff; // us max high + Entry.hw.sendQueue.CMD[index+9] = (value[i])&0xff; // angle value. 0 ~ 180 + } + + Entry.hw.update(); + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.robot_arm(%1, %2, %3, %4, %5, %6)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_dc_car: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + // front + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_DC_CAR_F, '0'], + [Lang.template.avatarbot_DC_CAR_B, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + // back + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_DC_CAR_F, '0'], + [Lang.template.avatarbot_DC_CAR_B, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + // on/off + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + // front + null, + { + type: 'number', + params: ['100'], + }, + { + type: 'number', + params: ['100'], + }, + // back + null, + { + type: 'number', + params: ['100'], + }, + { + type: 'number', + params: ['100'], + }, + // on/off + { + type: 'avatarbot_get_timer_number', + }, + ], + type: 'avatarbot_dc_car', + }, + paramsKeyMap: { + // front + VALUE1: 0, + VALUE2: 1, + VALUE3: 2, + // back + VALUE4: 3, + VALUE5: 4, + VALUE6: 5, + // on/off - timer + TIME: 6, + }, + class: 'avatarbot_dcCar', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + + // const cw_value = cw == '정회전' ? 1 : 0; + // const signal = script.getNumberValue('VALUE1', script); + let f_cw = script.getNumberValue('VALUE1', script); + let f_speed_l = script.getNumberValue('VALUE2', script); // dc_1 + let f_speed_r = script.getNumberValue('VALUE3', script); // dc_2 + + let b_cw = script.getNumberValue('VALUE4', script); + let b_speed_l = script.getNumberValue('VALUE5', script); // dc_1 + let b_speed_r = script.getNumberValue('VALUE6', script); // dc_2 + + // const run = script.getField('RUN'); + // const on = run == '1' ? 1 : 0; + const time = script.getNumberValue('TIME', script); + const on = time>0? 1:0; // 100ms ~ 1s = 1, 0ms = 0 + + // + f_speed_l = Math.round(f_speed_l); + f_speed_l = Math.max(f_speed_l, 0); + f_speed_l = Math.min(f_speed_l, 100); + // + f_speed_r = Math.round(f_speed_r); + f_speed_r = Math.max(f_speed_r, 0); + f_speed_r = Math.min(f_speed_r, 100); + // + b_speed_l = Math.round(b_speed_l); + b_speed_l = Math.max(b_speed_l, 0); + b_speed_l = Math.min(b_speed_l, 100); + // + b_speed_r = Math.round(b_speed_r); + b_speed_r = Math.max(b_speed_r, 0); + b_speed_r = Math.min(b_speed_r, 100); + // + let cw = [0, 0, 0, 0]; + cw[0] = f_cw; + cw[1] = (f_cw==0)?1:0; + cw[2] = b_cw; + cw[3] = (b_cw==0)?1:0; + + let index = Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + Entry.hw.sendQueue.CMD[index+1] = f_speed_l&0xff; + + index = 2 + Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + Entry.hw.sendQueue.CMD[index+1] = f_speed_r&0xff; + + index = 4 + Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + Entry.hw.sendQueue.CMD[index+1] = b_speed_l&0xff; + + index = 6 + Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + Entry.hw.sendQueue.CMD[index+1] = b_speed_r&0xff; + + for (let i = 0; i < 4; i++) { // 0 ~ 3 + Entry.avatarbot.dc_m_index[i] += 1; // 0 ~ 3 => 1 ~ 4 + if(Entry.avatarbot.dc_m_index[i] > 3) + { + Entry.avatarbot.dc_m_index[i] = 0; // 3, 4 => 0 + } + + if(on == 0) + { + Entry.avatarbot.dc_m_index[i] = 0; // 0 + } + + index = (i*2) + Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + // + Entry.hw.sendQueue.CMD[index] = (on + (cw[i]<<1) + (Entry.avatarbot.dc_m_index[i]<<2) + (time<<4))&0xff; // ch en + } + // + // Entry.hw.sendQueue.CMD[index+1] = speed&0xff; + Entry.hw.update(); + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.dc_car(%1, %2, %3, %4, %5, %6, %7)', + blockType: 'param', + textParams: [ + // front + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_DC_CAR_F, '0'], + [Lang.template.avatarbot_DC_CAR_B, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + // back + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_DC_CAR_F, '0'], + [Lang.template.avatarbot_DC_CAR_B, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + converter: Entry.block.converters.returnStringValue, + }, + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + // on/off - timer + { + type: 'Block', + accept: 'string', + }, + + ], + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_line_car_ir_init: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'number', + params: ['30'], + }, + { + type: 'number', + params: ['30'], + }, + ], + type: 'avatarbot_line_car_ir_init', + }, + paramsKeyMap: { + VALUE1: 0, + VALUE2: 1, + }, + class: 'avatarbot_LineCar', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + let ir1 = script.getNumberValue('VALUE1', script); + let ir2 = script.getNumberValue('VALUE2', script); + + let result = ir1; + result = Math.min(100, result); + result = Math.max(0, result); + Entry.avatarbot.dc_lineCar_ir_index[0] = Math.round(result*4095/100); // 0 ~ 100 -> 0 ~ 4095 + // + result = ir2; + result = Math.min(100, result); + result = Math.max(0, result); + Entry.avatarbot.dc_lineCar_ir_index[1] = Math.round(result*4095/100); // 0 ~ 100 -> 0 ~ 4095 + + // ir adc sensor on + // Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.ADC] = 1; + // Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.ADC + 1] = 1; + Entry.hw.update(); + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.dc_lineCar_ir_init(%1, %2)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_line_car_motor_init: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_DC_LINECAR_DETECTION_BOTH, '0'], + [Lang.template.avatarbot_DC_LINECAR_DETECTION_LEFT, '1'], + [Lang.template.avatarbot_DC_LINECAR_DETECTION_RIGHT, '2'], + [Lang.template.avatarbot_DC_LINECAR_DETECTION_NONE, '3'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + null, + { + type: 'number', + params: ['100'], + }, + { + type: 'number', + params: ['100'], + }, + { + type: 'number', + params: ['100'], + }, + { + type: 'number', + params: ['100'], + }, + ], + type: 'avatarbot_line_car_motor_init', + }, + paramsKeyMap: { + VALUE1: 0, + VALUE2: 1, + VALUE3: 2, + VALUE4: 3, + VALUE5: 4, + }, + class: 'avatarbot_LineCar', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + // + let i = 0; + let result = 0; + let speed = [0, 0, 0, 0]; + + let type = script.getNumberValue('VALUE1', script); + speed[0] = script.getNumberValue('VALUE2', script); // f_speed_l + speed[1] = script.getNumberValue('VALUE3', script); // f_speed_r + speed[2] = script.getNumberValue('VALUE4', script); // b_speed_l + speed[3] = script.getNumberValue('VALUE5', script); // b_speed_r + + let index = type*4; // type = 0 ~ 3 => 0, 4, 8, 12+a + for(i=0; i<4; i++) + { + result = speed[i]; + result = Math.min(100, result); + result = Math.max(0, result); + Entry.avatarbot.dc_lineCar_index[index+i] = result; + } + // + Entry.hw.update(); + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.dc_lineCar_motor_init(%1, %2, %3, %4, %5)', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_DC_LINECAR_DETECTION_BOTH, '0'], + [Lang.template.avatarbot_DC_LINECAR_DETECTION_LEFT, '1'], + [Lang.template.avatarbot_DC_LINECAR_DETECTION_RIGHT, '2'], + [Lang.template.avatarbot_DC_LINECAR_DETECTION_NONE, '3'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_line_car: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_func_off, '0'], + [Lang.template.avatarbot_func_on, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + + ], + events: {}, + def: { + params: [ + null, + ], + type: 'avatarbot_line_car', + }, + paramsKeyMap: { + VALUE1: 0 + }, + class: 'avatarbot_LineCar', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + // + const lineCar_On = script.getNumberValue('VALUE1', script); + + if(lineCar_On == 0) + { + // stop ir adc sensor + Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.ADC] = 0; + Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.ADC + 1] = 0; + + // stop motor + Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.DC_M] = (0)&0xff; // ch en + Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.DC_M + 2] = (0)&0xff; // ch en + Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.DC_M + 4] = (0)&0xff; // ch en + Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.DC_M + 6] = (0)&0xff; // ch en + + Entry.hw.update(); + return script.callReturn(); + } + + let i = 0; + let ir_index =[0, 0]; + let ir_sensorData = [0, 0]; + ir_index[0] = Entry.avatarbot.BoardFunType.ADC; + ir_index[1] = Entry.avatarbot.BoardFunType.ADC + 2; + for(i=0; i<2; i++) + { + let sensorData_low = Entry.hw.portData.CMD[ir_index[i] + 6]; // low + let sensorData_high = Entry.hw.portData.CMD[ir_index[i] + 7]<<8; // high + ir_sensorData[i] = sensorData_low + sensorData_high; + } + + // lineCar ir init 에서 on + Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.ADC] = 1; + Entry.hw.sendQueue.CMD[Entry.avatarbot.BoardFunType.ADC + 1] = 1; + // + const time = 2; // default time set. + const on = time>0? 1:0; // 100ms ~ 1s = 1, 0ms = 0 + + let f_cw = 0; // 0 = front, 1 = back + let b_cw = 0; // 0 = front, 1 = back + + let f_speed_l = 0; + let f_speed_r = 0; + let b_speed_l = 0; + let b_speed_r = 0; + + if(ir_sensorData[0] > Entry.avatarbot.dc_lineCar_ir_index[0] && ir_sensorData[1] > Entry.avatarbot.dc_lineCar_ir_index[1]) + { + // 라인 감지 + f_cw = 0; + b_cw = 0; + f_speed_l = Entry.avatarbot.dc_lineCar_index[0]; + f_speed_r = Entry.avatarbot.dc_lineCar_index[1]; + b_speed_l = Entry.avatarbot.dc_lineCar_index[2]; + b_speed_r = Entry.avatarbot.dc_lineCar_index[3]; + }else if(ir_sensorData[0] > Entry.avatarbot.dc_lineCar_ir_index[0]){ + // 왼쪽 센서 감지 + f_cw = 0; + b_cw = 0; + f_speed_l = Entry.avatarbot.dc_lineCar_index[4]; + f_speed_r = Entry.avatarbot.dc_lineCar_index[5]; + b_speed_l = Entry.avatarbot.dc_lineCar_index[6]; + b_speed_r = Entry.avatarbot.dc_lineCar_index[7]; + }else if(ir_sensorData[1] > Entry.avatarbot.dc_lineCar_ir_index[1]){ + // 오른쪽 센서 감지 + f_cw = 0; + b_cw = 0; + f_speed_l = Entry.avatarbot.dc_lineCar_index[8]; + f_speed_r = Entry.avatarbot.dc_lineCar_index[9]; + b_speed_l = Entry.avatarbot.dc_lineCar_index[10]; + b_speed_r = Entry.avatarbot.dc_lineCar_index[11]; + }else{ + // 라인을 잃음. + f_cw = 0; + b_cw = 0; + f_speed_l = Entry.avatarbot.dc_lineCar_index[12]; + f_speed_r = Entry.avatarbot.dc_lineCar_index[13]; + b_speed_l = Entry.avatarbot.dc_lineCar_index[14]; + b_speed_r = Entry.avatarbot.dc_lineCar_index[15]; + } + + // 백터 + let cw = [0, 0, 0, 0]; + cw[0] = f_cw; + cw[1] = (f_cw==0)?1:0; + cw[2] = b_cw; + cw[3] = (b_cw==0)?1:0; + + // speed setting. base = 160 + let index = Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + Entry.hw.sendQueue.CMD[index+1] = f_speed_l&0xff; + + index = 2 + Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + Entry.hw.sendQueue.CMD[index+1] = f_speed_r&0xff; + + index = 4 + Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + Entry.hw.sendQueue.CMD[index+1] = b_speed_l&0xff; + + index = 6 + Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + Entry.hw.sendQueue.CMD[index+1] = b_speed_r&0xff; + + // dc motor run + for (let i = 0; i < 4; i++) { // 0 ~ 3 + Entry.avatarbot.dc_m_index[i] += 1; // 0 ~ 3 => 1 ~ 4 + if(Entry.avatarbot.dc_m_index[i] > 3) + { + Entry.avatarbot.dc_m_index[i] = 0; // 3, 4 => 0 + } + + if(on == 0) + { + Entry.avatarbot.dc_m_index[i] = 0; // 0 + } + + index = (i*2) + Entry.avatarbot.BoardFunType.DC_M; // base+0,2,4,6 + // + Entry.hw.sendQueue.CMD[index] = (on + (cw[i]<<1) + (Entry.avatarbot.dc_m_index[i]<<2) + (time<<4))&0xff; // ch en + } + // + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.dc_lineCar(%1)', + blockType: 'param', + textParams: [ + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_func_off, '0'], + [Lang.template.avatarbot_func_on, '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_buzzer_sample: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + /* + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_func_on, '1'], + [Lang.template.avatarbot_func_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + */ + { + type: 'Block', + accept: 'string', + defaultType: 'number', }, ], events: {}, @@ -2775,13 +4175,92 @@ Entry.avatarbot.getBlocks = function() { converter: Entry.block.converters.returnStringValue, }, ], - + + }, + ], + }, + }, + //--------------------------------------------------------------- + avatarbot_led_strip_set: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'avatarbot_text', + params: ['64'], + }, + { + type: 'avatarbot_text', + params: ['64'], + }, + ], + type: 'avatarbot_led_strip_set', + }, + paramsKeyMap: { + VALUE1: 0, + VALUE2: 1, + }, + class: 'avatarbot_led', + isNotFor: ['avatarbot'], + func(sprite, script) { + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + + let value = script.getNumberValue('VALUE1'); // led number + let brightness = script.getNumberValue('VALUE2'); // brighteness + value = Math.round(value); + value = Math.max(value, 1); + value = Math.min(value, 100); + // + brightness = Math.round(brightness); + brightness = Math.max(brightness, 0); + brightness = Math.min(brightness, 100); + // Entry.hw.setDigitalPortValue(port, value); + + let index = Entry.avatarbot.BoardFunType.LED_Strip; + Entry.hw.sendQueue.CMD[index] = 1; // ch en + Entry.hw.sendQueue.CMD[index+1] = 0; // sample 0, 1~other... + Entry.hw.sendQueue.CMD[index+2] = value; + Entry.hw.sendQueue.CMD[index+7] = brightness; + Entry.hw.sendQueue.CMD[index+8] = 1; // setting enable. + Entry.hw.update(); + + return script.callReturn(); + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.set_led_strip_set(%1 %2)', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], }, ], }, }, //--------------------------------------------------------------- - avatarbot_led_strip_set: { + avatarbot_led_strip_indexOn: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, skeleton: 'basic', @@ -2797,49 +4276,102 @@ Entry.avatarbot.getBlocks = function() { accept: 'string', defaultType: 'number', }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_func_on, '1'], + [Lang.template.avatarbot_func_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, ], events: {}, def: { params: [ { type: 'avatarbot_text', - params: ['64'], + params: ['0'], }, { type: 'avatarbot_text', - params: ['64'], + params: ['255'], + }, + { + type: 'avatarbot_text', + params: ['255'], + }, + { + type: 'avatarbot_text', + params: ['255'], }, + null, ], - type: 'avatarbot_led_strip_set', + type: 'avatarbot_led_strip_indexOn', }, paramsKeyMap: { VALUE1: 0, VALUE2: 1, + VALUE3: 2, + VALUE4: 3, + RUN: 4, }, - class: 'avatarbot_led', + class: 'avatarbot_led_indexOn', isNotFor: ['avatarbot'], func(sprite, script) { if (!Entry.hw.sendQueue.CMD) { Entry.avatarbot.dataTableReset(); } - - let value = script.getNumberValue('VALUE1'); // led number - let brightness = script.getNumberValue('VALUE2'); // brighteness - value = Math.round(value); - value = Math.max(value, 1); - value = Math.min(value, 100); + // - brightness = Math.round(brightness); - brightness = Math.max(brightness, 0); - brightness = Math.min(brightness, 100); - // Entry.hw.setDigitalPortValue(port, value); + let i = 0; + let ledNum = script.getNumberValue('VALUE1'); // led number + let ledRGB = [0,0,0]; + ledRGB[0] = script.getNumberValue('VALUE2'); // Red + ledRGB[1] = script.getNumberValue('VALUE3'); // Green + ledRGB[2] = script.getNumberValue('VALUE4'); // Blue + let on = script.getNumberValue('RUN', script); + // + ledNum = Math.round(ledNum); + ledNum = Math.max(ledNum, 0); + ledNum = Math.min(ledNum, 99); + + if(on == 1) + { + for(i=0; i<3; i++) + { + ledRGB[i] = Math.round(ledRGB[i]); + ledRGB[i] = Math.max(ledRGB[i], 0); + ledRGB[i] = Math.min(ledRGB[i], 255); + } + }else{ + ledRGB[0] = 0; + ledRGB[1] = 0; + ledRGB[2] = 0; + } + // let index = Entry.avatarbot.BoardFunType.LED_Strip; - Entry.hw.sendQueue.CMD[index] = 1; // ch en - Entry.hw.sendQueue.CMD[index+1] = 0; // sample 0, 1~other... - Entry.hw.sendQueue.CMD[index+2] = value; - Entry.hw.sendQueue.CMD[index+7] = brightness; - Entry.hw.sendQueue.CMD[index+8] = 1; // setting enable. + + Entry.hw.sendQueue.CMD[index] = 1; // 1; // led strip on + Entry.hw.sendQueue.CMD[index+1] = 2; // sample type 2 + Entry.hw.sendQueue.CMD[index+3] = ledNum; // led number. + Entry.hw.sendQueue.CMD[index+4] = ledRGB[0]; // red + Entry.hw.sendQueue.CMD[index+5] = ledRGB[1]; // green + Entry.hw.sendQueue.CMD[index+6] = ledRGB[2]; // blue + Entry.hw.update(); return script.callReturn(); @@ -2848,13 +4380,41 @@ Entry.avatarbot.getBlocks = function() { js: [], py: [ { - syntax: 'avatarbot.set_led_strip_set(%1 %2)', + syntax: 'avatarbot.set_led_strip_indexOn(%1 %2 %3 %4 %5)', textParams: [ { type: 'Block', accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Dropdown', + options: [ + [Lang.template.avatarbot_func_on, '1'], + [Lang.template.avatarbot_func_off, '0'], + ], + value: '1', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, }, ], + }, ], }, @@ -2948,6 +4508,126 @@ Entry.avatarbot.getBlocks = function() { }, }, //--------------------------------------------------------------- + avatarbot_get_mpu6050_detail: { + color: EntryStatic.colorSet.block.default.HARDWARE, //블록 색상 + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, //경계선 색상 + fontColor: '#fff', // 폰트색상 basic_string_field는 기본 색상이 검정색(#000) 입니다. + skeleton: 'basic_string_field', // 블록 모양 정의 + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ['Acceleration', '0'], + ['Rotation', '1'], + // ['Temperature', '2'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + ['x', '0'], + ['y', '1'], + ['z', '2'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { // 보여질 블록 정의 + // def의 params의 경우는 초기값을 지정할수 있습니다. + // TextInput의 경우에도 def > params을 통해 값을 지정할수 있습니다. + params: [ + null, + ], + type: 'avatarbot_get_mpu6050_detail', // func name + }, + paramsKeyMap: { // 파라미터를 사용 할때 쓰는 Key값 정의 + VALUE1: 0, + VALUE2: 1, + + }, + class: 'avatarbot_mpu', + isNotFor: ['avatarbot'], + func(sprite, script) { // 블록 기능정의 + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + + // 해당 값을 getField, getValue로 가져오고 + // 가져 올때 paramsKeyMap에서 + // 정의한 VALUE라는 키값으로 데이터를 가져옵니다. + // const signal = script.getValue('VALUE', script); + // return Entry.hw.getAnalogPortValue(signal[1]); + const type = script.getNumberValue('VALUE1', script); + let index = Entry.avatarbot.BoardFunType.MPU6050_1; + // 가속도 값 + let acceleration_x = ((Entry.hw.portData.CMD[index+1]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+1]&0x7f) +"."+ ((Entry.hw.portData.CMD[index+2]>9)?"":"0") + Entry.hw.portData.CMD[index+2]; + let acceleration_y = ((Entry.hw.portData.CMD[index+3]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+3]&0x7f) +"."+ ((Entry.hw.portData.CMD[index+4]>9)?"":"0") + Entry.hw.portData.CMD[index+4]; + let acceleration_z = ((Entry.hw.portData.CMD[index+5]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+5]&0x7f) +"."+ ((Entry.hw.portData.CMD[index+6]>9)?"":"0") + Entry.hw.portData.CMD[index+6]; + // let temperature = ((Entry.hw.portData.CMD[index+7]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+7]&0x7f) +"."+ ((Entry.hw.portData.CMD[index+8]>9)?"":"0") + Entry.hw.portData.CMD[index+8]; + // + index = Entry.avatarbot.BoardFunType.MPU6050_2; + // 회전값 + let rotation_x = ((Entry.hw.portData.CMD[index+1]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+1]&0x7f) +"."+ ((Entry.hw.portData.CMD[index+2]>9)?"":"0") + Entry.hw.portData.CMD[index+2]; + let rotation_y = ((Entry.hw.portData.CMD[index+3]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+3]&0x7f) +"."+ ((Entry.hw.portData.CMD[index+4]>9)?"":"0") + Entry.hw.portData.CMD[index+4]; + let rotation_z = ((Entry.hw.portData.CMD[index+5]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+5]&0x7f) +"."+ ((Entry.hw.portData.CMD[index+6]>9)?"":"0") + Entry.hw.portData.CMD[index+6]; + + // let mpu6050 = `Acceleration X: ${acceleration_x}, Y: ${acceleration_y}, Z: ${acceleration_z} m/s^2\nRotation X: ${rotation_x}, Y: ${rotation_y}, Z: ${rotation_z} rad/s\nTemperature: ${temperature} degC`; + let mpu6050 = ""; + const unit = script.getNumberValue('VALUE2', script); + + if(type == 0){ + // mpu6050 = `Acceleration X: ${acceleration_x}, Y: ${acceleration_y}, Z: ${acceleration_z} m/s^2`; + if(unit == 0) + { + mpu6050 = `${acceleration_x}`; + }else if(unit == 1){ + mpu6050 = `${acceleration_y}`; + }else if(unit == 2){ + mpu6050 = `${acceleration_z}`; + } + }else if(type == 1){ + // mpu6050 = `Rotation X: ${rotation_x}, Y: ${rotation_y}, Z: ${rotation_z} rad/s`; + if(unit == 0) + { + mpu6050 = `${rotation_x}`; + }else if(unit == 1){ + mpu6050 = `${rotation_y}`; + }else if(unit == 2){ + mpu6050 = `${rotation_z}`; + } + }else if(type == 2){ + // mpu6050 = `Temperature: ${temperature} degC`; + } + + // + index = Entry.avatarbot.BoardFunType.MPU6050_1; + Entry.hw.sendQueue.CMD[index] = 1; // ch en + Entry.hw.update(); + + return mpu6050; + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.get_mpu6050_detail(%1, %2)', + blockType: 'param', + textParams: [ + ], + }, + ], + }, + }, + //--------------------------------------------------------------- avatarbot_ultra_sonic: { color: EntryStatic.colorSet.block.default.HARDWARE, //블록 색상 outerLine: EntryStatic.colorSet.block.darken.HARDWARE, //경계선 색상 @@ -3011,6 +4691,94 @@ Entry.avatarbot.getBlocks = function() { ], }, }, + //--------------------------------------------------------------- + avatarbot_ultra_sonic_detail: { + color: EntryStatic.colorSet.block.default.HARDWARE, //블록 색상 + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, //경계선 색상 + fontColor: '#fff', // 폰트색상 basic_string_field는 기본 색상이 검정색(#000) 입니다. + skeleton: 'basic_string_field', // 블록 모양 정의 + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Dropdown', + options: [ + ['cm', '0'], + ['inch', '1'], + ], + value: '0', + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { // 보여질 블록 정의 + // def의 params의 경우는 초기값을 지정할수 있습니다. + // TextInput의 경우에도 def > params을 통해 값을 지정할수 있습니다. + params: [ + { + type: 'avatarbot_get_port_number', // 상단 func 가져와서 사용. + }, + null + ], + type: 'avatarbot_ultra_sonic_detail', // func name + }, + paramsKeyMap: { // 파라미터를 사용 할때 쓰는 Key값 정의 + VALUE1: 0, + VALUE2: 1, + }, + class: 'avatarbot_sonic', + isNotFor: ['avatarbot'], + func(sprite, script) { // 블록 기능정의 + if (!Entry.hw.sendQueue.CMD) { + Entry.avatarbot.dataTableReset(); + } + // 해당 값을 getField, getValue로 가져오고 + // 가져 올때 paramsKeyMap에서 + // 정의한 VALUE라는 키값으로 데이터를 가져옵니다. + const signal = script.getNumberValue('VALUE1'); + let index = (signal*5) + Entry.avatarbot.BoardFunType.ULTRA_SONIC; + let cm = ((Entry.hw.portData.CMD[index+1]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+1]&0x7f) +"." + ((Entry.hw.portData.CMD[index+2]>9)?"":"0") + Entry.hw.portData.CMD[index+2]; + let inch = ((Entry.hw.portData.CMD[index+3]&0x80)==0?"":"-") + (Entry.hw.portData.CMD[index+3]&0x7f) +"." + ((Entry.hw.portData.CMD[index+4]>9)?"":"0") + Entry.hw.portData.CMD[index+4]; + + Entry.hw.sendQueue.CMD[index] = 1; // ch en + Entry.hw.sendQueue.CMD[index+1] = Entry.hw.portData.CMD[index+1]; + Entry.hw.sendQueue.CMD[index+2] = Entry.hw.portData.CMD[index+2]; + Entry.hw.sendQueue.CMD[index+3] = Entry.hw.portData.CMD[index+3]; + Entry.hw.sendQueue.CMD[index+4] = Entry.hw.portData.CMD[index+4]; + Entry.hw.update(); + // + let sonic = ``; + const type = script.getNumberValue('VALUE2', script); + if(type == 0){ + sonic = `${cm}`; + }else if(type == 1){ + sonic = `${inch}`; + } + + return sonic; + }, + syntax: { + js: [], + py: [ + { + syntax: 'avatarbot.get_ultra_sonic_detail(%1, %2)', + blockType: 'param', + textParams: [ + { + type: 'Block', + accept: 'string', + }, + ], + }, + ], + }, + }, //--------------------------------------------------------------- avatarbot_ir_receiver: { color: EntryStatic.colorSet.block.default.HARDWARE, //블록 색상 diff --git a/src/playground/blocks/hardware/block_dalgona.js b/src/playground/blocks/hardware/block_dalgona.js index 52f9d612f3..7fa4ac3a36 100644 --- a/src/playground/blocks/hardware/block_dalgona.js +++ b/src/playground/blocks/hardware/block_dalgona.js @@ -14,7 +14,7 @@ Entry.Dalgona = { }, //정지시 초기화 함수 - setZero: function() { + setZero: function () { if (!Entry.hw.sendQueue.SET) { Entry.hw.sendQueue = { GET: {}, @@ -26,12 +26,10 @@ Entry.Dalgona = { if (Entry.hw.sendQueue.SET[key].type == Entry.Dalgona.sensorTypes.SERVO) { Entry.hw.sendQueue.SET[key].data = 200; Entry.hw.sendQueue.SET[key].time = new Date().getTime(); - } - else if (Entry.hw.sendQueue.SET[key].type == Entry.Dalgona.sensorTypes.SERVO2) { + } else if (Entry.hw.sendQueue.SET[key].type == Entry.Dalgona.sensorTypes.SERVO2) { Entry.hw.sendQueue.SET[key].data.value1 = 200; Entry.hw.sendQueue.SET[key].time = new Date().getTime(); - } - else { + } else { Entry.hw.sendQueue.SET[key].data = 0; Entry.hw.sendQueue.SET[key].time = new Date().getTime(); } @@ -100,9 +98,11 @@ Entry.Dalgona = { GYROZ: 57, PULLUP: 58, TONETOGGLE: 59, + TEST_ULTRASONIC_TRIG: 60, + TEST_ULTRASONIC_ECHO: 61, }, toneTable: { - '0': 0, + 0: 0, C: 1, CS: 2, D: 3, @@ -117,18 +117,18 @@ Entry.Dalgona = { B: 12, }, toneMap: { - '1': [33, 65, 131, 262, 523, 1046, 2093, 4186], - '2': [35, 69, 139, 277, 554, 1109, 2217, 4435], - '3': [37, 73, 147, 294, 587, 1175, 2349, 4699], - '4': [39, 78, 156, 311, 622, 1245, 2849, 4978], - '5': [41, 82, 165, 330, 659, 1319, 2637, 5274], - '6': [44, 87, 175, 349, 698, 1397, 2794, 5588], - '7': [46, 92, 185, 370, 740, 1480, 2960, 5920], - '8': [49, 98, 196, 392, 784, 1568, 3136, 6272], - '9': [52, 104, 208, 415, 831, 1661, 3322, 6645], - '10': [55, 110, 220, 440, 880, 1760, 3520, 7040], - '11': [58, 117, 233, 466, 932, 1865, 3729, 7459], - '12': [62, 123, 247, 494, 988, 1976, 3951, 7902], + 1: [33, 65, 131, 262, 523, 1046, 2093, 4186], + 2: [35, 69, 139, 277, 554, 1109, 2217, 4435], + 3: [37, 73, 147, 294, 587, 1175, 2349, 4699], + 4: [39, 78, 156, 311, 622, 1245, 2849, 4978], + 5: [41, 82, 165, 330, 659, 1319, 2637, 5274], + 6: [44, 87, 175, 349, 698, 1397, 2794, 5588], + 7: [46, 92, 185, 370, 740, 1480, 2960, 5920], + 8: [49, 98, 196, 392, 784, 1568, 3136, 6272], + 9: [52, 104, 208, 415, 831, 1661, 3322, 6645], + 10: [55, 110, 220, 440, 880, 1760, 3520, 7040], + 11: [58, 117, 233, 466, 932, 1865, 3729, 7459], + 12: [62, 123, 247, 494, 988, 1976, 3951, 7902], }, direction: { CENTER: 0, @@ -152,40 +152,26 @@ Entry.Dalgona = { }, BlockState: {}, }; -Entry.Dalgona.setLanguage = function() { +Entry.Dalgona.setLanguage = function () { return { ko: { template: { - // set_neopixelinit: '디지털 %1 번 핀에 연결된 %2 개의 네오픽셀 LED 사용하기 %3', - // set_neopixel: '디지털 %1 번 핀에 연결된 %2 번째 네오픽셀 LED를 R: %3 , G: %4 , B: %5 색으로 켜기 %6', - - // FND_event: 'FND 4digit (TM1637)- CLK:D5, DIO:D4', - // FND_Control_init: 'FND %1 번 : 디지털 CLK %2, DIO %3 번 핀으로 설정', - // FND_Control_diplay_brightness: 'FND %1 번 : 밝기 %2 단계로 설정', - // FND_Control_display_onoff: 'FND %1 번 : 전원 %2', - // FND_Control_diplay_char: - // 'FND %1 번 : %2 출력하기:나머지0채우기 %3 %4 초 대기', - - - - - - dalgona_digital_title:'달고나 디지털 블럭', - dalgona_analog_title:'달고나 아날로그 블럭', - dalgona_pwm_title:'달고나 PWM 블럭', - dalgona_library_title:'달고나 라이브러리 블럭', - dalgona_neopixel_title:'달고나 네오픽셀 블럭', + dalgona_digital_title: '달고나 디지털 블럭', + dalgona_analog_title: '달고나 아날로그 블럭', + dalgona_pwm_title: '달고나 PWM 블럭', + dalgona_library_title: '달고나 라이브러리 블럭', + dalgona_neopixel_title: '달고나 네오픽셀 블럭', dalgona_ultrasonic_title: '달고나 초음파센서 블럭', dalgona_buzzer_title: '달고나 피에조 부저 블럭', - dalgona_dotmatrix_title:'달고나 8X8 도트매트릭스 블럭', - dalgona_rfid_title:'달고나 RFID 블럭', - dalgona_motor_title:'달고나 모터 블럭', - dalgona_stepmotor_title:'달고나 스텝모터 블럭', - dalgona_joystick_title:'달고나 조이스틱 블럭', - dalgona_LCD_title:'달고나 LCD 블럭', - dalgona_mp3_title:'달고나 mp3 블럭', - dalgona_HX711_title:'달고나 HX711 로드셀 블럭', - dalgona_sensor_title:'달고나 센서 블럭', + dalgona_dotmatrix_title: '달고나 8X8 도트매트릭스 블럭', + dalgona_rfid_title: '달고나 RFID 블럭', + dalgona_motor_title: '달고나 모터 블럭', + dalgona_stepmotor_title: '달고나 스텝모터 블럭', + dalgona_joystick_title: '달고나 조이스틱 블럭', + dalgona_LCD_title: '달고나 LCD 블럭', + dalgona_mp3_title: '달고나 mp3 블럭', + dalgona_HX711_title: '달고나 HX711 로드셀 블럭', + dalgona_sensor_title: '달고나 센서 블럭', dalgona_toggle_on: '켜기', dalgona_toggle_off: '끄기', dalgona_lcd_first_line: '첫 번째', @@ -197,30 +183,37 @@ Entry.Dalgona.setLanguage = function() { dalgona_get_infrared_value: '적외선센서(AO %1)값', dalgona_get_pullup: '풀업 저항 사용 버튼 %1 핀 눌림 상태', dalgona_get_button: '버튼 %1 핀 눌림 상태', - dalgona_get_analog_mapping: '아날로그 %1 번 핀 센서 값의 범위를 %2 ~ %3 에서 %4 ~ %5 로 바꾼 값', + dalgona_get_analog_mapping: + '아날로그 %1 번 핀 센서 값의 범위를 %2 ~ %3 에서 %4 ~ %5 로 바꾼 값', dalgona_mapping1: '%1 값을 %2 ~ %3 사이로 제한한 값', dalgona_mapping2: '%1 값을 %2 ~ %3 범위에서 %4 ~ %5 범위로 변환', dalgona_get_digital_ultrasonic: '초음파 Trig %1 핀 Echo %2 핀 센서 값', + test_dalgona_set_ultrasonic_trig: '초음파 Trig %1 신호 보내기 %2', + test_dalgona_get_ultrasonic_echo: '초음파 Echo %1 신호 받기', dalgona_get_digital: '디지털 %1 핀 읽기', dalgona_get_digital_toggle: '디지털 %1 핀 센서 값', dalgona_get_digital_pir: 'PIR %1 핀 센서 값', dalgona_set_digital_toggle: '디지털 %1 핀 %2 %3', dalgona_set_led_toggle: 'LED %1 핀 %2 %3', dalgona_set_digital_pwm: 'LED (PWM %1 핀)밝기 %2 출력 (0 ~ 255)%3', - dalgona_set_digital_rgbled: 'RGB LED (R %1 핀, G %2 핀, B %3 핀) 색 (R: %4, G: %5, B: %6) 출력 %7', + dalgona_set_digital_rgbled: + 'RGB LED (R %1 핀, G %2 핀, B %3 핀) 색 (R: %4, G: %5, B: %6) 출력 %7', dalgona_set_digital_servo: '서보 모터 %1 핀 %2 각도로 회전 %3', - dalgona_set_digital_servo2: "서보 모터 %1 핀 %2 ~ %3 각도로 %4 초 동안 회전 %5", + dalgona_set_digital_servo2: '서보 모터 %1 핀 %2 ~ %3 각도로 %4 초 동안 회전 %5', dalgona_set_digital_buzzer_toggle: '피에조부저 %1 핀 %2 %3', - dalgona_set_digital_buzzer_volume: '피에조부저 (PWM %1 핀) 음량 %2 출력 (0 ~ 255) %3', + dalgona_set_digital_buzzer_volume: + '피에조부저 (PWM %1 핀) 음량 %2 출력 (0 ~ 255) %3', dalgona_set_digital_buzzer: '피에조부저 %1 핀 %2 %3 음 %4 박자 연주 %5', dalgona_set_digital_dcmotor: 'DC모터 %1핀 %2 %3', dalgona_set_analog_dcmotor: 'DC모터(PWM %1 핀) 세기 %2 출력 (0 ~ 255) %3', - dalgona_set_neopixel_init: '네오픽셀 LED 시작하기 설정 ( %1 핀에 %2 개의 LED 연결) %3', + dalgona_set_neopixel_init: + '네오픽셀 LED 시작하기 설정 ( %1 핀에 %2 개의 LED 연결) %3', dalgona_set_neopixel_bright: '네오픽셀 LED ( %1 핀) 밝기 %2 으로 설정 (0 ~ 255) %3', dalgona_set_neopixel: '네오픽셀 LED ( %1 핀) %2 번째 LED 색 %3 출력 %4', dalgona_set_neopixel_all: '네오픽셀 LED ( %1 핀) 모든 LED 색 %2 출력 %3', dalgona_set_neopixel_clear: '네오픽셀 LED ( %1 핀) 모든 LED 끄기 %2', - dalgona_set_dotmatrix_init: '8x8 도트매트릭스 시작하기 설정 (DIN %1, CLK %2, CS %3) %4', + dalgona_set_dotmatrix_init: + '8x8 도트매트릭스 시작하기 설정 (DIN %1, CLK %2, CS %3) %4', dalgona_set_dotmatrix_bright: '도트매트릭스 밝기 %1 으로 설정 (0 ~ 8) %2', dalgona_set_dotmatrix: '도트매트릭스 LED %1 그리기 %2', dalgona_set_dotmatrix_emoji: '도트매트릭스 LED %1 그리기 %2', @@ -231,8 +224,8 @@ Entry.Dalgona.setLanguage = function() { dalgona_module_digital_lcd: 'LCD화면 %1 열 %2 행 부터 %3 출력 %4', dalgona_lcd_clear: 'LCD 화면 지우기 %1', dalgona_get_dht: 'DHT11 온습도센서(out %1)의 %2값', - //dalgona_get_dht_temp_value: 'DHT11 온습도센서(out %1)의 온도(°C)값', - //dalgona_get_dht_humi_value: 'DHT11 온습도센서(out %1)의 습도(%)값', + dalgona_dht_temp: '온도(°C)', + dalgona_dht_humi: '습도(%)', dalgona_set_mp3_init: 'mp3 초기화 ( tx: %1, rx: %2 ) %3', dalgona_set_mp3_play: 'mp3 %1 번 파일 재생 %2', @@ -255,121 +248,246 @@ Entry.Dalgona.setLanguage = function() { dalgona_get_joy_z: '%1 조이스틱 버튼 눌림 상태', dalgona_get_joy_move: '%1 조이스틱이 %2 방향으로 움직였을 때', + dalgona_joy_direction_centor: '가운데', + dalgona_joy_direction_up: '위', + dalgona_joy_direction_down: '아래', + dalgona_joy_direction_left: '왼쪽', + dalgona_joy_direction_right: '오른쪽', + dalgona_joy_direction_top_left: '왼쪽위', + dalgona_joy_direction_bottom_left: '왼쪽아래', + dalgona_joy_direction_top_right: '오른쪽위', + dalgona_joy_direction_bottom_right: '오른쪽아래', + + dalgona_joy_first: '첫번째', + dalgona_joy_second: '두번째', + dalgona_get_mlx: 'mlx90614 비접촉 온도센서 %1값', + dalgona_step_motor_first: '첫번째', + dalgona_step_motor_second: '두번째', + dalgona_step_motor_third: '세번째', + + dalgona_step_motor_forward_direction: '정방향', + dalgona_step_motor_reverse_direction: '역방향', + dalgona_step_init: '%1 스텝모터 시작하기 설정 (IN1 %2, IN2 %3, IN3 %4, IN4 %5) %6', dalgona_step_speed: '%1 스텝모터 속도를 %2 로 설정하기 (0 ~ 20) %3', dalgona_step_rotate: '%1 스텝모터 %2 으로 %3 바퀴 회전하기 %4', dalgona_step_rotate2: '%1 스텝모터 %2 으로 %3 도 회전하기 %4', dalgona_step_rotate3: '%1 스텝모터 %2 으로 %3 초 동안 회전하기 %4', - - // dalgona_get_digital_bluetooth: '블루투스 RX 2 핀 데이터 값', - // dalgona_module_digital_bluetooth: '블루투스 TX 3 핀에 %1 데이터 보내기 %2', - }, }, en: { template: { - // FND_event: 'FND 4digit (TM1637)- CLK:D5, DIO:D4', - // FND_Control_init: 'FND %1 번 : 디지털 CLK %2, DIO %3 번 핀으로 설정', - // FND_Control_diplay_brightness: 'FND %1 번 : 밝기 %2 단계로 설정', - // FND_Control_display_onoff: 'FND %1 번 : 전원 %2', - // FND_Control_diplay_char: - // 'FND %1 번 : %2 출력하기:나머지0채우기 %3 %4 초 대기', - - - - set_neopixelinit: '디지털 %1 번 핀에 연결된 %2 개의 네오픽셀 LED 사용하기 %3', - set_neopixel: '디지털 %1 번 핀에 연결된 %2 번째 네오픽셀 LED를 R: %3 , G: %4 , B: %5 색으로 켜기 %6', - - dalgona_digital_title:'달고나 디지털 블럭', - dalgona_analog_title:'달고나 아날로그 블럭', - dalgona_pwm_title:'달고나 PWM 블럭', - dalgona_library_title:'달고나 라이브러리 블럭', - dalgona_neopixel_title:'달고나 네오픽셀 블럭', - dalgona_ultrasonic_title: '달고나 초음파센서 블럭', - dalgona_buzzer_title: '달고나 피에조 부저 블럭', - dalgona_dotmatrix_title:'달고나 8X8 도트매트릭스 블럭', - dalgona_rfid_title:'달고나 RFID 블럭', - dalgona_motor_title:'달고나 모터 블럭', - dalgona_stepmotor_title:'달고나 스텝모터 블럭', - dalgona_joystick_title:'달고나 조이스틱 블럭', - dalgona_LCD_title:'달고나 LCD 블럭', - dalgona_mp3_title:'달고나 mp3 블럭', - dalgona_HX711_title:'달고나 HX711 로드셀 블럭', - dalgona_sensor_title:'달고나 센서 블럭', - + // set_neopixelinit: '디지털 %1 번 핀에 연결된 %2 개의 네오픽셀 LED 사용하기 %3', + // set_neopixel: '디지털 %1 번 핀에 연결된 %2 번째 네오픽셀 LED를 R: %3 , G: %4 , B: %5 색으로 켜기 %6', + + // dalgona_digital_title:'달고나 디지털 블럭', + // dalgona_analog_title:'달고나 아날로그 블럭', + // dalgona_pwm_title:'달고나 PWM 블럭', + // dalgona_library_title:'달고나 라이브러리 블럭', + // dalgona_neopixel_title:'달고나 네오픽셀 블럭', + // dalgona_ultrasonic_title: '달고나 초음파센서 블럭', + // dalgona_buzzer_title: '달고나 피에조 부저 블럭', + // dalgona_dotmatrix_title:'달고나 8X8 도트매트릭스 블럭', + // dalgona_rfid_title:'달고나 RFID 블럭', + // dalgona_motor_title:'달고나 모터 블럭', + // dalgona_stepmotor_title:'달고나 스텝모터 블럭', + // dalgona_joystick_title:'달고나 조이스틱 블럭', + // dalgona_LCD_title:'달고나 LCD 블럭', + // dalgona_mp3_title:'달고나 mp3 블럭', + // dalgona_HX711_title:'달고나 HX711 로드셀 블럭', + // dalgona_sensor_title:'달고나 센서 블럭', + + // dalgona_toggle_on: 'on', + // dalgona_toggle_off: 'off', + // dalgona_lcd_first_line: 'first', + // dalgona_lcd_seconds_line: 'seconds', + // dalgona_get_analog_value: 'Read analog %1 pin sensor value', + // dalgona_get_analog_mapping: 'Map analog %1 pin sensor value from %2 ~ %3 to %4 ~ %5', + // dalgona_mapping1: '%1 값을 %2 ~ %3 사이로 제한한 값', + // dalgona_mapping2: '%1 값을 %2 ~ %3 범위에서 %4 ~ %5 범위로 변환', + // dalgona_get_digital_bluetooth: 'Bluetooth RX 2 value', + // dalgona_get_digital_ultrasonic: 'Read ultrasonic Trig %1 Echo %2 sensor value', + // dalgona_get_digital: 'Digital %1 pin sensor value', + // dalgona_get_digital_toggle: 'Digital %1 pin sensor value', + // dalgona_set_digital_toggle: 'Digital %1 pin %2 %3', + // dalgona_set_digital_pwm: 'Digital pwm %1 Pin %2 %3', + // dalgona_set_digital_rgbled: 'Digital %1 pin RGB LED Red %2 Green %3 Blue %4 %5', + // dalgona_set_digital_servo: '서보 모터 %1 핀 %2 각도로 회전 %3', + // dalgona_set_digital_buzzer_toggle: '피에조부저 %1 핀 %2 %3', + // dalgona_set_digital_buzzer_volume: '피에조부저 (PWM %1 핀) 음량 %2 출력 (0 ~ 255) %3', + // dalgona_set_digital_buzzer:'피에조부저 %1 번 핀의 버저를 %2 %3 음으로 %4 박자 연주 %5', + // dalgona_set_digital_dcmotor: 'DC Motor %1 pin direction %2 %3 pin speed %4 %5', + // dalgona_set_neopixel_init:'네오픽셀 LED 시작하기 설정 ( %1 핀에 %2 개의 LED 연결) %3', + // dalgona_set_neopixel_bright: '네오픽셀 LED ( %1 핀) 밝기 %2 으로 설정 (0 ~ 255) %3', + // dalgona_set_neopixel: '네오픽셀 LED ( %1 핀) %2 번째 LED 색 %3 출력 %4', + // dalgona_set_neopixel_all: '네오픽셀 LED ( %1 핀) 모든 LED 색 %2 출력 %3', + // dalgona_set_neopixel_clear: '네오픽셀 LED ( %1 핀) 모든 LED 끄기 %2', + // dalgona_set_dotmatrix_init: '8x8 도트매트릭스 시작하기 설정 (DIN %1, CLK %2, CS %3) %4', + // dalgona_set_dotmatrix_bright: '도트매트릭스 밝기 %1 으로 설정 (0 ~ 8) %2', + // dalgona_set_dotmatrix: '도트매트릭스 LED 그리기 %1 %2', + // dalgona_set_dotmatrix_emoji: '도트매트릭스 LED %1 그리기 %2', + // dalgona_module_digital_lcd: 'LCD %1 열 %2 행 부터 %3 출력', + // dalgona_lcd_init: 'I2C LCD 시작하기 설정 (주소 %1 ,열 %2, 행 %3) %4', + + // dalgona_module_digital_bluetooth: 'Bluetooth TX 3 Pin %1 data send %2', + // dalgona_module_digital_oled: 'OLED X codinate %1 Y coodinate %2 appear %3 %4', + // dalgona_get_dht_temp_value: '온습도센서의 온도값', + // dalgona_get_dht_humi_value: '온습도센서의 습도값', + + // dalgona_set_mp3_init: 'mp3 초기화 ( tx: %1, rx: %2 ) %3', + // dalgona_set_mp3_play: 'mp3 %1 번 파일 재생 %2', + // dalgona_set_mp3_play2: 'mp3 %1 번 파일 %2 초 동안 재생 %3', + // dalgona_set_mp3_vol: 'mp3 볼륨 %1 으로 설정 (0 ~ 30) %2', + + // dalgona_load_init: 'HX711 로드셀 시작하기 설정 (DOUT %1, SCK %2) %3', + // dalgona_load_scale: 'HX711 로드셀 보정하기 %1 %2', + // dalgona_load_value: 'HX711 로드셀 값', + + // dalgona_get_dust: '미세먼지센서(LED %1, AO %2) 값(μg/m³)', + + // dalgona_rfid_init: 'RFID 시작하기 설정 (RST %1, SS %2) %3', + // dalgona_is_rfid_tapped: 'RFID 카드가 인식되었는가?', + // dalgona_get_rfid_value: 'RFID 카드 값', + + // dalgona_joy_init: '%1 조이스틱 시작하기 설정 (X AO %2, Y AO %3, Z %4) %5', + // dalgona_get_joy_x: '%1 조이스틱 X값', + // dalgona_get_joy_y: '%1 조이스틱 y값', + // dalgona_get_joy_z: '%1 조이스틱 버튼 눌림 상태', + // dalgona_get_joy_move: '%1 조이스틱이 %2 방향으로 움직였을 때', + + // dalgona_step_init: '%1 스텝모터 시작하기 설정 (IN1 %2, IN2 %3, IN3 %4, IN4 %5) %6', + // dalgona_step_speed: '%1 스텝모터 속도를 %2 로 설정하기 (0 ~ 20) %3', + // dalgona_step_rotate: '%1 스텝모터 %2 으로 %3 바퀴 회전하기 %4', + // dalgona_step_rotate2: '%1 스텝모터 %2 으로 %3 도 회전하기 %4', + // dalgona_step_rotate3: '%1 스텝모터 %2 으로 %3 초 동안 회전하기 %4', + + // dalgona_mlx: 'mlx90614 값', + + dalgona_digital_title: 'Dalgona Digital Block', + dalgona_analog_title: 'Dalgona Analog Block', + dalgona_pwm_title: 'Dalgona PWM block', + dalgona_library_title: 'Dalgona Library block', + dalgona_neopixel_title: 'Dalgona Neopixel block', + dalgona_ultrasonic_title: 'Dalgona Ultrasonic_Sensor block', + dalgona_buzzer_title: 'Dalgona Buzzer block', + dalgona_dotmatrix_title: 'Dalgona 8X8 Dotmatrix block', + dalgona_rfid_title: 'Dalgona RFID block', + dalgona_motor_title: 'Dalgona Motor block', + dalgona_stepmotor_title: 'Dalgona Step_Motor block', + dalgona_joystick_title: 'Dalgona Joystick block', + dalgona_LCD_title: 'Dalgona LCD block', + dalgona_mp3_title: 'Dalgona mp3 block', + dalgona_HX711_title: 'Dalgona HX711 Load_cell block', + dalgona_sensor_title: 'Dalgona Sensor block', dalgona_toggle_on: 'on', dalgona_toggle_off: 'off', dalgona_lcd_first_line: 'first', dalgona_lcd_seconds_line: 'seconds', dalgona_get_analog_value: 'Read analog %1 pin sensor value', - dalgona_get_analog_mapping: 'Map analog %1 pin sensor value from %2 ~ %3 to %4 ~ %5', - dalgona_mapping1: '%1 값을 %2 ~ %3 사이로 제한한 값', - dalgona_mapping2: '%1 값을 %2 ~ %3 범위에서 %4 ~ %5 범위로 변환', - dalgona_get_digital_bluetooth: 'Bluetooth RX 2 value', - dalgona_get_digital_ultrasonic: 'Read ultrasonic Trig %1 Echo %2 sensor value', - dalgona_get_digital: 'Digital %1 pin sensor value', - dalgona_get_digital_toggle: 'Digital %1 pin sensor value', + dalgona_get_light_value: 'Photoresistor (AO %1) sensor value', + dalgona_get_moisture_value: 'Soil moisture (AO %1) sensor value', + dalgona_get_sound_value: 'Sound (AO %1) sensor value', + dalgona_get_infrared_value: 'Infrared (AO %1) sensor value', + dalgona_get_pullup: 'Pullup resistor Button %1 pin pressed state', + dalgona_get_button: 'Button %1 pin pressed state', + dalgona_get_analog_mapping: + 'Map analog %1 pin sensor value from %2 ~ %3 to %4 ~ %5', + dalgona_mapping1: 'Value %1 limited to between %2 and %3', + dalgona_mapping2: 'Convert value %1 from range %2 to %3 to range %4 to %5', + dalgona_get_digital_ultrasonic: 'Ultrasonic Trig pin %1 Echo pin %2 sensor value', + dalgona_get_digital: 'Read digital %1 pin value', + dalgona_get_digital_toggle: 'Read digital %1 pin sensor value', + dalgona_get_digital_pir: 'PIR %1 pin sensor value', dalgona_set_digital_toggle: 'Digital %1 pin %2 %3', - dalgona_set_digital_pwm: 'Digital pwm %1 Pin %2 %3', - dalgona_set_digital_rgbled: 'Digital %1 pin RGB LED Red %2 Green %3 Blue %4 %5', - dalgona_set_digital_servo: '서보 모터 %1 핀 %2 각도로 회전 %3', - dalgona_set_digital_buzzer_toggle: '피에조부저 %1 핀 %2 %3', - dalgona_set_digital_buzzer_volume: '피에조부저 (PWM %1 핀) 음량 %2 출력 (0 ~ 255) %3', - dalgona_set_digital_buzzer:'피에조부저 %1 번 핀의 버저를 %2 %3 음으로 %4 박자 연주 %5', - dalgona_set_digital_dcmotor: 'DC Motor %1 pin direction %2 %3 pin speed %4 %5', - dalgona_set_neopixel_init:'네오픽셀 LED 시작하기 설정 ( %1 핀에 %2 개의 LED 연결) %3', - dalgona_set_neopixel_bright: '네오픽셀 LED ( %1 핀) 밝기 %2 으로 설정 (0 ~ 255) %3', - dalgona_set_neopixel: '네오픽셀 LED ( %1 핀) %2 번째 LED 색 %3 출력 %4', - dalgona_set_neopixel_all: '네오픽셀 LED ( %1 핀) 모든 LED 색 %2 출력 %3', - dalgona_set_neopixel_clear: '네오픽셀 LED ( %1 핀) 모든 LED 끄기 %2', - dalgona_set_dotmatrix_init: '8x8 도트매트릭스 시작하기 설정 (DIN %1, CLK %2, CS %3) %4', - dalgona_set_dotmatrix_bright: '도트매트릭스 밝기 %1 으로 설정 (0 ~ 8) %2', - dalgona_set_dotmatrix: '도트매트릭스 LED 그리기 %1 %2', - dalgona_set_dotmatrix_emoji: '도트매트릭스 LED %1 그리기 %2', - dalgona_module_digital_lcd: 'LCD %1 열 %2 행 부터 %3 출력', - dalgona_lcd_init: 'I2C LCD 시작하기 설정 (주소 %1 ,열 %2, 행 %3) %4', - - dalgona_module_digital_bluetooth: 'Bluetooth TX 3 Pin %1 data send %2', - dalgona_module_digital_oled: 'OLED X codinate %1 Y coodinate %2 appear %3 %4', - dalgona_get_dht_temp_value: '온습도센서의 온도값', - dalgona_get_dht_humi_value: '온습도센서의 습도값', - - dalgona_set_mp3_init: 'mp3 초기화 ( tx: %1, rx: %2 ) %3', - dalgona_set_mp3_play: 'mp3 %1 번 파일 재생 %2', - dalgona_set_mp3_play2: 'mp3 %1 번 파일 %2 초 동안 재생 %3', - dalgona_set_mp3_vol: 'mp3 볼륨 %1 으로 설정 (0 ~ 30) %2', - - dalgona_load_init: 'HX711 로드셀 시작하기 설정 (DOUT %1, SCK %2) %3', - dalgona_load_scale: 'HX711 로드셀 보정하기 %1 %2', - dalgona_load_value: 'HX711 로드셀 값', + dalgona_set_led_toggle: 'LED %1 pin %2 %3', + dalgona_set_digital_pwm: 'LED (PWM %1 pin) brightness %2 output (0 ~ 255) %3', + dalgona_set_digital_rgbled: + 'RGB LED (R %1 pin, G %2 pin, B %3 pin) color (R: %4, G: %5, B: %6) output %7', + dalgona_set_digital_servo: 'Servo motor pin %1 rotate by %2 degrees %3', + dalgona_set_digital_servo2: + 'Servo motor pin %1 rotates at angle %2 to %3 for %4 seconds %5', + dalgona_set_digital_buzzer_toggle: 'Piezo buzzer %1 pin %2 %3', + dalgona_set_digital_buzzer_volume: + 'Piezo buzzer (PWM %1 pin) volume %2 output (0 ~ 255) %3', + dalgona_set_digital_buzzer: 'Piezo buzzer %1 pin %2 %3 note %4 beat %5', + dalgona_set_digital_dcmotor: 'DC motor %1pin %2 %3', + dalgona_set_analog_dcmotor: 'DC motor(PWM %1 pin) intensity %2 output (0 ~ 255) %3', + dalgona_set_neopixel_init: 'Neopixel LED pin settings (%1 pin connects %2 LEDs) %3', + dalgona_set_neopixel_bright: + 'Neopixel LED (pin %1) brightness set to %2 (0 ~ 255) %3', + dalgona_set_neopixel: 'Neopixel LED (pin %1) %2th LED color %3 output %4', + dalgona_set_neopixel_all: 'Neopixel LED (pin %1) All LED colors %2 output %3', + dalgona_set_neopixel_clear: 'Neopixel LED (pin %1) Turn off all LEDs %2', + dalgona_set_dotmatrix_init: + '8x8 Dot Matrix starting settings (DIN %1, CLK %2, CS %3) %4', + dalgona_set_dotmatrix_bright: 'Dot Matrix set bright to %1 (0 ~ 8) %2', + dalgona_set_dotmatrix: 'Dot Matrix LED %1 turn on %2', + dalgona_set_dotmatrix_emoji: 'Dot Matrix LED %1 turn on emoji %2', + dalgona_set_dotmatrix_clear: 'Dot Matrix LED cleat %1', + dalgona_lcd_init: 'I2C LCD starting settings (address %1, column %2, row %3) %4', + dalgona_get_lcd_row: '%1', + dalgona_get_lcd_col: '%1', + dalgona_module_digital_lcd: 'LCD screen %1 column %2 row %3 output %4', + dalgona_lcd_clear: 'LCD screen clear %1', + dalgona_get_dht: 'DHT11 temperature and humidity sensor (out pin %1) %2 value', + dalgona_dht_temp: 'temperature(°C)', + dalgona_dht_humi: 'humidity(%)', + dalgona_set_mp3_init: 'Mp3 init ( tx: %1, rx: %2 ) %3', + dalgona_set_mp3_play: 'Play MP3 file %1 %2', + dalgona_set_mp3_play2: 'mp3 file %1 played for %2 seconds %3', + dalgona_set_mp3_vol: 'Set mp3 volume %1 (0 ~ 30) %2', + dalgona_get_analog_temp_value: 'DHT11 포트 %1의 %2 센서 값', - dalgona_get_dust: '미세먼지센서(LED %1, AO %2) 값(μg/m³)', + dalgona_load_init: 'HX711 Load Cell Startup Settings (DOUT %1, SCK %2) %3', + dalgona_load_scale: 'Calibrating the HX711 Load Cell %1 %2', + dalgona_load_value: 'HX711 load cell value', + + dalgona_get_dust: 'Fine dust sensor (LED %1, AO %2) value', + + dalgona_rfid_init: 'RFID pin settings (SS %1, RST %2) %3', + dalgona_is_rfid_tapped: 'Was the RFID card recognized?', + dalgona_get_rfid_value: 'RFID card value', + dalgona_joy_init: '%1 Joystick startup settings (X AO %2, Y AO %3, Z %4) %5', + dalgona_get_joy_x: '%1 joystick x value', + dalgona_get_joy_y: '%1 joystick y value', + dalgona_get_joy_z: '%1 Joystick button pressed state', + dalgona_get_joy_move: 'When the %1 joystick moves in the %2 direction', + + dalgona_joy_direction_centor: 'center', + dalgona_joy_direction_up: 'up', + dalgona_joy_direction_down: 'down', + dalgona_joy_direction_left: 'left', + dalgona_joy_direction_right: 'right', + dalgona_joy_direction_top_left: 'top left', + dalgona_joy_direction_bottom_left: 'bottom left', + dalgona_joy_direction_top_right: 'top right', + dalgona_joy_direction_bottom_right: 'bottom right', + + dalgona_joy_first: 'First', + dalgona_joy_second: 'Second', - dalgona_rfid_init: 'RFID 시작하기 설정 (RST %1, SS %2) %3', - dalgona_is_rfid_tapped: 'RFID 카드가 인식되었는가?', - dalgona_get_rfid_value: 'RFID 카드 값', + dalgona_get_mlx: 'mlx90614 비접촉 온도센서 %1값', - dalgona_joy_init: '%1 조이스틱 시작하기 설정 (X AO %2, Y AO %3, Z %4) %5', - dalgona_get_joy_x: '%1 조이스틱 X값', - dalgona_get_joy_y: '%1 조이스틱 y값', - dalgona_get_joy_z: '%1 조이스틱 버튼 눌림 상태', - dalgona_get_joy_move: '%1 조이스틱이 %2 방향으로 움직였을 때', + dalgona_step_motor_first: 'First', + dalgona_step_motor_second: 'Second', + dalgona_step_motor_third: 'Third', - dalgona_step_init: '%1 스텝모터 시작하기 설정 (IN1 %2, IN2 %3, IN3 %4, IN4 %5) %6', - dalgona_step_speed: '%1 스텝모터 속도를 %2 로 설정하기 (0 ~ 20) %3', - dalgona_step_rotate: '%1 스텝모터 %2 으로 %3 바퀴 회전하기 %4', - dalgona_step_rotate2: '%1 스텝모터 %2 으로 %3 도 회전하기 %4', - dalgona_step_rotate3: '%1 스텝모터 %2 으로 %3 초 동안 회전하기 %4', + dalgona_step_motor_forward_direction: 'forward direction', + dalgona_step_motor_reverse_direction: 'reverse direction', - dalgona_mlx: 'mlx90614 값', + dalgona_step_init: + '%1 Stepper motor starting settings (IN1 %2, IN2 %3, IN3 %4, IN4 %5) %6', + dalgona_step_speed: '%1 Set step motor speed to %2 (0 ~ 20) %3', + dalgona_step_rotate: 'Rotate the %1 step motor %2 %3 turn %4', + dalgona_step_rotate2: 'Rotate %1 step motor %2 to rotate %3 degrees %4', + dalgona_step_rotate3: 'Rotate %1 step motor in %2 for %3 seconds %4', }, }, }; }; Entry.Dalgona.blockMenuBlocks = [ - // 'FND_event', // 'FND_Control_diplay_brightness', // 'FND_Control_display_onoff', @@ -385,7 +503,7 @@ Entry.Dalgona.blockMenuBlocks = [ 'dalgona_get_analog_mapping', 'dalgona_mapping1', 'dalgona_mapping2', - + 'dalgona_pwm_title', 'dalgona_set_digital_pwm', 'dalgona_set_digital_rgbled', @@ -401,6 +519,8 @@ Entry.Dalgona.blockMenuBlocks = [ 'dalgona_ultrasonic_title', 'dalgona_get_digital_ultrasonic', + // 'test_dalgona_set_ultrasonic_trig', + // 'test_dalgona_get_ultrasonic_echo', 'dalgona_buzzer_title', 'dalgona_set_digital_buzzer_toggle', @@ -475,11 +595,11 @@ Entry.Dalgona.blockMenuBlocks = [ // 'dalgona_get_digital_bluetooth', // 'dalgona_module_digital_bluetooth', ]; -Entry.Dalgona.getBlocks = function() { +Entry.Dalgona.getBlocks = function () { var tx; var din; // var clk; - // var cs; + // var cs; var dout; var sck; var joyx, joyy, joyz; @@ -494,7 +614,6 @@ Entry.Dalgona.getBlocks = function() { var num = 0; return { - // FND_Control_init: { // color: EntryStatic.colorSet.block.default.HARDWARE, // outerLine: EntryStatic.colorSet.block.darken.HARDWARE, @@ -600,7 +719,6 @@ Entry.Dalgona.getBlocks = function() { // Entry.hw.sendQueue.SET = {}; // } - // script.isStart = true; // script.timeFlag = 1; // const fps = Entry.FPS || 60; @@ -685,7 +803,7 @@ Entry.Dalgona.getBlocks = function() { // }, // time: new Date().getTime(), // }; - + // setTimeout(() => { // script.timeFlag = 0; // }, timeValue); @@ -800,7 +918,6 @@ Entry.Dalgona.getBlocks = function() { // time: new Date().getTime(), // }; - // setTimeout(() => { // script.timeFlag = 0; // }, timeValue); @@ -1217,9 +1334,6 @@ Entry.Dalgona.getBlocks = function() { events: {}, }, - - - dalgona_list_analog_basic: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, @@ -1250,7 +1364,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { PORT: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('PORT'); }, }, @@ -1292,7 +1406,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { PORT: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getStringField('PORT'); }, }, @@ -1328,7 +1442,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { OCTAVE: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('OCTAVE'); }, }, @@ -1362,7 +1476,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { PORT: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getStringField('PORT'); }, }, @@ -1392,7 +1506,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { OPERATOR: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getStringField('OPERATOR'); }, }, @@ -1422,7 +1536,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { OPERATOR: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getStringField('OPERATOR'); }, }, @@ -1463,7 +1577,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { NOTE: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('NOTE'); }, }, @@ -1510,7 +1624,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'neopixel', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getNumberValue('NUM'); if (!script.isStart) { @@ -1527,7 +1641,7 @@ Entry.Dalgona.getBlocks = function() { data: value, time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -1588,7 +1702,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'neopixel', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getNumberValue('NUM'); @@ -1611,7 +1725,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -1677,7 +1791,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'neopixel', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { //var sq = Entry.hw.sendQueue; var port = script.getNumberValue('PORT', script); var num = script.getNumberValue('NUM', script); @@ -1718,7 +1832,7 @@ Entry.Dalgona.getBlocks = function() { }, time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, 10); return script; @@ -1774,7 +1888,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'neopixel', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT', script); var value = script.getStringField('COLOR', script); @@ -1811,7 +1925,7 @@ Entry.Dalgona.getBlocks = function() { }, time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, 10); return script; @@ -1862,7 +1976,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'neopixel', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); if (!script.isStart) { if (!Entry.hw.sendQueue['SET']) { @@ -1878,7 +1992,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -1922,7 +2036,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { LINE: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('LINE'); }, }, @@ -1979,7 +2093,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'dotmatrix', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port1 = script.getNumberValue('PORT1', script); var port2 = script.getNumberValue('PORT2', script); var port3 = script.getNumberValue('PORT3', script); @@ -2007,7 +2121,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -2058,7 +2172,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'dotmatrix', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM', script); num = Math.round(num); @@ -2080,7 +2194,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -2134,7 +2248,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -2183,7 +2297,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'dotmatrix', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var text = script.getValue('STRING'); if (!script.isStart) { if (!Entry.hw.sendQueue['SET']) { @@ -2203,7 +2317,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -2255,7 +2369,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { LINE: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('LINE'); }, }, @@ -2291,7 +2405,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'dotmatrix', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var value = script.getNumberValue('LIST'); if (!script.isStart) { if (!Entry.hw.sendQueue['SET']) { @@ -2309,7 +2423,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -2353,7 +2467,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { LINE: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('LINE'); }, }, @@ -2515,7 +2629,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'analog', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getValue('PORT', script); var ANALOG = Entry.hw.portData.ANALOG; @@ -2551,7 +2665,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getValue('PORT', script); var ANALOG = Entry.hw.portData.ANALOG; @@ -2589,7 +2703,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getValue('PORT', script); var ANALOG = Entry.hw.portData.ANALOG; @@ -2641,7 +2755,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'motor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getValue('VALUE'); @@ -2711,7 +2825,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'motor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getNumberValue('VALUE'); @@ -2757,7 +2871,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getValue('PORT', script); var ANALOG = Entry.hw.portData.ANALOG; @@ -2793,7 +2907,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getValue('PORT', script); var ANALOG = Entry.hw.portData.ANALOG; @@ -2829,11 +2943,11 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); // var pu = Entry.hw.portData.PULLUP; var pu = Entry.hw.portData.DIGITAL; - + if (!Entry.hw.sendQueue['GET']) { Entry.hw.sendQueue['GET'] = {}; } @@ -2855,10 +2969,8 @@ Entry.Dalgona.getBlocks = function() { var pullupvalue = pu ? pu[port] || 0 : 0; return !pullupvalue; - - }, - + syntax: { js: [], py: [] }, }, dalgona_get_button: { @@ -2887,7 +2999,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT', script); var DIGITAL = Entry.hw.portData.DIGITAL; @@ -2969,7 +3081,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'analog', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getValue('PORT', script); var result = 0; var ANALOG = Entry.hw.portData.ANALOG; @@ -3050,7 +3162,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'analog', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM', script); var value2 = script.getNumberValue('VALUE2', script); @@ -3135,7 +3247,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'analog', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM', script); var flag = 0; @@ -3217,7 +3329,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'ultrasonic', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port1 = script.getNumberValue('PORT1'); var port2 = script.getNumberValue('PORT2'); @@ -3244,6 +3356,106 @@ Entry.Dalgona.getBlocks = function() { py: ['dalgona.get_digital_ultrasonic(%1, %2)'], }, }, + test_dalgona_set_ultrasonic_trig: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic', + statements: [], + template: Lang.template.test_dalgona_set_ultrasonic_trig, + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [ + { + type: 'arduino_get_port_number', + params: ['3'], + }, + null, + ], + type: 'test_dalgona_set_ultrasonic_trig', + }, + paramsKeyMap: { + PORT: 0, + }, + class: 'ultrasonic', + isNotFor: ['Dalgona'], + func: function (sprite, script) { + var port = script.getNumberValue('PORT'); + + if (!Entry.hw.sendQueue['SET']) { + Entry.hw.sendQueue['SET'] = {}; + } + Entry.hw.sendQueue['SET'][port] = { + type: Entry.Dalgona.sensorTypes.TEST_ULTRASONIC_TRIG, + time: new Date().getTime(), + }; + Entry.Utils.sleep(10); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + test_dalgona_get_ultrasonic_echo: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + template: Lang.template.test_dalgona_get_ultrasonic_echo, + params: [ + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [ + { + type: 'arduino_get_port_number', + params: ['2'], + }, + null, + ], + type: 'test_dalgona_get_ultrasonic_echo', + }, + paramsKeyMap: { + PORT: 0, + }, + class: 'ultrasonic', + isNotFor: ['Dalgona'], + func: function (sprite, script) { + var port = script.getNumberValue('PORT'); + + if (!Entry.hw.sendQueue['GET']) { + Entry.hw.sendQueue['GET'] = {}; + } + Entry.hw.sendQueue['GET'][Entry.Dalgona.sensorTypes.TEST_ULTRASONIC_ECHO] = { + port: port, + time: new Date().getTime(), + }; + Entry.Utils.sleep(30); + return Entry.hw.portData.ULTRASONIC[port] || 0; + }, + syntax: { + js: [], + py: [], + }, + }, + dalgona_get_dust: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, @@ -3280,7 +3492,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port1 = script.getNumberValue('PORT1'); var port2 = script.getNumberValue('PORT2'); @@ -3332,7 +3544,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'digital', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var DIGITAL = Entry.hw.portData.DIGITAL; @@ -3379,7 +3591,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var DIGITAL = Entry.hw.portData.DIGITAL; @@ -3422,7 +3634,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var DIGITAL = Entry.hw.portData.DIGITAL; @@ -3480,7 +3692,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'digital', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getValue('VALUE'); @@ -3548,7 +3760,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'digital', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getValue('VALUE'); @@ -3618,7 +3830,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'pwm', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getNumberValue('VALUE'); @@ -3717,7 +3929,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'pwm', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port1 = script.getNumberValue('PORT1', script); var port2 = script.getNumberValue('PORT2', script); var port3 = script.getNumberValue('PORT3', script); @@ -3743,7 +3955,6 @@ Entry.Dalgona.getBlocks = function() { // time: new Date().getTime(), // }; // return script.callReturn(); - // if (!script.isStart) { // script.isStart = true; @@ -3807,7 +4018,7 @@ Entry.Dalgona.getBlocks = function() { data: value3, time: new Date().getTime(), }; - return script.callReturn(); + return script.callReturn(); }, syntax: { js: [], py: [{}] }, }, @@ -3854,7 +4065,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'motor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getNumberValue('VALUE'); value = Math.min(value, 180); @@ -3948,7 +4159,7 @@ Entry.Dalgona.getBlocks = function() { // if (!Entry.hw.sendQueue['SET']) { // Entry.hw.sendQueue['SET'] = {}; // } - + // Entry.hw.sendQueue['SET'][port] = { // type: Entry.Dalgona.sensorTypes.SERVO2, // data: { @@ -3960,7 +4171,7 @@ Entry.Dalgona.getBlocks = function() { // }; // return script.callReturn(); // }, - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value1 = script.getNumberValue('VALUE1', script); var value2 = script.getNumberValue('VALUE2', script); @@ -3989,7 +4200,7 @@ Entry.Dalgona.getBlocks = function() { }, time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, 10); return script; @@ -4046,7 +4257,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'buzzer', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getValue('VALUE'); @@ -4119,7 +4330,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'buzzer', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var value = script.getNumberValue('VALUE'); @@ -4201,7 +4412,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'buzzer', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var duration = script.getNumberValue('DURATION'); var octave = script.getNumberValue('OCTAVE') - 1; @@ -4252,7 +4463,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, duration + 32); return script; @@ -4326,7 +4537,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'LCD', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var list = script.getNumberValue('LIST'); var col = script.getNumberValue('COL'); var line = script.getValue('LINE'); @@ -4351,7 +4562,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -4419,7 +4630,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'LCD', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var row = script.getNumberValue('ROW'); var col = script.getNumberValue('COL'); var text = script.getValue('STRING'); @@ -4445,7 +4656,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -4496,7 +4707,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -4529,8 +4740,8 @@ Entry.Dalgona.getBlocks = function() { { type: 'Dropdown', options: [ - ['온도(°C)', '0'], - ['습도(%)', '1'], + [Lang.template.dalgona_dht_temp, '0'], + [Lang.template.dalgona_dht_humi, '1'], ], value: '0', fontSize: 11, @@ -4545,7 +4756,6 @@ Entry.Dalgona.getBlocks = function() { type: 'arduino_get_port_number', params: ['4'], }, - ], type: 'dalgona_get_dht', }, @@ -4555,7 +4765,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = script.getNumberValue('PORT'); var type = script.getNumberValue('DHT_SELECT'); @@ -4631,7 +4841,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'mp3', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { tx = script.getNumberValue('PORT1'); var rx = script.getNumberValue('PORT2'); @@ -4653,7 +4863,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -4705,7 +4915,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'mp3', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM'); if (!Entry.hw.sendQueue['SET']) { @@ -4776,7 +4986,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'mp3', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM'); var time_value = script.getNumberValue('TIME'); @@ -4799,7 +5009,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, time_value); return script; @@ -4858,7 +5068,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'mp3', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var vol = script.getNumberValue('VOL'); vol = Math.round(vol); @@ -4883,7 +5093,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -4945,7 +5155,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'HX711', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port1 = script.getNumberValue('PORT1', script); var port2 = script.getNumberValue('PORT2', script); @@ -4970,7 +5180,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -5022,7 +5232,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'HX711', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM', script); if (!script.isStart) { @@ -5042,7 +5252,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -5075,7 +5285,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: {}, class: 'HX711', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { if (!Entry.hw.sendQueue['SET']) { Entry.hw.sendQueue['SET'] = {}; } @@ -5106,8 +5316,8 @@ Entry.Dalgona.getBlocks = function() { { type: 'Dropdown', options: [ - ['첫번째', '1'], - ['두번째', '2'], + [Lang.template.dalgona_joy_first, '1'], + [Lang.template.dalgona_joy_second, '2'], ], value: '1', fontSize: 11, @@ -5122,10 +5332,11 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { NUM: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('NUM'); }, }, + dalgona_joy_init: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, @@ -5189,7 +5400,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'joystick', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM', script); var port1 = script.getNumberValue('PORT1', script); var port2 = script.getNumberValue('PORT2', script); @@ -5237,7 +5448,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; } - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -5284,7 +5495,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'joystick', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var ANALOG = Entry.hw.portData.ANALOG; var num = script.getNumberValue('NUM', script); if (num == 1) { @@ -5327,7 +5538,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'joystick', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var ANALOG = Entry.hw.portData.ANALOG; var num = script.getNumberValue('NUM', script); if (num == 1) { @@ -5370,7 +5581,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'joystick', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var DIGITAL = Entry.hw.portData.DIGITAL; var num = script.getNumberValue('NUM', script); @@ -5410,15 +5621,15 @@ Entry.Dalgona.getBlocks = function() { { type: 'Dropdown', options: [ - ['가운데', '0'], - ['위', '1'], - ['아래', '4'], - ['왼쪽', '2'], - ['오른쪽', '3'], - ['왼쪽위', '5'], - ['왼쪽아래', '6'], - ['오른쪽위', '7'], - ['오른쪽아래', '8'], + [Lang.template.dalgona_joy_direction_centor, '0'], + [Lang.template.dalgona_joy_direction_up, '1'], + [Lang.template.dalgona_joy_direction_down, '4'], + [Lang.template.dalgona_joy_direction_left, '2'], + [Lang.template.dalgona_joy_direction_right, '3'], + [Lang.template.dalgona_joy_direction_top_left, '5'], + [Lang.template.dalgona_joy_direction_bottom_left, '6'], + [Lang.template.dalgona_joy_direction_top_right, '7'], + [Lang.template.dalgona_joy_direction_bottom_right, '8'], ], value: '0', fontSize: 11, @@ -5433,7 +5644,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { DIR: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('DIR'); }, }, @@ -5478,7 +5689,7 @@ Entry.Dalgona.getBlocks = function() { const ANALOG = Entry.hw.portData.ANALOG; num = script.getNumberValue('NUM', script); - const getValue = function(w) { + const getValue = function (w) { return ANALOG[w] <= 100 ? 0 : ANALOG[w] >= 930 ? 2 : 1; }; @@ -5564,9 +5775,9 @@ Entry.Dalgona.getBlocks = function() { { type: 'Dropdown', options: [ - ['첫번째', '1'], - ['두번째', '2'], - ['세번째', '3'], + [Lang.template.dalgona_step_motor_first, '1'], + [Lang.template.dalgona_step_motor_second, '2'], + [Lang.template.dalgona_step_motor_third, '3'], ], value: '1', fontSize: 11, @@ -5581,7 +5792,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { NUM: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('NUM'); }, }, @@ -5658,7 +5869,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'step', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM', script); var port1 = script.getNumberValue('PORT1', script); var port2 = script.getNumberValue('PORT2', script); @@ -5739,7 +5950,7 @@ Entry.Dalgona.getBlocks = function() { }; } - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -5800,7 +6011,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'step', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var num = script.getNumberValue('NUM', script); var sp = script.getNumberValue('SPEED', script); @@ -5854,7 +6065,7 @@ Entry.Dalgona.getBlocks = function() { }; } - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -5882,8 +6093,8 @@ Entry.Dalgona.getBlocks = function() { { type: 'Dropdown', options: [ - ['정방향', '1'], - ['역방향', '2'], + [Lang.template.dalgona_step_motor_forward_direction, '1'], + [Lang.template.dalgona_step_motor_reverse_direction, '2'], ], value: '1', fontSize: 11, @@ -5898,7 +6109,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: { DIR: 0, }, - func: function(sprite, script) { + func: function (sprite, script) { return script.getField('DIR'); }, }, @@ -5955,7 +6166,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'step', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var dir = script.getNumberValue('DIR', script); num = script.getNumberValue('NUM', script); var val = script.getNumberValue('VALUE', script); @@ -6004,7 +6215,7 @@ Entry.Dalgona.getBlocks = function() { }; } - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -6094,7 +6305,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'step', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var dir = script.getNumberValue('DIR', script); num = script.getNumberValue('NUM', script); var val = script.getNumberValue('VALUE', script); @@ -6144,7 +6355,7 @@ Entry.Dalgona.getBlocks = function() { }; } - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -6234,7 +6445,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'step', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { num = script.getNumberValue('NUM'); var dir = script.getNumberValue('DIR'); var sec = script.getNumberValue('SEC'); @@ -6278,9 +6489,12 @@ Entry.Dalgona.getBlocks = function() { }; } - setTimeout(function() { - script.timeFlag = 0; - }, sec * 1000 + 32); + setTimeout( + function () { + script.timeFlag = 0; + }, + sec * 1000 + 32 + ); return script; } else if (script.timeFlag == 1) { return script; @@ -6367,7 +6581,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port = 0; var coodinate_x = script.getNumberValue('VALUE0'); var coodinate_y = script.getNumberValue('VALUE1'); @@ -6424,7 +6638,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -6483,7 +6697,7 @@ Entry.Dalgona.getBlocks = function() { }, class: 'RFID', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { var port1 = script.getNumberValue('PORT1', script); var port2 = script.getNumberValue('PORT2', script); @@ -6507,7 +6721,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; - setTimeout(function() { + setTimeout(function () { script.timeFlag = 0; }, timeValue); return script; @@ -6540,7 +6754,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: {}, class: 'RFID', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { if (!Entry.hw.sendQueue['GET']) { Entry.hw.sendQueue['GET'] = {}; } @@ -6569,7 +6783,7 @@ Entry.Dalgona.getBlocks = function() { paramsKeyMap: {}, class: 'RFID', isNotFor: ['Dalgona'], - func: function(sprite, script) { + func: function (sprite, script) { if (!Entry.hw.sendQueue['SET']) { Entry.hw.sendQueue['SET'] = {}; } @@ -6619,10 +6833,9 @@ Entry.Dalgona.getBlocks = function() { }, class: 'sensor', isNotFor: ['Dalgona'], - - func: function(sprite, script) { - var type = script.getNumberValue('MLX_SELECT') + func: function (sprite, script) { + var type = script.getNumberValue('MLX_SELECT'); if (!Entry.hw.sendQueue['GET']) { Entry.hw.sendQueue['GET'] = {}; @@ -6640,7 +6853,7 @@ Entry.Dalgona.getBlocks = function() { time: new Date().getTime(), }; return Entry.hw.portData.MLXAMB || 0; - } + } }, syntax: { js: [], @@ -6650,4 +6863,4 @@ Entry.Dalgona.getBlocks = function() { }; }; -module.exports = Entry.Dalgona; \ No newline at end of file +module.exports = Entry.Dalgona; diff --git a/src/playground/blocks/hardware/block_jcboard.js b/src/playground/blocks/hardware/block_jcboard.js index 069376c17d..0bb8198266 100644 --- a/src/playground/blocks/hardware/block_jcboard.js +++ b/src/playground/blocks/hardware/block_jcboard.js @@ -745,7 +745,7 @@ Entry.JCBoard.getBlocks = function() { const what = script.getNumberValue('BUTTON_WHAT', script); sensorData = sensorData[0] == 0x26 ? sensorData : oldSensorData; oldSensorData = sensorData; - return !!(sensorData[Entry.JCBoard.Sensor.SENSOR_BUTTON] & (0x01 << what)); + return (sensorData[Entry.JCBoard.Sensor.SENSOR_BUTTON] & (0x01 << what))!=0? 1 : 0; }, syntax: { js: [], py: [] }, }, diff --git a/src/playground/blocks/hardware/block_robodog.js b/src/playground/blocks/hardware/block_robodog.js new file mode 100644 index 0000000000..8213fb8341 --- /dev/null +++ b/src/playground/blocks/hardware/block_robodog.js @@ -0,0 +1,1537 @@ +'use strict'; +let headLED_Backup = new Int8Array(16); +let bodyLED_Backup = new Int8Array(16); +let mp3ID = 0; +Entry.RoboDog = { + + + Cmd: { + CMD_CHECKSUM: 5, + CMD_MP3TRACK: 7, + CMD_MP3VOLUME: 8, + CMD_EXTSERVO: 12, + CMD_SERVOSPEED: 13, + CMD_LEDTYPE: 14, + CMD_TYPE: 15, + CMD_GESTURE: 16, + CMD_LEG0: 16, + CMD_LEG1: 17, + CMD_LEG2: 18, + CMD_LEG3: 19, + CMD_MOVEVEL: 20, + CMD_DEG_VEL:21, + CMD_DEG_LOW:22, + CMD_DEG_HIGH:23, + CMD_LEDDRAW: 24, + CMD_BODYLED0: 24, + CMD_BODYLED1: 28, + CMD_BODYLED2: 32, + CMD_BODYLED3: 36, + CMD_SERVOSPEED_EXT: 40, + }, + Sensor: { + SENSOR_BATTERY: 6, + SENSOR_TOF: 7, + SENSOR_TILT_LR: 8, + SENSOR_TILT_FB: 9, + SENSOR_YAW_LOW: 10, + SENSOR_YAW_HIGH: 11, + SENSOR_RB_DATA: 12, + SENSOR_BUTTON: 16, + SENSOR_RB_WATHDOG: 17, + }, + setZero: function() { + Entry.hw.sendQueue.CMD = [ + 0x26, 0xA8, 0x14, 0x81, 0x30, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100 + ]; + for (let n=0; n<16; n++){ + headLED_Backup[n] = 0; + bodyLED_Backup[n] = 0; + } + Entry.hw.update(); + }, + id: '1D.5', + name: 'RoboDog', + url: 'http://www.junilab.co.kr', + imageName: 'robodog.png', + title: { + 'en': 'RoboDog', + 'ko': '로보독', + }, + monitorTemplate: { + width: 1500, + height: 600, + listPorts: { + 'BATTERY': { + name: '배터리(%)', + type: 'input', + pos: { + x: 0, + y: 0, + }, + }, + 'TOF': { + name: '거리센서', + type: 'input', + pos: { + x: 0, + y: 20, + }, + }, + 'BUTTON': { + name: '버튼', + type: 'input', + pos: { + x: 0, + y: 40, + }, + }, + 'ROLL': { + name: '좌/우 기울기', + type: 'input', + pos: { + x: 0, + y: 60, + }, + }, + 'PITCH': { + name: '앞/뒤 기울기', + type: 'input', + pos: { + x: 0, + y: 80, + }, + }, + + 'YAW': { + name: '회전', + type: 'input', + pos: { + x: 0, + y: 100, + }, + }, + 'RB_WATCHDOG': { + name: '라즈베리파이 준비상태', + type: 'input', + pos: { + x: 0, + y: 40, + }, + }, + 'RB0': { + name: '라즈베리파이D1', + type: 'input', + pos: { + x: 0, + y: 120, + }, + }, + 'RB1': { + name: '라즈베리파이D2', + type: 'input', + pos: { + x: 0, + y: 140, + }, + }, + 'RB2': { + name: '라즈베리파이D3', + type: 'input', + pos: { + x: 0, + y: 160, + }, + }, + 'RB3': { + name: '라즈베리파이D4', + type: 'input', + pos: { + x: 0, + y: 160, + }, + }, + 'RB4': { + name: '라즈베리파이D5', + type: 'input', + pos: { + x: 0, + y: 160, + }, + }, + 'RB5': { + name: '라즈베리파이D6', + type: 'input', + pos: { + x: 0, + y: 160, + }, + }, + }, + ports: { + }, + mode: 'both', + }, +}; + +function checksum(cmd){ + let sum = 0; + + cmd.forEach(function (value, idx) { + if(idx > 5) + sum += value; + }); + return sum&0xFF; +} + +function check_cmdInit(){ + if (typeof Entry.hw.sendQueue.CMD == 'undefined') { + Entry.hw.sendQueue.CMD = [ + 0x26, 0xA8, 0x14, 0x81, 0x30, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100 + ]; + } +} + + +function set_option(cmd, option, initValue) { + console.log("set option : "+cmd[Entry.RoboDog.Cmd.CMD_TYPE]+" "+option) + if(cmd[Entry.RoboDog.Cmd.CMD_TYPE] != option){ + for (let n = 0; n < 8; n++){ + cmd[Entry.RoboDog.Cmd.CMD_LEG0+n] = initValue; + } + } + cmd[Entry.RoboDog.Cmd.CMD_TYPE] = option; +} + +Entry.RoboDog.setLanguage = function() { + return { + ko: { + template: { + 'robodog_gesture': '%1 자세 취하기 %2', + 'robodog_gesture0': '준비', + 'robodog_gesture1': '앉기', + 'robodog_gesture2': '물구나무서기', + 'robodog_gesture3': '기지개 켜기', + 'robodog_gesture4': '인사하기', + + 'robodog_legact': '%1를 %2높이로 설정하기 %3', + 'robodog_legact0': '네다리', + 'robodog_legact1': '앞다리', + 'robodog_legact2': '뒷다리', + 'robodog_legact3': '왼쪽다리', + 'robodog_legact4': '오른쪽다리', + + 'robodog_move': '%1(으)로 %2빠르기로 이동하기 %3', + 'robodog_move0': '앞', + 'robodog_move1': '뒤', + + 'robodog_leg': '%1다리높이 %2, 발끝앞뒤%3로 설정하기 %4', + 'robodog_leg0': '왼쪽 위', + 'robodog_leg1': '왼쪽 아래', + 'robodog_leg2': '오른쪽 아래', + 'robodog_leg3': '오른쪽 위', + 'robodog_leg4': '앞다리', + 'robodog_leg5': '뒷다리', + 'robodog_leg6': '왼쪽다리', + 'robodog_leg7': '오른쪽다리', + 'robodog_leg8': '네다리', + + 'robodog_motor': '%1어깨 %2도, 무릎%3도 설정하기 %4', + + 'robodog_rotation': '%1으로 %2도를 %3각속도로 회전하기 %4', + 'robodog_rotation0': '시계방향', + 'robodog_rotation1': '반시계방향', + + 'robodog_servospeed': '%1 회전속도를 어깨 %2, 무릎 %3(으)로 설정하기 %4', + + 'robodog_headledexp': '%1 표정을 헤드LED에 표현하기 %2', + 'robodog_headledexp0': '초롱초롱', + 'robodog_headledexp1': 'I❤U', + 'robodog_headledexp2': '눈감기', + 'robodog_headledexp3': '감사', + 'robodog_headledexp4': '고마워요', + 'robodog_headledexp5': '뱁새', + 'robodog_headledexp6': '좌우굴리기', + 'robodog_headledexp7': '찢눈', + 'robodog_headledexp8': '찢눈 깜박임', + 'robodog_headledexp9': '곤충', + 'robodog_headledexp10': '깜박', + 'robodog_headledexp11': '뱀눈', + 'robodog_headledexp12': '바람개비', + 'robodog_headledexp13': '왕눈이', + + 'robodog_headledprint': '%1 헤드LED에 %2 문자 출력하기 %3', + 'robodog_headledprint0': '왼쪽', + 'robodog_headledprint1': '오른쪽', + + 'robodog_bodyled': '%1번 바디LED를 R:%2, G:%3, B:%4색상 출력하기 %5', + + 'robodog_mp3play': '%1소리를 %2출력하기 %3', + 'robodog_mp3play01': '멍멍', + 'robodog_mp3play02': '으르렁', + 'robodog_mp3play03': '화난', + 'robodog_mp3play04': '신음', + 'robodog_mp3play05': '거친숨', + 'robodog_mp3play11': '안녕', + 'robodog_mp3play12': '기다려', + 'robodog_mp3play13': '비켜', + 'robodog_mp3play14': '출발', + 'robodog_mp3play21': '레이저', + 'robodog_mp3play22': '모터회전', + 'robodog_mp3play23': '띠리리', + 'robodog_mp3play24': '외계신호', + 'robodog_mp3play25': '동작', + 'robodog_mp3play26': '충돌', + 'robodog_mp3play31': '도', + 'robodog_mp3play32': '레', + 'robodog_mp3play33': '미', + 'robodog_mp3play34': '파', + 'robodog_mp3play35': '솔', + 'robodog_mp3play36': '라', + 'robodog_mp3play37': '시', + 'robodog_mp3play38': '#도', + + 'robodog_mp3playvol0': '작게', + 'robodog_mp3playvol1': '중간으로', + 'robodog_mp3playvol2': '크게', + + 'robodog_expservo': '확장 서보모터를 %1도 설정하기 %2', + + 'robodog_button': '버튼', + 'robodog_battery': '배터리(%)', + 'robodog_getalt': '거리센서', + 'robodog_gettilt': '%1기울기', + 'robodog_tilt0': '좌우', + 'robodog_tilt1': '앞뒤', + 'robodog_getrot': '회전', + + 'robodog_isrbalive': '라즈베리파이 준비상태', + 'robodog_getrbdata': '라즈베리파이 %1번 값', + 'robodog_getrbstr': '라즈베리파이 문자열', + }, + }, + en: { + template: { + 'robodog_gesture': '%1 자세 취하기 %2', + 'robodog_gesture0': '준비', + 'robodog_gesture1': '앉기', + 'robodog_gesture2': '물구나무서기', + 'robodog_gesture3': '기지개 켜기', + 'robodog_gesture4': '인사하기', + + 'robodog_legact': '%1를 %2높이로 설정하기 %3', + 'robodog_legact0': '네다리', + 'robodog_legact1': '앞다리', + 'robodog_legact2': '뒷다리', + 'robodog_legact3': '왼쪽다리', + 'robodog_legact4': '오른쪽다리', + + 'robodog_move': '%1(으)로 %2빠르기로 이동하기 %3', + 'robodog_move0': '앞', + 'robodog_move1': '뒤', + + 'robodog_leg': '%1다리높이 %2, 발끝앞뒤%3로 설정하기 %4', + 'robodog_leg0': '왼쪽 위', + 'robodog_leg1': '왼쪽 아래', + 'robodog_leg2': '오른쪽 아래', + 'robodog_leg3': '오른쪽 위', + 'robodog_leg4': '앞다리', + 'robodog_leg5': '뒷다리', + 'robodog_leg6': '왼쪽다리', + 'robodog_leg7': '오른쪽다리', + 'robodog_leg8': '네다리', + + 'robodog_motor': '%1어깨 %2도, 무릎%3도 설정하기 %4', + + 'robodog_rotation': '%1으로 %2도를 %3각속도로 회전하기 %4', + 'robodog_rotation0': '시계방향', + 'robodog_rotation1': '반시계방향', + + 'robodog_servospeed': '%1 회전속도를 어깨 %2, 무릎 %3(으)로 설정하기 %4', + + 'robodog_headledexp': '%1 표정을 헤드LED에 표현하기 %2', + 'robodog_headledexp0': '초롱초롱', + 'robodog_headledexp1': 'I❤U', + 'robodog_headledexp2': '눈감기', + 'robodog_headledexp3': '감사', + 'robodog_headledexp4': '고마워요', + 'robodog_headledexp5': '뱁새', + 'robodog_headledexp6': '좌우굴리기', + 'robodog_headledexp7': '찢눈', + 'robodog_headledexp8': '찢눈 깜박임', + 'robodog_headledexp9': '곤충', + 'robodog_headledexp10': '깜박', + 'robodog_headledexp11': '뱀눈', + 'robodog_headledexp12': '바람개비', + 'robodog_headledexp13': '왕눈이', + + 'robodog_headledprint': '%1 헤드LED에 %2 문자 출력하기', + 'robodog_headledprint0': '왼쪽', + 'robodog_headledprint1': '오른쪽', + + 'robodog_bodyled': '%1번 바디LED를 R:%2, G:%3, B:%4색상 출력하기 %5', + + 'robodog_mp3play': '%1소리를 %2출력하기 %3', + 'robodog_mp3play01': '멍멍', + 'robodog_mp3play02': '으르렁', + 'robodog_mp3play03': '화난', + 'robodog_mp3play04': '신음', + 'robodog_mp3play05': '거친숨', + 'robodog_mp3play11': '안녕', + 'robodog_mp3play12': '기다려', + 'robodog_mp3play13': '비켜', + 'robodog_mp3play14': '출발', + 'robodog_mp3play21': '레이저', + 'robodog_mp3play22': '모터회전', + 'robodog_mp3play23': '띠리리', + 'robodog_mp3play24': '외계신호', + 'robodog_mp3play25': '동작', + 'robodog_mp3play26': '충돌', + 'robodog_mp3play31': '도', + 'robodog_mp3play32': '레', + 'robodog_mp3play33': '미', + 'robodog_mp3play34': '파', + 'robodog_mp3play35': '솔', + 'robodog_mp3play36': '라', + 'robodog_mp3play37': '시', + 'robodog_mp3play38': '#도', + + 'robodog_mp3playvol0': '작게', + 'robodog_mp3playvol1': '중간으로', + 'robodog_mp3playvol2': '크게', + + 'robodog_expservo': '확장 서보모터를 %1도 설정하기 %2', + + 'robodog_button': '버튼', + 'robodog_battery': '배터리(%)', + 'robodog_getalt': '거리센서', + 'robodog_gettilt': '%1기울기', + 'robodog_tilt0': '좌우', + 'robodog_tilt1': '앞뒤', + 'robodog_getrot': '회전', + + 'robodog_isrbalive': '라즈베리파이 준비상태', + 'robodog_getrbdata': '라즈베리파이 %1번 값', + 'robodog_getrbstr': '라즈베리파이 문자열', + }, + }, + }; +}; + + +Entry.RoboDog.blockMenuBlocks = [ + 'robodog_gesture', + 'robodog_legact', + 'robodog_move', + 'robodog_leg', + 'robodog_motor', + 'robodog_rotation', + 'robodog_servospeed', + 'robodog_headledexp', + 'robodog_headledprint', + 'robodog_bodyled', + 'robodog_mp3play', + 'robodog_expservo', + 'robodog_button', + 'robodog_battery', + 'robodog_getalt', + 'robodog_gettilt', + 'robodog_getrot', + 'robodog_isrbalive', + 'robodog_getrbdata', + 'robodog_getrbstr' +]; + + + +Entry.RoboDog.getBlocks = function() { + return { + //region RoboDog + robodog_gesture: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_gesture0, 0], + [Lang.template.robodog_gesture1, 1], + [Lang.template.robodog_gesture2, 2], + [Lang.template.robodog_gesture3, 3], + [Lang.template.robodog_gesture4, 4], + ], + 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: [null], + type: 'robodog_gesture', + }, + paramsKeyMap: { + MOTION: 0 + }, + class: 'RoboDog_Action', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let motion = script.getField('MOTION', script); + let cmd = Entry.hw.sendQueue.CMD; + + set_option(cmd, 0x04, 0); + cmd[Entry.RoboDog.Cmd.CMD_GESTURE] = motion; + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + robodog_legact: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_legact0, 0], + [Lang.template.robodog_legact1, 1], + [Lang.template.robodog_legact2, 2], + [Lang.template.robodog_legact3, 3], + [Lang.template.robodog_legact4, 4], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + value: '60', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_legact', + }, + paramsKeyMap: { + WHAT_LEG: 0, + LEG_ALT: 1 + }, + class: 'RoboDog_Action', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let what_leg = script.getField('WHAT_LEG', script); + let alt_leg = script.getNumberValue('LEG_ALT', script); + let cmd = Entry.hw.sendQueue.CMD; + + set_option(cmd, 0x01, 0); + + if(what_leg == 0) { + for (let n = 0; n < 4; n++) + cmd[Entry.RoboDog.Cmd.CMD_LEG0 + n] = alt_leg; + } + if(what_leg == 1) + cmd[Entry.RoboDog.Cmd.CMD_LEG0] = cmd[Entry.RoboDog.Cmd.CMD_LEG0+3] = alt_leg; + if(what_leg == 2) + cmd[Entry.RoboDog.Cmd.CMD_LEG0+1] = cmd[Entry.RoboDog.Cmd.CMD_LEG0+2] = alt_leg; + if(what_leg == 3) + cmd[Entry.RoboDog.Cmd.CMD_LEG0] = cmd[Entry.RoboDog.Cmd.CMD_LEG0+1] = alt_leg; + if(what_leg == 4) + cmd[Entry.RoboDog.Cmd.CMD_LEG0+2] = cmd[Entry.RoboDog.Cmd.CMD_LEG0+3] = alt_leg; + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + robodog_move: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_move0, 0], + [Lang.template.robodog_move1, 1], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + value: '50', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_move', + }, + paramsKeyMap: { + DIRECTION: 0, + VELOCITY: 1 + }, + class: 'RoboDog_Action', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let direction = script.getField('DIRECTION', script); + let velocity = script.getNumberValue('VELOCITY', script); + let cmd = Entry.hw.sendQueue.CMD; + set_option(cmd, 0x01, 0); + + velocity = velocity>100? 100 : velocity<-100? -100 : velocity; + if(direction == 1) + velocity = -1*velocity; + cmd[Entry.RoboDog.Cmd.CMD_MOVEVEL] = velocity; + + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + + robodog_leg: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_leg0, 0], + [Lang.template.robodog_leg1, 1], + [Lang.template.robodog_leg2, 2], + [Lang.template.robodog_leg3, 3], + [Lang.template.robodog_leg4, 4], + [Lang.template.robodog_leg5, 5], + [Lang.template.robodog_leg6, 6], + [Lang.template.robodog_leg7, 7], + [Lang.template.robodog_leg8, 8], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + value: '60', + fontSize: 11, + }, + { + type: 'Block', + accept: 'string', + value: '0', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_leg', + }, + paramsKeyMap: { + WHAT_LEG: 0, + LEG_ALT: 1, + LEG_FB: 2 + }, + class: 'RoboDog_Action', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let what_leg = script.getField('WHAT_LEG', script); + let leg_alt = script.getNumberValue('LEG_ALT', script); + let leg_fb = script.getNumberValue('LEG_FB', script); + let cmd = Entry.hw.sendQueue.CMD; + + set_option(cmd, 0x02, -127); + + const pos = [[1, 0, 0, 0],[0, 1, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1],[1, 0, 0, 1],[0, 1, 1, 0],[1, 1, 0, 0],[0, 0, 1, 1],[1, 1, 1, 1]]; + leg_alt = leg_alt>90? 90 : leg_alt<20? 20 : leg_alt; + leg_fb = leg_fb>90? 90 : leg_fb<-90? -90 : leg_fb; + let _pos = pos[what_leg]; + for(let n=0; n<4; n++){ + if(_pos[n] == 1){ + cmd[Entry.RoboDog.Cmd.CMD_LEG0+n*2] = leg_alt; + cmd[Entry.RoboDog.Cmd.CMD_LEG0+n*2+1] = leg_fb; + } + } + + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + + robodog_motor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_leg0, 0], + [Lang.template.robodog_leg1, 1], + [Lang.template.robodog_leg2, 2], + [Lang.template.robodog_leg3, 3], + [Lang.template.robodog_leg4, 4], + [Lang.template.robodog_leg5, 5], + [Lang.template.robodog_leg6, 6], + [Lang.template.robodog_leg7, 7], + [Lang.template.robodog_leg8, 8], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + value: '0', + fontSize: 11, + }, + { + type: 'Block', + accept: 'string', + value: '0', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_motor', + }, + paramsKeyMap: { + WHAT_LEG: 0, + MOTOR_DEG0: 1, + MOTOR_DEG1: 2 + }, + class: 'RoboDog_Action', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let what_leg = script.getField('WHAT_LEG', script); + let motor_deg0 = script.getNumberValue('MOTOR_DEG0', script); + let motor_deg1 = script.getNumberValue('MOTOR_DEG1', script); + let cmd = Entry.hw.sendQueue.CMD; + const pos = [[1, 0, 0, 0],[0, 1, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1],[1, 0, 0, 1],[0, 1, 1, 0],[1, 1, 0, 0],[0, 0, 1, 1],[1, 1, 1, 1]]; + set_option(cmd, 0x03, -127); + + motor_deg0 = motor_deg0>90? 90 : motor_deg0<-90? -90 : motor_deg0; + motor_deg1 = motor_deg1>70? 70 : motor_deg1<-90? -90 : motor_deg1; + + let _pos = pos[what_leg]; + for(let n=0; n<4; n++){ + if(_pos[n] == 1){ + cmd[Entry.RoboDog.Cmd.CMD_LEG0+n*2] = motor_deg0; + cmd[Entry.RoboDog.Cmd.CMD_LEG0+n*2+1] = motor_deg1; + } + } + + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + robodog_rotation: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_rotation0, 0], + [Lang.template.robodog_rotation1, 1], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + value: '90', + fontSize: 11, + }, + { + type: 'Block', + accept: 'string', + value: '100', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_rotation', + }, + paramsKeyMap: { + ROT_DIR: 0, + DEGREE: 1, + DEG_VEL: 2 + }, + class: 'RoboDog_Action', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let rot_dir = script.getField('ROT_DIR', script); + let degree = script.getNumberValue('DEGREE', script); + let deg_vel = script.getNumberValue('DEG_VEL', script); + let cmd = Entry.hw.sendQueue.CMD; + + set_option(cmd, 0x01, 0) + + degree = degree>1000? 1000 : degree<-1000? -1000 : degree; + deg_vel = deg_vel>100? 100 : deg_vel<10? 10 : deg_vel; + if(rot_dir == 1) + degree = -1*degree; + cmd[Entry.RoboDog.Cmd.CMD_DEG_VEL] = deg_vel; + cmd[Entry.RoboDog.Cmd.CMD_DEG_LOW] = degree&0xFF; + cmd[Entry.RoboDog.Cmd.CMD_DEG_HIGH] = (degree>>8)&0xFF; + + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + robodog_servospeed: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_leg0, 0], + [Lang.template.robodog_leg1, 1], + [Lang.template.robodog_leg2, 2], + [Lang.template.robodog_leg3, 3], + [Lang.template.robodog_leg4, 4], + [Lang.template.robodog_leg5, 5], + [Lang.template.robodog_leg6, 6], + [Lang.template.robodog_leg7, 7], + [Lang.template.robodog_leg8, 8], + ], + value: 8, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + value: '50', + fontSize: 11, + }, + { + type: 'Block', + accept: 'string', + value: '50', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_servospeed', + }, + paramsKeyMap: { + WHAT_LEG: 0, + MOTOR1: 1, + MOTOR2: 2, + }, + class: 'RoboDog_Action', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let what_leg = script.getField('WHAT_LEG', script); + let motor1_speed = script.getNumberValue('MOTOR1', script); + let motor2_speed = script.getNumberValue('MOTOR2', script); + let cmd = Entry.hw.sendQueue.CMD; + console.log(typeof motor1_speed + " "+motor1_speed) + motor1_speed = motor1_speed>100? 100 : motor1_speed<10? 10 : motor1_speed; + motor2_speed = motor2_speed>100? 100 : motor2_speed<10? 10 : motor2_speed; + + const pos = [[1, 0, 0, 0],[0, 1, 0, 0],[0, 0, 1, 0],[0, 0, 0, 1],[1, 0, 0, 1],[0, 1, 1, 0],[1, 1, 0, 0],[0, 0, 1, 1],[1, 1, 1, 1]]; + let _pos = pos[what_leg]; + for(let n=0; n<4; n++){ + if(_pos[n] == 1){ + cmd[Entry.RoboDog.Cmd.CMD_SERVOSPEED_EXT+n*2] = motor1_speed; + cmd[Entry.RoboDog.Cmd.CMD_SERVOSPEED_EXT+n*2+1] = motor2_speed; + } + } + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + robodog_headledexp: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_headledexp0, 0], + [Lang.template.robodog_headledexp1, 1], + [Lang.template.robodog_headledexp2, 2], + [Lang.template.robodog_headledexp3, 3], + [Lang.template.robodog_headledexp4, 4], + [Lang.template.robodog_headledexp5, 5], + [Lang.template.robodog_headledexp6, 6], + [Lang.template.robodog_headledexp7, 7], + [Lang.template.robodog_headledexp8, 8], + [Lang.template.robodog_headledexp9, 9], + [Lang.template.robodog_headledexp10, 10], + [Lang.template.robodog_headledexp11, 11], + [Lang.template.robodog_headledexp12, 12], + [Lang.template.robodog_headledexp13, 13], + ], + 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: [null], + type: 'robodog_headledexp', + }, + paramsKeyMap: { + LED_EXP: 0 + }, + class: 'RoboDog_LED', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let led_exp = script.getField('LED_EXP', script); + let cmd = Entry.hw.sendQueue.CMD; + for (let n=0; n<16; n++) + cmd[Entry.RoboDog.Cmd.CMD_LEDDRAW+n] = headLED_Backup[n]; + + cmd[Entry.RoboDog.Cmd.CMD_LEDDRAW] = led_exp; + cmd[Entry.RoboDog.Cmd.CMD_LEDTYPE] = 0x02; + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + + for (let n=0; n<16; n++) + headLED_Backup[n] = cmd[Entry.RoboDog.Cmd.CMD_LEDDRAW+n]; + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + robodog_headledprint: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_headledprint0, 0], + [Lang.template.robodog_headledprint1, 1], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + value: 'A', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_headledprint', + }, + paramsKeyMap: { + WHAT_LED: 0, + WHAT_CHAR: 1, + }, + class: 'RoboDog_LED', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let what_led = script.getField('WHAT_LED', script); + let what_char = script.getStringValue('WHAT_CHAR', script); + let cmd = Entry.hw.sendQueue.CMD; + + for (let n=0; n<16; n++) + cmd[Entry.RoboDog.Cmd.CMD_LEDDRAW+n] = headLED_Backup[n]; + + cmd[Entry.RoboDog.Cmd.CMD_LEDDRAW+what_led*8] = what_char.charCodeAt(0) + + cmd[Entry.RoboDog.Cmd.CMD_LEDTYPE] = 0x03; + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + for (let n=0; n<16; n++) + headLED_Backup[n] = cmd[Entry.RoboDog.Cmd.CMD_LEDDRAW+n]; + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + robodog_bodyled: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ["1~4", 0], + ["1", 1], + ["2", 2], + ["3", 3], + ["4", 4], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Block', + accept: 'string', + value: '255', + fontSize: 11, + }, + { + type: 'Block', + accept: 'string', + value: '255', + fontSize: 11, + }, + { + type: 'Block', + accept: 'string', + value: '255', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_bodyled', + }, + paramsKeyMap: { + WHAT_LED: 0, + RED: 1, + GREEN: 2, + BLUE: 3 + }, + class: 'RoboDog_LED', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + script.get + let what = script.getField('WHAT_LED', script); + let red = script.getNumberValue('RED', script); + let green = script.getNumberValue('GREEN', script); + let blue = script.getNumberValue('BLUE', script); + let cmd = Entry.hw.sendQueue.CMD; + + for (let n=0; n<16; n++) + cmd[Entry.RoboDog.Cmd.CMD_BODYLED0+n] = bodyLED_Backup[n]; + + const pos = [[1, 1, 1, 1], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]; + let _pos = pos[what]; + + for(let n=0; n<4; n++){ + if(_pos[n] == 1){ + cmd[Entry.RoboDog.Cmd.CMD_BODYLED0+n*4] = red; + cmd[Entry.RoboDog.Cmd.CMD_BODYLED0+n*4+1] = green; + cmd[Entry.RoboDog.Cmd.CMD_BODYLED0+n*4+2] = blue; + } + } + cmd[Entry.RoboDog.Cmd.CMD_LEDTYPE] = 0x04; + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + + for (let n=0; n<16; n++) + bodyLED_Backup[n] = cmd[Entry.RoboDog.Cmd.CMD_BODYLED0+n]; + + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + + robodog_mp3play: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_mp3play01, 1], + [Lang.template.robodog_mp3play02, 2], + [Lang.template.robodog_mp3play03, 3], + [Lang.template.robodog_mp3play04, 4], + [Lang.template.robodog_mp3play05, 5], + [Lang.template.robodog_mp3play11, 11], + [Lang.template.robodog_mp3play12, 12], + [Lang.template.robodog_mp3play13, 13], + [Lang.template.robodog_mp3play14, 14], + [Lang.template.robodog_mp3play21, 21], + [Lang.template.robodog_mp3play22, 22], + [Lang.template.robodog_mp3play23, 23], + [Lang.template.robodog_mp3play24, 24], + [Lang.template.robodog_mp3play25, 25], + [Lang.template.robodog_mp3play26, 26], + [Lang.template.robodog_mp3play31, 31], + [Lang.template.robodog_mp3play32, 32], + [Lang.template.robodog_mp3play33, 33], + [Lang.template.robodog_mp3play34, 34], + [Lang.template.robodog_mp3play35, 35], + [Lang.template.robodog_mp3play36, 36], + [Lang.template.robodog_mp3play37, 37], + [Lang.template.robodog_mp3play38, 38], + ], + value: 1, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_mp3playvol0, 1], + [Lang.template.robodog_mp3playvol1, 2], + [Lang.template.robodog_mp3playvol2, 3], + ], + value: 3, + 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: 'robodog_mp3play', + }, + paramsKeyMap: { + WHAT_MP3: 0, + VOLUME: 1, + }, + class: 'RoboDog_ETC', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + script.get + let what_mp3 = script.getField('WHAT_MP3', script); + let volume = script.getField('VOLUME', script); + let cmd = Entry.hw.sendQueue.CMD; + mp3ID = (mp3ID&0x80)==0x80? 0 : 0x80; + cmd[Entry.RoboDog.Cmd.CMD_MP3TRACK] = what_mp3 | mp3ID; + cmd[Entry.RoboDog.Cmd.CMD_MP3VOLUME] = volume; + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + robodog_expservo: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Block', + accept: 'string', + value: '45', + fontSize: 11, + }, + { + type: 'Indicator', + img: 'block_icon/hardware_icon.svg', + size: 12, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_expservo', + }, + paramsKeyMap: { + SERVO_DEG: 0, + }, + class: 'RoboDog_ETC', + isNotFor: ['RoboDog'], + + func: function(sprite, script) { + check_cmdInit(); + let servo_deg = script.getNumberValue('SERVO_DEG', script); + let cmd = Entry.hw.sendQueue.CMD; + + servo_deg = servo_deg>90? 90 : servo_deg<-90? -90 : servo_deg; + cmd[Entry.RoboDog.Cmd.CMD_EXTSERVO] = servo_deg; + + cmd[Entry.RoboDog.Cmd.CMD_CHECKSUM] = checksum(cmd); + Entry.hw.update(); + return script.callReturn(); + }, + syntax: { js: [], py: [] }, + }, + + + robodog_button: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robodog_button', + }, + class: 'RoboDog_Sensor', + isNotFor: ['RoboDog'], + func: function(sprite, script) { + let sensorData = Entry.hw.portData.SENSORDATA; + return sensorData[Entry.RoboDog.Sensor.SENSOR_BUTTON]; + }, + syntax: { js: [], py: [] }, + }, + + robodog_battery: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robodog_battery', + }, + class: 'RoboDog_Sensor', + isNotFor: ['RoboDog'], + func: function(sprite, script) { + let sensorData = Entry.hw.portData.SENSORDATA; + console.log("battery:" + sensorData[6], " len:"+sensorData.length); + return sensorData[Entry.RoboDog.Sensor.SENSOR_BATTERY]; + }, + syntax: { js: [], py: [] }, + }, + robodog_getalt: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robodog_getalt', + }, + class: 'RoboDog_Sensor', + isNotFor: ['RoboDog'], + func: function(sprite, script) { + let sensorData = Entry.hw.portData.SENSORDATA; + console.log("tof:" + sensorData[7], " len:"+sensorData.length); + return sensorData[Entry.RoboDog.Sensor.SENSOR_TOF]; + }, + syntax: { js: [], py: [] }, + }, + + robodog_gettilt: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.template.robodog_tilt0, 0], + [Lang.template.robodog_tilt1, 1], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_gettilt', + }, + class: 'RoboDog_Sensor', + paramsKeyMap: { + TILT_DIR: 0, + }, + isNotFor: ['RoboDog'], + func: function(sprite, script) { + let tilt_dir = script.getField('TILT_DIR', script); + let sensorData = Entry.hw.portData.SENSORDATA; + console.log("tilt:" + sensorData[Entry.RoboDog.Sensor.SENSOR_TILT_LR], " FB:"+sensorData[Entry.RoboDog.Sensor.SENSOR_TILT_FB]); + let val = tilt_dir==0? sensorData[Entry.RoboDog.Sensor.SENSOR_TILT_LR] : sensorData[Entry.RoboDog.Sensor.SENSOR_TILT_FB]; + val = val>127? val-256 : val; + return val; + }, + syntax: { js: [], py: [] }, + }, + + robodog_getrot: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robodog_getrot', + }, + class: 'RoboDog_Sensor', + isNotFor: ['RoboDog'], + func: function(sprite, script) { + let sensorData = Entry.hw.portData.SENSORDATA; + let yaw = sensorData[Entry.RoboDog.Sensor.SENSOR_YAW_LOW]; + yaw |= (sensorData[Entry.RoboDog.Sensor.SENSOR_YAW_HIGH]<<8); + yaw = yaw>0x7FFF? yaw-0x10000 : yaw; + return yaw; + }, + syntax: { js: [], py: [] }, + }, + + robodog_isrbalive: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robodog_isrbalive', + }, + class: 'RoboDog_Sensor', + isNotFor: ['RoboDog'], + func: function(sprite, script) { + let sensorData = Entry.hw.portData.SENSORDATA; + return sensorData[Entry.RoboDog.Sensor.SENSOR_RB_WATHDOG]; + }, + syntax: { js: [], py: [] }, + }, + + robodog_getrbdata: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + ["0", 0], + ["1", 1], + ["2", 2], + ["3", 3], + ], + value: 0, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null], + type: 'robodog_getrbdata', + }, + class: 'RoboDog_Sensor', + paramsKeyMap: { + WHAT_RB: 0, + }, + isNotFor: ['RoboDog'], + func: function(sprite, script) { + let what_rb = script.getField('WHAT_RB', script); + + let sensorData = Entry.hw.portData.SENSORDATA; + let val = sensorData[Entry.RoboDog.Sensor.SENSOR_RB_DATA + what_rb]; + val = val>127? val-256 : val; + return val; + }, + syntax: { js: [], py: [] }, + }, + + + robodog_getrbstr: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + fontColor: '#fff', + skeleton: 'basic_string_field', + statements: [], + params: [], + events: {}, + def: { + params: [null], + type: 'robodog_getrbstr', + }, + class: 'RoboDog_Sensor', + isNotFor: ['RoboDog'], + func: function(sprite, script) { + let sensorData = Entry.hw.portData.SENSORDATA; + let tmp = new Int8Array(6) + for( let n=0; n<4; n++) + tmp[n] = sensorData[Entry.RoboDog.Sensor.SENSOR_RB_DATA+n]; + tmp[4] = sensorData[Entry.RoboDog.Sensor.SENSOR_RB_DATA+6]; + tmp[5] = sensorData[Entry.RoboDog.Sensor.SENSOR_RB_DATA+7]; + + let stop = 5; + for(; stop>=0; stop--){ + if(tmp[stop] != 0) + break; + } + + const slicedArray = tmp.slice(0, stop+1); + const decoder = new TextDecoder(); + return decoder.decode(slicedArray); + }, + syntax: { js: [], py: [] }, + }, + //endregion RoboDog + }; +}; + +module.exports = Entry.RoboDog; diff --git a/src/playground/blocks/hardware/block_robotori.js b/src/playground/blocks/hardware/block_robotori.js index 08a9bd0d26..498d66d894 100644 --- a/src/playground/blocks/hardware/block_robotori.js +++ b/src/playground/blocks/hardware/block_robotori.js @@ -21,7 +21,7 @@ Entry.robotori = { RIGHT_MOTOR: 0xff, //default stop LEFT_MOTOR: 0xff, //default stop }, - setZero: function() { + setZero: function () { //Entry.hw.sendQueue.readablePorts = []; var portMap = Entry.robotori.PORT_MAP; @@ -48,20 +48,20 @@ Entry.robotori = { width: 395, height: 372, 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 } }, - D2: { name: 'D2', type: 'input', pos: { x: 0, y: 0 } }, - D3: { name: 'D3', type: 'input', pos: { x: 0, y: 0 } }, + A0: { name: 'A1', type: 'input', pos: { x: 0, y: 0 } }, + A1: { name: 'A2', type: 'input', pos: { x: 0, y: 0 } }, + A2: { name: 'A3', type: 'input', pos: { x: 0, y: 0 } }, + A3: { name: 'A4', type: 'input', pos: { x: 0, y: 0 } }, + A4: { name: 'A5', type: 'input', pos: { x: 0, y: 0 } }, + A5: { name: 'A6', type: 'input', pos: { x: 0, y: 0 } }, + D2: { name: 'D7', type: 'input', pos: { x: 0, y: 0 } }, + D3: { name: 'D8', type: 'input', pos: { x: 0, y: 0 } }, }, mode: 'both', }, }; -Entry.robotori.setLanguage = function() { +Entry.robotori.setLanguage = function () { return { ko: { template: { @@ -71,36 +71,45 @@ Entry.robotori.setLanguage = function() { robotori_analogOutput: '아날로그 %1 %2 %3', robotori_servo: '서보모터 각도 %1 %2', robotori_dc_direction: 'DC모터 %1 회전 %2 %3', + robotori_dc_forward: 'DC모터 %1 %2 %3', + robotori_dc_stop: 'DC모터 정지 ', + robotori_temperature_sensor: '%1 보드, 온도 센서 %2 핀', + robotori_gas_sensor: '%1 보드, 가스 센서 %2 핀', }, Blocks: { - robotori_D2_Input: '디지털 2번 핀 입력 값', - robotori_D3_Input: '디지털 3번 핀 입력 값', - robotori_A0_Input: '아날로그 0번 핀 입력 값', - robotori_A1_Input: '아날로그 1번 핀 입력 값', - robotori_A2_Input: '아날로그 2번 핀 입력 값', - robotori_A3_Input: '아날로그 3번 핀 입력 값', - robotori_A4_Input: '아날로그 4번 핀 입력 값', - robotori_A5_Input: '아날로그 5번 핀 입력 값', + robotori_D2_Input: '디지털 7번 핀 입력 값', + robotori_D3_Input: '디지털 8번 핀 입력 값', + robotori_A0_Input: '아날로그 1번', + robotori_A1_Input: '아날로그 2번', + robotori_A2_Input: '아날로그 3번', + robotori_A3_Input: '아날로그 4번', + robotori_A4_Input: '아날로그 5번', + robotori_A5_Input: '아날로그 6번', + robotori_board_type_1: 'BASE(E5-1)', + robotori_board_type_2: 'TORIANO(E10)', robotori_digital: '디지털', - robotori_D10_Output: '10번', - robotori_D11_Output: '11번', - robotori_D12_Output: '12번', - robotori_D13_Output: '13번', + robotori_D10_Output: '11번', + robotori_D11_Output: '12번', + robotori_D12_Output: '13번', + robotori_D13_Output: '14번', robotori_pin_OutputValue: '핀, 출력 값', robotori_On: '켜짐', robotori_Off: '꺼짐', robotori_analog: '아날로그', - robotori_analog5: '5번 핀 출력 값', - robotori_analog6: '6번 핀 출력 값', - robotori_analog9: '9번 핀 출력 값', + robotori_analog5: '15번 핀 출력 값', + robotori_analog6: '16번 핀 출력 값', + robotori_analog9: '17번 핀 출력 값', robotori_Servo: '서보모터', robotori_DC: 'DC모터', robotori_DC_rightmotor: '오른쪽', robotori_DC_leftmotor: '왼쪽', + robotori_DC_forward: '전진', + robotori_DC_backward: '후진', robotori_DC_STOP: '정지', robotori_DC_CW: '시계방향', robotori_DC_CCW: '반시계방향', robotori_DC_select: '회전', + }, }, en: { @@ -111,32 +120,40 @@ Entry.robotori.setLanguage = function() { robotori_analogOutput: 'Analog %1 %2 %3', robotori_servo: 'Servo Motor Angle %1 %2', robotori_dc_direction: 'DC Motor %1 Direction %2 %3', + robotori_dc_forward: 'DC Motor Forward', + robotori_dc_backward: 'DC Motor Backward', + robotori_temperature_sensor: '%1 Board, Tempture Sensor %2 PIN', + robotori_gas_sensor: '%1 Board, Gas Sensor %2 PIN', }, Blocks: { - robotori_D2_Input: 'Digital Pin 2 Input Value', - robotori_D3_Input: 'Digital Pin 3 Input Value', - robotori_A0_Input: 'Analog Pin 0 Input Value', - robotori_A1_Input: 'Analog Pin 1 Input Value', - robotori_A2_Input: 'Analog Pin 2 Input Value', - robotori_A3_Input: 'Analog Pin 3 Input Value', - robotori_A4_Input: 'Analog Pin 4 Input Value', - robotori_A5_Input: 'Analog Pin 5 Input Value', + robotori_D2_Input: 'Digital Pin 7 Input Value', + robotori_D3_Input: 'Digital Pin 8 Input Value', + robotori_A0_Input: 'Analog Pin 1 Input Value', + robotori_A1_Input: 'Analog Pin 2 Input Value', + robotori_A2_Input: 'Analog Pin 3 Input Value', + robotori_A3_Input: 'Analog Pin 4 Input Value', + robotori_A4_Input: 'Analog Pin 5 Input Value', + robotori_A5_Input: 'Analog Pin 6 Input Value', + robotori_board_type_1: 'BASE(E5-1)', + robotori_board_type_2: 'TORIANO(E10)', robotori_digital: 'Digital', - robotori_D10_Output: 'Pin 10', - robotori_D11_Output: 'Pin 11', - robotori_D12_Output: 'Pin 12', - robotori_D13_Output: 'Pin 13', + robotori_D10_Output: 'Pin 11', + robotori_D11_Output: 'Pin 12', + robotori_D12_Output: 'Pin 13', + robotori_D13_Output: 'Pin 14', robotori_pin_OutputValue: 'Output Value', robotori_On: 'On', robotori_Off: 'Off', robotori_analog: 'Analog', - robotori_analog5: 'Pin 5 Output Value', - robotori_analog6: 'Pin 6 Output Value', - robotori_analog9: 'Pin 9 Output Value', + robotori_analog5: 'Pin 15 Output Value', + robotori_analog6: 'Pin 16 Output Value', + robotori_analog9: 'Pin 17 Output Value', robotori_Servo: 'Servo Motor', robotori_DC: 'DC Motor', robotori_DC_rightmotor: 'Right', robotori_DC_leftmotor: 'Left', + robotori_DC_forward: 'Forward', + robotori_DC_backward: 'Backward', robotori_DC_STOP: 'Stop', robotori_DC_CW: 'clockwise', robotori_DC_CCW: 'anticlockwise', @@ -154,10 +171,14 @@ Entry.robotori.blockMenuBlocks = [ 'robotori_analogOutput', 'robotori_servo', 'robotori_dc_direction', + 'robotori_dc_forward', + 'robotori_dc_stop', + 'robotori_temperature_sensor', + 'robotori_gas_sensor' //robotori add 20161129 end ]; -Entry.robotori.getBlocks = function() { +Entry.robotori.getBlocks = function () { return { //region robotori 로보토리 robotori_digitalInput: { @@ -188,7 +209,7 @@ Entry.robotori.getBlocks = function() { }, class: 'robotori_sensor', isNotFor: ['robotori'], - func: function(sprite, script) { + func: function (sprite, script) { var pd = Entry.hw.portData; var dev = script.getField('DEVICE'); return pd[dev]; @@ -226,7 +247,7 @@ Entry.robotori.getBlocks = function() { }, class: 'robotori_sensor', isNotFor: ['robotori'], - func: function(sprite, script) { + func: function (sprite, script) { var pd = Entry.hw.portData; var dev = script.getField('DEVICE'); return pd[dev]; @@ -279,7 +300,7 @@ Entry.robotori.getBlocks = function() { }, class: 'robotori_sensor', isNotFor: ['robotori'], - func: function(sprite, script) { + func: function (sprite, script) { var sq = Entry.hw.sendQueue; var dev = script.getStringField('DEVICE', script); var value = script.getStringField('VALUE', script); @@ -358,7 +379,7 @@ Entry.robotori.getBlocks = function() { }, class: 'robotori_sensor', isNotFor: ['robotori'], - func: function(sprite, script) { + func: function (sprite, script) { var sq = Entry.hw.sendQueue; var dev = script.getStringField('DEVICE', script); var value = script.getNumberValue('VALUE', script); @@ -406,7 +427,7 @@ Entry.robotori.getBlocks = function() { }, class: 'robotori_motor', isNotFor: ['robotori'], - func: function(sprite, script) { + func: function (sprite, script) { var sq = Entry.hw.sendQueue; sq.SERVO = script.getNumberValue('SERVO'); @@ -459,7 +480,7 @@ Entry.robotori.getBlocks = function() { }, class: 'robotori_motor', isNotFor: ['robotori'], - func: function(sprite, script) { + func: function (sprite, script) { var sq = Entry.hw.sendQueue; var dev = script.getStringField('DEVICE', script); var value = script.getStringField('VALUE', script); @@ -484,6 +505,219 @@ Entry.robotori.getBlocks = function() { return script.callReturn(); }, }, + robotori_dc_forward: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotori_DC_forward, 'FORWARD'], + [Lang.Blocks.robotori_DC_backward, 'BACKWARD'], + ], + 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, null, null], + type: 'robotori_dc_forward', + }, + paramsKeyMap: { + DEVICE: 0, + VALUE: 1, + }, + class: 'robotori_motor', + isNotFor: ['robotori'], + func: function (sprite, script) { + var sq = Entry.hw.sendQueue; + var dev = script.getStringField('DEVICE', script); + var value = script.getStringField('VALUE', script); + if (dev == 'FORWARD') { + sq.RIGHT_MOTOR = 0x00; + sq.LEFT_MOTOR = 0xb4; + + } + else { + sq.RIGHT_MOTOR = 0xb4; + sq.LEFT_MOTOR = 0x00; + } + + + return script.callReturn(); + }, + }, + robotori_dc_stop: { + 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: [], + type: 'robotori_dc_stop', + }, + paramsKeyMap: { + DEVICE: 0, + VALUE: 1, + }, + class: 'robotori_motor', + isNotFor: ['robotori'], + func: function (sprite, script) { + var sq = Entry.hw.sendQueue; + var dev = script.getStringField('DEVICE', script); + var value = script.getStringField('VALUE', script); + + sq.RIGHT_MOTOR = 0xff; + sq.LEFT_MOTOR = 0xff; + + return script.callReturn(); + }, + }, + robotori_temperature_sensor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotori_board_type_1, 'AT128'], + [Lang.Blocks.robotori_board_type_2, 'TORIANO'], + ], + value: 'AT128', + fontSize: 12, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotori_A0_Input, 'A0'], + [Lang.Blocks.robotori_A1_Input, 'A1'], + [Lang.Blocks.robotori_A2_Input, 'A2'], + [Lang.Blocks.robotori_A3_Input, 'A3'], + [Lang.Blocks.robotori_A4_Input, 'A4'], + [Lang.Blocks.robotori_A5_Input, 'A5'], + ], + value: 'A0', + fontSize: 12, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotori_temperature_sensor', // 블록의 타입 이름을 변경 + }, + paramsKeyMap: { + board: 0, + pin: 1, + + }, + class: 'robotori_sensor', + isNotFor: ['robotori'], + func: function (sprite, script) { + var pd = Entry.hw.portData; + var board_type = script.getField('board', script); + var dev = script.getField('pin', script); + + var originValue = pd[dev]; + var temperature; + + if (board_type == 'AT128') { + temperature = originValue * 0.42; + } + if (board_type == 'TORIANO') { + temperature = originValue * 0.30; + } + + return temperature; + }, + }, + robotori_gas_sensor: { + color: EntryStatic.colorSet.block.default.HARDWARE, + outerLine: EntryStatic.colorSet.block.darken.HARDWARE, + skeleton: 'basic_string_field', + statements: [], + params: [ + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotori_board_type_1, 'AT128'], + [Lang.Blocks.robotori_board_type_2, 'TORIANO'], + ], + value: 'AT128', + fontSize: 12, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + { + type: 'Dropdown', + options: [ + [Lang.Blocks.robotori_A0_Input, 'A0'], + [Lang.Blocks.robotori_A1_Input, 'A1'], + [Lang.Blocks.robotori_A2_Input, 'A2'], + [Lang.Blocks.robotori_A3_Input, 'A3'], + [Lang.Blocks.robotori_A4_Input, 'A4'], + [Lang.Blocks.robotori_A5_Input, 'A5'], + ], + value: 'A0', + fontSize: 12, + bgColor: EntryStatic.colorSet.block.darken.HARDWARE, + arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, + }, + ], + events: {}, + def: { + params: [null, null], + type: 'robotori_gas_sensor', // 블록의 타입 이름을 변경 + }, + paramsKeyMap: { + board: 0, + pin: 1, + + }, + class: 'robotori_sensor', + isNotFor: ['robotori'], + func: function (sprite, script) { + var pd = Entry.hw.portData; + var board_type = script.getField('board', script); + var dev = script.getField('pin', script); + + var originValue = pd[dev]; + var temperature; + + if (board_type == 'AT128') { + temperature = originValue * 0.42; + } + if (board_type == 'TORIANO') { + temperature = originValue * 0.30; + } + + return temperature; + }, + }, + //endregion robotori 로보토리 }; }; diff --git a/src/playground/blocks/hardware/block_zumiMini.js b/src/playground/blocks/hardware/block_zumiMini.js index 42910127f0..489d209b2f 100644 --- a/src/playground/blocks/hardware/block_zumiMini.js +++ b/src/playground/blocks/hardware/block_zumiMini.js @@ -183,7 +183,6 @@ Entry.ZumiMini.setLanguage = function () { turn_right: '오른쪽으로 회전 %1', going_forward_until_sensing : '물체 감지할 때까지 앞으로 가기 %1', following_line_until_sensing : '교차로 만날 때까지 선 따라가기 %1', - LED_color: 'LED 불빛 %1 동작 %2 %3', front_sensor: '앞 센서 %1 %2', bottom_sensor: '바닥 센서 %1 %2', button_input: '버튼 입력 %1', @@ -299,7 +298,6 @@ Entry.ZumiMini.setLanguage = function () { turn_right : 'turning right %1', going_forward_until_sensing: 'going forward until sensing the object %1', following_line_until_sensing: 'following the line until meet the intersection %1', - LED_color: 'LED light color %1 action %2 %3', front_sensor: 'front sensor %1 %2', bottom_sensor: 'bottom sensor %1 %2', button_inpput: 'button input %1', @@ -342,7 +340,6 @@ Entry.ZumiMini.blockMenuBlocks = [ 'following_line_dist', 'following_line_infinite', - 'LED_color', 'LED_control', 'button_boolean_input', @@ -367,143 +364,7 @@ Entry.ZumiMini.blockMenuBlocks = [ Entry.ZumiMini.getBlocks = function() { - return { - LED_color: { - color: EntryStatic.colorSet.block.default.HARDWARE, - outerLine: EntryStatic.colorSet.block.darken.HARDWARE, - fontColor: '#ffffff', - skeleton: 'basic', - params: [ - { - type: 'Dropdown', - options: [ - [Lang.Blocks.RED, 'RED'], - [Lang.Blocks.GREEN, 'GREEN'], - [Lang.Blocks.BLUE, 'BLUE'] - ], - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { - type: 'Dropdown', - options: [ - [Lang.Blocks.ON, 'ON'], - [Lang.Blocks.OFF, 'OFF'] - ], - fontSize: 11, - bgColor: EntryStatic.colorSet.block.darken.HARDWARE, - arrowColor: EntryStatic.colorSet.arrow.default.HARDWARE, - }, - { type: 'Indicator', img: 'block_icon/hardware_icon.svg', size: 14 }, - ], - def: { - params: ['BLUE', 'ON', null], - type: 'LED_color', - }, - paramsKeyMap: { - COLOR: 0, - ACTION: 1, - }, - class: "led", - isNotFor: ['zumi_mini'], - func: function (sprite, script) { - - const Z_WAIT = 0; - const Z_SEND_PACKET = 1; - const Z_MOVING = 2; - - const READY = 0; - const PROCESS = 1; - - const COMMAND_LED_RED = 11; - const COMMAND_LED_BLUE = 12; - const COMMAND_LED_GREEN = 13; - const COMMAND_LED_OFF = 14; - - //var exTime = new Date(); - //var firstCheck = true; - var pStep = Z_WAIT; - var iter = 0; - var _exit = false; - - console.log("LED block Start!"); - - var _col = script.getStringField('COLOR', script); - var _act = script.getStringField('ACTION', script); - - return new Promise(resolve => { - - new Promise(resolve => { - setTimeout(function () { - console.log("exCnt: " + exCnt + " tempCnt:" + tempCnt); - if (exCnt == tempCnt) { - _exit = true; - - } - resolve(); - }, 200); - }) - .then(() => { - - return new Promise(resolve => { - var ttt = setInterval(() => { - - if(_exit == true) { - console.log("block skip!"); - resolve(); - clearInterval(ttt); - } - - var _stat = Entry.hw.portData.inputData['pStat']; - - if ((pStep == Z_WAIT) && (_stat == READY)) pStep = Z_SEND_PACKET; - else if ((pStep == Z_WAIT) && (_stat == PROCESS)) pStep = Z_WAIT; //wait until other action ends. - - if ((pStep == Z_SEND_PACKET) && (_stat == READY)) { //send command until hardware start to action. - - if (iter < 5) { - if ((_col == 'RED') && (_act == 'ON')) Entry.hw.sendQueue['com'] = COMMAND_LED_RED; - else if ((_col == 'BLUE') && (_act == 'ON')) Entry.hw.sendQueue['com'] = COMMAND_LED_BLUE; - else if ((_col == 'GREEN') && (_act == 'ON')) Entry.hw.sendQueue['com'] = COMMAND_LED_GREEN; - - if (_act == 'OFF') Entry.hw.sendQueue['com'] = COMMAND_LED_OFF; - - console.log("send protocol!"); - } - else Entry.hw.sendQueue['com'] = 0x00; - - pStep = Z_SEND_PACKET; - //iter++; - } - else if ((pStep == Z_SEND_PACKET) && (_stat == PROCESS)) { - pStep = Z_MOVING; - Entry.hw.sendQueue['com'] = 0x00; - } - - if ((pStep == Z_MOVING) && (_stat == READY)) { - - console.log("block exit!"); - Entry.hw.sendQueue['com'] = 0x00; - pStep = Z_WAIT; - resolve(); - clearInterval(ttt); - } - else if ((pStep == Z_MOVING) && (_stat == PROCESS)) pStep = Z_MOVING; //wait until the action ends. - - }, 50); - - }); - - }) - .then(() => { - resolve(); - }) - - }); - }, - }, - + return { motion_stop: { color: EntryStatic.colorSet.block.default.HARDWARE, outerLine: EntryStatic.colorSet.block.darken.HARDWARE, @@ -643,7 +504,7 @@ Entry.ZumiMini.getBlocks = function() { }, ], def: { - params: ['FORWARD', 'MID', 20, null], + params: ['FORWARD', 'MID', 10, null], type: 'move_straight', }, paramsKeyMap: { @@ -722,7 +583,7 @@ Entry.ZumiMini.getBlocks = function() { else if (_spd == 'MID') Entry.hw.sendQueue['speed'] = SPEED_MID; else if (_spd == 'SLOW') Entry.hw.sendQueue['speed'] = SPEED_LOW; - if (_dist < 20) _dist = 20; else if (_dist > 200) _dist = 200; + // if (_dist < 20) _dist = 20; else if (_dist > 200) _dist = 200; Entry.hw.sendQueue['dist'] = _dist; console.log("send protocol!"); @@ -2333,7 +2194,7 @@ Entry.ZumiMini.getBlocks = function() { }, ], def: { - params: [20], + params: [18], type: 'april_boolean_detector', }, paramsKeyMap: { diff --git a/src/playground/blocks/hardwareLite/block_microbit2_lite.js b/src/playground/blocks/hardwareLite/block_microbit2_lite.js index a22a7ccd53..8135c352f6 100644 --- a/src/playground/blocks/hardwareLite/block_microbit2_lite.js +++ b/src/playground/blocks/hardwareLite/block_microbit2_lite.js @@ -1487,6 +1487,13 @@ const EVENT_INTERVAL = 150; params: [ { type: 'Led2', + value: [ + [0, 0, 0, 0, 0], + [0, 9, 0, 9, 0], + [0, 0, 0, 0, 0], + [9, 0, 0, 0, 9], + [0, 9, 9, 9, 0], + ], }, { type: 'Indicator', diff --git a/src/playground/field/led2.js b/src/playground/field/led2.js index 0357be457c..959c2971ec 100644 --- a/src/playground/field/led2.js +++ b/src/playground/field/led2.js @@ -7,6 +7,8 @@ import { LedPicker } from '@entrylabs/tool'; /* * */ +const DEFAULT_LED_SIZE = 5; + Entry.FieldLed2 = class FieldLed2 extends Entry.Field { constructor(content, blockView, index) { super(content, blockView, index); @@ -35,6 +37,7 @@ Entry.FieldLed2 = class FieldLed2 extends Entry.Field { [0, 9, 9, 9, 0], ] ); + this.ledSize = this.getValue().length || DEFAULT_LED_SIZE; /* */ @@ -46,8 +49,8 @@ Entry.FieldLed2 = class FieldLed2 extends Entry.Field { renderLed() { const ledStatus = this.getValue(); - const ledDist = 3; - const ledOffset = 0.5; + const ledDist = 3 * (DEFAULT_LED_SIZE / this.ledSize); + const ledOffset = 0.5 * (DEFAULT_LED_SIZE / this.ledSize); const currentStatus = ledStatus.params || ledStatus; currentStatus.map((leds, x_pos) => { return leds.map((led, y_pos) => { @@ -107,7 +110,7 @@ Entry.FieldLed2 = class FieldLed2 extends Entry.Field { fill: '#008380', }); - this._rect = [[], [], [], [], []]; + this._rect = Array.from({ length: this.ledSize }, () => []); this.renderLed(); this._arrow = this.svgGroup.elem('path', { d: `M 30.79 -1.182