음... 이걸 명시적 코딩이라고 하던가요?
코드를 누가 봐도 좀만 분석하면 척하고 아 이건 무슨 목적으로 만들었구나~ 하는걸 알 수 있도록 하는것요.
이를 위해서는 코드를 되도록 간결하고 불필요한 부분을 적게 만들 필요가 있다고 하죠
저희 팀장님은 이러한 명시적 코딩의 일환으로, 한개의 파일(*.c)에 한개의 함수만을 위치시킨다는 신념을 갖고 계시죠. (실제로 참조만 잘 걸어주면 찾기가 쉽기도 하구요)
아직 그 단계까지는 못해서 아두이노나 깔짝이면서 배워나가는 단계이긴 합니다만...
아래의 링크에 있는 코드를 한번 봐주세요.
이건 예전에 졸업과제 할때 썼던 Nextion디스플레이라는걸 사용하는 코드입니다.
졸업과제 당시와는 달리, Nextion 디스플레이의 라이브러리에 의존하지 않고, 에디터를 통해 특정 버튼을 누르면 시리얼통신으로 제가 정한 양식의 신호를 쏘도록만 설정한 뒤, 이걸 아두이노의 하드웨어 시리얼포트로 받아서 인식하는 코드죠.
그래서 우선, 0x39 0x52를 연속하여 수신하는걸 시작 트리거로, 0xFF를 연속으로 세번 받으면 종료 트리거를 의미한답시고 만든게 위 링크의 SerialInputSignalSwitchONOFF 라는 이름의 함수입니다.
Nextion 디스플레이의 라이브러리에 정의된 시리얼 통신을 통한 전송 바이트 수는 최대 8바이트였던지라, 일단 버퍼 배열의 사이즈를 7로 설정(0~7이므로 총 8바이트, 단 아두이노 시리얼통신의 반환은 int로 이루어지므로 int로 설정하였으므로 실제로는 2바이트)
그리고 7개의 배열에 시리얼통신으로 받아들이는 데이터를 차례로 기록한 뒤 특정한 배열(여기서는 앞의 두 바이트가 0x39 0x52이고, 뒤에는 0xFF 연속 세 바이트가 등장)이 만족되면 특정 핀을 ON/OFF 하는 식으로요.
일단 동작 자체는 구현에 성공했지만, 제가보기엔 이 코드가 위의 의도를 정확히 전달할 수 없는것같아보입니다.
우선 시리얼로 들어오는 데이터의 버퍼가 연속으로 0x39 0x52일 때, 이것을 어떠한 이벤트의 트리거로 삼는다 라는 의미도 충족하지 못하는것같고, 0xFF가 연속 세번 들어오는것을 신호의 끝으로 본다는 의미도 전혀 전달이 안되는것같습니다.
그리고 SerialRecordArray 함수쪽은... 그냥 뭔가 이상합니다.
함수의 시작부분에 if(Serial.available)을 사용해서, 시리얼통신으로 수신된 데이터가 있을 경우에만(Serial.available로 수신된 데이터가 있으면 양수를 반환하는 성질을 사용하여 if문의 트리거로 사용) 별도의 버퍼에 기록하는것을 허가하는 식으로 시작하는데, 이후 for문 안에 다시한번 if(available)을 걸어주지 않으면 수신이 끝난 다음, Serial.read가 아무것도 없다고 0xFFFF(-1)를 반환해버려서 남는 자리가 -1로 싹 채워져버립니다.
이걸 막기위해서 for문 안에 다시금 if(available)을 걸어주는데, 이것또 앞서 말한 "명시적이지 못한" 코드같습니다. 단적으로 깔끔하지가 않다는거죠.
사실 제가 생각하는 가장 이상적인 통신방법은 시리얼통신으로 데이터가 들어올 때 마다 충분히 긴 버퍼에 한칸씩 밀어내며 기록을 하고, 이 배열이 위치에 상관없이, -예를들어, 16바이트의 버퍼가 있을 때 다른 시리얼통신을 통해 들어온 데이터가 [2~7]에 존재하든, [6~11]에 존재하든 상관없이, 특정한 시작과 끝바이트만을 만족하면 해당 구간을 읽어내어 거기에 맞는 명령을 실행하고 그부분은 0으로 초기화하는 식으로 구현하는게 가장 이상적이라 생각하고 어떻게든 머리를 쥐어짜내 만들었지만 이러한 의도는 전혀 반영되어 있지 않은 것 같네요...
그러니 부디, 선배님들의 입장에서 문제점을 좀 짚어주시길 부탁드립니다 (_ _)꾸벅
데이터 길이가 길 때에는 메모리 낭비로 임베디드에서는 개인적으로 추천하지 않고
플레그나 카운트 변수, 혹은 둘 다로 시작지점과 끝지점을 판단하는방식이 좋다고 보고
절대적으로 아무리 아두이노라지만 통신코드가 루프로 돌아가는건 바람직하지않습니다.
시리얼 데이터등의 통신 받아오는 방식은 인터럽트를 적극 활용해주시는베 시스템 반응 및 부하관리에 좋습니다