diff --git a/extern/lang/en.js b/extern/lang/en.js index bbab97aaaa..62a807bb9c 100644 --- a/extern/lang/en.js +++ b/extern/lang/en.js @@ -986,6 +986,275 @@ Lang.Blocks = { behaviorConduct03014004: 'use escalator safely', behaviorConduct03015007: 'live on fine dusty day', behaviorConduct03015003: 'live by sector', + emergencyActionGuidelines01001: 'typhoon', + emergencyActionGuidelines01001001: '태풍 예보 시', + emergencyActionGuidelines01001002: '태풍 특보 시', + emergencyActionGuidelines01001003: '태풍 이후', + emergencyActionGuidelines01002: 'flood', + emergencyActionGuidelines01002001: '홍수 예·경보 시', + emergencyActionGuidelines01002002: '홍수 우려 때', + emergencyActionGuidelines01002003: '물이 밀려들 때', + emergencyActionGuidelines01002004: '물이 빠진 후에', + emergencyActionGuidelines01003: 'heavy rain', + emergencyActionGuidelines01003001: '호우 대비', + emergencyActionGuidelines01003002: '호우 예보 시', + emergencyActionGuidelines01003003: '호우 특보 중', + emergencyActionGuidelines01003004: '호우 이후', + emergencyActionGuidelines01004: 'strong wind', + emergencyActionGuidelines01004001: '강풍 대비', + emergencyActionGuidelines01004002: '강풍 발생 시', + emergencyActionGuidelines01004003: '강풍 관련', + emergencyActionGuidelines01005: 'heavy snow', + emergencyActionGuidelines01005001: '대설 대비', + emergencyActionGuidelines01005002: '대설 예보 시', + emergencyActionGuidelines01005003: '대설 특보 시', + emergencyActionGuidelines01005004: '대설 이후', + emergencyActionGuidelines01006: 'cold wave', + emergencyActionGuidelines01006001: '한파 대비', + emergencyActionGuidelines01006002: '한파 발생 시', + emergencyActionGuidelines01007: 'rough seas', + emergencyActionGuidelines01007001: '풍랑 특보 시', + emergencyActionGuidelines01008: 'yellow dust', + emergencyActionGuidelines01008001: '황사 대비', + emergencyActionGuidelines01008002: '황사 발생 시', + emergencyActionGuidelines01008003: '황사 이후', + emergencyActionGuidelines01008003: '황사 관련', + emergencyActionGuidelines01009: 'heat wave', + emergencyActionGuidelines01009001: '폭염 대비', + emergencyActionGuidelines01009002: '폭염 발생 시', + emergencyActionGuidelines01009003: '폭염 관련', + emergencyActionGuidelines01010: 'drought', + emergencyActionGuidelines01010001: '가뭄 시 생활', + emergencyActionGuidelines01010002: '가뭄 시 농촌', + emergencyActionGuidelines01011: 'earthquake', + emergencyActionGuidelines01011007: '지진 발생 시 상황별', + emergencyActionGuidelines01011008: '지진 발생 시 장소별', + emergencyActionGuidelines01011009: '지진 대비', + emergencyActionGuidelines01011010: '지진 발생 시', + emergencyActionGuidelines01011011: '지진 장소별', + emergencyActionGuidelines01011012: '지진 대피 후', + emergencyActionGuidelines01012: 'tsunami', + emergencyActionGuidelines01012005: '발생 시 (선박 위)', + emergencyActionGuidelines01012006: '발생 시 (지상 대피)', + emergencyActionGuidelines01013: 'tidal wave', + emergencyActionGuidelines01013001: '해일 대비', + emergencyActionGuidelines01013002: '해일 때', + emergencyActionGuidelines01013003: '해일 발생 때', + emergencyActionGuidelines01013004: '미쳐 대피 못한 때', + emergencyActionGuidelines01013005: '폭풍해일', + emergencyActionGuidelines01014: 'landslide', + emergencyActionGuidelines01014001: '산사태 취약 지역 (주의보)', + emergencyActionGuidelines01014002: '산사태 취약 지역 (경보)', + emergencyActionGuidelines01014003: '일반 지역 (주의보)', + emergencyActionGuidelines01014004: '일반 지역 (경보)', + emergencyActionGuidelines01015: 'volcanic eruption', + emergencyActionGuidelines01015001: '화산재 낙하 대비', + emergencyActionGuidelines01015002: '화산재 낙하 시', + emergencyActionGuidelines01015003: '화산재 제거 이유', + emergencyActionGuidelines02001: 'marine pollution', + emergencyActionGuidelines02001001: '발생 전', + emergencyActionGuidelines02001002: '발생 시', + emergencyActionGuidelines02001003: '조치 완료 후', + emergencyActionGuidelines02002: 'large-scale water pollution', + emergencyActionGuidelines02002001: '사고 시', + emergencyActionGuidelines02002002: '구별 방법', + emergencyActionGuidelines02003: 'water shortage', + emergencyActionGuidelines02003001: '급수중단 발령 시', + emergencyActionGuidelines02003002: 'Ⅰ급상황 발생 시', + emergencyActionGuidelines02003003: 'Ⅱ급상황 발생 시', + emergencyActionGuidelines02004: 'utility tunnel disaster', + emergencyActionGuidelines02004001: '발생 우려 시', + emergencyActionGuidelines02004002: '발생 시', + emergencyActionGuidelines02005: 'livestock disease', + emergencyActionGuidelines02005001: '구제역 발생 시', + emergencyActionGuidelines02005002: '조류인플루엔자(AI) 발생 시', + emergencyActionGuidelines02005003: '발생 방지 대책', + emergencyActionGuidelines02005004: '발생 의심 시', + emergencyActionGuidelines02005005: '발생 확인 시', + emergencyActionGuidelines02006: 'infectious disease', + emergencyActionGuidelines02006001: '예방 대책', + emergencyActionGuidelines02006002: '증상이 나타날 때', + emergencyActionGuidelines02006003: '중동호흡기증후군(MERS)', + emergencyActionGuidelines02007: 'railway and subway', + emergencyActionGuidelines02007001: '지하철 화재 발생 시', + emergencyActionGuidelines02007002: '고속철도 화재 발생 시', + emergencyActionGuidelines02007003: '사고 및 테러(독가스) 발생 시', + emergencyActionGuidelines02008: 'financial IT system', + emergencyActionGuidelines02008001: '보이스피싱 피해금 지급 정지', + emergencyActionGuidelines02008002: '보이스피싱 피해 예방', + emergencyActionGuidelines02009: 'nuclear power plant accident', + emergencyActionGuidelines02009001: '국민보호조치 발표 시', + emergencyActionGuidelines02009002: '방사능구름 통과 시', + emergencyActionGuidelines02009003: '옥내 대피 및 소개 시', + emergencyActionGuidelines02010: 'chemical accident', + emergencyActionGuidelines02010001: '화학물질 유출 시', + emergencyActionGuidelines02010002: '니트로글리세린 누출 시', + emergencyActionGuidelines02010003: '트리니트로톨루엔 누출 시', + emergencyActionGuidelines02010004: '화학유해물질(독성가스) 누출 시', + emergencyActionGuidelines02011: 'fire', + emergencyActionGuidelines02011001: '일반', + emergencyActionGuidelines02011002: '예방 대책', + emergencyActionGuidelines02011003: '화재 발생 후', + emergencyActionGuidelines02011004: '화재 시', + emergencyActionGuidelines02011005: '화재 시 긴급 대피', + emergencyActionGuidelines02011006: '화재 시 피해 복구', + emergencyActionGuidelines02011007: '가정에서의 안전', + emergencyActionGuidelines02011008: '연기 관련 정보', + emergencyActionGuidelines02011009: '아파트 화재 시', + emergencyActionGuidelines02011010: '아파트 화재 대비', + emergencyActionGuidelines02011011: '도로 터널 화재', + emergencyActionGuidelines02011012: '대형 화재', + emergencyActionGuidelines02011013: '고층 건물 화재', + emergencyActionGuidelines02011014: '지하상가 화재 안전수칙', + emergencyActionGuidelines02011015: '지하철 화재 발생 시', + emergencyActionGuidelines02012: 'wildfire', + emergencyActionGuidelines02012001: '주택가 산불 확산 시', + emergencyActionGuidelines02012002: '산불 방지', + emergencyActionGuidelines02012003: '봄철 산불 관련', + emergencyActionGuidelines02012004: '산불 예방', + emergencyActionGuidelines02012005: '산불 발생 후', + emergencyActionGuidelines02012006: '산불 대피', + emergencyActionGuidelines02012007: '산불 피해 지역 가축 관리', + emergencyActionGuidelines02013: 'building collapse', + emergencyActionGuidelines02013001: '사고 발생 시', + emergencyActionGuidelines02013002: '징조를 느낄 때', + emergencyActionGuidelines02013003: '건물 내부에 있을 때', + emergencyActionGuidelines02013004: '건물 외부에 있을 때', + emergencyActionGuidelines02013005: '붕괴, 매몰된 경우', + emergencyActionGuidelines02013007: '도로 공사장 붕괴', + emergencyActionGuidelines02013008: '상수도 공사장 붕괴', + emergencyActionGuidelines02013009: '아파트 공사장 붕괴', + emergencyActionGuidelines02013010: '지하철 공사장 붕괴', + emergencyActionGuidelines02014: 'dam collapse', + emergencyActionGuidelines02014001: '붕괴 우려 시', + emergencyActionGuidelines02014002: '붕괴 발생 시', + emergencyActionGuidelines02014003: '물이 빠진 후', + emergencyActionGuidelines02015: 'explosion', + emergencyActionGuidelines02015001: '가스 폭발 시', + emergencyActionGuidelines02015004: '폭발 현장', + emergencyActionGuidelines02016: 'aircraft accident', + emergencyActionGuidelines02016001: '항공기 사고 예방', + emergencyActionGuidelines02017: 'CBRN incident', + emergencyActionGuidelines02017001: '사고 발생 시', + emergencyActionGuidelines02018: 'power outage', + emergencyActionGuidelines02018001: '정전 시', + emergencyActionGuidelines02018002: '정전 발생 시', + emergencyActionGuidelines02018003: '정전 상황별', + emergencyActionGuidelines02019: 'electricity·gas', + emergencyActionGuidelines02019001: '전기사고 예방', + emergencyActionGuidelines02019002: '침수지역 감전 사고 예방', + emergencyActionGuidelines02019003: '대피 명령 시 전기설비 조치', + emergencyActionGuidelines02019004: '정전 발생 시 조치', + emergencyActionGuidelines02019005: '야외 주의 사항', + emergencyActionGuidelines02019006: '가스사고 예방', + emergencyActionGuidelines02019007: '가스사고 발생 시', + emergencyActionGuidelines02019008: 'LPG 응급조치', + emergencyActionGuidelines02019009: '도시가스(LNG) 응급조치', + emergencyActionGuidelines02019010: '이동식 부탄가스 안전점검', + emergencyActionGuidelines02019011: '가스 사용 시 안전점검', + emergencyActionGuidelines02019012: '가스 누출 발생 시 대피', + emergencyActionGuidelines02019013: '배관 등에서 대량 누출 시', + emergencyActionGuidelines02019014: '기타 사항', + emergencyActionGuidelines02019015: '암모니아가스 인체 접촉 시', + emergencyActionGuidelines02019016: '염소가스 누출 시', + emergencyActionGuidelines02020: 'passenger ship', + emergencyActionGuidelines02020001: '이용객 금지 행위', + emergencyActionGuidelines02020002: '사고 발생 시', + emergencyActionGuidelines02021: 'water accident', + emergencyActionGuidelines02021001: '하천이나 계곡물', + emergencyActionGuidelines02021002: '무릎 이상의 깊은 급류', + emergencyActionGuidelines02021003: '물에 빠졌을 때', + emergencyActionGuidelines02021004: '파도가 높아져 위험할 때', + emergencyActionGuidelines02021005: '수초에 감겼을 때', + emergencyActionGuidelines02021006: '의식 없는 사고자를 구했을 때', + emergencyActionGuidelines02021007: '고립 지역', + emergencyActionGuidelines02021008: '계곡에서 야영지를 선택 시', + emergencyActionGuidelines02021009: '보트 전복 등에 따른 대처', + emergencyActionGuidelines02021010: '갯바위 등 바다낚시 사고 예방', + emergencyActionGuidelines02021011: '갯벌 해루질 사고 예방', + emergencyActionGuidelines02022: 'terrorism', + emergencyActionGuidelines02022007: '신고 요령', + emergencyActionGuidelines02022008: '대형, 고층건물 재난 시', + emergencyActionGuidelines02022009: '폭발물 발견 시', + emergencyActionGuidelines02022010: '화학 테러(독가스 등) 발생 시', + emergencyActionGuidelines02022011: '생물 테러 발생 시', + emergencyActionGuidelines02022012: '방사능 테러 발생 시', + emergencyActionGuidelines02022013: '화재 발생 시', + emergencyActionGuidelines02022014: '총격 현장', + emergencyActionGuidelines02022015: '매몰, 붕괴 시', + emergencyActionGuidelines02022016: '억류, 납치 시', + emergencyActionGuidelines02022017: '테러범·의심물체 등', + emergencyActionGuidelines02023: 'power shortage', + emergencyActionGuidelines02023001: '단계별', + emergencyActionGuidelines03002: 'first aid', + emergencyActionGuidelines03002001: '일반', + emergencyActionGuidelines03002002: '화상', + emergencyActionGuidelines03002003: '온열질환', + emergencyActionGuidelines03002004: '뱀에 물렸을 때', + emergencyActionGuidelines03002005: '벌에 쏘였을 때', + emergencyActionGuidelines03002006: '과호흡증후군', + emergencyActionGuidelines03002007: '상비약', + emergencyActionGuidelines03003: 'CPR', + emergencyActionGuidelines03003001: '성인', + emergencyActionGuidelines03003002: '영유아', + emergencyActionGuidelines03003003: '자동제세동기', + emergencyActionGuidelines03004: 'fire extinguisher', + emergencyActionGuidelines03004001: '분말 소화기', + emergencyActionGuidelines03004002: '투척용 소화기', + emergencyActionGuidelines03004003: '설치/취급 및 사용법', + emergencyActionGuidelines03004004: '소화기의 종류', + emergencyActionGuidelines03005: 'food poisoning', + emergencyActionGuidelines03005001: '일반', + emergencyActionGuidelines03005002: '음식점/급식소 운영자', + emergencyActionGuidelines03006: 'hiking', + emergencyActionGuidelines03006001: '위급 상황 시', + emergencyActionGuidelines03006002: '구조 요청 시', + emergencyActionGuidelines03006003: '응급조치', + emergencyActionGuidelines03007: "children's playground", + emergencyActionGuidelines03007001: '탑승 대기', + emergencyActionGuidelines03007002: '안전 이용', + emergencyActionGuidelines03007003: '탑승 제한', + emergencyActionGuidelines03007004: '어린이 탑승', + emergencyActionGuidelines03007005: '탑승 시 주의', + emergencyActionGuidelines03007006: '운행 중 자세', + emergencyActionGuidelines03007007: '탑승 완료 후 퇴장', + emergencyActionGuidelines03008: 'missing·kidnapping', + emergencyActionGuidelines03008001: '예방 방법', + emergencyActionGuidelines03009: 'sexual violence', + emergencyActionGuidelines03009001: '예방 방법', + emergencyActionGuidelines03010: 'school violence', + emergencyActionGuidelines03010001: '예방 방법', + emergencyActionGuidelines03011: 'domestic violence', + emergencyActionGuidelines03011001: '예방 방법', + emergencyActionGuidelines03012: 'detention·abduction', + emergencyActionGuidelines03012001: '대처 요령', + emergencyActionGuidelines03013: 'traffic accident', + emergencyActionGuidelines03013001: '사고 예방', + emergencyActionGuidelines03013002: '발생 시', + emergencyActionGuidelines03013003: '상황 판단', + emergencyActionGuidelines03013004: '구출', + emergencyActionGuidelines03013005: '차량에서의 구조', + emergencyActionGuidelines03014: 'elevator', + emergencyActionGuidelines03014001: '안전 이용', + emergencyActionGuidelines03014002: '안전 문화', + emergencyActionGuidelines03014003: '고장 시 안전 구조', + emergencyActionGuidelines03014004: '에스컬레이터 안전 수칙', + emergencyActionGuidelines03014005: '엘리베이터 사고 예방', + emergencyActionGuidelines03014006: '에스컬레이터 및 무빙워크 사고 예방', + emergencyActionGuidelines03015: 'fine dust', + emergencyActionGuidelines03015001: '특성', + emergencyActionGuidelines03015002: '미세먼지 예보 등급별', + emergencyActionGuidelines03015003: '부문별 생활 수칙', + emergencyActionGuidelines03015004: '인체에 미치는 영향', + emergencyActionGuidelines03015005: '미세먼지 정보', + emergencyActionGuidelines03015006: '미세먼지 발생 시', + emergencyActionGuidelines03015007: '미세먼지 많은 날', + emergencyActionGuidelines03016: 'fire hydrant', + emergencyActionGuidelines03016001: '옥내소화전 사용법', + emergencyActionGuidelines03016002: '경보 설비', + emergencyActionGuidelines03017: 'home safety inspection', + emergencyActionGuidelines03017001: '안전점검의 날 준비', + emergencyActionGuidelines03017002: '계절별 대비', tts_female: 'female', tts_male: 'male', ROBOID_tail: 'tail', @@ -4955,6 +5224,8 @@ Lang.Msgs = { 'It is a collection of blocks about behavior-guidelines that the public should follow when natural disasters occur. (Provided by MPSS)', expansion_behaviorConductLifeSafety_description: 'It is a collection of blocks about basic behavior-guidelines that the public should follow for safty in life. (Provided by MPSS)', + expansion_emergencyActionGuidelines_description: + 'It is a collection of blocks about emergency action guidelines for citizens to follow in order to stay safe during natural and social disasters, as well as in everyday life.', ai_utilize_tts_description: 'It is a collection of blocks that can read text in a variety of voice using the Clova.', hardware_need_update_title: 'Entry HW update', @@ -6187,6 +6458,18 @@ Lang.Helper = { "\nThe number of behavior-guideline's when selected life problem occurs.", get_lifeSafety_behavior: '\nReports the information about behavior-guidelines when selected life problem occurs.', + count_disaster_guideline: + 'The number of guidelines in the selected natural disaster.\n\n- Natural disaster: typhoon, flood, heavy rain, strong wind, heavy snow, cold wave, rough seas, yellow dust, heat wave, drought, earthquake, tsunami, tidal wave, landslide, volcanic eruption', + get_disaster_guideline: + 'Reports the information about the guidelines of the selected natural disaster.\n\n- Natural disaster: typhoon, flood, heavy rain, strong wind, heavy snow, cold wave, rough seas, yellow dust, heat wave, drought, earthquake, tsunami, tidal wave, landslide, volcanic eruption', + count_social_disaster_guideline: + 'Reports the information about the guidelines of the selected social disaster.\n\n- Social disaster: marine pollution, large-scale water pollution, water shortage, utility tunnel disaster, livestock disease, infectious disease, railway and subway, financial IT system, nuclear power plant accident, chemical accident, fire, wildfire, building collapse, dam collapse, explosion, aircraft accident, CBRN incident, power outage, electricity·gas, passenger ship, water accident, terrorism, power shortage', + get_social_disaster_guideline: + 'Reports the information about the guidelines of the selected social disaster.\n\n- Social disaster: marine pollution, large-scale water pollution, water shortage, utility tunnel disaster, livestock disease, infectious disease, railway and subway, financial IT system, nuclear power plant accident, chemical accident, fire, wildfire, building collapse, dam collapse, explosion, aircraft accident, CBRN incident, power outage, electricity·gas, passenger ship, water accident, terrorism, power shortage"', + count_safety_accident_guideline: + "The number of methods in the selected life safety accident.\n\n- Life safety accidents: first aid, CPR, fire extinguisher, food poisoning, hiking, children's playground, missing·kidnapping, sexual violence, school violence, domestic violence, detention·abduction, traffic accident, elevator, fine dust, fire hydrant, home safety inspection", + get_safety_accident_guideline: + "first aid, CPR, fire extinguisher, food poisoning, hiking, children's playground, missing·kidnapping, sexual violence, school violence, domestic violence, detention·abduction, traffic accident, elevator, fine dust, fire hydrant, home safety inspection", read_text: 'Read the entered text in setted voice.', set_tts_property: 'Set the selected voice to selected speed and selected pitch. \n The selected voice will be set up to selected speed and selected pitch.', @@ -6937,6 +7220,13 @@ Lang.template = { video_body_part_coord: "%3 coordinate of %1 th human's %2", behaviorConductDisaster_title_text: 'Disaster', behaviorConductLifeSafety_title_text: 'LifeSafety', + emergencyActionGuidelines_title_text: 'Emergency action guidelines', + count_disaster_guideline: 'number of guidelines in natural disaster %1 %2', + get_disaster_guideline: '%3 th item of guidelines in natural disaster %1 %2', + count_social_disaster_guideline: 'number of guidelines in social disaster %1 %2', + get_social_disaster_guideline: '%3 th item of guidelines in social disaster %1 %2', + count_safety_accident_guideline: 'number of guidelines in life safety accident %1 %2', + get_safety_accident_guideline: '%3 th item of guidelines in life safety accident %1 %2', tts_title_text: 'Read', hamster_hand_found: 'hand found?', hamster_value: '%1', diff --git a/extern/lang/ko.js b/extern/lang/ko.js index e05098d167..683719069f 100644 --- a/extern/lang/ko.js +++ b/extern/lang/ko.js @@ -292,6 +292,275 @@ Lang.Blocks = { behaviorConduct03014004: '에스컬레이터 안전 이용', behaviorConduct03015007: '미세먼지 많은 날 생활', behaviorConduct03015003: '부문별 생활', + emergencyActionGuidelines01001: '태풍', + emergencyActionGuidelines01001001: '태풍 예보 시', + emergencyActionGuidelines01001002: '태풍 특보 시', + emergencyActionGuidelines01001003: '태풍 이후', + emergencyActionGuidelines01002: '홍수', + emergencyActionGuidelines01002001: '홍수 예·경보 시', + emergencyActionGuidelines01002002: '홍수 우려 때', + emergencyActionGuidelines01002003: '물이 밀려들 때', + emergencyActionGuidelines01002004: '물이 빠진 후에', + emergencyActionGuidelines01003: '호우', + emergencyActionGuidelines01003001: '호우 대비', + emergencyActionGuidelines01003002: '호우 예보 시', + emergencyActionGuidelines01003003: '호우 특보 중', + emergencyActionGuidelines01003004: '호우 이후', + emergencyActionGuidelines01004: '강풍', + emergencyActionGuidelines01004001: '강풍 대비', + emergencyActionGuidelines01004002: '강풍 발생 시', + emergencyActionGuidelines01004003: '강풍 관련', + emergencyActionGuidelines01005: '대설', + emergencyActionGuidelines01005001: '대설 대비', + emergencyActionGuidelines01005002: '대설 예보 시', + emergencyActionGuidelines01005003: '대설 특보 시', + emergencyActionGuidelines01005004: '대설 이후', + emergencyActionGuidelines01006: '한파', + emergencyActionGuidelines01006001: '한파 대비', + emergencyActionGuidelines01006002: '한파 발생 시', + emergencyActionGuidelines01007: '풍랑', + emergencyActionGuidelines01007001: '풍랑 특보 시', + emergencyActionGuidelines01008: '황사', + emergencyActionGuidelines01008001: '황사 대비', + emergencyActionGuidelines01008002: '황사 발생 시', + emergencyActionGuidelines01008003: '황사 이후', + emergencyActionGuidelines01008003: '황사 관련', + emergencyActionGuidelines01009: '폭염', + emergencyActionGuidelines01009001: '폭염 대비', + emergencyActionGuidelines01009002: '폭염 발생 시', + emergencyActionGuidelines01009003: '폭염 관련', + emergencyActionGuidelines01010: '가뭄', + emergencyActionGuidelines01010001: '가뭄 시 생활', + emergencyActionGuidelines01010002: '가뭄 시 농촌', + emergencyActionGuidelines01011: '지진', + emergencyActionGuidelines01011007: '지진 발생 시 상황별', + emergencyActionGuidelines01011008: '지진 발생 시 장소별', + emergencyActionGuidelines01011009: '지진 대비', + emergencyActionGuidelines01011010: '지진 발생 시', + emergencyActionGuidelines01011011: '지진 장소별', + emergencyActionGuidelines01011012: '지진 대피 후', + emergencyActionGuidelines01012: '지진해일', + emergencyActionGuidelines01012005: '발생 시 (선박 위)', + emergencyActionGuidelines01012006: '발생 시 (지상 대피)', + emergencyActionGuidelines01013: '해일', + emergencyActionGuidelines01013001: '해일 대비', + emergencyActionGuidelines01013002: '해일 때', + emergencyActionGuidelines01013003: '해일 발생 때', + emergencyActionGuidelines01013004: '미쳐 대피 못한 때', + emergencyActionGuidelines01013005: '폭풍해일', + emergencyActionGuidelines01014: '산사태', + emergencyActionGuidelines01014001: '산사태 취약 지역 (주의보)', + emergencyActionGuidelines01014002: '산사태 취약 지역 (경보)', + emergencyActionGuidelines01014003: '일반 지역 (주의보)', + emergencyActionGuidelines01014004: '일반 지역 (경보)', + emergencyActionGuidelines01015: '화산폭발', + emergencyActionGuidelines01015001: '화산재 낙하 대비', + emergencyActionGuidelines01015002: '화산재 낙하 시', + emergencyActionGuidelines01015003: '화산재 제거 이유', + emergencyActionGuidelines02001: '해양오염', + emergencyActionGuidelines02001001: '발생 전', + emergencyActionGuidelines02001002: '발생 시', + emergencyActionGuidelines02001003: '조치 완료 후', + emergencyActionGuidelines02002: '대규모 수질오염', + emergencyActionGuidelines02002001: '사고 시', + emergencyActionGuidelines02002002: '구별 방법', + emergencyActionGuidelines02003: '식용수', + emergencyActionGuidelines02003001: '급수중단 발령 시', + emergencyActionGuidelines02003002: 'Ⅰ급상황 발생 시', + emergencyActionGuidelines02003003: 'Ⅱ급상황 발생 시', + emergencyActionGuidelines02004: '공동구 재난', + emergencyActionGuidelines02004001: '발생 우려 시', + emergencyActionGuidelines02004002: '발생 시', + emergencyActionGuidelines02005: '가축질병', + emergencyActionGuidelines02005001: '구제역 발생 시', + emergencyActionGuidelines02005002: '조류인플루엔자(AI) 발생 시', + emergencyActionGuidelines02005003: '발생 방지 대책', + emergencyActionGuidelines02005004: '발생 의심 시', + emergencyActionGuidelines02005005: '발생 확인 시', + emergencyActionGuidelines02006: '감염병', + emergencyActionGuidelines02006001: '예방 대책', + emergencyActionGuidelines02006002: '증상이 나타날 때', + emergencyActionGuidelines02006003: '중동호흡기증후군(MERS)', + emergencyActionGuidelines02007: '철도·지하철', + emergencyActionGuidelines02007001: '지하철 화재 발생 시', + emergencyActionGuidelines02007002: '고속철도 화재 발생 시', + emergencyActionGuidelines02007003: '사고 및 테러(독가스) 발생 시', + emergencyActionGuidelines02008: '금융전산', + emergencyActionGuidelines02008001: '보이스피싱 피해금 지급 정지', + emergencyActionGuidelines02008002: '보이스피싱 피해 예방', + emergencyActionGuidelines02009: '원전사고', + emergencyActionGuidelines02009001: '국민보호조치 발표 시', + emergencyActionGuidelines02009002: '방사능구름 통과 시', + emergencyActionGuidelines02009003: '옥내 대피 및 소개 시', + emergencyActionGuidelines02010: '화학물질', + emergencyActionGuidelines02010001: '화학물질 유출 시', + emergencyActionGuidelines02010002: '니트로글리세린 누출 시', + emergencyActionGuidelines02010003: '트리니트로톨루엔 누출 시', + emergencyActionGuidelines02010004: '화학유해물질(독성가스) 누출 시', + emergencyActionGuidelines02011: '화재', + emergencyActionGuidelines02011001: '일반', + emergencyActionGuidelines02011002: '예방 대책', + emergencyActionGuidelines02011003: '화재 발생 후', + emergencyActionGuidelines02011004: '화재 시', + emergencyActionGuidelines02011005: '화재 시 긴급 대피', + emergencyActionGuidelines02011006: '화재 시 피해 복구', + emergencyActionGuidelines02011007: '가정에서의 안전', + emergencyActionGuidelines02011008: '연기 관련 정보', + emergencyActionGuidelines02011009: '아파트 화재 시', + emergencyActionGuidelines02011010: '아파트 화재 대비', + emergencyActionGuidelines02011011: '도로 터널 화재', + emergencyActionGuidelines02011012: '대형 화재', + emergencyActionGuidelines02011013: '고층 건물 화재', + emergencyActionGuidelines02011014: '지하상가 화재 안전수칙', + emergencyActionGuidelines02011015: '지하철 화재 발생 시', + emergencyActionGuidelines02012: '산불', + emergencyActionGuidelines02012001: '주택가 산불 확산 시', + emergencyActionGuidelines02012002: '산불 방지', + emergencyActionGuidelines02012003: '봄철 산불 관련', + emergencyActionGuidelines02012004: '산불 예방', + emergencyActionGuidelines02012005: '산불 발생 후', + emergencyActionGuidelines02012006: '산불 대피', + emergencyActionGuidelines02012007: '산불 피해 지역 가축 관리', + emergencyActionGuidelines02013: '건축물 붕괴', + emergencyActionGuidelines02013001: '사고 발생 시', + emergencyActionGuidelines02013002: '징조를 느낄 때', + emergencyActionGuidelines02013003: '건물 내부에 있을 때', + emergencyActionGuidelines02013004: '건물 외부에 있을 때', + emergencyActionGuidelines02013005: '붕괴, 매몰된 경우', + emergencyActionGuidelines02013007: '도로 공사장 붕괴', + emergencyActionGuidelines02013008: '상수도 공사장 붕괴', + emergencyActionGuidelines02013009: '아파트 공사장 붕괴', + emergencyActionGuidelines02013010: '지하철 공사장 붕괴', + emergencyActionGuidelines02014: '댐 붕괴', + emergencyActionGuidelines02014001: '붕괴 우려 시', + emergencyActionGuidelines02014002: '붕괴 발생 시', + emergencyActionGuidelines02014003: '물이 빠진 후', + emergencyActionGuidelines02015: '폭발', + emergencyActionGuidelines02015001: '가스 폭발 시', + emergencyActionGuidelines02015004: '폭발 현장', + emergencyActionGuidelines02016: '항공기', + emergencyActionGuidelines02016001: '항공기 사고 예방', + emergencyActionGuidelines02017: '화생방', + emergencyActionGuidelines02017001: '사고 발생 시', + emergencyActionGuidelines02018: '정전 및 전력부족', + emergencyActionGuidelines02018001: '정전 시', + emergencyActionGuidelines02018002: '정전 발생 시', + emergencyActionGuidelines02018003: '정전 상황별', + emergencyActionGuidelines02019: '전기·가스', + emergencyActionGuidelines02019001: '전기사고 예방', + emergencyActionGuidelines02019002: '침수지역 감전 사고 예방', + emergencyActionGuidelines02019003: '대피 명령 시 전기설비 조치', + emergencyActionGuidelines02019004: '정전 발생 시 조치', + emergencyActionGuidelines02019005: '야외 주의 사항', + emergencyActionGuidelines02019006: '가스사고 예방', + emergencyActionGuidelines02019007: '가스사고 발생 시', + emergencyActionGuidelines02019008: 'LPG 응급조치', + emergencyActionGuidelines02019009: '도시가스(LNG) 응급조치', + emergencyActionGuidelines02019010: '이동식 부탄가스 안전점검', + emergencyActionGuidelines02019011: '가스 사용 시 안전점검', + emergencyActionGuidelines02019012: '가스 누출 발생 시 대피', + emergencyActionGuidelines02019013: '배관 등에서 대량 누출 시', + emergencyActionGuidelines02019014: '기타 사항', + emergencyActionGuidelines02019015: '암모니아가스 인체 접촉 시', + emergencyActionGuidelines02019016: '염소가스 누출 시', + emergencyActionGuidelines02020: '유도선', + emergencyActionGuidelines02020001: '이용객 금지 행위', + emergencyActionGuidelines02020002: '사고 발생 시', + emergencyActionGuidelines02021: '수난사고', + emergencyActionGuidelines02021001: '하천이나 계곡물', + emergencyActionGuidelines02021002: '무릎 이상의 깊은 급류', + emergencyActionGuidelines02021003: '물에 빠졌을 때', + emergencyActionGuidelines02021004: '파도가 높아져 위험할 때', + emergencyActionGuidelines02021005: '수초에 감겼을 때', + emergencyActionGuidelines02021006: '의식 없는 사고자를 구했을 때', + emergencyActionGuidelines02021007: '고립 지역', + emergencyActionGuidelines02021008: '계곡에서 야영지를 선택 시', + emergencyActionGuidelines02021009: '보트 전복 등에 따른 대처', + emergencyActionGuidelines02021010: '갯바위 등 바다낚시 사고 예방', + emergencyActionGuidelines02021011: '갯벌 해루질 사고 예방', + emergencyActionGuidelines02022: '테러', + emergencyActionGuidelines02022007: '신고 요령', + emergencyActionGuidelines02022008: '대형, 고층건물 재난 시', + emergencyActionGuidelines02022009: '폭발물 발견 시', + emergencyActionGuidelines02022010: '화학 테러(독가스 등) 발생 시', + emergencyActionGuidelines02022011: '생물 테러 발생 시', + emergencyActionGuidelines02022012: '방사능 테러 발생 시', + emergencyActionGuidelines02022013: '화재 발생 시', + emergencyActionGuidelines02022014: '총격 현장', + emergencyActionGuidelines02022015: '매몰, 붕괴 시', + emergencyActionGuidelines02022016: '억류, 납치 시', + emergencyActionGuidelines02022017: '테러범·의심물체 등', + emergencyActionGuidelines02023: '전력수급', + emergencyActionGuidelines02023001: '단계별', + emergencyActionGuidelines03002: '응급처치', + emergencyActionGuidelines03002001: '일반', + emergencyActionGuidelines03002002: '화상', + emergencyActionGuidelines03002003: '온열질환', + emergencyActionGuidelines03002004: '뱀에 물렸을 때', + emergencyActionGuidelines03002005: '벌에 쏘였을 때', + emergencyActionGuidelines03002006: '과호흡증후군', + emergencyActionGuidelines03002007: '상비약', + emergencyActionGuidelines03003: '심폐소생술', + emergencyActionGuidelines03003001: '성인', + emergencyActionGuidelines03003002: '영유아', + emergencyActionGuidelines03003003: '자동제세동기', + emergencyActionGuidelines03004: '소화기', + emergencyActionGuidelines03004001: '분말 소화기', + emergencyActionGuidelines03004002: '투척용 소화기', + emergencyActionGuidelines03004003: '설치/취급 및 사용법', + emergencyActionGuidelines03004004: '소화기의 종류', + emergencyActionGuidelines03005: '식중독', + emergencyActionGuidelines03005001: '일반', + emergencyActionGuidelines03005002: '음식점/급식소 운영자', + emergencyActionGuidelines03006: '산행', + emergencyActionGuidelines03006001: '위급 상황 시', + emergencyActionGuidelines03006002: '구조 요청 시', + emergencyActionGuidelines03006003: '응급조치', + emergencyActionGuidelines03007: '어린이 놀이시설', + emergencyActionGuidelines03007001: '탑승 대기', + emergencyActionGuidelines03007002: '안전 이용', + emergencyActionGuidelines03007003: '탑승 제한', + emergencyActionGuidelines03007004: '어린이 탑승', + emergencyActionGuidelines03007005: '탑승 시 주의', + emergencyActionGuidelines03007006: '운행 중 자세', + emergencyActionGuidelines03007007: '탑승 완료 후 퇴장', + emergencyActionGuidelines03008: '실종유괴', + emergencyActionGuidelines03008001: '예방 방법', + emergencyActionGuidelines03009: '성폭력', + emergencyActionGuidelines03009001: '예방 방법', + emergencyActionGuidelines03010: '학교폭력', + emergencyActionGuidelines03010001: '예방 방법', + emergencyActionGuidelines03011: '가정폭력', + emergencyActionGuidelines03011001: '예방 방법', + emergencyActionGuidelines03012: '억류 및 납치', + emergencyActionGuidelines03012001: '대처 요령', + emergencyActionGuidelines03013: '교통사고', + emergencyActionGuidelines03013001: '사고 예방', + emergencyActionGuidelines03013002: '발생 시', + emergencyActionGuidelines03013003: '상황 판단', + emergencyActionGuidelines03013004: '구출', + emergencyActionGuidelines03013005: '차량에서의 구조', + emergencyActionGuidelines03014: '승강기', + emergencyActionGuidelines03014001: '안전 이용', + emergencyActionGuidelines03014002: '안전 문화', + emergencyActionGuidelines03014003: '고장 시 안전 구조', + emergencyActionGuidelines03014004: '에스컬레이터 안전 수칙', + emergencyActionGuidelines03014005: '엘리베이터 사고 예방', + emergencyActionGuidelines03014006: '에스컬레이터 및 무빙워크 사고 예방', + emergencyActionGuidelines03015: '미세먼지', + emergencyActionGuidelines03015001: '특성', + emergencyActionGuidelines03015002: '미세먼지 예보 등급별', + emergencyActionGuidelines03015003: '부문별 생활 수칙', + emergencyActionGuidelines03015004: '인체에 미치는 영향', + emergencyActionGuidelines03015005: '미세먼지 정보', + emergencyActionGuidelines03015006: '미세먼지 발생 시', + emergencyActionGuidelines03015007: '미세먼지 많은 날', + emergencyActionGuidelines03016: '소화전', + emergencyActionGuidelines03016001: '옥내소화전 사용법', + emergencyActionGuidelines03016002: '경보 설비', + emergencyActionGuidelines03017: '가정 안전점검', + emergencyActionGuidelines03017001: '안전점검의 날 준비', + emergencyActionGuidelines03017002: '계절별 대비', tts_female: '여성', tts_male: '남성', tts_kind: '친절한', @@ -5326,6 +5595,8 @@ Lang.Msgs = { '자연재난 발생 시 국민이 지켜야하는 기본적인 행동요령에 대한 블록들의 모음입니다. [국민안전처 제공]', expansion_behaviorConductLifeSafety_description: '생활 속 안전을 위해 국민이 지켜야 하는 행동요령에 대한 블록 모음입니다. [국민안전처 제공]', + expansion_emergencyActionGuidelines_description: + '자연∙사회재난 및 생활안전 사고 발생 시 국민이 지켜야 하는 행동요령에 대한 블록 모음입니다. [행정안전부 제공]', ai_utilize_tts_description: 'nVoice 음성합성 기술로 다양한 목소리로 문장을 읽는 블록모음 입니다. (한국어 엔진 지원)', hardware_need_update_title: '업데이트 안내', @@ -6568,6 +6839,18 @@ Lang.Helper = { '선택한 생활 속 문제가 발생했을 때 해야할 행동요령의 수입니다.\n *옵션\n 생활 속 문제: 응급처치, 심폐소생술, 소화기·소화전 사용법, 식중독, 산행안전, 실종유괴, 성폭력, 학교폭력, 가정 폭력, 억류 및 납치, 교통사고, 승강기 안전사고, 미세먼지\n 상황: 생활 속 문제에 따라 다름 ', get_lifeSafety_behavior: '선택한 생활 속 문제가 발생했을 때 해야할 행동요령에 대한 정보입니다.\n *옵션\n 생활 속 문제: 응급처치, 심폐소생술, 소화기·소화전 사용법, 식중독, 산행안전, 실종유괴, 성폭력, 학교폭력, 가정 폭력, 억류 및 납치, 교통사고, 승강기 안전사고, 미세먼지\n 상황: 생활 속 문제에 따라 다름 ', + count_disaster_guideline: + '선택한 자연재난과 진행 정도에 따른 행동요령의 수입니다.\n\n- 자연재난: 태풍, 홍수, 호우, 강풍, 대설, 한파, 풍랑, 황사, 폭염, 가뭄, 지진, 지진해일, 해일, 산사태, 화산폭발', + get_disaster_guideline: + '선택한 자연재난과 진행 정도에 따른 행동요령의 내용입니다.\n\n- 자연재난: 태풍, 홍수, 호우, 강풍, 대설, 한파, 풍랑, 황사, 폭염, 가뭄, 지진, 지진해일, 해일, 산사태, 화산폭발', + count_social_disaster_guideline: + '선택한 사회재난과 진행 정도에 따른 행동요령의 수입니다.\n\n- 사회재난: 해양오염, 대규모 수질오염, 식용수, 공동구 재난, 가축질병, 감염병, 철도·지하철, 금융전산, 원전사고, 화학물질, 화재, 산불, 건축물 붕괴, 댐 붕괴, 폭발, 항공기, 화생방, 정전 및 전력부족, 전기·가스, 유도선, 수난사고, 테러, 전력수급', + get_social_disaster_guideline: + '선택한 사회재난과 진행 정도에 따른 행동요령의 내용입니다.\n\n- 사회재난: 해양오염, 대규모 수질오염, 식용수, 공동구 재난, 가축질병, 감염병, 철도·지하철, 금융전산, 원전사고, 화학물질, 화재, 산불, 건축물 붕괴, 댐 붕괴, 폭발, 항공기, 화생방, 정전 및 전력부족, 전기·가스, 유도선, 수난사고, 테러, 전력수급', + count_safety_accident_guideline: + '"선택한 생활 안전 사고가 발생했을 때 해야할 행동요령의 수입니다.\n\n- 생활안전 사고: 응급처치, 심폐소생술, 소화기, 식중독, 산행, 어린이 놀이시설, 실종유괴, 성폭력, 학교 폭력, 가정 폭력, 억류 및 납치, 교통사고, 승강기, 미세먼지, 소화전, 가정 안전점검"', + get_safety_accident_guideline: + '응급처치, 심폐소생술, 소화기, 식중독, 산행, 어린이 놀이시설, 실종유괴, 성폭력, 학교 폭력, 가정 폭력, 억류 및 납치, 교통사고, 승강기, 미세먼지, 소화전, 가정 안전점검', read_text: '입력한 문자값을 설정된 목소리로 읽습니다.\n입력은 2500자까지 가능합니다.\n인터넷에 연결되어 있지 않거나 인터넷 환경이 불안할 경우, 해당 블록이 실행되지 않고 다음 블록으로 넘어갈 수 있습니다.', set_tts_property: '선택한 목소리가 선택한 속도와 선택한 음높이로 설정됩니다.', @@ -7504,6 +7787,13 @@ Lang.template = { video_body_part_coord: '%1 번째 사람의 %2 의 %3 좌표', behaviorConductDisaster_title_text: '자연재난 국민행동요령', behaviorConductLifeSafety_title_text: '생활안전 국민행동요령', + emergencyActionGuidelines_title_text: '국민행동요령', + count_disaster_guideline: '자연재난 %1 %2 의 행동요령 수', + get_disaster_guideline: '자연재난 %1 %2 의 행동요령 %3 번째 항목', + count_social_disaster_guideline: '사회재난 %1 %2 의 행동요령 수', + get_social_disaster_guideline: '사회재난 %1 %2 의 행동요령 %3 번째 항목', + count_safety_accident_guideline: '생활안전 %1 %2 의 행동요령 수', + get_safety_accident_guideline: '생활안전 %1 중 %2 의 행동요령 %3 번째 항목', tts_title_text: '읽어주기', hamster_hand_found: '손 찾음?', hamster_value: '%1', diff --git a/extern/util/static.js b/extern/util/static.js index 7a09537120..68ecfe6f32 100644 --- a/extern/util/static.js +++ b/extern/util/static.js @@ -466,7 +466,6 @@ EntryStatic.getAllBlocks = function () { 'get_time_weather', 'get_time_weather_data', 'check_time_weather', - 'check_weather', 'check_finedust', 'get_weather_data', @@ -480,12 +479,13 @@ EntryStatic.getAllBlocks = function () { 'festival_title', 'count_festival', 'get_festival_info', - 'behaviorConductDisaster_title', - 'count_disaster_behavior', - 'get_disaster_behavior', - 'behaviorConductLifeSafety_title', - 'count_lifeSafety_behavior', - 'get_lifeSafety_behavior', + 'emergencyActionGuidelines_title', + 'count_disaster_guideline', + 'get_disaster_guideline', + 'count_social_disaster_guideline', + 'get_social_disaster_guideline', + 'count_safety_accident_guideline', + 'get_safety_accident_guideline', ], }, { diff --git a/images/hardware/guideline.png b/images/hardware/guideline.png new file mode 100644 index 0000000000..51ed876d51 Binary files /dev/null and b/images/hardware/guideline.png differ diff --git a/src/class/Expansion.js b/src/class/Expansion.js index 071f9ec419..389b73b81e 100644 --- a/src/class/Expansion.js +++ b/src/class/Expansion.js @@ -3,6 +3,7 @@ import '../playground/blocks/block_expansion_weather'; import '../playground/blocks/block_expansion_festival'; import '../playground/blocks/block_expansion_behaviorconduct_disaster'; import '../playground/blocks/block_expansion_behaviorconduct_lifesafety'; +import '../playground/blocks/block_expansion_emergencyActionGuidelines'; export default class Expansion { constructor(playground) { @@ -12,7 +13,9 @@ export default class Expansion { async init() { const blockObject = {}; Object.entries(Entry.EXPANSION_BLOCK).forEach(([key, value]) => { - Entry.EXPANSION_BLOCK_LIST[key] = value; + if (!value.disabled) { + Entry.EXPANSION_BLOCK_LIST[key] = value; + } if ('getBlocks' in value) { Object.assign(blockObject, value.getBlocks()); } diff --git a/src/playground/blocks/block_calc.js b/src/playground/blocks/block_calc.js index 38d2ead7c9..57c86b93b3 100644 --- a/src/playground/blocks/block_calc.js +++ b/src/playground/blocks/block_calc.js @@ -2060,15 +2060,7 @@ module.exports = { func(sprite, script) { const originStr = script.getStringValue('STRING', script); const targetStr = script.getStringValue('TARGET', script); - - let count = 0; - const substrLength = targetStr.length; - for (let i = 0; i <= originStr.length - substrLength; i++) { - if (originStr.substring(i, i + substrLength) === targetStr) { - count++; - } - } - return count; + return originStr.split(targetStr).length - 1; }, syntax: { js: [], @@ -2253,13 +2245,9 @@ module.exports = { const oldWord = script .getStringValue('OLD_WORD', script) .replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); - - return script - .getStringValue('STRING', script) - .replace( - new RegExp(oldWord, 'gm'), - script.getStringValue('NEW_WORD', script) - ); + const newWord = script.getStringValue('NEW_WORD', script); + const originalString = script.getStringValue('STRING', script); + return originalString.split(oldWord).join(newWord); }, syntax: { js: [], @@ -2600,7 +2588,6 @@ module.exports = { }, func(sprite, script) { const bool = script.getValue('BOOLEAN', script); - console.log('bool', bool); if (Boolean(bool)) { return 'TRUE'; } diff --git a/src/playground/blocks/block_expansion_behaviorconduct_disaster.js b/src/playground/blocks/block_expansion_behaviorconduct_disaster.js index d4f2a5b429..f348ac4239 100644 --- a/src/playground/blocks/block_expansion_behaviorconduct_disaster.js +++ b/src/playground/blocks/block_expansion_behaviorconduct_disaster.js @@ -72,6 +72,7 @@ Entry.EXPANSION_BLOCK.behaviorConductDisaster = { description: Lang.Msgs.expansion_behaviorConductDisaster_description, descriptionKey: 'Msgs.expansion_behaviorConductDisaster_description', isInitialized: false, + disabled: true, init() { if (this.isInitialized) { return; @@ -82,9 +83,9 @@ Entry.EXPANSION_BLOCK.behaviorConductDisaster = { apiType: '01', }; -Entry.EXPANSION_BLOCK.behaviorConductDisaster.getBlocks = function() { +Entry.EXPANSION_BLOCK.behaviorConductDisaster.getBlocks = function () { const categoryMap = getInitialCategoryMap(); - const getCategory = function() { + const getCategory = function () { return Object.keys(categoryMap).map((category) => [categoryMap[category].lang, category]); }; const defaultCategory = Object.keys(categoryMap)[0]; diff --git a/src/playground/blocks/block_expansion_behaviorconduct_lifesafety.js b/src/playground/blocks/block_expansion_behaviorconduct_lifesafety.js index 8866b0d66f..66229e1228 100644 --- a/src/playground/blocks/block_expansion_behaviorconduct_lifesafety.js +++ b/src/playground/blocks/block_expansion_behaviorconduct_lifesafety.js @@ -76,6 +76,7 @@ Entry.EXPANSION_BLOCK.behaviorConductLifeSafety = { description: Lang.Msgs.expansion_behaviorConductLifeSafety_description, descriptionKey: 'Msgs.expansion_behaviorConductLifeSafety_description', isInitialized: false, + disabled: true, init() { if (this.isInitialized) { return; @@ -86,9 +87,9 @@ Entry.EXPANSION_BLOCK.behaviorConductLifeSafety = { apiType: '03', }; -Entry.EXPANSION_BLOCK.behaviorConductLifeSafety.getBlocks = function() { +Entry.EXPANSION_BLOCK.behaviorConductLifeSafety.getBlocks = function () { const categoryMap = getInitialCategoryMap(); - const getCategory = function() { + const getCategory = function () { return Object.keys(categoryMap).map((category) => [categoryMap[category].lang, category]); }; const defaultCategory = Object.keys(categoryMap)[0]; diff --git a/src/playground/blocks/block_expansion_emergencyActionGuidelines.js b/src/playground/blocks/block_expansion_emergencyActionGuidelines.js new file mode 100644 index 0000000000..d8204d6cc4 --- /dev/null +++ b/src/playground/blocks/block_expansion_emergencyActionGuidelines.js @@ -0,0 +1,706 @@ +'use strict'; + +const PromiseManager = require('../../core/promiseManager'); +const { callApi } = require('../../util/common'); + +function getInitialCategoryMap() { + return { + '01': { + '01001': { + lang: Lang.Blocks.emergencyActionGuidelines01001, + sub: ['01001001', '01001002', '01001003'], + }, + '01002': { + lang: Lang.Blocks.emergencyActionGuidelines01002, + sub: ['01002001', '01002002', '01002003', '01002004'], + }, + '01003': { + lang: Lang.Blocks.emergencyActionGuidelines01003, + sub: ['01003001', '01003002', '01003003', '01003004'], + }, + '01004': { + lang: Lang.Blocks.emergencyActionGuidelines01004, + sub: ['01004001', '01004002', '01004003'], + }, + '01005': { + lang: Lang.Blocks.emergencyActionGuidelines01005, + sub: ['01005001', '01005002', '01005003', '01005004'], + }, + '01006': { + lang: Lang.Blocks.emergencyActionGuidelines01006, + sub: ['01006001', '01006002'], + }, + '01007': { + lang: Lang.Blocks.emergencyActionGuidelines01007, + sub: ['01007001'], + }, + '01008': { + lang: Lang.Blocks.emergencyActionGuidelines01008, + sub: ['01008001', '01008002', '01008003', '01008004'], + }, + '01009': { + lang: Lang.Blocks.emergencyActionGuidelines01009, + sub: ['01009001', '01009002', '01009003'], + }, + '01010': { + lang: Lang.Blocks.emergencyActionGuidelines01010, + sub: ['01010001', '01010002'], + }, + '01011': { + lang: Lang.Blocks.emergencyActionGuidelines01011, + sub: ['01011007', '01011008', '01011009', '01011010', '01011012'], + }, + '01012': { + lang: Lang.Blocks.emergencyActionGuidelines01012, + sub: ['01012005', '01012006'], + }, + '01013': { + lang: Lang.Blocks.emergencyActionGuidelines01013, + sub: ['01013001', '01013002', '01013003', '01013004', '01013005'], + }, + '01014': { + lang: Lang.Blocks.emergencyActionGuidelines01014, + sub: ['01014001', '01014002', '01014003', '01014004'], + }, + '01015': { + lang: Lang.Blocks.emergencyActionGuidelines01015, + sub: ['01015001', '01015002', '01015003'], + }, + }, + '02': { + '02001': { + lang: Lang.Blocks.emergencyActionGuidelines02001, + sub: ['02001001', '02001002', '02001003'], + }, + '02002': { + lang: Lang.Blocks.emergencyActionGuidelines02002, + sub: ['02002001', '02002002'], + }, + '02003': { + lang: Lang.Blocks.emergencyActionGuidelines02003, + sub: ['02003001', '02003002', '02003003'], + }, + '02004': { + lang: Lang.Blocks.emergencyActionGuidelines02004, + sub: ['02004001', '02004002'], + }, + '02005': { + lang: Lang.Blocks.emergencyActionGuidelines02005, + sub: ['02005001', '02005002', '02005003', '02005004', '02005005'], + }, + '02006': { + lang: Lang.Blocks.emergencyActionGuidelines02006, + sub: ['02006001', '02006002', '02006003'], + }, + '02007': { + lang: Lang.Blocks.emergencyActionGuidelines02007, + sub: ['02007001', '02007002', '02007003'], + }, + '02008': { + lang: Lang.Blocks.emergencyActionGuidelines02008, + sub: ['02008001', '02008002'], + }, + '02009': { + lang: Lang.Blocks.emergencyActionGuidelines02009, + sub: ['02009001', '02009002', '02009003'], + }, + '02010': { + lang: Lang.Blocks.emergencyActionGuidelines02010, + sub: ['02010001', '02010002', '02010003', '02010004'], + }, + '02011': { + lang: Lang.Blocks.emergencyActionGuidelines02011, + sub: [ + '02011001', + '02011002', + '02011003', + '02011004', + '02011005', + '02011006', + '02011007', + '02011008', + '02011009', + '02011010', + '02011011', + '02011012', + '02011013', + '02011014', + '02011015', + ], + }, + '02012': { + lang: Lang.Blocks.emergencyActionGuidelines02012, + sub: [ + '02012001', + '02012002', + '02012003', + '02012004', + '02012005', + '02012006', + '02012007', + ], + }, + '02013': { + lang: Lang.Blocks.emergencyActionGuidelines02013, + sub: [ + '02013001', + '02013002', + '02013003', + '02013004', + '02013005', + '02013007', + '02013008', + '02013009', + '02013010', + ], + }, + '02014': { + lang: Lang.Blocks.emergencyActionGuidelines02014, + sub: ['02014001', '02014002', '02014003'], + }, + '02015': { + lang: Lang.Blocks.emergencyActionGuidelines02015, + sub: ['02015001', '02015004'], + }, + '02016': { + lang: Lang.Blocks.emergencyActionGuidelines02016, + sub: ['02016001'], + }, + '02017': { + lang: Lang.Blocks.emergencyActionGuidelines02017, + sub: ['02017001'], + }, + '02018': { + lang: Lang.Blocks.emergencyActionGuidelines02018, + sub: ['02018001', '02018002', '02018003'], + }, + '02019': { + lang: Lang.Blocks.emergencyActionGuidelines02019, + sub: [ + '02019001', + '02019002', + '02019003', + '02019004', + '02019005', + '02019006', + '02019007', + '02019008', + '02019009', + '02019010', + '02019011', + '02019012', + '02019013', + '02019014', + '02019015', + '02019016', + ], + }, + '02020': { + lang: Lang.Blocks.emergencyActionGuidelines02020, + sub: ['02020001', '02020002'], + }, + '02021': { + lang: Lang.Blocks.emergencyActionGuidelines02021, + sub: [ + '02021001', + '02021002', + '02021003', + '02021004', + '02021005', + '02021006', + '02021007', + '02021008', + '02021009', + '02021010', + '02021011', + ], + }, + '02022': { + lang: Lang.Blocks.emergencyActionGuidelines02022, + sub: [ + '02022007', + '02022008', + '02022009', + '02022010', + '02022011', + '02022012', + '02022013', + '02022014', + '02022015', + '02022016', + '02022017', + ], + }, + '02023': { + lang: Lang.Blocks.emergencyActionGuidelines02023, + sub: ['02023001'], + }, + }, + '03': { + '03002': { + lang: Lang.Blocks.emergencyActionGuidelines03002, + sub: [ + '03002001', + '03002002', + '03002003', + '03002004', + '03002005', + '03002006', + '03002007', + ], + }, + '03003': { + lang: Lang.Blocks.emergencyActionGuidelines03003, + sub: ['03003001', '03003002', '03003003'], + }, + '03004': { + lang: Lang.Blocks.emergencyActionGuidelines03004, + sub: ['03004001', '03004002', '03004003', '03004004'], + }, + '03005': { + lang: Lang.Blocks.emergencyActionGuidelines03005, + sub: ['03005001', '03005002'], + }, + '03006': { + lang: Lang.Blocks.emergencyActionGuidelines03006, + sub: ['03006001', '03006002', '03006003'], + }, + '03007': { + lang: Lang.Blocks.emergencyActionGuidelines03007, + sub: [ + '03007001', + '03007002', + '03007003', + '03007004', + '03007005', + '03007006', + '03007007', + ], + }, + '03008': { + lang: Lang.Blocks.emergencyActionGuidelines03008, + sub: ['03008001'], + }, + '03009': { + lang: Lang.Blocks.emergencyActionGuidelines03009, + sub: ['03009001'], + }, + '03010': { + lang: Lang.Blocks.emergencyActionGuidelines03010, + sub: ['03010001'], + }, + '03011': { + lang: Lang.Blocks.emergencyActionGuidelines03011, + sub: ['03011001'], + }, + '03012': { + lang: Lang.Blocks.emergencyActionGuidelines03012, + sub: ['03012001'], + }, + '03013': { + lang: Lang.Blocks.emergencyActionGuidelines03013, + sub: ['03013001', '03013002', '03013003', '03013004', '03013005'], + }, + '03014': { + lang: Lang.Blocks.emergencyActionGuidelines03014, + sub: ['03014001', '03014002', '03014003', '03014004', '03014005', '03014006'], + }, + '03015': { + lang: Lang.Blocks.emergencyActionGuidelines03015, + sub: [ + '03015001', + '03015002', + '03015003', + '03015004', + '03015005', + '03015006', + '03015007', + ], + }, + '03016': { + lang: Lang.Blocks.emergencyActionGuidelines03016, + sub: ['03016001', '03016002'], + }, + }, + }; +} + +const defaultCategory = { + '01': '01001', + '02': '02001', + '03': '03002', +}; + +Entry.EXPANSION_BLOCK.emergencyActionGuidelines = { + name: 'emergencyActionGuidelines', + imageName: 'guideline.png', + title: { + ko: '국민행동요령', + en: 'Emergency action guidelines', + }, + titleKey: 'template.emergencyActionGuidelines_title_text', + description: Lang.Msgs.expansion_emergencyActionGuidelines_description, + descriptionKey: 'Msgs.expansion_emergencyActionGuidelines_description', + isInitialized: false, + init() { + if (this.isInitialized) { + return; + } + Entry.EXPANSION_BLOCK.emergencyActionGuidelines.isInitialized = true; + }, + api: '/api/expansionBlock/emergencyActionGuidelines', + apiType: '01', +}; + +const getGuideline = (params, defaultValue, index = null) => { + const key = `emergencyActionGuidelines-${params.category}-${params.subCategory}`; + const promiseManager = new PromiseManager(); + const job = promiseManager + // eslint-disable-next-line new-cap + .Promise((resolve) => { + callApi(key, { + // eslint-disable-next-line max-len + url: `${Entry.EXPANSION_BLOCK.emergencyActionGuidelines.api}/${params.category}/${params.subCategory}`, + }) + .then((result) => { + if (result) { + const items = result.data.body.filter( + (i) => + i.hasOwnProperty('actRmks') && i.safety_cate3 == params.subCategory2 + ); + if (index) { + return resolve(items[index - 1].actRmks); + } + return resolve(items.length); + } + return resolve(defaultValue); + }) + .catch(() => resolve(defaultValue)); + }) + .catch(() => defaultValue); + + return job; +}; + +Entry.EXPANSION_BLOCK.emergencyActionGuidelines.getBlocks = function () { + const categoryMap = getInitialCategoryMap(); + const categoryDisasterMap = getInitialCategoryMap(); + const getCategories = function (cate1) { + return Object.keys(categoryMap[cate1]).map((cate2) => [ + categoryMap[cate1][cate2].lang, + cate2, + ]); + }; + + const getCategory = (cate1 = '01', isPython) => { + const param = { + type: 'Dropdown', + options: getCategories(cate1), + value: defaultCategory[cate1], + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.EXPANSION, + arrowColor: EntryStatic.colorSet.common.WHITE, + dropdownSync: 'emergencyAction', + }; + if (isPython) { + param.converter = Entry.block.converters.returnStringValue; + } + return param; + }; + + const getSubCategory = (cate1 = '01', isPython = false) => { + const param = { + type: 'DropdownDynamic', + value: null, + menuName() { + const value = this.getTargetValue('emergencyAction'); + if (!value) { + return [[Lang.Blocks.no_target, 'null']]; + } + return categoryMap[cate1][value].sub.map((category) => [ + Lang.Blocks[`emergencyActionGuidelines${category}`], + category, + ]); + }, + needDeepCopy: true, + fontSize: 11, + bgColor: EntryStatic.colorSet.block.darken.EXPANSION, + arrowColor: EntryStatic.colorSet.common.WHITE, + defaultValue: (value, options) => { + if (options.length) { + return options[0][1]; + } + return null; + }, + }; + if (isPython) { + param.converter = Entry.block.converters.returnStringValue; + } + return param; + }; + + return { + emergencyActionGuidelines_title: { + template: '%1', + skeleton: 'basic_text', + color: EntryStatic.colorSet.common.TRANSPARENT, + params: [ + { + type: 'Text', + text: Lang.template.emergencyActionGuidelines_title_text, + color: EntryStatic.colorSet.common.TEXT, + align: 'center', + }, + ], + def: { + type: 'emergencyActionGuidelines_title', + }, + class: 'emergencyActionGuidelines', + isNotFor: ['emergencyActionGuidelines'], + events: {}, + }, + count_disaster_guideline: { + color: EntryStatic.colorSet.block.default.EXPANSION, + outerLine: EntryStatic.colorSet.block.darken.EXPANSION, + skeleton: 'basic_string_field', + statements: [], + params: [getCategory('01'), getSubCategory('01')], + events: {}, + def: { + params: [getCategory('01').value, null], + type: 'count_disaster_guideline', + }, + pyHelpDef: { + params: ['A&value', 'B&value'], + type: 'count_disaster_guideline', + }, + paramsKeyMap: { + CATEGORY: 0, + SUB_CATEGORY: 1, + }, + class: 'emergencyActionGuidelines', + isNotFor: ['emergencyActionGuidelines'], + func(sprite, script) { + const params = { + category: '01', + subCategory: script.getField('CATEGORY', script), + subCategory2: script.getField('SUB_CATEGORY', script), + }; + + return getGuideline(params, 0); + }, + syntax: { + js: [], + py: [], + }, + }, + get_disaster_guideline: { + color: EntryStatic.colorSet.block.default.EXPANSION, + outerLine: EntryStatic.colorSet.block.darken.EXPANSION, + skeleton: 'basic_string_field', + statements: [], + params: [ + getCategory('01'), + getSubCategory('01'), + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [getCategory('01').value, null, 1], + type: 'get_disaster_guideline', + }, + pyHelpDef: { + params: ['A&value', 'B&value', 'C&value'], + type: 'get_disaster_guideline', + }, + paramsKeyMap: { + CATEGORY: 0, + SUB_CATEGORY: 1, + NUMBER: 2, + }, + class: 'emergencyActionGuidelines', + isNotFor: ['emergencyActionGuidelines'], + func(sprite, script) { + const number = script.getStringValue('NUMBER', script); + const defaultValue = Lang.Blocks.no_data; + const params = { + category: '01', + subCategory: script.getField('CATEGORY', script), + subCategory2: script.getField('SUB_CATEGORY', script), + }; + + return getGuideline(params, defaultValue, number); + }, + syntax: { + js: [], + py: [], + }, + }, + count_social_disaster_guideline: { + color: EntryStatic.colorSet.block.default.EXPANSION, + outerLine: EntryStatic.colorSet.block.darken.EXPANSION, + skeleton: 'basic_string_field', + statements: [], + params: [getCategory('02'), getSubCategory('02')], + events: {}, + def: { + params: [getCategory('02').value, null], + type: 'count_social_disaster_guideline', + }, + pyHelpDef: { + params: ['A&value', 'B&value'], + type: 'count_social_disaster_guideline', + }, + paramsKeyMap: { + CATEGORY: 0, + SUB_CATEGORY: 1, + }, + class: 'emergencyActionGuidelines', + isNotFor: ['emergencyActionGuidelines'], + func(sprite, script) { + const params = { + category: '02', + subCategory: script.getField('CATEGORY', script), + subCategory2: script.getField('SUB_CATEGORY', script), + }; + + return getGuideline(params, 0); + }, + syntax: { + js: [], + py: [], + }, + }, + get_social_disaster_guideline: { + color: EntryStatic.colorSet.block.default.EXPANSION, + outerLine: EntryStatic.colorSet.block.darken.EXPANSION, + skeleton: 'basic_string_field', + statements: [], + params: [ + getCategory('02'), + getSubCategory('02'), + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [getCategory('02').value, null, 1], + type: 'get_social_disaster_guideline', + }, + pyHelpDef: { + params: ['A&value', 'B&value', 'C&value'], + type: 'get_social_disaster_guideline', + }, + paramsKeyMap: { + CATEGORY: 0, + SUB_CATEGORY: 1, + NUMBER: 2, + }, + class: 'emergencyActionGuidelines', + isNotFor: ['emergencyActionGuidelines'], + func(sprite, script) { + const number = script.getStringValue('NUMBER', script); + const defaultValue = Lang.Blocks.no_data; + const params = { + category: '02', + subCategory: script.getField('CATEGORY', script), + subCategory2: script.getField('SUB_CATEGORY', script), + }; + + return getGuideline(params, defaultValue, number); + }, + syntax: { + js: [], + py: [], + }, + }, + count_safety_accident_guideline: { + color: EntryStatic.colorSet.block.default.EXPANSION, + outerLine: EntryStatic.colorSet.block.darken.EXPANSION, + skeleton: 'basic_string_field', + statements: [], + params: [getCategory('03'), getSubCategory('03')], + events: {}, + def: { + params: [getCategory('03').value, null], + type: 'count_safety_accident_guideline', + }, + pyHelpDef: { + params: ['A&value', 'B&value'], + type: 'count_safety_accident_guideline', + }, + paramsKeyMap: { + CATEGORY: 0, + SUB_CATEGORY: 1, + }, + class: 'emergencyActionGuidelines', + isNotFor: ['emergencyActionGuidelines'], + func(sprite, script) { + const params = { + category: '03', + subCategory: script.getField('CATEGORY', script), + subCategory2: script.getField('SUB_CATEGORY', script), + }; + + return getGuideline(params, 0); + }, + syntax: { + js: [], + py: [], + }, + }, + get_safety_accident_guideline: { + color: EntryStatic.colorSet.block.default.EXPANSION, + outerLine: EntryStatic.colorSet.block.darken.EXPANSION, + skeleton: 'basic_string_field', + statements: [], + params: [ + getCategory('03'), + getSubCategory('03'), + { + type: 'Block', + accept: 'string', + defaultType: 'number', + }, + ], + events: {}, + def: { + params: [getCategory('03').value, null, 1], + type: 'get_safety_accident_guideline', + }, + pyHelpDef: { + params: ['A&value', 'B&value', 'C&value'], + type: 'get_safety_accident_guideline', + }, + paramsKeyMap: { + CATEGORY: 0, + SUB_CATEGORY: 1, + NUMBER: 2, + }, + class: 'emergencyActionGuidelines', + isNotFor: ['emergencyActionGuidelines'], + func(sprite, script) { + const number = script.getStringValue('NUMBER', script); + const defaultValue = Lang.Blocks.no_data; + const params = { + category: '03', + subCategory: script.getField('CATEGORY', script), + subCategory2: script.getField('SUB_CATEGORY', script), + }; + + return getGuideline(params, defaultValue, number); + }, + syntax: { + js: [], + py: [], + }, + }, + }; +}; 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_microbit2.js b/src/playground/blocks/hardware/block_microbit2.js index cb2025f8d7..37a2ccf982 100644 --- a/src/playground/blocks/hardware/block_microbit2.js +++ b/src/playground/blocks/hardware/block_microbit2.js @@ -231,9 +231,9 @@ Entry.Microbit2 = new (class Microbit2 { 'microbit2_screen_toggle', 'microbit2_set_led', 'microbit2_get_led', - 'microbit2_show_preset_image', 'microbit2_show_custom_image', 'microbit2_show_string', + 'microbit2_show_preset_image', 'microbit2_reset_screen', 'microbit2_radio_toggle', 'microbit2_radio_setting', @@ -373,7 +373,7 @@ Entry.Microbit2 = new (class Microbit2 { microbit2_screen_toggle: 'LED 기능 %1 %2', microbit2_set_led: 'LED의 X: %1 Y: %2 를 밝기 %3 (으)로 밝히기 %4', microbit2_get_led: 'LED의 X: %1 Y: %2 밝기 값', - microbit2_show_preset_image: 'LED를 %1 모양으로 밝히기 %2', + microbit2_show_preset_image: 'LED에 %1 모양 나타내기 %2', microbit2_show_custom_image: 'LED %1 밝히기 %2', microbit2_show_string: 'LED에 %1 을(를) 밝히기 %2', microbit2_reset_screen: 'LED 모두 %1 %2', @@ -395,7 +395,7 @@ Entry.Microbit2 = new (class Microbit2 { microbit2_get_field_strength_axis: '%1 의 자기장 세기 값', microbit2_get_light_level: '빛 센서 값', microbit2_get_temperature: '온도', - microbit2_get_sound_level: '마이크 소리 크기 값', + microbit2_get_sound_level: '마이크 소리 크기', microbit2_set_servo: '핀 %1 에 서보 모터 각도를 %2 로 정하기 %3', microbit2_set_pwm: '핀 %1 에 서보 펄스 폭을 %2 %3초로 정하기 %4', microbit2_common_title: '마이크로비트 공통', @@ -589,9 +589,9 @@ Entry.Microbit2 = new (class Microbit2 { microbit2_get_acc: 'acceleration value of %1', microbit2_get_direction: 'compass direction', microbit2_get_field_strength_axis: 'magnetic field strength value of %1 ', - microbit2_get_light_level: 'Light sensor value', - microbit2_get_temperature: 'temperature value', - microbit2_get_sound_level: 'microphone volume value', + microbit2_get_light_level: 'light sensor value', + microbit2_get_temperature: 'temperature', + microbit2_get_sound_level: 'microphone volume', microbit2_set_servo: 'Set servo pin %1 angle to %2 %3', microbit2_set_pwm: 'set servo pin %1 pulse to %2 %3 %4', microbit2_common_title: 'Common Blocks', @@ -649,6 +649,8 @@ Entry.Microbit2 = new (class Microbit2 { unplot: 'unplot', on: 'Turn on', off: 'Turn off', + remove: 'Clear', + light: 'Light', microbit_2_HEART: 'heart', microbit_2_HEART_SMALL: 'small heart', microbit_2_HAPPY: 'happy', 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 8c36638adf..7e140e9dae 100644 --- a/src/playground/blocks/hardwareLite/block_microbit2_lite.js +++ b/src/playground/blocks/hardwareLite/block_microbit2_lite.js @@ -241,9 +241,9 @@ const EVENT_INTERVAL = 150; 'microbit2lite_screen_toggle', 'microbit2lite_set_led', 'microbit2lite_get_led', - 'microbit2lite_show_preset_image', 'microbit2lite_show_custom_image', 'microbit2lite_show_string', + 'microbit2lite_show_preset_image', 'microbit2lite_reset_screen', 'microbit2lite_radio_toggle', 'microbit2lite_radio_setting', @@ -413,7 +413,7 @@ const EVENT_INTERVAL = 150; microbit2lite_screen_toggle: 'LED 기능 %1 %2', microbit2lite_set_led: 'LED의 X: %1 Y: %2 를 밝기 %3 (으)로 밝히기 %4', microbit2lite_get_led: 'LED의 X: %1 Y: %2 밝기 값', - microbit2lite_show_preset_image: 'LED를 %1 모양으로 밝히기 %2', + microbit2lite_show_preset_image: 'LED에 %1 모양 나타내기 %2', microbit2lite_show_custom_image: 'LED %1 밝히기 %2', microbit2lite_show_string: 'LED에 %1 을(를) 밝히기 %2', microbit2lite_reset_screen: 'LED 모두 %1 %2', @@ -435,7 +435,7 @@ const EVENT_INTERVAL = 150; microbit2lite_get_field_strength_axis: '%1 의 자기장 세기 값', microbit2lite_get_light_level: '빛 센서 값', microbit2lite_get_temperature: '온도', - microbit2lite_get_sound_level: '마이크 소리 크기 값', + microbit2lite_get_sound_level: '마이크 소리 크기', microbit2lite_set_servo: '핀 %1 에 서보 모터 각도를 %2 로 정하기 %3', microbit2lite_set_pwm: '핀 %1 에 서보 펄스 폭을 %2 %3초로 정하기 %4', microbit2lite_common_title: '마이크로비트 공통', @@ -637,9 +637,9 @@ const EVENT_INTERVAL = 150; microbit2lite_get_direction: 'compass direction', microbit2lite_get_field_strength_axis: 'magnetic field strength value of %1 ', - microbit2lite_get_light_level: 'Light sensor value', - microbit2lite_get_temperature: 'temperature value', - microbit2lite_get_sound_level: 'microphone volume value', + microbit2lite_get_light_level: 'light sensor value', + microbit2lite_get_temperature: 'temperature', + microbit2lite_get_sound_level: 'microphone volume', microbit2lite_set_servo: 'Set servo pin %1 angle to %2 %3', microbit2lite_set_pwm: 'set servo pin %1 pulse to %2 %3 %4', microbit2lite_common_title: 'Common Blocks', @@ -697,6 +697,8 @@ const EVENT_INTERVAL = 150; unplot: 'unplot', on: 'Turn on', off: 'Turn off', + remove: 'Clear', + light: 'Light', microbit_2_HEART: 'heart', microbit_2_HEART_SMALL: 'small heart', microbit_2_HAPPY: 'happy', @@ -1488,6 +1490,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/blocks/hardwareLite/block_microbit2ble_lite.js b/src/playground/blocks/hardwareLite/block_microbit2ble_lite.js index 6edb4ba9e1..ed55e4de10 100644 --- a/src/playground/blocks/hardwareLite/block_microbit2ble_lite.js +++ b/src/playground/blocks/hardwareLite/block_microbit2ble_lite.js @@ -372,9 +372,9 @@ const convertPresetImageToLedState = (preset) => { 'microbit2blelite_screen_toggle', 'microbit2blelite_set_led', 'microbit2blelite_get_led', - 'microbit2blelite_show_preset_image', 'microbit2blelite_show_custom_image', 'microbit2blelite_show_string', + 'microbit2blelite_show_preset_image', 'microbit2blelite_reset_screen', // 'microbit2blelite_radio_toggle', @@ -484,7 +484,7 @@ const convertPresetImageToLedState = (preset) => { microbit2blelite_screen_toggle: 'LED 기능 %1 %2', microbit2blelite_set_led: 'LED의 X: %1 Y: %2 를 밝기 %3 (으)로 밝히기 %4', microbit2blelite_get_led: 'LED의 X: %1 Y: %2 밝기 값', - microbit2blelite_show_preset_image: 'LED를 %1 모양으로 밝히기 %2', + microbit2blelite_show_preset_image: 'LED에 %1 모양 나타내기 %2', microbit2blelite_show_custom_image: 'LED %1 밝히기 %2', microbit2blelite_show_string: 'LED에 %1 을(를) 밝히기 %2', microbit2blelite_reset_screen: 'LED 모두 %1 %2', @@ -506,7 +506,7 @@ const convertPresetImageToLedState = (preset) => { microbit2blelite_get_field_strength_axis: '%1 의 자기장 세기 값', microbit2blelite_get_light_level: '빛 센서 값', microbit2blelite_get_temperature: '온도', - microbit2blelite_get_sound_level: '마이크 소리 크기 값', + microbit2blelite_get_sound_level: '마이크 소리 크기', microbit2blelite_set_servo: '핀 %1 에 서보 모터 각도를 %2 로 정하기 %3', microbit2blelite_set_pwm: '핀 %1 에 서보 펄스 폭을 %2 %3초로 정하기 %4', microbit2blelite_common_title: '마이크로비트 공통', @@ -712,9 +712,9 @@ const convertPresetImageToLedState = (preset) => { microbit2blelite_get_direction: 'compass direction', microbit2blelite_get_field_strength_axis: 'magnetic field strength value of %1 ', - microbit2blelite_get_light_level: 'Light sensor value', - microbit2blelite_get_temperature: 'temperature value', - microbit2blelite_get_sound_level: 'microphone volume value', + microbit2blelite_get_light_level: 'light sensor value', + microbit2blelite_get_temperature: 'temperature', + microbit2blelite_get_sound_level: 'microphone volume', microbit2blelite_set_servo: 'Set servo pin %1 angle to %2 %3', microbit2blelite_set_pwm: 'set servo pin %1 pulse to %2 %3 %4', microbit2blelite_common_title: 'Common Blocks', @@ -772,6 +772,8 @@ const convertPresetImageToLedState = (preset) => { unplot: 'unplot', on: 'Turn on', off: 'Turn off', + remove: 'Clear', + light: 'Light', microbit_2_HEART: 'heart', microbit_2_HEART_SMALL: 'small heart', microbit_2_HAPPY: 'happy', 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