저는 두 가지 중 하나에 대해 GSM 모뎀을 사용하는 응용 프로그램을 작성했습니다. 서버에 GET 요청을 보내거나 UDP를 사용하여 서버에 데이터를 보내 내장 된 HTTP 스택을 사용하여 상태를 확인하십시오. 가능한 한 신뢰할 수있는 여러 가지 방법을 시도했으며 마침내 도움을 요청할 준비가되었습니다.GSM 모뎀 드라이버 작성 중?
내 응용 프로그램은 SIMCOM908 모듈과 PIC18 플랫폼 용으로 작성되었습니다 (개발을 위해 PIC18 Explorer를 사용하고 있습니다).
그래서 문제는 때로는 모뎀이 뭔가를하는 중입니다. 명령을 놓친 경우입니다. 인간으로서 나는 그것을보고 그냥 명령을 다시 보냅니다. MCU에 시간 초과 및 재전송 기능을 추가하는 것은 문제가되지 않습니다.
문제는 모뎀이 다른 이벤트 후에 요청하지 않은 응답을 보내는 문제입니다. 모뎀이 등록 상태 (셀 타워 포함)를 변경하면 +CGREG: 1, ...
으로 응답하거나 GPS가 준비되었을 때 GPS Ready
으로 응답합니다. 이러한 응답은 명령의 중간 (IP 연결 작성과 같은)을 포함하여 언제든지 발생할 수 있습니다.
이 문제를 해결할 방법을 생각하지 않았기 때문에 이것은 문제입니다. 내 응용 프로그램이 명령을 보내야합니다 (예 : AT+CIPSTART="UDP","example.com",5000
과 같은 서버에 연결).이 명령은 'OK'로 응답 한 다음 명령이 'CONNECT OK'를 완료하면 응답합니다. 그러나 나는 다른 많은 가능한 반응에 반응 할 수 있어야하고, 나는 이것을하는 방법을 알아 내지 못했다. 내 코드로 무엇을해야합니까? 모뎀으로부터의 응답을 기다리고, 응답을 확인하고, 그 응답을 기반으로 동작을 수행합니까?
저는 코드가 제한되어 있으며 (8 비트 마이크로 컨트롤러입니다!) 반복 반복을 최소로하고 싶습니다. GSM 모듈 (요청 또는 지금)로부터 응답을 받고 내 프로그램의 나머지 부분에서 무슨 일이 일어나는지 응답 함수를 작성하려면 어떻게해야합니까?
이상적으로 나는 이러한 응답으로 무엇인가하고 싶습니다. 마찬가지로 내가 GPS Ready
을들을 때, 나는 등 GPS 전원을 공급할 수 알고 (내부 상태를 유지
어쩌면 나는 생각한다, 또는 어쩌면 이미이 문제를 해결 오픈 소스 프로젝트 거기에 몇 가지가있다?
.는 여기에 지금까지이 작업은 다음과 같습니다.
/* Command responses */
enum {
// Common
OK = 0,
ERROR,
TIMEOUT,
OTHER,
// CGREG
NOT_REGISTERED,
// CGATT
NOT_ATTACHED,
// Network Status
NO_NETWORK,
// GPRS status
NO_ADDRESS,
// HTTP ACTION
NETWORK_ERROR,
// IP Stack State
IP_INITIAL,
IP_STATUS,
IP_CONFIG,
UDP_CLOSING,
UDP_CLOSED,
UDP_CONNECTING
} gsmResponse;
int gsm_sendCommand(const char * cmd) {
unsigned long timeout = timer_getCurrentTime() + 5000;
uart_clearb(GSM_UART); // Clear the input buffer
uart_puts(GSM_UART, cmd); // Send the command to the module
while (strstr(bf2, "\r") == NULL) { // Keep waiting for a response from the module
if (timeout < timer_getCurrentTime()) { // Check we haven't timed out yet
printf("Command timed out: %s\r\n", cmd);
return TIMEOUT;
}
}
timer_delay(100); // Let the rest of the response be received.
return OK;
}
int gsm_simpleCommand(const char * cmd) {
if (gsm_sendCommand(cmd) == TIMEOUT)
return TIMEOUT;
// Getting an ERROR response is quick, so if there is a response, this will be there
if (strstr(bf2, "ERROR") != NULL)
return ERROR;
// Sometimes the OK (meaning the command ran) can take a while
// As long as there wasn't an error, we can wait for the OK
while (strstr(bf2, "OK") == NULL);
return OK;
}
간단한 명령은 AT
같은 구체적으로 응답 OK
또는 ERROR
을 찾고 명령 AT 어떤 무언가 그러나 나는 또한 AT+CPIN?
같은 고급 명령을 위해 사용하기 때문에 그것 전체 응답을 캡처 한 후 +CPIN: READY
을 더 검색 할 수 있습니다. 그러나이 중 어느 것도 원치 않는 응답에 실제로 응답하지 않습니다. 사실 원하지 않는 응답이 수신되면 gsm_sendCommand()
함수는 일찍 반환됩니다.
복잡하고 때로는 원치 않는 상태 메시지를 관리하는 좋은 방법은 무엇입니까? 이 응용 프로그램은 C로 작성되었으며 8 비트 마이크로 컨트롤러에서 실행됩니다. 당신이 들어오는 스트림을 역 다중화 필요하고 적절한 처리기에 결과를 파견하기 때문에 동일한 데이터 스트림의 요청에 모두 원치 않는 메시지뿐만 아니라 응답을 처리하는 데
는
상태 기계 (FSM)를 구현해야합니다 :'newstate = oldstate [message]', 그리고 아마도 다른 쪽이 상태 기계라고 생각할 수도 있습니다. – wildplasser
그 부분은 내가 생각하기에. 그러나이 경우 전체 FSM은 최상의 옵션처럼 보이지 않습니다. 단일 시스템의 여러 상태 라기보다는 서로 다른 두 가지 원치 않는 코드의 이진 상태를 추적해야합니다. 나는 추적 할 두 개의 글로벌 부울 유형을 간단히 갖게 될 것이다. – dantheman