So I am working on an Arduino project and have trouble communicating over UART.
I have a SIM7600G-H 4G Module from Waveshare and hooked it up to an Arduino Nano ESP32. The connections are as follows:
SIM7600<->Nano ESP32
TXD<->RX0
RXD<->TX0
VIN<->VUSB
GND<->GND
CTS<->D3
RTS<->D12
It mostly works, I can send AT commands and receive responds. However sometimes I only receive parts and chunks are missing or being send to the next command. I strongly suspect RSPs ("unsolicited result code") to be the reason behind it. As documented in the manual RSPs are being send without an implicit action and happens for example if the module receives a call or SMS.
I have read about hardware flow control which seems to theoretically solve the problem of those module talking over each other and have connected the CTS and RTS pins to generic digital pins. According the manual the SIM Module it has hardware flow control enabled as an default.
On the Arduino side of things I have added these lines in hopes of enabling it, however I do not see a change, they do not return any error but I still see data missing. I have also tried swapping CTS and RTS just for fun, but without any luck.
Serial0.setPins(-1,-1,12,3);
Serial0.setHwFlowCtrlMode(UART_HW_FLOWCTRL_CTS_RTS);
Here are the logs which shows some responds being cut off.
20:57:47.991 -> Send AT command: AT
20:57:47.991 -> Response: AT
20:57:47.991 -> OK
20:57:47.991 ->
20:57:47.992 -> Send AT command: AT+CPIN=1234
20:57:47.992 -> Response: AT+CPIN=1234 <- This responds ending is cut off
20:57:47.992 -> Send AT command: AT+CSQ
20:57:48.025 -> Response: <- This responds start is cut off
20:57:48.025 -> OK
20:57:48.025 ->
20:57:48.025 -> Send AT command: AT+CREG=1
20:57:48.059 -> Response: AT+CREG=1
20:57:48.059 -> OK
20:57:48.059 ->
And this is my function to send those commands.
char* SIMClass::send(const char* command) {
// Clear buffer
while (Serial0.available() > 0) Serial0.read();
Serial.print("Send AT command: ");
Serial.println(command);
unsigned long timeout = millis() + 10000;
char* response = (char*)malloc(1024 * sizeof(char));
uint16_t index = 0;
Serial0.print(command);
Serial0.print("\r");
while (Serial0.available() == 0) {
if (millis() > timeout) {
response[index] = '\0';
return response;
}
}
while (Serial0.available() > 0) {
response[index++] = Serial0.read();
timeout = millis() + 1000;
}
response[index] = '\0';
Serial.print("Response: ");
Serial.println(response);
return response;
}
After enabling hardware flow control unsing Serial0.setHwFlowCtrlMode(UART_HW_FLOWCTRL_CTS_RTS) I expected Serial0.print(message) to wait until the SIM module is not busy and vice versa. Am I wrong in that assumption? Am I missing something else or is it maybe recommend to implement the hardware flow yourself?
Yeah, fast edges on the buttons. I think the whole design was originally intended to be 2 sided. The third layer has almost a complete ground plane, and the other two have sufficient infill and stitching to be a typical 2 sided design. Stuff would have needed to be moved around some to make room for the button contacts, but there was more than enough space.
From what I recall of the guys doing the software hack, I think the STM32 H7 microcontroller was emulating the original 6502 based ROM. So maybe they were optimising the hardware as much as possible to avoid the typical timing issues present in emulation in challenging parts of the game.
The coolest part of the hardware design is actually that little DC switch mode converter and battery manager. It is crazy efficient. Like, a full charge on the lithium cell will be at around half charged still after a couple of years, and while playing, it lasts abnormally long for such a device. It is not a particularly large cell either.