업데이트
본 예제를 실행해서 로봇과 연결하려면 Edubot과 최신 펌웨어가 있어야 한다. Edubot과 펌웨어 관련한 내용은 https://github.com/oroca/OROCA-EduBot/tree/android_app을 참고한다. 펌웨어 개발환경 구축은 https://cafe.naver.com/openrt/19738을 참고한다.
이제 Scratch Link와 확장블럭에 대한 모든 것이 준비되었으니 실제 사용해보록 한다.
지난번 포스팅에서 언급했던 개발환경 (https://ahnbk.com/?p=366)은 모두 갖춰져 있다는 가정하에 진행한다.
scratch 3.0의 원래 소스를 가져와 현재 작업중인 OROCA-EduBot에 대한 확장블럭을 작성하였다. 수정된 소스는 다음의 링크에서 확인 가능하다. 지난번과는 달리 scratch-blocks에 대한 부분은 현재까진 수정할 필요가 없으므로, 이는 사용하지 않는다.
개발환경 구축 포스팅에서 설명했던 것과 같이, 임의의 디렉토리에 위 repository를 클론한다. (윈도우나 macOS나 모두 동일함).
$ git clone https://github.com/byeongkyu/scratch-gui.git
$ git clone https://github.com/byeongkyu/scratch-vm.git
scratch-vm부터 설치한다.
$ cd scratch-vm
$ npm install
$ npm link
다음으로 scratch-gui를 설치한다.
$ cd ../scratch-gui
$ npm install
$ npm link scratch-vm
이제 실행해보면
$ npm start
크롬이나 사파리, 인터넷 익스플로러 등 브라우져를 열고 http://localhost:8601 로 접속하면 다음의 화면을 볼 수 있다.
왼쪽 하단의 확장블럭 추가 버튼을 누른다.
Edubot의 확장카드가 보이고 이를 누르면,
스캔을 자동을 실행하고, 주변의 Edubot을 보여준다. Connect 버튼을 눌러 연결한다.
정상적으로 연결됨을 볼 수 있다. 이제 Go to Editor 버튼을 눌러 메인 화면으로 이동한다.
왼쪽에 Edubot에 대한 블럭들이 생겼음을 볼 수 있다. 이제 이 블럭들을 이용하여 코딩해보면 된다.
몇 가지 궁금한 점이 있어서 댓글을 남깁니다~~
이전 내용에서 알려주신 ‘index.js’의 내용은 어느 정도 숙지하고 실제로 간단하게 만들어서 확장하는데 성공했습니다~~!! 덕분에 많은 걸 배워갑니다 ㅎㅎ 하지만 뭔가 더 하고 싶은 마음에 통신을 해보고 싶은데 잘 되지 않아서 이렇게 글을 남깁니다.
일단 통신은 아두이도의 블루투스를 연결 및 펌웨어를 작성했고, PC에서는 블루투스 동글을 이용하여 시리얼 컴포트로 간단하게 통신이 되는 것을 확인했습니다.
하지만 해당 확장 코드를 작성하여 스크래치에서도 동작하고 싶은데… 쉽지가 않아 이렇게 글을 올립니다. 다른 확장 기능들을 보면 해당 디바이스 검색 및 BLE 또는 BT를 임포트하여 사용하는 것을 확인했습니다.
이와 관련된 예제나 URL 또는 키워드를 알려주시면 도움이 될 것 같습니다 ㅠㅠ 확인 부탁드립니다~~
같은 경우인 EV3 확장블럭 코드를 참고하시면 될듯 합니다. 스크래치3는 scratch-link를 이용해서 외부와 통신하기 때문에, 결국 scratch-link와 json-rpc websocket 통신을 하면 됩니다. 그에 대한 함수들은 이미 만들어져 있고요. 패킷만 정하시고 (PC-아두이노), 이를 보내주기만 하면 됩니다.
알려주신대로 소스 코드를 확인하고 있습니다. 코드 해석 중에 궁금한 것도 댓글로 남겨도 될까요?? ㅠㅠ
흠… 말씀해주신김에 저도 소스를 살펴보고 있는데, 현재로선 블루투스-시리얼만 지원하는듯 합니다. Arduio와 같이 USB-시리얼로 되어 있는 형태는 달리 구현해야할 듯 하네요. io 확장기능을 추가하면 될듯 하긴한데… 좀더 깊게 살펴보도록 하겠습니다.
EV3 확장 블럭 코드를 확인하고 있으면서 몇 가지 테스트를 하고 있습니다.
일단 사용할 블루투스 디바이스는 PC 상에 페어링이 되어 상태에서 EV3 확장 코드를 실행하면
기기를 검색이 되지 않습니다.
해당 소스 코드를 분석하면서 아래에 해당하는 부분이 검색할 때 사용하는 부분인 것 같습니다.
scan () {
if (this._bt) {
this._bt.disconnect();
}
this._bt = new BT(this._runtime, this._extensionId, {
majorDeviceClass: 8,
minorDeviceClass: 1
}, this._onConnect, this.disconnect, this._onMessage);
}
해당 소스 코드에서 ‘majorDeviceClass’ 와 ‘minorDeviceClass’의 값을 변경하는 것 외에는 딱히 건드릴 수 있는
부분이 없는 것 같습니다 ㅠㅠ…
해당 2개의 클래스의 값을 변경하면 PC에 페어링 되어 있는 디바이스를 검색할 수 있을까요??
그리고 2개의 값(8, 1)의 값은 어떻게 정해지는지 알고 계시나요 ㅠㅠ?? 확인 부탁드립니다~~
몇 가지 테스트한 결과를 말씀드릴려고 합니다~~
위의 글에서 ‘majorDeviceClass’ 와 ‘minorDeviceClass’의 값을 0, 0으로 정하고 실행하였더니 PC에서 페어링되어 있는 제품이 검색되었습니다.
하지만 정확한 값을 설정해서 제가 원하는 디바이스를 검색하는 것이 아무래도 좋아보입니다~~ ㅎㅎ
현재 열심히 검색 중이며, 해당 내용과 관련된 키워드나 정보를 알려주시면 감사하겠습니다 ㅠㅠㅋㅋㅋ
흠.. 소스를 살펴보니 USB 시리얼포트를 이용한 연결은 아직 지원되지 않는 것 같습니다. Bluetooth 시리얼 통신은 해보셨듯이 가능하고요. usb를 지원하기 위해선 Scratch Link를 수정하여 사용하는 것이 가장 효율적이라고 생각됩니다.
말씀하신 majorDeviceClass, minorDeviceClass는 macOS라면 System Information 앱을 이용하여 파악이 가능합니다. 윈도우의 경우엔 잘 모르겠네요..^^
이거 혹시 수신은 안되는 건가요…??
송신(‘send(message)’)에 대한 부분은 검증이 끝났는데… 수신(‘_onMessage(params)’)은 안되고 있습니다…
혹시 몰라서 다른 SW로 테스트 해본 결과 디바이스는 정상 작동하고 있었습니다.
혹시 몰라 bt.js의 거의 모든 부분에 console.log()를 찍어봤지만…
수신에 의해 반응하는 함수를 찾지 못했습니다 ㅠㅠ
확인 부탁드립니다…
수신도 당연히 되죠.
bt.js 내에서 로그를 보시려면 log 패키지를 사용하시면 됩니다. log.info() 등등
Scratch Link와의 통신 내용을 확인하시려면, Chrome, 사파리 등에서 개발자 도구를 활용하시면 됩니다. json-rpc 통신 내용을 확인할 수 있습니다.
EV3를 사용하여 실제로 통신이 되는지 확인하고 있는 중입니다..
송신은 아래와 같이 변경했습니다.
motorTurnClockwise (args) { //EV3 ‘index.js’ 1125 line
const ping = [0xff, 0xff, 0x00, 0x06, 0x01, 0x01, 0x0a];
this._peripheral.send(ping);
console.log(“motorTurnClockwise (args)”);
console.log(ping);
}
송신을 했을 때, 저희가 가지고 있는 디바이스는 정상 반응을 합니다.
위의 프로토콜을 보내면 똑같은 내용을 다시 PC로 보내주어야 하지만… 반응을 하지 않습니다.
수신은 아래와 같이 변경했습니다.
_onMessage (params) { //EV3 ‘index.js’ 788 line
const message = params.message;
const data = Base64Util.base64ToUint8Array(message);
console.log(data);
// log.info(`received array: ${array}`);
…(생략)…
}
그리고 모든 bt.js에 console.log를 찍었고, 아래는 해당 로그입니다..
isConnected ()
bt.js:106 sendMessage (options)
bt.js:101 isConnected ()
bt.js:106 sendMessage (options)
index.js:1128 motorTurnClockwise (args)
index.js:1129 (7) [255, 255, 0, 6, 1, 1, 10]
블루투스 수신에 대해서 전혀 방향을 못 잡고 있습니다.
혹시 블루투스 수신에 대해서 진핼할 만한 테스트나 조언을 해주시면 감사하겠습니다 ㅠㅠ
EV3 연결해서 확인해본 결과, 별다른 설정없이 데이터가 수신되면 바로 보내주는 것 같습니다. 사파리의 개발자 도구를 통해 확인해 봐도, 송신/수신 데이터를 확인해 볼 수 있고요.
{“params”:{“encoding”:”base64″,”message”:”IwAAAAJ+fn5+fn5+fn5+fn5+fn5+AAAAAAAAAAAAAAAAAAAAAA==”},”jsonrpc”:”2.0″,”method”:”didReceiveMessage”}
와 같이 didReceiveMessage가 들어오고 있죠…
글쎄요… 일단 개발자도구를 통해 데이터가 오고 가는지 확인해보는 방법 밖엔 생각이 나지 않네요..
현재 ‘jsonrpc.js’ 파일의 ‘_handleResponse’ 함수에 ‘openRequest.resolve(result);’ 까지 실행을 확인했습니다..
하지만 이 이후에 어떻게 실행되는지에 대해 막막해 하고 있습니다..
제가 비동기나 프로미스에 대한 이해가 부족한 것 같습니다.. ㅠㅠ
이에 대한 해결 방향에 대해 댓글이나 참조를 적어주시면 감사하겠습니다 ㅠㅠ
블투에 데이터가 들어오면, Json으로 패키징해서 보내주는 것은 Scrach-link가 담당할테니 프로토콜이 문제있는 것 같진 않습니다. 소스 레벨을 분석해서 해결할 만한 내용은 아니고, 말씀 드린것 처럼, 개발자 도구를 이용해 패킷이 오가는 부분을 확인해 보시면 되겠습니다.
패킷이 오가는 부분이 무슨 말씀인지요… ㅠㅠ???
현재 ‘index.js’의 ‘send (message)’ 함수는 정상적으로 동작은 합니다. (디바이스가 프로토콜에 따라 변화함을 확인)
하지만… ‘index.js’의 ‘_onMessage (params)’ 함수는 동작하지 않습니다 ㅠㅠ
_onMessage (params) {
console.log(“_onMessage (params)”);
함수 정의문 바로 아래에 ‘console.log(“_onMessage (params)”);’ 를 입력했고 콘솔창에는 로그가 생성되지 않았습니다…
그리고 ‘bt.js’의 ‘didReceiveCall (method, params)’ 함수도 반응을 하지 않습니다…
(최초 디바이스를 검색할 때는 로그가 찍힙니다. 디바이스의 개수만큼…)
didReceiveCall (method, params) {
console.log(“didReceiveCall : ” + method);
console.log(“didReceiveCall : ” + params);
‘bt.js’의 ‘didReceiveCall (method, params)’ 함수를 어디서 호출되는지 확인하다가 아래로 깊게 내려간 것 같습니다…
혹시 ‘bt.js’를 이용한 단순 통신 예제가 있으신가요??
(블록에 텍스트를 쓰면 송신되고 수신되면 콘솔에 찍힌다던지… 뭐 그런…. ㅎ)
(EV3를 수정해서 통신을 확인하고 있어서 혹시나 다른 부분도 변경됐나 의심하고 있습니다…)
아니면 참고할만한 자료의 링크를 걸어주신다면 감사하겠습니다… ㅠㅠ
넵.. 전 코드 상에서가 아닌, 개발자 도구 (사파리, 크롬 등)을 이용해서 패킷이 오가는 부분을 먼저 확인해 보심이 어떤가 해서요. 현재 다른 일 때문에 확인은 못하고 있는데, 개발자 도구 (Cmd+Alt+I)를 실행하시고, Network 탭을 확인해보시면, 웹소켓을 통한 통신 내역을 확인해 볼 수 있습니다.
추후 이 관련한 내용을 진행하게 되면 확인해보도록 하겠습니다.
바쁘신 와중에 도와주셔서 항상 감사합니다~~ ^^
알려주신대로 [개발자도구] – [네트워크] – [bt] – [messages] 부분을 확인했습니다.
아래는 송신에 대한 수신입니다.
– 송신 : {“jsonrpc”:”2.0″,”method”:”send”,”params”:{“message”:”//8ABgEBCg==”,”encoding”:”base64″},”id”:2}
-> Protocol(message) : 0xFF 0xFF 0x00 0x06 0x01 0x01 0x0a
– 수신 : {“jsonrpc”:”2.0″,”id”:2,”result”:7}
-> 송신 값(0xFF 0xFF 0x00 0x06 0x01 0x01 0x0a)을 받으면 같은 데이터를 수신 받게 되어있음.
전혀 갈피를 못 잡고 있습니다 ㅠㅠ
기존 테스트를 진행하던 디바이스 말고 아두이노를 이용해서 다시 POC를 진행해볼까 합니다.
(아두이노에서 블루투스로 데이터를 송신했을 때 어떻게 되는지 확인을 해볼까 합니다.)
혹시 알려주신 방법이외에 다른 방법이 있다는 알려주시면 매우 감사하겠습니다 ^^
매번 도움을 주셔서 정말 감사합니다~~
아두이노를 이용해서 테스트를 하는 중입니다만… 위의 내용은 제가 잘 못 생각한 것 같습니다…
스크래치에서 송신할 때, 아두이노에서는 수신이 됩니다.
그리고는 위의 수신 데이터와 같이 크롬 콘솔 로그에 찍힙니다…({“jsonrpc”:”2.0″,”id”:2,”result”:7})
그리고 아두이노에서 송신할 때, 스크래치에서는 반응이 없습니다…(콘솔 로그 및 네트워크 반응 없음)
확인 부탁드립니다~~