[아두이노] S4A 스크래치에서 아두이노로 이미지 조정하기

IOT/아두이노|2019. 10. 1. 09:00

[아두이노] S4A 스크래치에서 아두이노로 이미지 조정하기



오늘은 어제 이야기 하려다 못한 내용으로 아두이노로 스크래치 이미지를 컨트롤하는 실험을 해볼까 합니다. 스크래치와 아두이노는 서로 쌍방 통신이 가능합니다. 스크래치에서 아두이노에 연결된 Sensor를 읽을 수 있고 아두이노에서 스크래치에 그려지 이미지(케릭터)를 조정을 할 수 도 있습니다. 서로 쌍방 통신으로 읽기/출력이 가능하기 때문에 스크래치를 이용하면 재밌는 것들을 만들 수 있습니다. 어제는 스크래치에서 아두이노 출력하는 LED 깜박이기 였다면 오늘실험은 스크래치에서 아두이노 값을 읽어 오는 방법을 간단히 실험해 보겠습니다. 내용은 아두이노에 연결 된 가변저항기를 조절하여 스크래치 상 고양이 케릭터를 조정해보는 실험이 되겠습니다.

1. S4A 스크래치 이미지 세팅


무대 세팅 : 


무대 창을 누르면 스크립트/배경/소리가 있는데 여기서 배경에서 새로운 배경을 가져오기 눌러 스크래치에 제공되는 배경 이미지를 찾아 적당한 걸 가져오시면 됩니다. 참고로, 소리를 눌러보세요. 여러가지 사운드를 제공하는데 게임같은 것을 만들 때 배경음악으로 사용하면 좀 더 그럴싸한 표현을 할 수 있습니다.

스프라이트 고양이 추가 :


위 화살표를 보시고 스프라이트 파일 선택을 눌러서 고양이 이미지를 가져 옵니다, 참고로 왼쪽에 스프라이트 창에서 모양을 눌러 가져오기를 다시 눌러서 다른 고양이 장면을 가져 오세요. 그러면 하나의 스프라이트창에 두개의 이미지를 넣을 수 있습니다. 이렇게 하면 두 이미지를 교대로 교체하면 고양이 걷는 모션을 만들어 낼 수 있습니다. 참고로, 무대 세팅에서 배경 이미지도 무대에 여러개 배경 이미지를 배치 할 수 있습니다. 그렇게 되면, 무대는 상황에 따라 각기 다른 배경 이미지를 사용할 수 있게 됩니다.

이렇게 해서 이미지 세팅은 끝났습니다.

하지만 아래 창을 보시면 무대 창이 아두이노 이미지에 묻혀 있어서 뭔가를 만들려고 해도 아두이노 때문에 표현하기가 힘들어 보이죠.


위 아두이노 스프라이트 이미지는 삭제할 수 없습니다. 삭제하면 아두이노 연결이 안되니깐요. 그렇기 때문에 아두이노 스프라이트는 안보이게 숨겨야 합니다.

아두이노 핀 값을 출력하는 창은 마우스 오른쪽 버턴을 해당 창에서 클릭하면 아래와 같이 숨기기 기능 선택 창이 뜨고 숨기기로 안보이게 할 수 있습니다.


그 다음 아두이노 그림은 아래 창에서 편집을 눌러 주세요.


그러면 아래 창이 나타나고 지우기를 눌러주세요.


그리고 무대 배경 색의 점을 만드시든 적당한 티 안하는 점을 하나를 아무 위치에 찍어 주시고 확인을 눌러주세요. 그러면 해당 점이 아두이노우노가 됩니다.


이렇게 해서 아두이노 관련 이미지들이 사라졌습니다. 참고로 자세히 보시면 하얀 점이 있지요. 그냥 post 예시를 들기 위해서 하얀색 점으로 한 것이고요. 이 점을 마우스로 클릭해서 드래그 하시면 이동이 됩니다. 해당 점을 안보이는 곳으로 드래그 하시면 완벽하게 숨길 수 있습니다.

이렇게 해서 이미지 세팅이 끝났네요. 이제는 아두이노 세팅과 스크래치 블록코딩을 합시다.

2. 아두이노우노 조정기 만들기



위 그림처럼 간단합니다. 가변저항을 A0핀에 연결하여 가변저항을 돌리면 발생하는 가변저항값을 토대로 스트래치 이미지를 움직이게 할 꺼에요.

이제 아두이노우노에 S4A 스크래치를 사용할 수 있게 펌웨어 소스를 이식시켜야 합니다.



위 post에서 아두이노우노에 펌웨어 소스를 인식하는 방법을 지난시간에 이야기 했기 때문에 설명은 생략하고 위 post를 보시기 바랍니다.

이렇게 해서 아두이노우노에서 기본 세팅은 끝났습니다.


3. S4A 스크래치 블록 코딩


S4A 스크래치에서 가변저항 값 읽기


아두이노 가변저항기에서 가변저항값을 읽기 위해서는 우선 그 가변저항값을 저장하는 변수를 선언해야 합니다. 케릭터 이동에 가변저항값이 사용하기 때문에 변수 이름을 move라는 변수를 하나 만들겠습니다.


위 그림은 이미 만들어 진 상태의 모습입니다. 새로 만들 때는 변수만들기를 누르면 보시는 것과 같은 창이 뜨고 변수이름을 치시면 변수 하나가 생성이 됩니다. 실험에서는 가변저항값을 현재 가변저항값과 이전 가변저항값을 비교하기 위해서 move, premove라는 변수를 만들었는데 이 부분은 나중에 설명 드릴께요. 두개 변수가 필요하니깐 우선 변수만 만들어 놓으세요.

그럼 변수를 만들었으면 그 변수에 실제 아두이노 가변저항값을 읽어 올까요.


제어, 동작, 변수 항목에서 표시한 블록들을 사용하여 읽게 됩니다. 어느 블록이 어느 위치에 있는지 잘 확인해 주세요. 첨에는 블록 위치가 햇갈려 할 수 있으며 색으로 구별하시면 아마 쉽게 구별이 가능 할 꺼에요. 총 4개의 블록으로 코딩을 하게 됩니다.

설계 :

  • 센서값 읽기 <= 계속 무한으로 읽어야겠죠.(실시간 조정을 위함)
  • 읽은 센서값 저장 <= move 변수를 만들었으니 여기에 저장해야겠죠.


끝! 위 블록 코딩으로 S4A 스크래치에서 이제 아두이노 가변저항값을 읽어와서 move 변수에 계속 실시간으로 저장하게 됩니다. 아무때나 move 변수값을 체크하면 현재 아두이노 가변저항값을 확인 할 수 있게 되었습니다.

고양이 좌/우 이동


아두이노의 가변저항기를 돌리면 고양이가 좌/우로 움직이게 하려면 어떻게 해야 할까요. 우선 고양이를 좌/우 이동을 시켜 봐야 합니다. 지난 시간에 고양이를 좌/우로 왔다 갔다 하는 동작을 샘플로 했었죠. 그 방법을 응용 할 거에요.


위 블록으로 x좌표로 좌/우로 이동을 했었습니다.


설계 :

  • 가변저항값을 x좌표로 변환 (0~1023을 x좌표 -200~200 값으로 변환)
  • 고양이 걷기 동작 만들기
  • 고양이 이동 (가변저항기를 돌리면 돌린 만큼 고양이를 이동시킨다)

가변저항값을 x좌표로 변환 (0~1023을 x좌표 양쪽 끝지점 -200~200 값으로 변환)

가변저항값을 어떤 특정값의 범위로 맞추기 위해서는 아두이노에서 map()함수를 사용했습니다.

long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

위 식을 줄여서 그냥 0~400사이의 값으로 나오게 바꿨네요.

(move - 0) * (400 - 0) / (1023 - 0) + 0

=> move*400/1023

이렇게 줄였습니다. 그러면 가변저항기를 돌리면 0~400사이로 줄어 들게 됩니다.

그 다음 x 좌표는 양쪽 끝점 기준으로 -200~200사이가 됩니다. 그래서 가변저항값이 200일 때 0이 되어야 합니다. 그럼 식에 -200을 해주면 됩니다.

x좌표 : (move*400/1023) - 200

이렇게 해서 실제 고양이가 이동 할 x좌표를 구할 수 있게 되었습니다.



고양이 걷기 동작 만들기

가변저항기를 돌리게 되면 move값이 갱신이 되고 그 값을 기준으로 고양이를 이동시킨다고 했죠.

여기서, 고양이는 언제 걷기를 하나요. 바로 고양이가 이동 할 때 입니다. 즉, 가변저항기를 돌리는 순간 고양이는 걷는 동작을 해야 합니다. 이 표현을 블록 코딩 하면 다음과 같습니다.


이 원리는 딜레이 없이 딜레이 함수를 사용할 때 시간값을 비교할 때 코딩했던 로직과 유사한 원리입니다. 시간의 변화가 특정 조건에 만족할 때 그 동작을 수행하고 끝나는 시점에 현재 시간값을 저장하고 다음 시간을 비교하는 원리를 이용하였습니다. 여기에서는 가변저항기가 변화가 일어나면 그 변화한 만큼 고양이를 이동시킨 후 끝나는 시점에 현재 move(가변저항) 값을 premove(이전저항)값에 저장하여 새로운 가변저항값과 비교하여 변화가 일어나는지 체크하는 용도로 사용 하였습니다. 그래서 현재 가변값과 이전 가변값을 비교하기 위해서 premove 변수를 하나 더 만들어 사용 했네요.

위 블록코딩을 살펴보면 아래와 같은 C코딩으로 표현을 해보았습니다.

premove=0; //초기값

while(1){
  if(move<>premove){
   다음모양(고양이걷기);
   premove=move;
  }
}

여기서, 다음모양은 위 고양이 이미지 세팅에서 고양이 스프라이트에 2개의 이미지를 저장 했었죠. 이때 A, B 이미지가 있는데 다음모양 블록은 현재 이미지에서 다음 이미지로 무조건 바꾸라는 명령입니다. 참고로 다음 이미지는 순차적으로 이미지가 바뀝니다. 여기에서는 2장의 이미지인데 1번 이미지에서 다음모양블록을 만나면 2번 이미지로 바뀌게 됩니다.


위 그림에서 a가 현재 이미지면 다음모양 하면 b 이미지로 교체 됩니다. 현재 이미지가 b이면 다음모양 하면 a 이미지가 됩니다.

위 블록코딩은 가변저항기를 돌리는 순간 if문에서 이전 가변저항값과 현재 가변저항값이 다른지 체크하게 되고 다르면 가변저항기가 움직였다는 소리가 되고 그 순간 다음모양 블록으로 고양이 이미지를 다음 이미지로 바뀌고 고양이가 걷는 동작을 만들어 내게 됩니다.

[결과]


위 결과는 고양이를 x좌표로 이동하는 블록이 없어서 실제 x좌표로 이동하지 않고 가변저항기를 돌리면 제자리 걷는 동작만 수행하네요.


고양이 이동 (가변저항기를 돌리면 돌린 만큼 고양이를 이동시킨다)

사용 블록 :


위 블록에다가 위의 x좌표 구한 블록식을 x 위치에 배치하면 됩니다.


이렇게 배치하면 가변저항기가 움직이면 x좌표값이 바뀌고 해당 값의 위치로 고양이가 이동하게 됩니다.

종합


[아두이노 스프라이트 블록코딩]


[고양이 스프라이트 블록코딩]


[결과]

4. 자연스럽게 고양이 걷는 동작 만들기


이 내용은 안보셔도 됩니다. 스크래치 영역이고 아두이노를 다루는 것이 목적이지 고양이를 자연스럼게 움직이게 하는게 목적이 아니기 때문에 생략하셔도 됩니다. 그냥 뭔가 걷는게 부자연스럽게 보여서 블록 코딩을 수정한 것 뿐입니다. 수정 된 블록 코딩으로 하면 오늘 post의 의미 전달이 잘 안될 것 같아서 따로 분리 해서 설명합니다.

이 내용은 좀 더 자연스럽게 고양이가 오른쪽으로 걸을 때 오른 방향을 바라보도록 하고 왼쪽으로 걷게 되면 왼쪽을 바라보게 하는 방식입니다.


위 그림이 핵심 블록 코딩입니다. 우선 화살표가 가리키는 모양의 아이콘을 클릭해주세요. 좌우 이동시 회전 방향을 나타냅니다. 방향전환을 할 때 회전방향을 어떤 방식으로 회전 시키느냐에 따라서 고양이의 움직임이 바뀌게 됩니다. 좌/우 방향으로 바라보도록 회전 시키려면 화살표가 가리키는 모양의 아이콘을 클릭하면 됩니다.

여기서, 고양이의 방향 전환은 어쩔 때 일어나는지 알아야 합니다. 현재시점과 이전시점을 기준으로 비교하면 방향을 알아 낼 수 있는 두가지 방법이 있는데 그 중 하나를 선택하여 실험 했네요.

방향 찾기 :

  • 현재 가변저항값과 이전 가변저항값를 비교하여 방향을 정한다.
  • 현재 x좌표값과 이전 x좌표값을 비교하여 방향을 정한다.

가변저항값이든 x좌표값이든 선택은 여러분 몫입니다. 방향 전환을 할 때 예를 들면, 이전 가변저항값이 100일 때 현재 가변저항값이 110이면 어떻게 될까요. 고양이가 x좌표로 10만큼 이동하게 됩니다. 오른쪽으로 이동하는 것이기 때문에 고양이는 오른쪽 방향이 됩니다. 만약 현재 가병저항값이 90이면 x좌표는 왼쪽으로 10만큼 이동하게 되는데 고양이는 왼쪽 방향이 되겠죠.


위 코딩은 완성된 블록 코딩인데 x좌표 변수를 하나 더 만들었네요. 그리고 move와 premove변수가 기존에 있기 때문에 방향찾기는 가변저항값을 비교하여 방향을 결정했네요.

나머지 블록은 앞에서 설명 드렸기 때문에 생략합니다.

[결과]


영상을 보시면 가변저항기로 조정하면 깔금하게 해당 방향으로 고양이가 방향 전환을 하네요.

마무리


아! 이야기를 너무 풀어서 설명하다 보니 길어졌네요.


댓글()