My board is a Pro Micro with the on board UART as Serial1 (RX on 0, TX on 1) and the virtual UART as Serial on the USB. I am talking to the modem on a SIMCOM7000G. The modem is locked at 9600 8N1. TX on the modem is connected to RX (pin 0) on the board, and RX on the modem is connected to TX (pin 1) on the board.
I'm sending a short AT string to the modem and expecting a response, but not getting any.
This is a test sketch that I am using:
#define MONITOR true
#define BAUD 9600
const char AT_ECHO_ON[] PROGMEM = {"ATE1\r\n"};
void uart_put_P(const uint8_t *s) {
while (pgm_read_byte(s) != 0x00) {
uint8_t uartByte = (pgm_read_byte(s++));
Serial1.write(uartByte);
if (MONITOR) {
Serial.write(uartByte);
}
}
}
char recvText[161];
void uart_get() {
uint8_t b = 0;
if (MONITOR) Serial.print("Serial1.available:\t"); Serial.println(Serial1.available());
while (Serial1.available() > 0) {
uint8_t recvByte = Serial1.read();
recvText[b] = recvByte;
b++;
if (MONITOR) {
Serial.write(recvByte);
}
}
recvText[b] = 0x00;
}
void setup() {
if (MONITOR) {
Serial.begin(BAUD); // Serial is the virtual UART via USB
while (!Serial) {
; // we're going nowhere if we can't talk to the monitor when we need to
}
}
Serial1.begin(BAUD); // Serial1 is the real UART connected to the modem RXD on 0, TXD on 1
while (!Serial1) {
; // we're going nowhere if there is no connection to the modem
}
uart_put_P(AT_ECHO_ON);
uart_get();
}
void loop() {
}
This is what I see on the Serial monitor:
16:30:34.407 -> ATE1
16:30:34.407 -> Serial1.available: 0
To check whether there is actually any output from the modem I then diverted the modem TX away from the Micro board and fed it into a separate monitor program. This is what I see in this monitor:
[16:30:34:416] ATE1␍␍␊
[16:30:34:416] OK␍␊
This tells me that my input is being accepted by the modem, the command is being echoed, and there is an "OK" acknowledgement.
My question is: Why is the Serial1.available showing "0", hence blocking my uart_get() function from not reading the modem output.
You can’t expect the answer to be ready a few micro seconds after you sent the command - that’s why available() returns 0.
Your UART is an asynchronous protocol so you should not second guess timing. Wait until something is available and read it. Accumulate data until some sort of end of message is reached, analyze the answer and proceed.
I would suggest to study Serial Input Basics to better understand the concepts of dealing with a serial line
Sure, if data comes from the modem and we're not connected the - squirrels, but If we're not connected to the modem then we're not going to be able to send data to the modem in the first place,
Putting the uart_Get and show_Data in the loop does work because of the loop, but I'm trying to get a loop to work in the setup and that is causing me grief - just can't get the logic right...
Actually I think the problem might be that there are two \n characters - one before the OK and another after. The string that is returning is \r\nOK\r\n so it looks like I might have to count up the \r
Yeah if you ask many times after a while the data will show up. But then you need to architect the code so that the loop keeps looping until you can issue the next AT command… you need some sort of state machine to see if you are waiting for the answer to a command or if you can Proceed
I have actually now got some sensible responses from the uart y putting the initialisation AT statements into loop and ensuring that it only runs once in there.
My next problem looks to be the uart RX buffer size. I issue a AT+CGNSINF to tell the modem to send the GPS data string. I know that this string is about 100 characters long but it looks as if I'm only getting 64 bytes. I tried sending a short delay and another uart_get() but nothing. Do I need to keep flogging the horse for about 10 iterations to see if anything more comes in.
The Serial class uses a buffer implemented in software that has a size of 64 bytes. You can study Robin's Serial Input Basics - updated to get some ideas how to work around that problem.
But seeing that you seem to have solved the issue, it will be a bit like putting the horse behind the cart But it ill be a useful read anyway.
It might help other people that encounter the same problem if you post the working code. It might also be useful to get some feedback if needed.
This is you trying to second guess the timing of an asynchronous process… it’s not robust.
The tutorial you are being referred to is the way to handle that : just accumulate the data while it’s coming and when it’s all there (end marker) deal with the command/data