Low data throughput on nRF9151DK compared to nRF9160

Hi, I'm experiencing a significant performance drop when switching from the nRF9160 to the nRF9151DK.

I have a firmware that sends around 300 kBytes of data over UART in about 20 seconds using data mode with the Serial LTE Modem (SLM) on the nRF9160. However, running the same firmware (with minor adjustments) on the nRF9151DK, the same 300 kBytes take about 2 minutes to transmit.

Data is being sent over UART in SLM data mode (i.e., after AT+CFUN=1, AT+CMEE=1, AT+KTCPCNX, etc.). I'm using UART2 with HW Async mode enabled (CONFIG_UART_2_NRF_HW_ASYNC=y) and a baudrate of 921600.

I would like to ask:

  • Are there any known differences between the nRF9160 and nRF9151 that could explain this performance drop?

  • Are there specific UART, modem, or clock configurations required for the nRF9151 to achieve similar throughput?

  • Does using HW Async with TIMER2 on the nRF9151 require special considerations?

Any guidance would be greatly appreciated.
Thanks!

Conectado à porta COM13 a 921600 bps.
Enviando: AT+CFUN=0
Resposta:
ERROR
------------------------------
Enviando: AT%POWERCLASS=5
Resposta:
OK
------------------------------
Enviando: AT%XSYSTEMMODE=1,0,0,0
Resposta:
OK
------------------------------
Enviando: AT+CFUN=1
Resposta:
OK
------------------------------
Enviando: AT+CFUN?
Resposta:
+CFUN: 1
OK
------------------------------
Enviando: AT+COPS=1,2,"72405"
Resposta:
OK
------------------------------
Enviando: AT+CGDCONT=1,"IP","em"
Resposta:
OK
------------------------------
Enviando: AT+CEREG=1
Resposta:
OK
------------------------------
Enviando: AT+COPS?
Resposta:
+COPS: 1
OK
------------------------------
Enviando: AT+CEREG?
Resposta:
+CEREG: 1,4
OK
------------------------------
Aguardando registro na rede... Tentando novamente em 5 segundos.
Enviando: AT+CEREG?
Resposta:
+CEREG: 2
+CEREG: 5
+CEREG: 1,5
OK
------------------------------
Registrado na rede com sucesso.
Enviando: AT#XMQTTCFG="clientId-NdUYzNW5CM",60,1
Resposta:
OK
------------------------------
Enviando: AT#XMQTTCON=1,"","","XXXXXXXXXX",1883
Resposta:
OK
------------------------------
Aguardando evento 0,0...
Recebido: #XMQTTEVT: 0,0
Enviando: AT#XMQTTPUB="test/consumo/nrf9151","",2,0
Resposta:
OK
------------------------------
Entrando em modo de dados. Iniciando envios de payloads...

[Payload 1/74]
[18:00:24] Enviando payload 1
[18:00:25] Recebido: #XMQTTEVT: 4,0
[18:00:25] Recebido: #XMQTTEVT: 6,0

[Payload 2/74]
[18:00:25] Enviando payload 2
[18:00:26] Recebido: #XMQTTEVT: 4,0
[18:00:27] Recebido: #XMQTTEVT: 6,0

[Payload 3/74]
[18:00:27] Enviando payload 3
[18:00:28] Recebido: #XMQTTEVT: 4,0
[18:00:28] Recebido: #XMQTTEVT: 6,0

[Payload 4/74]
[18:00:28] Enviando payload 4
[18:00:29] Recebido: #XMQTTEVT: 4,0
[18:00:29] Recebido: #XMQTTEVT: 6,0

[Payload 5/74]
[18:00:29] Enviando payload 5
[18:00:30] Recebido: #XMQTTEVT: 4,0
[18:00:31] Recebido: #XMQTTEVT: 6,0

[Payload 6/74]
[18:00:31] Enviando payload 6
[18:00:31] Recebido: #XMQTTEVT: 4,0
[18:00:31] Recebido: #XMQTTEVT: 6,0

[Payload 7/74]
[18:00:31] Enviando payload 7
[18:00:32] Recebido: #XMQTTEVT: 4,0
[18:00:32] Recebido: #XMQTTEVT: 6,0

[Payload 8/74]
[18:00:32] Enviando payload 8
[18:00:33] Recebido: #XMQTTEVT: 4,0
[18:00:34] Recebido: #XMQTTEVT: 6,0

[Payload 9/74]
[18:00:34] Enviando payload 9
[18:00:34] Recebido: #XMQTTEVT: 4,0
[18:00:35] Recebido: #XMQTTEVT: 6,0

[Payload 10/74]
[18:00:35] Enviando payload 10
[18:00:35] Recebido: #XMQTTEVT: 4,0
[18:00:35] Recebido: #XMQTTEVT: 6,0

[Payload 11/74]
[18:00:35] Enviando payload 11
[18:00:36] Recebido: #XMQTTEVT: 4,0
[18:00:37] Recebido: #XMQTTEVT: 6,0

[Payload 12/74]
[18:00:37] Enviando payload 12
[18:00:38] Recebido: #XMQTTEVT: 4,0
[18:00:38] Recebido: #XMQTTEVT: 6,0

[Payload 13/74]
[18:00:38] Enviando payload 13
[18:00:39] Recebido: #XMQTTEVT: 4,0
[18:00:39] Recebido: #XMQTTEVT: 6,0

[Payload 14/74]
[18:00:39] Enviando payload 14
[18:00:40] Recebido: #XMQTTEVT: 4,0
[18:00:41] Recebido: #XMQTTEVT: 6,0

[Payload 15/74]
[18:00:41] Enviando payload 15
[18:00:42] Recebido: #XMQTTEVT: 4,0
[18:00:43] Recebido: #XMQTTEVT: 6,0

[Payload 16/74]
[18:00:43] Enviando payload 16
[18:00:43] Recebido: #XMQTTEVT: 4,0
[18:00:44] Recebido: #XMQTTEVT: 6,0

[Payload 17/74]
[18:00:44] Enviando payload 17
[18:00:45] Recebido: #XMQTTEVT: 4,0
[18:00:45] Recebido: #XMQTTEVT: 6,0

[Payload 18/74]
[18:00:45] Enviando payload 18
[18:00:46] Recebido: #XMQTTEVT: 4,0
[18:00:46] Recebido: #XMQTTEVT: 6,0

[Payload 19/74]
[18:00:46] Enviando payload 19
[18:00:47] Recebido: #XMQTTEVT: 4,0
[18:00:47] Recebido: #XMQTTEVT: 6,0

[Payload 20/74]
[18:00:47] Enviando payload 20
[18:00:48] Recebido: #XMQTTEVT: 4,0
[18:00:48] Recebido: #XMQTTEVT: 6,0

[Payload 21/74]
[18:00:48] Enviando payload 21
[18:00:49] Recebido: #XMQTTEVT: 4,0
[18:00:49] Recebido: #XMQTTEVT: 6,0

[Payload 22/74]
[18:00:49] Enviando payload 22
[18:00:50] Recebido: #XMQTTEVT: 4,0
[18:00:50] Recebido: #XMQTTEVT: 6,0

[Payload 23/74]
[18:00:50] Enviando payload 23
[18:00:51] Recebido: #XMQTTEVT: 4,0
[18:00:51] Recebido: #XMQTTEVT: 6,0

[Payload 24/74]
[18:00:51] Enviando payload 24
[18:00:52] Recebido: #XMQTTEVT: 4,0
[18:00:52] Recebido: #XMQTTEVT: 6,0

[Payload 25/74]
[18:00:52] Enviando payload 25
[18:00:53] Recebido: #XMQTTEVT: 4,0
[18:00:53] Recebido: #XMQTTEVT: 6,0

[Payload 26/74]
[18:00:53] Enviando payload 26
[18:00:54] Recebido: #XMQTTEVT: 4,0
[18:00:54] Recebido: #XMQTTEVT: 6,0

[Payload 27/74]
[18:00:54] Enviando payload 27
[18:00:55] Recebido: #XMQTTEVT: 4,0
[18:00:55] Recebido: #XMQTTEVT: 6,0

[Payload 28/74]
[18:00:55] Enviando payload 28
[18:00:56] Recebido: #XMQTTEVT: 4,0
[18:00:56] Recebido: #XMQTTEVT: 6,0

[Payload 29/74]
[18:00:56] Enviando payload 29
[18:00:57] Recebido: #XMQTTEVT: 4,0
[18:00:57] Recebido: #XMQTTEVT: 6,0

[Payload 30/74]
[18:00:57] Enviando payload 30
[18:00:58] Recebido: #XMQTTEVT: 4,0
[18:00:59] Recebido: #XMQTTEVT: 6,0

[Payload 31/74]
[18:00:59] Enviando payload 31
[18:00:59] Recebido: #XMQTTEVT: 4,0
[18:00:59] Recebido: #XMQTTEVT: 6,0

[Payload 32/74]
[18:00:59] Enviando payload 32
[18:01:00] Recebido: #XMQTTEVT: 4,0
[18:01:01] Recebido: #XMQTTEVT: 6,0

[Payload 33/74]
[18:01:01] Enviando payload 33
[18:01:02] Recebido: #XMQTTEVT: 4,0
[18:01:02] Recebido: #XMQTTEVT: 6,0

[Payload 34/74]
[18:01:02] Enviando payload 34
[18:01:03] Recebido: #XMQTTEVT: 4,0
[18:01:03] Recebido: #XMQTTEVT: 6,0

[Payload 35/74]
[18:01:03] Enviando payload 35
[18:01:03] Recebido: #XMQTTEVT: 4,0
[18:01:04] Recebido: #XMQTTEVT: 6,0

[Payload 36/74]
[18:01:04] Enviando payload 36
[18:01:05] Recebido: #XMQTTEVT: 4,0
[18:01:05] Recebido: #XMQTTEVT: 6,0

[Payload 37/74]
[18:01:05] Enviando payload 37
[18:01:06] Recebido: #XMQTTEVT: 4,0
[18:01:06] Recebido: #XMQTTEVT: 6,0

[Payload 38/74]
[18:01:06] Enviando payload 38
[18:01:07] Recebido: #XMQTTEVT: 4,0
[18:01:08] Recebido: #XMQTTEVT: 6,0

[Payload 39/74]
[18:01:08] Enviando payload 39
[18:01:08] Recebido: #XMQTTEVT: 4,0
[18:01:09] Recebido: #XMQTTEVT: 6,0

[Payload 40/74]
[18:01:09] Enviando payload 40
[18:01:09] Recebido: #XMQTTEVT: 4,0
[18:01:10] Recebido: #XMQTTEVT: 6,0

[Payload 41/74]
[18:01:10] Enviando payload 41
[18:01:11] Recebido: #XMQTTEVT: 4,0
[18:01:11] Recebido: #XMQTTEVT: 6,0

[Payload 42/74]
[18:01:11] Enviando payload 42
[18:01:11] Recebido: #XMQTTEVT: 4,0
[18:01:12] Recebido: #XMQTTEVT: 6,0

[Payload 43/74]
[18:01:12] Enviando payload 43
[18:01:12] Recebido: #XMQTTEVT: 4,0
[18:01:13] Recebido: #XMQTTEVT: 6,0

[Payload 44/74]
[18:01:13] Enviando payload 44
[18:01:13] Recebido: #XMQTTEVT: 4,0
[18:01:14] Recebido: #XMQTTEVT: 6,0

[Payload 45/74]
[18:01:14] Enviando payload 45
[18:01:15] Recebido: #XMQTTEVT: 4,0
[18:01:15] Recebido: #XMQTTEVT: 6,0

[Payload 46/74]
[18:01:15] Enviando payload 46
[18:01:16] Recebido: #XMQTTEVT: 4,0
[18:01:16] Recebido: #XMQTTEVT: 6,0

[Payload 47/74]
[18:01:16] Enviando payload 47
[18:01:17] Recebido: #XMQTTEVT: 4,0
[18:01:18] Recebido: #XMQTTEVT: 6,0

[Payload 48/74]
[18:01:18] Enviando payload 48
[18:01:19] Recebido: #XMQTTEVT: 4,0
[18:01:19] Recebido: #XMQTTEVT: 6,0

[Payload 49/74]
[18:01:19] Enviando payload 49
[18:01:20] Recebido: #XMQTTEVT: 4,0
[18:01:20] Recebido: #XMQTTEVT: 6,0

[Payload 50/74]
[18:01:20] Enviando payload 50
[18:01:21] Recebido: #XMQTTEVT: 4,0
[18:01:21] Recebido: #XMQTTEVT: 6,0

[Payload 51/74]
[18:01:21] Enviando payload 51
[18:01:22] Recebido: #XMQTTEVT: 4,0
[18:01:23] Recebido: #XMQTTEVT: 6,0

[Payload 52/74]
[18:01:23] Enviando payload 52
[18:01:24] Recebido: #XMQTTEVT: 4,0
[18:01:24] Recebido: #XMQTTEVT: 6,0

[Payload 53/74]
[18:01:24] Enviando payload 53
[18:01:25] Recebido: #XMQTTEVT: 4,0
[18:01:25] Recebido: #XMQTTEVT: 6,0

[Payload 54/74]
[18:01:25] Enviando payload 54
[18:01:26] Recebido: #XMQTTEVT: 4,0
[18:01:27] Recebido: #XMQTTEVT: 6,0

[Payload 55/74]
[18:01:27] Enviando payload 55
[18:01:27] Recebido: #XMQTTEVT: 4,0
[18:01:28] Recebido: #XMQTTEVT: 6,0

[Payload 56/74]
[18:01:28] Enviando payload 56
[18:01:29] Recebido: #XMQTTEVT: 4,0
[18:01:29] Recebido: #XMQTTEVT: 6,0

[Payload 57/74]
[18:01:29] Enviando payload 57
[18:01:29] Recebido: #XMQTTEVT: 4,0
[18:01:30] Recebido: #XMQTTEVT: 6,0

[Payload 58/74]
[18:01:30] Enviando payload 58
[18:01:31] Recebido: #XMQTTEVT: 4,0
[18:01:31] Recebido: #XMQTTEVT: 6,0

[Payload 59/74]
[18:01:31] Enviando payload 59
[18:01:32] Recebido: #XMQTTEVT: 4,0
[18:01:32] Recebido: #XMQTTEVT: 6,0

[Payload 60/74]
[18:01:32] Enviando payload 60
[18:01:33] Recebido: #XMQTTEVT: 4,0
[18:01:33] Recebido: #XMQTTEVT: 6,0

[Payload 61/74]
[18:01:33] Enviando payload 61
[18:01:34] Recebido: #XMQTTEVT: 4,0
[18:01:34] Recebido: #XMQTTEVT: 6,0

[Payload 62/74]
[18:01:34] Enviando payload 62
[18:01:35] Recebido: #XMQTTEVT: 4,0
[18:01:35] Recebido: #XMQTTEVT: 6,0

[Payload 63/74]
[18:01:35] Enviando payload 63
[18:01:36] Recebido: #XMQTTEVT: 4,0
[18:01:36] Recebido: #XMQTTEVT: 6,0

[Payload 64/74]
[18:01:36] Enviando payload 64
[18:01:37] Recebido: #XMQTTEVT: 4,0
[18:01:38] Recebido: #XMQTTEVT: 6,0

[Payload 65/74]
[18:01:38] Enviando payload 65
[18:01:39] Recebido: #XMQTTEVT: 4,0
[18:01:39] Recebido: #XMQTTEVT: 6,0

[Payload 66/74]
[18:01:39] Enviando payload 66
[18:01:40] Recebido: #XMQTTEVT: 4,0
[18:01:40] Recebido: #XMQTTEVT: 6,0

[Payload 67/74]
[18:01:40] Enviando payload 67
[18:01:41] Recebido: #XMQTTEVT: 4,0
[18:01:41] Recebido: #XMQTTEVT: 6,0

[Payload 68/74]
[18:01:41] Enviando payload 68
[18:01:42] Recebido: #XMQTTEVT: 4,0
[18:01:42] Recebido: #XMQTTEVT: 6,0

[Payload 69/74]
[18:01:42] Enviando payload 69
[18:01:43] Recebido: #XMQTTEVT: 4,0
[18:01:43] Recebido: #XMQTTEVT: 6,0

[Payload 70/74]
[18:01:43] Enviando payload 70
[18:01:44] Recebido: #XMQTTEVT: 4,0
[18:01:45] Recebido: #XMQTTEVT: 6,0

[Payload 71/74]
[18:01:45] Enviando payload 71
[18:01:46] Recebido: #XMQTTEVT: 4,0
[18:01:46] Recebido: #XMQTTEVT: 6,0

[Payload 72/74]
[18:01:46] Enviando payload 72
[18:01:47] Recebido: #XMQTTEVT: 4,0
[18:01:47] Recebido: #XMQTTEVT: 6,0

[Payload 73/74]
[18:01:47] Enviando payload 73
[18:01:48] Recebido: #XMQTTEVT: 4,0
[18:01:49] Recebido: #XMQTTEVT: 6,0

[Payload 74/74]
[18:01:49] Enviando payload 74
[18:01:49] Recebido: #XMQTTEVT: 4,0
[18:01:50] Recebido: #XMQTTEVT: 6,0
Envio finalizado. Saindo do modo de dados.


import serial
import time
import hexdump

# Configurações
PORT = 'COM13'
BAUDRATE = 921600
TIMEOUT = 0.5

at_commands = [
    'AT+CFUN=0',
    'AT%POWERCLASS=5',
    'AT%XSYSTEMMODE=1,0,0,0',
    'AT+CFUN=1',
    'AT+CFUN?',
    'AT+COPS=1,2,"72405"',
    'AT+CGDCONT=1,"IP","em"',
    #'AT+CGDCONT=1,"IP","waterlog.claro.com.br"',
    'AT+CEREG=1',
    'AT+COPS?',
    'AT+CEREG?',
    'AT#XMQTTCFG="clientId-NdUYzNW5CM",60,1',
    'AT#XMQTTCON=1,"","","XXXXXXXXX",1883',
    'AT#XMQTTPUB="test/consumo/nrf9151","",2,0',
]

def generate_payload(bytes=4000):
    #return ''.join([str(v) for v in range(0,4096)])
    payload = ['0'] * bytes
    cont = 0
    for i in range(0, bytes):
        payload[i] = str(cont)
        cont += 1
        if cont > 9:
            cont = 0
    return ''.join(payload)

def send_at_command(ser, command):
    print(f"Enviando: {command}")
    ser.write((command + '\r\n').encode())
    ser.flush()

    response = []
    while True:
        line = ser.readline().decode(errors='ignore')
        if not line:
            break
        stripped_line = line.strip()
        if stripped_line:
            response.append(stripped_line)
            if stripped_line in ('OK', 'ERROR'):
                break

    print("Resposta:")
    print('\n'.join(response))
    print("-" * 30)
    return response

def wait_for_mqtt_event(ser, expected_evt_type, expected_result=0, timeout=10):
    print(f"Aguardando evento {expected_evt_type},{expected_result}...")
    start_time = time.time()
    while (time.time() - start_time) < timeout:
        line = ser.readline().decode(errors='ignore').strip()
        if line:
            print(f"Recebido: {line}")
            if line.startswith('#XMQTTEVT:'):
                try:
                    parts = line.split(':')[1].split(',')
                    evt_type = int(parts[0].strip())
                    result = int(parts[1].strip())
                    if evt_type == expected_evt_type and result == expected_result:
                        return True
                except:
                    pass
        else:
            time.sleep(0.1)
    print(f"Timeout aguardando evento {expected_evt_type},{expected_result}")
    return False

def main():
    try:
        payload_total = generate_payload(4096)

        with serial.Serial(PORT, BAUDRATE, timeout=TIMEOUT) as ser:
            print(f"Conectado à porta {PORT} a {BAUDRATE} bps.")
            time.sleep(2)

            ser.write(b'+++')
            ser.write(b'AT')


            for cmd in at_commands:
                if cmd == 'AT+CEREG?':
                    while True:
                        response = send_at_command(ser, cmd)
                        cereg_ok = any(line.startswith('+CEREG: ') and (('1,5' in line) or ('1,1' in line)) for line in response)
                        if cereg_ok:
                            print("Registrado na rede com sucesso.")
                            break
                        else:
                            print("Aguardando registro na rede... Tentando novamente em 5 segundos.")
                            time.sleep(5)
                elif cmd.startswith('AT#XMQTTCON'):
                    send_at_command(ser, cmd)
                    wait_for_mqtt_event(ser, expected_evt_type=0)
                elif cmd.startswith('AT#XMQTTPUB') and '""' in cmd:
                    send_at_command(ser, cmd)
                    print("Entrando em modo de dados. Iniciando envios de payloads...")

                    for i in range(74):
                        print(f"\n[Payload {i+1}/74]")

                        # Horário real de envio
                        t_envio = time.strftime("%H:%M:%S")
                        print(f"[{t_envio}] Enviando payload {i+1}")
                        ser.write(payload_total.encode())
                        ser.flush()

                        # Esperar evento e registrar horário real de recepção
                        t_ini_espera = time.time()
                        while (time.time() - t_ini_espera) < 10:
                            line = ser.readline()
                            #hexdump.hexdump(line,result='print')                            
                            line = line.decode(errors='ignore').strip()
                            if line:
                                t_recebido = time.strftime("%H:%M:%S")
                                print(f"[{t_recebido}] Recebido: {line}")
                                if line.startswith('#XMQTTEVT:'):
                                    try:
                                        parts = line.split(':')[1].split(',')
                                        evt_type = int(parts[0].strip())
                                        result = int(parts[1].strip())
                                        if evt_type == 6 and result == 0:
                                            break  # Evento correto recebido
                                    except:
                                        pass
                            else:
                                time.sleep(0.1)

                        else:
                            print(f"[{time.strftime('%H:%M:%S')}] Timeout aguardando evento 6,0. Abortando.")
                            break

                    ser.write(b'+++')
                    print("Envio finalizado. Saindo do modo de dados.")
                else:
                    send_at_command(ser, cmd)

    except serial.SerialException as e:
        print(f"Erro na serial: {e}")
    except Exception as e:
        print(f"Erro inesperado: {e}")

if __name__ == '__main__':
    main()

Parents
  • Hi,

    Have you observed any other communication issue apart from slower transfer on nrf9151-dk?

    Can you try to change your baudrate to 460800? What is the result?

    Which NCS version version do you use?

    Best regards,
    Dejan

    • Hi Dejan,

      Thanks for your response.

      I don’t think the baudrate is the limiting factor in this case. I’ve tested the nRF9151-DK using both 115200 and 921600 baudrates, and the data rate difference between the two is minimal.

      As an example, In the print attached is sent 300 kB of data over MQTT using the nRF9151-DK. The full transfer took approximately 85 seconds, resulting in a measured throughput of:

      - ~3.45 kB/s
      - ~3529 bytes/s
      - ~28.24 kbps

      This is significantly below the theoretical maximum data rate for LTE Cat-M1, which can reach up to **300 kbps downlink** and **375 kbps uplink** under ideal conditions. This suggests that the limitation is likely not on the link layer or UART baudrate, but instead somewhere higher up — possibly in the modem’s internal processing, MQTT handling..

      Here is a summary of my current setup:
      - nRF Connect SDK: v3.0.2
      - Toolchain: v3.0.2
      - Modem firmware: nrf9151dk_mfw-2.0.2_sdk-3.0.0
      - UART: Configured on UART2 with CONFIG_UART_2_NRF_HW_ASYNC=y and 921600 baudrate

      I’m happy to provide logs or test additional configurations if needed.



      # General system config
      CONFIG_LOG=y
      CONFIG_ASSERT=y
      CONFIG_ASSERT_VERBOSE=n
      CONFIG_LOG_DEFAULT_LEVEL=3
      CONFIG_STACK_SENTINEL=y
      CONFIG_PICOLIBC_IO_FLOAT=y
      CONFIG_RING_BUFFER=y
      CONFIG_REBOOT=y
      CONFIG_EVENTFD=y
      
      # Segger RTT config
      CONFIG_USE_SEGGER_RTT=y
      CONFIG_RTT_CONSOLE=y
      CONFIG_UART_CONSOLE=n
      CONFIG_LOG_BACKEND_RTT=y
      CONFIG_LOG_BACKEND_UART=n
      
      # Networking
      CONFIG_NETWORKING=y
      CONFIG_NET_SOCKETS=y
      CONFIG_NET_NATIVE=n
      CONFIG_NET_IPV4=y
      CONFIG_NET_IPV6=y
      
      # Modem
      CONFIG_NRF_MODEM_LIB=y
      CONFIG_AT_CMD_CUSTOM=y
      CONFIG_ZVFS_OPEN_MAX=8
      CONFIG_NRF_MODEM_LIB_ON_FAULT_APPLICATION_SPECIFIC=y
      
      # GPIO
      CONFIG_GPIO=y
      CONFIG_GPIO_NRFX=y
      
      # UART interface
      CONFIG_SERIAL=y
      CONFIG_UART_USE_RUNTIME_CONFIGURE=y
      CONFIG_UART_ASYNC_API=y
      CONFIG_NRFX_TIMER2=y
      
      # Stacks and heaps
      CONFIG_MAIN_STACK_SIZE=4096
      CONFIG_HEAP_MEM_POOL_SIZE=16384
      CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
      CONFIG_AT_MONITOR_HEAP_SIZE=4096
      
      # Power management
      CONFIG_PM_DEVICE=y
      
      # FOTA
      CONFIG_HTTP_PARSER_URL=y
      CONFIG_FOTA_DOWNLOAD=y
      CONFIG_FOTA_DOWNLOAD_PROGRESS_EVT=y
      CONFIG_DFU_TARGET=y
      CONFIG_DOWNLOADER=y
      CONFIG_DOWNLOADER_STACK_SIZE=4096
      CONFIG_DOWNLOADER_MAX_FILENAME_SIZE=2048
      CONFIG_BOOTLOADER_MCUBOOT=y
      CONFIG_IMG_MANAGER=y
      
      # Flash
      CONFIG_FLASH=y
      CONFIG_FLASH_PAGE_LAYOUT=y
      CONFIG_FLASH_MAP=y
      CONFIG_STREAM_FLASH=y
      CONFIG_MPU_ALLOW_FLASH_WRITE=y
      CONFIG_IMG_ERASE_PROGRESSIVELY=y
      
      # Settings
      CONFIG_SETTINGS=y
      CONFIG_SETTINGS_NVS=y
      CONFIG_NVS=y
      
      # nRF Cloud
      CONFIG_NRF_CLOUD=y
      CONFIG_NRF_CLOUD_MQTT=y
      CONFIG_NRF_CLOUD_FOTA=n
      CONFIG_NRF_CLOUD_AGNSS=y
      CONFIG_NRF_CLOUD_AGNSS_FILTERED=n
      CONFIG_NRF_CLOUD_PGPS=n
      CONFIG_NRF_CLOUD_LOCATION=y
      CONFIG_NRF_CLOUD_LOG_LEVEL_INF=y
      CONFIG_NRF_CLOUD_GPS_LOG_LEVEL_INF=y
      CONFIG_NRF_CLOUD_CLIENT_ID_SRC_INTERNAL_UUID=y
      CONFIG_NRF_CLOUD_WIFI_LOCATION_ENCODE_OPT_MAC_RSSI=y
      CONFIG_DATE_TIME=y
      CONFIG_MODEM_INFO=y
      CONFIG_MODEM_INFO_ADD_DATE_TIME=n
      
      # UUID and JWT
      CONFIG_MODEM_JWT=y
      
      # MQTT
      CONFIG_MQTT_CLEAN_SESSION=y
      
      # AT command helper
      CONFIG_AT_PARSER=y
      CONFIG_AT_MONITOR=y
      
      # TF-M logging
      CONFIG_TFM_LOG_LEVEL_SILENCE=y
      
      # SLM specific
      CONFIG_SLM_CUSTOMER_VERSION=""
      CONFIG_SLM_EXTERNAL_XTAL=n
      CONFIG_SLM_UART_RX_BUF_SIZE=512
      CONFIG_SLM_UART_TX_BUF_SIZE=512
      CONFIG_SLM_MQTTC_MESSAGE_BUFFER_LEN=4096
      CONFIG_SLM_NRF_CLOUD=n
      
      # Debug options (optional)
      #CONFIG_LOG_BUFFER_SIZE=16384
      #CONFIG_SLM_LOG_LEVEL_DBG=y
      #CONFIG_LOG_PRINTK=n
      #CONFIG_LOG_MODE_IMMEDIATE=y
      


      / {
      	chosen {
      		ncs,slm-uart = &uart2;
      	};
      };
      
      &uart0 {
      	compatible = "nordic,nrf-uarte";
      	current-speed = <115200>;
      	status = "disabled";
      	pinctrl-0 = <&uart0_default>;
      	pinctrl-1 = <&uart0_sleep>;
      	pinctrl-names = "default", "sleep";
      };
      
      &uart2 {
      	compatible = "nordic,nrf-uarte";
      	current-speed = <921600>;
      	status = "okay";
      	pinctrl-0 = <&uart2_default_alt>;
      	pinctrl-1 = <&uart2_sleep_alt>;
      	pinctrl-names = "default", "sleep";
      };
      
      &i2c2 {
      	status = "disabled";
      };
      
      &pinctrl {
      	uart0_default: uart0_default {
      		group1 {
      			psels = <NRF_PSEL(UART_TX, 0, 27)>;
      		};
      		group2 {
      			psels = <NRF_PSEL(UART_RX, 0, 26)>;
      			bias-pull-up;
      		};
      	};
      
      	uart0_sleep: uart0_sleep {
      		group1 {
      			psels = <NRF_PSEL(UART_TX, 0, 27)>,
      			        <NRF_PSEL(UART_RX, 0, 26)>;
      			low-power-enable;
      		};
      	};
      
      	uart2_default_alt: uart2_default_alt {
      		group1 {
      			psels = <NRF_PSEL(UART_RX, 0, 11)>;
      			bias-pull-up;
      		};
      		group2 {
      			psels = <NRF_PSEL(UART_TX, 0, 10)>;
      		};
      	};
      
      	uart2_sleep_alt: uart2_sleep_alt {
      		group1 {
      			psels = <NRF_PSEL(UART_TX, 0, 10)>,
      			        <NRF_PSEL(UART_RX, 0, 11)>;
      			low-power-enable;
      		};
      	};
      };
      
      &gd25wb256 {
      	status = "okay";
      };
      
      &clock {
      	status = "okay";
      };
      
      &timer2 {
      	status = "okay";
      };
      
      &power {
      	status = "okay";
      };
      

  • Hello Øyvind,

    I have captured a new modem trace, making sure to press the reset button on the DK right after starting the trace in the Cellular Monitor to include the full start-up sequence. The trace was run for 30 minutes.

    On a positive note, it seems the issue with the SIM card has been resolved. I was able to verify its connectivity and status on our carrier's dashboard before this test.

    The new trace file is attached. Please let me know if this provides the necessary information from the start-up.

    Kind regards,

    Lucas

    trace-2025-08-22T13-04-49.595Z.mtrace

  • Thanks for sharing a new modem trace. Glad to hear that SIM issue is resolved. I assume that you are still using the same SIM?

  • Yes, that's correct. This trace was captured using one of the original Claro SIM cards.

    My initial thought was that the SIM itself wasn't the root cause, as I had tested with two different cards and both were functioning correctly.

    Let me know what you find in the new trace.

  • Hi, our modem team have tried to look into this and provided the following feedback:

    the log again does not contain any data transfer. There isn’t even LTE attach in the log, but modem is already attached when the log starts. The log is 30 minutes long, so that matches the description. Also, RRC connection gets only activated once in the log. It happens because of a tracking area update 5 minutes before the log ends and the RRC connection is active only for ~200 ms.

    I have assumed that the logs should contain data transfer, because the original issue was data throughput issue with nRF9151, but I have not seen any data transfer in any of the logs. There isn’t any socket RPC messages and RRC connection isn’t active either, so the modem can not be transmitting any data. So, just wondering where the data is actually going.

    To verify what my colleague is asking, is the data transfer just over UART or via modem?

    Kind regards,
    Øyvind

  • Hello Øyvind,

    Thank you for the detailed feedback and clarification. My apologies for the misunderstanding—I misinterpreted the request and captured the previous logs to show the modem's general connection behavior, not an active data transfer.

    To confirm, our application is designed to send data via the modem over an LTE connection.

    I have now captured a new trace, this time during an active data transfer. The log covers the entire process of my script sending a 300kB payload, which took approximately two minutes to complete.

    The new trace is attached to this reply. Please let me know if this is sufficient. If you still need a longer, 30-minute trace that includes continuous data transfer, I can certainly provide that, but please be aware the log file will be quite large.

    Kind regards,

    Lucas
    trace-2025-08-26T13-24-25.085Z.mtrace

Reply
  • Hello Øyvind,

    Thank you for the detailed feedback and clarification. My apologies for the misunderstanding—I misinterpreted the request and captured the previous logs to show the modem's general connection behavior, not an active data transfer.

    To confirm, our application is designed to send data via the modem over an LTE connection.

    I have now captured a new trace, this time during an active data transfer. The log covers the entire process of my script sending a 300kB payload, which took approximately two minutes to complete.

    The new trace is attached to this reply. Please let me know if this is sufficient. If you still need a longer, 30-minute trace that includes continuous data transfer, I can certainly provide that, but please be aware the log file will be quite large.

    Kind regards,

    Lucas
    trace-2025-08-26T13-24-25.085Z.mtrace

Children
  • HI Lucas, no worries, and thanks for providing a new trace. Appreciate the patience! 

    The important part of the trace is to see activity from reset, in order to analyze the SIM communication, and then the data transfer to determine what is causing the bottleneck. I will forward the modem trace to our team and hope to have some feedback by end of tomorrow. 

    Kind regards,
    Øyvind

  • Hello again,  here is the feedback I got:

    now it looks like I expected. There are no obvious problems, but a lot of time is spent waiting for TCP ACKs and MQTT messages from the server, i.e. not transmitting data. Would it be possible for the customer to capture a reference log with nRF9160? It would be helpful to see the difference in a modem log.

    Can you please capture one from nRF9160 in the environment?

    Thanks!

    Kind regards,
    Øyvind

  • Hello Øyvind,

    Thank you for analyzing the trace and for the insightful feedback. It is very helpful to know that the delay seems to be related to waiting for TCP ACKs and server responses.

    I will capture the reference log with the nRF9160 under the same test conditions. I expect to have this for you by the end of this week.

    Regarding the delays, you mentioned the modem is spending a lot of time waiting. In your experience, is this type of latency typically caused by the cellular network itself? We are testing on the Claro network here in Brazil.

    To rule out the server, we have already tested this with both a private and a public MQTT broker and observed similar transmission times, which leads us to suspect the network might be the primary factor.

    I look forward to your thoughts and will send the nRF9160 trace as soon as it's ready.

    Kind regards,

    Lucas

  • Hi Lucas,

    There is naturally some roundtrip delay caused by LTE-M. The way data is sent is currently is not optimal. I’m not that familiar with MQTT, but in the log each MQTT message is used to send a few kBs of data. After each MQTT message, the device waits for acknowledgement before it starts sending the next message. Could more data be sent in each MQTT message, or even the whole payload at once?

    That said, we asked for the nRF9160 log to see why it does not suffer from similar delays.

    Kind regards,
    Øyvind

Related