Beitian BN-180 (M8030-KT) cannot receive UBX commands via Arduino

I have a Beitian BN-180 (M8030-KT) that I have confirmed does indeed function correctly in UBlox U-Center and can be switched into UBX-RXM-PMREQ mode successfully. I am trying to emulate this in Arduino, by using the referenced link in the code below ( I constantly received "failed" due to hitting the timeout. Is this a checksum issue, or something else? For what it's worth, I am writing this to an ESP32 device via the Arduino IDE.

 GPS Level Convertor Board Test Script
 03/05/2012 2E0UPU
 This example connects the GPS via Software Serial.
 Initialise the GPS Module in Flight Mode and then echo's out the NMEA Data to the Arduinos onboard Serial port.
 This example code is in the public domain.
 Additional Code by J Coxon (

#include <SoftwareSerial.h>
SoftwareSerial GPS(34, 35);
byte gps_set_success = 0 ;
void setup()
  Serial.println("Setting uBlox GPS off: ");
  uint8_t turnGPSoff[] = {0xB5, 0x62, 0x02, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4D, 0x3B};
    sendUBX(turnGPSoff, sizeof(turnGPSoff)/sizeof(uint8_t));
void loop()

// Send a byte array of UBX protocol to the GPS
void sendUBX(uint8_t *MSG, uint8_t len) {
  for(int i=0; i<len; i++) {
    Serial.print(MSG[i], HEX);
// Calculate expected UBX ACK packet and parse UBX response from GPS
boolean getUBX_ACK(uint8_t *MSG) {
  uint8_t b;
  uint8_t ackByteID = 0;
  uint8_t ackPacket[10];
  unsigned long startTime = millis();
  Serial.print(" * Reading ACK response: ");
  // Construct the expected ACK packet    
  ackPacket[0] = 0xB5;  // header
  ackPacket[1] = 0x62;  // header
  ackPacket[2] = 0x05;  // class
  ackPacket[3] = 0x01;  // id
  ackPacket[4] = 0x02;  // length
  ackPacket[5] = 0x00;
  ackPacket[6] = MSG[2];  // ACK class
  ackPacket[7] = MSG[3];  // ACK id
  ackPacket[8] = 0;   // CK_A
  ackPacket[9] = 0;   // CK_B
  // Calculate the checksums
  for (uint8_t i=2; i<8; i++) {
    ackPacket[8] = ackPacket[8] + ackPacket[i];
    ackPacket[9] = ackPacket[9] + ackPacket[8];
  while (1) {
    // Test for success
    if (ackByteID > 9) {
      // All packets in order!
      Serial.println(" (SUCCESS!)");
      return true;
    // Timeout if no valid response in 3 seconds
    if (millis() - startTime > 3000) { 
      Serial.println(" (FAILED!)");
      return false;
    // Make sure data is available to read
    if (GPS.available()) {
      b =;
      // Check that bytes arrive in sequence as per expected ACK packet
      if (b == ackPacket[ackByteID]) { 
        Serial.print(b, HEX);
      else {
        ackByteID = 0;  // Reset and look again, invalid order

Is this specifically an ESP32 issue? Would love to know what could be causing this issue, as the above appears to have been the solution for others on this forum. Worst case, I can consider a transistor switch as a solution.

Use hardware serial for the GPS.

Mixing software serial for receive and hardware Serial prints can cause problems unless great care is taken with the program, read about the problem here;

Hi Srnet, thanks for the reply. Unfortunately, I had the same outcome. Do you think there is anything else that could be messing this up?

B56224180000020004D3B * Reading ACK response:  (FAILED!)

No idea.

You will need to put a USB\Serial adapter on the GPS pins so you can monitor, with a PC, what is actaually being sent to the GPS and what is the actual reply.

Meh, none of this is honestly worth it. A transistor switch will do the trick, so I'll just go with that.