본문 바로가기

▶3D 프린팅/삼디강좌

[김성민의 삼디 Life] LCD 메뉴를 추가하다 (Marlin 펌웨어 수정)

[김성민의 삼디 Life - LCD 메뉴를 내 마음대로]


애덤 그랜트의 '오리지널스' 라는 책에 나오는 내용이다.

직장내에 창의적인 사람과 그렇지 않은 사람을 비교 연구해보았더니

창의적인 사람들은 인터넷 브라우저로 크롬이나 파이어폭스를 썼고

그렇지 않은 사람은 인터넷 익스플로어나 사파리를 쓰더라는 것이다. 


창의적이고 싶은 마음에 갑자기 인터넷 브라우저를 바꿀 필요는 없다. 

이런 결과가 나온 것은 창의적이고 무언가 도전하려는 사람은 기존에 default 로 주어진 것 - 윈도우면 인터넷 익스플로어, 맥이면 사파리 - 에 만족하는 것이 아니라 새로운 것을 찾고 대안을 생각하는 습관이 있다는 뜻이다. 


3D 프린터에 입문하여 많은 불량을 경험하고 그로 부터 나름 배움과 성장이 있었다고 생각한다. 얼마전 내가 올렸던 글에 댓글을 단 한분이  내가 남들이 대충 넘어갔을 불량에 대해 원인을 찾고 해결하는 모습을 보면서 특별한 능력을 가지고 있다는 낯간지런 말을 남겼다. 궂이 부정하고 싶지는 않으나 내가 다른 사람보다 더 뛰어나다고는 생각하지 않는다. 여전히 나보다 뛰어난 전기 분야, 통신분야, 기계적 장치분야, 프로그램 언어 분야의 고수분들이 있음은 부인할 수 없기 때문이다. 아니 나는 그들의 발밑에도 미치지 못할 거라고 생각한다. 사실이다. 

하지만 내가 조금 다른게 있었다면 내가 처음에 동네 무한상상실에서 접했던 프린터가 Zortrax M200 이라고 하는 FDM 방식으로는 그래도 가격적인 부분이나 사양이 높은 장비였다는 사실이다. 사실 입문자에게는 가격이 비싸든 싸든 그 차이를 알리가 없다. 내게는 그냥 똑같은 3D 프린터일 뿐 그 이상도 그 이하도 아니었다.  고수들은 당연히 아는 것을 입문자인 나는 알지 못했던 것이다. 비싼 프린터의 품질은 어떠할 것이고, 중국산 최저가의 프린터는 어떠하다는 한계 말이다. 

그런 무지로 부터 나는 비싼 그 장비에서 출력한 것을 3D 프린터가 당연하고 마땅히 내야하는 결과물이라고 생각하였고, 내가 갓 조립한 프린터로 만든 출력물이 그에 미치지 않는 것을 보고 그 상태가 '당연한' 상태가 아니라 '문제적' 상황이라고 인식했었다. 


그리고 그런 인식의 결과는 결국 몇일 전 출력한 미니 드래곤으로 나왔다고 생각한다. 



이제 어느정도 출력물의 품질이 잡히고 나니 조금 다른 부분에 관심을 갖게 되었다.  진동 소음도 줄이고 싶어서 모터 댐퍼나 TMC2100 이라는 모터 드라이버도 적용해보고, 옥토프린터로 원격제어를 실현해보는가하면 이제는 출력 메뉴도 손을 대보게 되었다. 


그렇다. 서론이 많이 길었는데, 오늘 이야기는 LCD 의 메뉴를 변경해보는 도전에 대한 내용을 나누고자 한다. 이걸 도전이라고 표현한 이유는 코딩에 대해서는 조건문과 반복문이 있고  선언을 해줘야 하고 변수와 상수가 있다는 정말 기초적인 것 외에는 아무것도 모르는 사람이 해보려고 했기 때문이다. 구구단정도 외울 수 있는 초등학생이 미적분을 풀려는 꼴이 아닐까 싶다. 그래도 만일 자신의 프린터가 있는 그대로 쓰려고 하는 사람이 아니라 뭔가 자신의 필요에 맞게 변화를 줘보려고 하는 사람이라면 오늘 이 포스팅이 조금의 참고가 되었으면 좋겠다. 



1. 뭘 바꿔야 할까?


LCD 의 메뉴는 펌웨어를 통해 작동한다는 것은 알고 있었다. 

기존 기본 셋팅된 펌웨어에서 Skynet3d(skynet3d 는 Marlin 을 anet a8 프린터에 맞춰 수정한 버전입니다)라고 하는 펌웨어로 업데이트 하였더니 메뉴가 바뀌고 작동이 달라진것을 보고 눈치챈것이다. 

그런데 뭘 어떻게 바꿔야 하는것인가? 


Skynet3d 혹은 Marlin 의 ino 파일을 열면 다음과 같은 화면이 나온다. 



메뉴라고 해야하나.. 그런것이 엄청나게 존재했던 것이다. 하나 하나가 암호와도 같은 코딩언어로 되어 있었고, 다 읽어볼 수는 없는 일이었다. 읽는다고 해도 알 수는 있었겠는가. 


내가 아는 것은 저기 수 많은 xxxxx.h  혹은 xxxxxx.cpp 라고 하는 것이 모두 하나의 펌웨어를 만들기 위해 유기적으로 엮여서 어떤 기능을 하는 녀석들이라는 것쯤이었다.  하지만 그정도면 충분했다. 저기에 있는 것들 중에 하나는 내가 목적으로 하는 LCD 에 메뉴를 추가하는 기능을 하고 있을거라는 판단이면 되었다. 



2. LCD 메뉴 항목을 찾아내다


나는 LCD 메뉴상에 있는 Move axis 에 10mm, 1mm, 0.1mm 의 이동만 있는 것이 불만스러웠다. 기존에 Skynet3d 를 사용할 때에는 10mm 를 누르면 메뉴에 맞지 않게 50mm 인가가 휙휙 하고 움직여 이상하게 생각했긴 했지만 그렇게 움직여야 할 필요가 있다고 여겨 그다지 불편하게 생각하진 않았다.  그런데 Marlin 으로 펌웨어를 바꾸고 나니깐 10mm 를 누르면 정확하게 10mm 만 움직인다. 만약 조절방식이 버튼이 아니라 돌리는 노브 방식이었다고 하면 크게 문제되지 않았을 것이다. 그런데 버튼이다 보니 10cm 를 이동하려고 하면 10mm 버튼 10번을 눌러야 하는 것이다. 뭔가 방법이 없을까? 하고 생각하다가 메뉴를 추가해보자는 생각까지 이르렀던 것이다. 


어쨋든 내가 추가하고 싶은 것은 해당 메뉴에 100mm 이동은 좀 큰 것 같고 50mm 이동을 추가해 넣는 것이었다. 이렇게 목표가 정해졌다.


LCD 메뉴에 나와 있는 것은 모두 펌웨어 어딘가에 숨어 있을 것이다. 

1단계는 그게 어느 파일에 존재하는지를 찾아서 그 부분을 살짝 바꿔주거나 비슷하게 추가해주면 되지 않을까 하는 생각이 들었다.

찾아보고 나서 내가 도무지 접근할 수 없는 거라면 그때 가서 빠르게 단념해버리면 된다. 


메뉴에 나와있는 "Move 0.1mm" 로 찾기를 해보았다. 



짜잔!  찾았다.  

language_en.h 라는 파일에 있었다. 그런데 그뿐 아니라 온갖 language 파일에는 모두 해당 항목이 적혀 있었다. 당연 나의 LCD 메뉴에는 영어로 되어 있기에 다른 것은 무시하기로 했다.  (나중에 나머지 언어에 대한 파일을 모두 삭제를 했는데 이유는 언어만 다르고 모두 같은 기능을 하는 거라고 생각했기 때문이다. 삭제하고도 컴파일이나 업로드가 아무 문제 없이 정상으로 됨을 확인했다)



3. 무엇을 수정해주면 될지 알게 되다


뭔지 잘 모르겠지만 Move 0.1mm 라고 LCD 에 메뉴를 띄우는 것은 그 앞에 #define 되어 있는 MSG_MOVE_01MM 과 연관되어 있다고 생각했다.


그렇다고 한다면 이제 MSG_MOVE_01MM 가 어디에 있는지를 찾으면 되었다. 같은 방법으로 찾아보았다. 



간단히 검색되어 나왔다. 

ultralcd.cpp 라는 파일에 중간쯤 있었다.  그리고 더 이상 language 파일을 제외하고는 같은 내용이 나오지 않았다. 

그말은 여기만 어떻게 잘 수정해주면 메뉴 추가나 수정이 가능하지 않을까 하는 자신감이 생겼다는 것이다. 

게다가 위의 나열된 항목은 규칙성을 가지고 있다. 규칙성이 있다는 것은 그 규칙에 따라 코딩 1도 몰라도 그냥 따라 하면 될 것이라는 생각도 들었다. 


물론 아주 조심스럽긴 했다. 하지만 문제 생기면 백업해둔 걸로 다시 펌웨어 업로드 하면 되지 뭐. 하는 마음으로 해보기로 하였다. 


그리고 MSG_MOVE_01MM 과 함께 적혀 있는 lcd_move_menu_01mm 이라는 새로운 것이 어떻게 연결되어 있는지도 확인해보았다.  단순히 생각해도 저기에 동일한 방식으로 한줄을 추가했다고 해서 그게 제대로 작동되지 않을거라는 느낌은 있었던 것이다.  뭔가 다른 것과 연결되어 있다면 내가 추가해준건 아무 의미없는 줄 끊긴 정보가 될테니깐 찾아봐야 한다. 




해당 내용으로 찾기를 해보니 아주 가까이 바로 위에 함수 비슷하게 생긴 모양으로 존재했다. 그리고 더 이상 같은 내용은 존재하지 않았다. 동일한 방식으로 _goto_manual_move 도 찾아보았다. 



방금전 찾았던 내용 바로 위에 존재하였고 그 외에는 없었다.

내용을 살펴보니 constant float scale 이라는 값을 받아서 그 값을 이용해서 뭔가를 해주는 함수 같아 보였다. 

물론 내용을 알면 좋겠지만 모르더라도 _goto_manual_move() 의 괄호안에 10.0 이 들어가면 10mm 이동, 1.0 이 들어가면 1mm 이동이 된다는 것은 대략 눈치를 챌 수 있었다. 


이제 나는 내가 필요한 것을 다 찾은 것 같았다. 

0.1, 1.0, 10.0 들 사이에 50.0 의 값을 동일한 방식으로 추가하면 되지 않을까? 



4. 펌웨어 수정을 완료하다


내가 여기서 부터 한 것은 그저 지금까지 찾았던 값들 사이에 50.0 을 움직이는 값을 한줄씩  추가해주면 되는 것이었다. 

추가해주는 것은 찾기 순서의 역순으로 하였다. 


1) _goto_manual_move(50.0) 추가



2) lcd_move_menu_50mm() 추가



3) MSG_MOVE_50MM 추가


위에 항목추가는 모두 ultralcd.cpp 내에서 이루어졌지만

이 항목은 language_en.h 에서 수정해주었다.



처음에 할 때는 이곳 language_en.h 의 내용을 추가해주지 않았는데 컴파일을 할 때 친절하게도 그 부분이 문제라고 에러가 떴었다. 

넣어주니 일단 컴파일은 성공했다. 과연 이게 작동을 할까? 



5. 결과


수정한 펌웨어를 업로드 한 결과 화면은 다음과 같다. 




보는 바와 같이 Move axis 내에 50mm 이동 항목이 제대로 추가된 것을 볼 수 있었다.  Move X 뿐만 아니라 Move Y, Move Z 항목에도 다 같이 들어 있었다. 지금까지 했던게 가능했다면 나와 있는 메뉴 항목을 지우거나 이름을 수정하는 것도 당연히 가능할 것이다. 메뉴의 순서를 바꾸는 것도 어려울게 없다고 생각되었다. 


그런데, 작동은 어땟느냐고?  버튼을 누르자 정확히 50mm 만큼씩 이동을 휙휙 하는 것이 시원시원하다. 



이렇게 코딩 초짜가 펌웨어를 수정에 성공하였다.

어찌보면 무척 간단한 작업이었다.

단순히 펌웨어 상에 ultralcd.cpp 와 language_en.h 에 몇줄 추가하는 것뿐이었으니 말이다. 

그것을 애덤그랜트의 창의성 이야기로 부터 시작하여 이토록 장황하게 이야기를 한 것은 내가 워낙 말의 핵심만 전달하는 능력이 떨어지기 때문일 것이다. 하지만 또하나 나처럼 코딩을 모르면서도 LCD 메뉴를 바꾸고 싶어하는 사람 중에 꼭 이동 방식만이 아니라 메뉴의 순서나 기타 다른 부분을 수정하고 싶어하는 사람도 있을 것 같았다. 그런면에서 결과가 아니라 과정을 공유하면 직접 찾아서 해보려고 했을 때 도움이 되지 않을까 하는 생각이 들어서였다. 

그런 의미로 생각해주고 스압을 이해해주면 감사하겠다.


이상 왕초보의 펌웨어 수정기인데  한번 여러분도 자신이 원하는 결과를 위해 도전해 보길 응원한다. 혹시 망치면 어떻겠는가. 백업해놓은 걸로 원상복구하면 되지 않겠는가. 오히려 실패라는 것은 경험의 다른 이름일 뿐일테니 말이다. 




김성민의 북리지 - 함께 성장하는 책 리더십 지혜