2024-07-29 04:17 PM
void sendAT(char command[], char answer[], int waitForAnswer) { char ATcommand[500]; uint8_t buffer[500] = { 0 }; uint8_t ATisOK = 0; sprintf(ATcommand, "%s\r\n", command); DEBUG_PRINT("Sending AT Command: "); DEBUG_PRINT(ATcommand); while (!ATisOK) { HAL_UART_Transmit(&huart2, (uint8_t*) ATcommand, strlen(ATcommand), 2000); HAL_UART_Receive(&huart2, buffer, sizeof(buffer) - 1, 300); buffer[sizeof(buffer) - 1] = '\0'; HAL_Delay(500); ATisOK = !waitForAnswer; if (strstr((char*) buffer, "OK")) { ATisOK = 1; } DEBUG_PRINT("GSM: "); DEBUG_PRINT((char* ) buffer); HAL_Delay(1000); memset(buffer, 0, sizeof(buffer)); } } char* sendATWithReturn(char command[]) { char ATcommand[500]; uint8_t buffer[300] = { 0 }; char *returnBuffer = malloc(300 * sizeof(char)); if (returnBuffer == NULL) { return NULL; } sprintf(ATcommand, "%s\r\n", command); HAL_UART_Transmit(&huart2, (uint8_t*) ATcommand, strlen(ATcommand), 1000); HAL_UART_Receive(&huart2, buffer, 300, 100); HAL_Delay(500); DEBUG_PRINT("GSM: "); DEBUG_PRINT((char* ) buffer); strncpy(returnBuffer, (char*) buffer, 300); return returnBuffer; }
void modemStart(char *apn, char *user, char *pwd) { sendATWithReturn("AT"); HAL_Delay(1000); sendATWithReturn("AT+CPIN?"); HAL_Delay(1000); sendATWithReturn("AT+CREG?"); HAL_Delay(1000); sendATWithReturn("AT+CGATT?"); HAL_Delay(1000); sendATWithReturn("AT+CSQ"); HAL_Delay(1000); char command[500]; snprintf(command, sizeof(command), "AT+CGDCONT=1,\"IP\",\"%s\"", apn); sendAT(command, "OK", 1); memset(command, 0, sizeof(command)); HAL_Delay(1000); sendAT("AT+CGATT=1", "OK", 0); HAL_Delay(1000); sendATWithReturn("AT+CSTT?"); HAL_Delay(1000); snprintf(command, sizeof(command), "AT+CSTT=\"%s\",\"%s\",\"%s\"", apn, user, pwd); sendAT(command, "OK", 1); memset(command, 0, sizeof(command)); HAL_Delay(1000); sendATWithReturn("AT+CIICR"); HAL_Delay(1000); sendATWithReturn("AT+CIFSR"); HAL_Delay(1000); sendATWithReturn("AT+CIPMUX=1"); /* AT+CPIN?: Verifica o status do PIN do SIM. AT+CREG?: Verifica o status de registro na rede. Sequência de Inicialização: AT+NETCLOSE: Fecha qualquer conexão de rede existente. AT+CGATT=0: Desativa o GPRS. AT+CGATT=1: Ativa o GPRS. AT+CGDCONT: Define o contexto PDP. AT+CSTT: Define o APN, usuário e senha. AT+CIICR: Inicia a conexão sem fio. AT+CIFSR: Obtém o endereço IP. AT+CIPMUX=1: Habilita o modo de múltiplas conexões. */ }
19:37:54.671 -> Serial2: Send AT: 19:37:54.671 -> Sending AT Command: AT 19:37:54.671 -> GSM: AT 19:37:54.671 -> OK 19:37:54.671 -> 19:37:56.282 -> Serial2: GSM: AT 19:37:56.282 -> OK 19:37:56.282 -> 19:37:57.878 -> Serial2: GSM: AT+CPIN? 19:37:57.878 -> +CPIN: READY 19:37:57.878 -> 19:37:57.878 -> OK 19:37:57.878 -> 19:37:59.455 -> Serial2: GSM: AT+CREG? 19:37:59.455 -> +CREG: 0,1 19:37:59.455 -> 19:37:59.455 -> OK 19:37:59.455 -> 19:38:01.060 -> Serial2: GSM: AT+CGATT? 19:38:01.060 -> +CGATT: 1 19:38:01.060 -> 19:38:01.060 -> OK 19:38:01.060 -> 19:38:04.242 -> Serial2: GSM: AT+CSQ 19:38:04.242 -> +CSQ: 18,0 19:38:04.242 -> 19:38:04.242 -> OK 19:38:04.242 -> Sending AT Command: AT+CGDCONT=1,"IP","zap.vivo.com.br" 19:38:04.287 -> GSM: AT+CGDCONT=1,"IP","zap.vivo.com.br" 19:38:04.287 -> OK 19:38:04.287 -> 19:38:06.839 -> Serial2: Sending AT Command: AT+CGATT=1 19:38:06.839 -> GSM: AT+CGATT=1 19:38:06.885 -> OK 19:38:06.885 -> 19:38:11.069 -> Serial2: GSM: AT+CSTT? 19:38:11.069 -> ERROR 19:38:11.069 -> Sending AT Command: AT+CSTT="zap.vivo.com.br","vivo","vivo" 19:38:11.069 -> GSM: A+CSTT="zap.vivo.com.br","vivo","vivo" 19:38:11.069 -> ERROR 19:38:11.069 -> 19:38:12.670 -> Serial2: GSM: A+CSTT="zap.vivo.com.br","vivo","vivo" 19:38:12.670 -> ERROR
Solved! Go to Solution.
2024-07-30 07:05 AM - edited 2024-07-30 07:12 AM
I'm starting to doubt this question has anything to do with STM32.
Can you share a link to the AT command manual you're using for this module? None of the ones I've found list AT+CSTT as a valid command.
@Pavel A. cool idea. could also just use a second USB-serial cable, and connect its RX alternately to either direction to see what's going on. no custom SW needed. But really, a Chinese clone 24Mhz LA costs ~10$ and does the job perfectly.
2024-07-30 07:19 AM - edited 2024-07-30 07:22 AM
@BarryWhit wrote:Can you share a link to the AT command manual you're using for this module? None of the ones I've found list AT+CSTT as a valid command.
But At+CSTT is a listed command for the much older SIM900 module from the same company, which was used in older shields for arduino.
2024-07-30 05:04 PM
Well... Apparently the CSTT command doesn't really exist, I ended up basing it on an old library and not paying attention to the manual.
But thank you all, I got a good result by implementing the buffer and the interrupts.
Here's the code for anyone who wants to deal with a stack of AT commands and GSM modems:
uint8_t Rx_buffer[100]; uint8_t rx_answer[100]; uint8_t Rx_data = 0; int rx_index = 0; uint16_t lastRxTick = 0; int gsmStatus = 0; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == huart1.Instance) { } if (huart->Instance == huart2.Instance) { Rx_buffer[rx_index++] = Rx_data; lastRxTick = HAL_GetTick(); gsmStatus = 2; HAL_UART_Receive_IT(&huart2, &Rx_data, 1); } } uint16_t sendTick = 0; void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == huart1.Instance) { } if (huart->Instance == huart2.Instance) { if (gsmStatus == 0) { DEBUG_PRINT("Send...\r\n"); gsmStatus = 1; sendTick = HAL_GetTick(); } } } void sendAT(char command[], char answer[], int waitForAnswer) { char ATcommand[200]; uint8_t commandBuffer[200] = { 0 }; uint8_t buffer[200] = { 0 }; uint8_t ATisOK = 0; HAL_UART_Receive_IT(&huart2, &Rx_data, 1); snprintf(ATcommand, sizeof(ATcommand), "AT%s\r\n", command); memcpy(commandBuffer, (uint8_t*) ATcommand, strlen(ATcommand) + 1); DEBUG_PRINT("Sending AT Command: \r\n"); DEBUG_PRINT(ATcommand); while (!ATisOK) { if (gsmStatus == 0) HAL_UART_Transmit_IT(&huart2, commandBuffer, sizeof(commandBuffer)); if (gsmStatus == 3) { rx_answer[sizeof(rx_answer) - 1] = '\0'; ATisOK = !waitForAnswer; if (strstr((char*) rx_answer, "OK")) { ATisOK = 1; } DEBUG_PRINT("GSM answer: \r\n"); char ATanswer[200]; sprintf(ATanswer, "%s\r\n", (char* ) rx_answer); DEBUG_PRINT(ATanswer); memset(rx_answer, 0, sizeof(rx_answer)); gsmStatus = 0; } if (gsmStatus >= 1) { if(gsmStatus == 2){ if (HAL_GetTick() >= lastRxTick + 40) { memcpy(rx_answer, Rx_buffer, sizeof(Rx_buffer)); rx_index = 0; memset(Rx_buffer, 0, sizeof(Rx_buffer)); gsmStatus = 3; } } if(gsmStatus != 3){ if (HAL_GetTick() >= sendTick + 6000) { DEBUG_PRINT("TimeOut\r\n"); rx_index = 0; memset(rx_answer, 0, sizeof(rx_answer)); memset(Rx_buffer, 0, sizeof(Rx_buffer)); gsmStatus = 0; } } } } } void modemStart(char *apn, char *user, char *pwd) { sendAT("", "OK", 1); sendAT("+CPIN?", "OK", 1); sendAT("+CREG?", "OK", 1); sendAT("+CSQ", "OK", 1); char command[200]; snprintf(command, sizeof(command), "+CGAUTH=1,1,\"%s\",\"%s\"", user, pwd); sendAT(command, "OK", 1); memset(command, 0, sizeof(command)); snprintf(command, sizeof(command), "+CGDCONT=1,\"IP\",\"%s\"", apn); sendAT(command, "OK", 1); memset(command, 0, sizeof(command)); sendAT("+CGACT=1,1", "OK", 0); sendAT("+CGATT?", "OK", 1); } //A7670X Init
2024-07-30 07:26 PM - edited 2024-07-30 07:28 PM
In the OP you claimed the UART data is being corrupted. Instead, you were getting an error because you were sending an invalid command and that red herring sent everyone trying to help you down the wrong path.
In the future, keep this mind and try to be sure that you're sure about what you're sure of. I hope your project goes smoothly from here on.