Hello,
I want to send data from peripheral devices to central device. My peripheral device code is based on "ble_peripheral_uart" sample and my central device code is based on "Multi NUS" sample.
https://github.com/NordicMatt/multi-NUS
I am checking difference between timestamps in every data packet (timestamp is from peripheral device, so it is from the sending moment).
When I connect peripheral device with nRF Connect app on android phone everything is OK. Difference between timestamps are 8ms sometimes 9ms.
But when I connect peripheral device to Multi NUS there is problem. Every 5th data packet have bigger difference in timestamp.
Interesting is it, that average difference between data frames is about 12 ms. It doesn't matter if peripheral device is sending data every 8ms or every 10ms average is 12ms, because in 8ms case difference between 4th timestamp and 5th timestamp is bigger than in 10ms case.
Annother interesting thing is it, that when I connect second peripheral device to Multi NUS it's not worse, but this problem happens for two devices.
I am sending data (17 Bytes) every 8ms, but I have problem with receiving it with Multi NUS application.
Below is picture presenting what is in my data:
Below are my codes changes snippets:
Peripheral UART:
// Peripheral UART (code snippets - changes) ... // --------------======================-----------------------========================--------------------=====================--------------------- struct bt_conn *my_conn = NULL; void on_le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, uint16_t timeout) { double connection_interval = interval*1.25; // in ms uint16_t supervision_timeout = timeout*10; // in ms LOG_INF("Connection parameters updated: interval %.2f ms, latency %d intervals, timeout %d ms", connection_interval, latency, supervision_timeout); } /* STEP 7.1 - Define the function to update the connection's PHY */ static void update_phy(struct bt_conn *conn) // Preferowany PHY { int err; const struct bt_conn_le_phy_param preferred_phy = { .options = BT_CONN_LE_PHY_OPT_NONE, .pref_rx_phy = BT_GAP_LE_PHY_2M, .pref_tx_phy = BT_GAP_LE_PHY_2M, // .pref_rx_phy = BT_GAP_LE_PHY_CODED, // .pref_tx_phy = BT_GAP_LE_PHY_CODED, }; err = bt_conn_le_phy_update(conn, &preferred_phy); if (err) { LOG_ERR("bt_conn_le_phy_update() returned %d", err); } } /* STEP 8.1 - Write a callback function to inform about updates in the PHY */ void on_le_phy_updated(struct bt_conn *conn, struct bt_conn_le_phy_info *param) { // PHY Updated if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_1M) { LOG_INF("PHY updated. New PHY: 1M"); } else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_2M) { LOG_INF("PHY updated. New PHY: 2M"); } else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_CODED_S8) { LOG_INF("PHY updated. New PHY: Long Range"); } } // --------------======================-----------------------========================--------------------=====================--------------------- ... static void connected(struct bt_conn *conn, uint8_t err) { char addr[BT_ADDR_LE_STR_LEN]; if (err) { LOG_ERR("Connection failed (err %u)", err); return; } bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); LOG_INF("Connected %s", addr); // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// my_conn = bt_conn_ref(conn); // dk_set_led(CONNECTION_STATUS_LED, 1); /* STEP 1.1 - Declare a structure to store the connection parameters */ struct bt_conn_info info; err = bt_conn_get_info(conn, &info); if (err) { LOG_ERR("bt_conn_get_info() returned %d", err); return; } /* STEP 7.2 - Update the PHY mode */ update_phy(my_conn); // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// current_conn = bt_conn_ref(conn); dk_set_led_on(CON_STATUS_LED); is_conn = true; ///////////////////////////////////////////////////////////////// LOG_INF("BLE address: %s\n", addr); LOG_WRN("BLE address: %s\n", addr); LOG_ERR("BLE address: %s\n", addr); printk("BLE address: %s\n", addr); } static void disconnected(struct bt_conn *conn, uint8_t reason) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); LOG_INF("Disconnected: %s (reason %u)", addr, reason); if (auth_conn) { bt_conn_unref(auth_conn); auth_conn = NULL; } if (current_conn) { bt_conn_unref(current_conn); current_conn = NULL; dk_set_led_off(CON_STATUS_LED); is_conn = false; ///////////////////////////////////////////////////////////////// } // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bt_conn_unref(my_conn); // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } #ifdef CONFIG_BT_NUS_SECURITY_ENABLED static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err) { char addr[BT_ADDR_LE_STR_LEN]; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if (!err) { LOG_INF("Security changed: %s level %u", addr, level); } else { LOG_WRN("Security failed: %s level %u err %d", addr, level, err); } } #endif BT_CONN_CB_DEFINE(conn_callbacks) = { .connected = connected, .disconnected = disconnected, .le_param_updated = on_le_param_updated, /* STEP 8.3 - Add the callback for PHY mode updates */ .le_phy_updated = on_le_phy_updated, #ifdef CONFIG_BT_NUS_SECURITY_ENABLED .security_changed = security_changed, #endif }; ... uint8_t data_send_table[] = {0xFF, 0xAA, 0xBB, 0xCC, 0x00, 0x00, 0x22, 0x33, 0x00, 0x00, 0x55, 0x5A, 0xAA, 0xBB, 0x00, 0x00, 0x01}; void update_data_send_table(uint32_t variable) { data_send_table[0] = (variable >> 24) & 0xFF; data_send_table[1] = (variable >> 16) & 0xFF; data_send_table[2] = (variable >> 8) & 0xFF; data_send_table[3] = variable & 0xFF; } void update_data_send_table_iter_counter(uint32_t iter_counter) { data_send_table[10] = (iter_counter >> 24) & 0xFF; data_send_table[11] = (iter_counter >> 16) & 0xFF; data_send_table[12] = (iter_counter >> 8) & 0xFF; data_send_table[13] = iter_counter & 0xFF; } void update_data_send_table_iter_counter_TEST(uint32_t iter_counter) { data_send_table[6] = (iter_counter >> 24) & 0xFF; data_send_table[7] = (iter_counter >> 16) & 0xFF; data_send_table[8] = (iter_counter >> 8) & 0xFF; data_send_table[9] = iter_counter & 0xFF; } void print_data_send_table() { for (int i = 0; i < sizeof(data_send_table); i++) { printf("0x%02X ", data_send_table[i]); } printf("\n"); } ... int main(void) { ... } ... void ble_write_NUM_thread(void){ k_sem_take(&ble_init_ok, K_FOREVER); for (;;) { timer_state = k_uptime_get(); update_data_send_table(timer_state); // timer state update_data_send_table_iter_counter(iter_counter); uint8_t *iter_counter_t_d = data_send_table; uint16_t size_t_d = sizeof(data_send_table); LOG_WRN(":%u;\n", iter_counter); if (bt_nus_send(my_conn, iter_counter_t_d, size_t_d)) { LOG_WRN("Failed to send --TEST-- data over BLE connection"); } iter_counter++; // k_msleep(10); k_msleep(8); } } K_THREAD_DEFINE(ble_write_NUM_thread_id, STACKSIZE, ble_write_NUM_thread, NULL, NULL, NULL, 1, 0, 0);
Multi NUS:
// Multi NUS (code snippets - changes) ... // --------------======================-----------------------========================--------------------=====================--------------------- struct bt_conn *my_conn = NULL; void on_le_param_updated(struct bt_conn *conn, uint16_t interval, uint16_t latency, uint16_t timeout) { double connection_interval = interval*1.25; // in ms uint16_t supervision_timeout = timeout*10; // in ms LOG_INF("Connection parameters updated: interval %.2f ms, latency %d intervals, timeout %d ms", connection_interval, latency, supervision_timeout); } /* STEP 7.1 - Define the function to update the connection's PHY */ static void update_phy(struct bt_conn *conn) // Preferowany PHY { int err; const struct bt_conn_le_phy_param preferred_phy = { .options = BT_CONN_LE_PHY_OPT_NONE, .pref_rx_phy = BT_GAP_LE_PHY_2M, .pref_tx_phy = BT_GAP_LE_PHY_2M, // .pref_rx_phy = BT_GAP_LE_PHY_CODED, // .pref_tx_phy = BT_GAP_LE_PHY_CODED, }; err = bt_conn_le_phy_update(conn, &preferred_phy); if (err) { LOG_ERR("bt_conn_le_phy_update() returned %d", err); } } /* STEP 8.1 - Write a callback function to inform about updates in the PHY */ void on_le_phy_updated(struct bt_conn *conn, struct bt_conn_le_phy_info *param) { // PHY Updated if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_1M) { LOG_INF("PHY updated. New PHY: 1M"); } else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_2M) { LOG_INF("PHY updated. New PHY: 2M"); } else if (param->tx_phy == BT_CONN_LE_TX_POWER_PHY_CODED_S8) { LOG_INF("PHY updated. New PHY: Long Range"); } } // --------------======================-----------------------========================--------------------=====================--------------------- ... uint32_t timer_state = 0; uint32_t timer_recv_data = 0; static uint8_t ble_data_received(struct bt_nus_client *nus,const uint8_t *const data, uint16_t len) { int err; char text_buffer[64]; // char text_buffer[32]; char temp_buffer[16]; for (uint16_t pos = 0; pos != len;) { struct uart_data_t *tx = k_malloc(sizeof(*tx)); if (!tx) { LOG_WRN("Not able to allocate UART send data buffer"); return BT_GATT_ITER_CONTINUE; } /* Keep the last byte of TX buffer for potential LF char. */ size_t tx_data_size = sizeof(tx->data) - 1; if ((len - pos) > tx_data_size) { tx->len = tx_data_size; } else { tx->len = (len - pos); } // memcpy(tx->data, &data[pos], tx->len); pos += tx->len; /* Append the LF character when the CR character triggered * transmission from the peer. */ if ((pos == len) && (data[len - 1] == '\r')) { tx->data[tx->len] = '\n'; tx->len++; } /* Routed messages. See the comments above. * Check for *, if there's a star, send it over to the multi-nus send function */ if (( data[0] == '*') || (routedMessage == true) ) { multi_nus_send(tx); } // // // ------------------------------------------------------------------------------------------------------------------------------- timer_recv_data = k_uptime_get(); timer_state = k_uptime_get(); uint32_t prev = timer_state; LOG_INF("Received data: "); for (int i = 0; i < len; i++) { // printk("%02X ", data[i]); ///* if(i == 0) { snprintf(text_buffer, sizeof(text_buffer), "%02X", data[i]); // Writes a number in hexadecimal format } else { snprintf(temp_buffer, sizeof(temp_buffer), "%02X", data[i]); // Writes a number in hexadecimal format strcat(text_buffer, temp_buffer); } } // printk("\n"); // strcat(text_buffer, ";\r\n"); strcat(text_buffer, ";"); char tmp_index[16]; snprintf(tmp_index, sizeof(tmp_index), "%d", bt_conn_get_dst(nus->conn)); strcat(text_buffer, tmp_index); strcat(text_buffer, "\r\n"); // printk("text_buffer = %s\n", text_buffer); printk("\n\tTimer_recv_data: %u \t %s\n", timer_recv_data, text_buffer); timer_state = k_uptime_get(); uint32_t difference_pars = timer_state - prev; printk("\tParsing data time: %u ms\n", difference_pars); uint32_t prev_do_uart = timer_state; uint16_t txt_buff_size = strlen(text_buffer); tx->len = txt_buff_size; memcpy(tx->data, text_buffer, tx->len); // // // ------------------------------------------------------------------------------------------------------------------------------- err = uart_tx(uart, tx->data, tx->len, SYS_FOREVER_MS); if (err) { k_fifo_put(&fifo_uart_tx_data, tx); } timer_state = k_uptime_get(); uint32_t to_uart_difference = timer_state - prev_do_uart; printk("\t\t UART data send time: %u ms\n", to_uart_difference); } return BT_GATT_ITER_CONTINUE; } ... static void connected(struct bt_conn *conn, uint8_t conn_err) { char addr[BT_ADDR_LE_STR_LEN]; int err; /* struct bt_nus_client_init_param init = { .cb = { .received = ble_data_received, .sent = ble_data_sent, } }; */ bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); if (conn_err) { LOG_INF("Failed to connect to %s (%d)", addr,conn_err); if (default_conn == conn) { bt_conn_unref(default_conn); default_conn = NULL; err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE); if (err) { LOG_ERR("Scanning failed to start (err %d)", err); } } return; } LOG_INF("Connected: %s", addr); // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// my_conn = bt_conn_ref(conn); // dk_set_led(CONNECTION_STATUS_LED, 1); /* STEP 1.1 - Declare a structure to store the connection parameters */ struct bt_conn_info info; err = bt_conn_get_info(conn, &info); if (err) { LOG_ERR("bt_conn_get_info() returned %d", err); return; } /* STEP 7.2 - Update the PHY mode */ update_phy(my_conn); // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /*Allocate memory for this connection using the connection context library. For reference, this code was taken from hids.c */ struct bt_nus_client *nus_client =bt_conn_ctx_alloc(&conns_ctx_lib, conn); if (!nus_client) { LOG_WRN("There is no free memory to " "allocate the connection context"); } struct bt_nus_client_init_param init = { .cb = { .received = ble_data_received, .sent = ble_data_sent, } }; memset(nus_client, 0, bt_conn_ctx_block_size_get(&conns_ctx_lib)); err = bt_nus_client_init(nus_client, &init); bt_conn_ctx_release(&conns_ctx_lib, (void *)nus_client); if (err) { LOG_ERR("NUS Client initialization failed (err %d)", err); }else{ LOG_INF("NUS Client module initialized"); } gatt_discover(conn); /*Stop scanning during the discovery*/ err = bt_scan_stop(); if ((!err) && (err != -EALREADY)) { LOG_ERR("Stop LE scan failed (err %d)", err); } LOG_INF("BLE address: %s\n", addr); LOG_WRN("BLE address: %s\n", addr); LOG_ERR("BLE address: %s\n", addr); printk("BLE address: %s\n", addr); } static void disconnected(struct bt_conn *conn, uint8_t reason) { char addr[BT_ADDR_LE_STR_LEN]; int err; bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); LOG_INF("Disconnected: %s (reason %u)", addr,reason); err = bt_conn_ctx_free(&conns_ctx_lib, conn); if (err) { LOG_WRN("The memory was not allocated for the context of this " "connection."); } bt_conn_unref(conn); default_conn = NULL; // err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE); // if (err) { // LOG_ERR("Scanning failed to start (err %d)", // err); // } // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bt_conn_unref(my_conn); // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } ... static struct bt_conn_cb conn_callbacks = { .connected = connected, .disconnected = disconnected, // .security_changed = security_changed .security_changed = security_changed, .le_param_updated = on_le_param_updated, /* STEP 8.3 - Add the callback for PHY mode updates */ .le_phy_updated = on_le_phy_updated, }; ...
Below is log from UART (from Multi NUS device)
COM11_2024_10_22.17.47.05.386.txt
and python program to analyze it (you have to change 'path_for_file' variable and log name to "data")
import binascii from collections import defaultdict def is_hex(s): try: int(s, 16) return True except ValueError: return False # Function to process the lines and perform the subtraction for timestamps def process_timestamps(lines): results = [] for i in range(len(lines) - 1): # Extract the 8 hex digits from each line hex1 = lines[i][:8] hex2 = lines[i + 1][:8] # Convert hex to integers int1 = int(hex1, 16) int2 = int(hex2, 16) # Perform the subtraction diff = int2 - int1 # Convert the difference to decimal and hex diff_decimal = diff diff_hex = format(diff, 'x').upper() # Format the result string result = f"{hex1} - {hex2} = {diff_decimal} = {diff_hex}" results.append(result) return results # Function to process the lines and perform the subtraction for increments def process_increments(lines): results = [] for i in range(len(lines) - 1): # Extract the 8 hex digits from each line hx_check = lines[i][20:28] if is_hex(hx_check): hex1 = lines[i][20:28] else: hex1 = "0" hx_check = lines[i + 1][20:28] if is_hex(hx_check): hex2 = lines[i + 1][20:28] else: hex2 = "1" # Convert hex to integers int1 = int(hex1, 16) int2 = int(hex2, 16) # Perform the subtraction diff = int2 - int1 # Convert the difference to decimal and hex diff_decimal = diff diff_hex = format(diff, 'x').upper() # Format the result string result = f"{hex1} - {hex2} = {diff_decimal} = {diff_hex}" results.append(result) return results # Function to calculate summary statistics def calculate_summary(lines, x): summary_results = [] # Difference between the 10th frame and the 5th from the end if len(lines) >= 15: hex_10th_timestamp = lines[9][:8] hex_5th_from_end_timestamp = lines[-5][:8] hex_10th_increment = lines[9][20:28] hex_5th_from_end_increment = lines[-5][20:28] timestamp_diff_decimal = int(hex_5th_from_end_timestamp, 16) - int(hex_10th_timestamp, 16) increment_diff_decimal = int(hex_5th_from_end_increment, 16) - int(hex_10th_increment, 16) summary_results.append(f"Difference between 10th frame and 5th from end (timestamp): {timestamp_diff_decimal}") summary_results.append(f"Difference between 10th frame and 5th from end (increment): {increment_diff_decimal}") # Check if increments go sequentially and count mismatches mismatches_count = 0 for i in range(len(lines) - 1): increment_current = int(lines[i][20:28], 16) increment_next = int(lines[i + 1][20:28], 16) if increment_next != increment_current + 1: mismatches_count += 1 summary_results.append(f"Number of mismatches in increments: {mismatches_count}") # Calculate average difference in timestamps total_diff_timestamps = sum(int(lines[i + 1][:8], 16) - int(lines[i][:8], 16) for i in range(len(lines) - 1)) avg_diff_timestamps = total_diff_timestamps / (len(lines) - 1) summary_results.append(f"Average difference in timestamps: {avg_diff_timestamps}") # Count cases where timestamp difference is greater than x and calculate percentage count_greater_than_x = sum(1 for i in range(len(lines) - 1) if (int(lines[i + 1][:8], 16) - int(lines[i][:8], 16)) > x) percentage_greater_than_x = (count_greater_than_x / (len(lines) - 1)) * 100 summary_results.append(f"Number of cases where timestamp difference is greater than {x}: {count_greater_than_x}") summary_results.append(f"Percentage of cases where timestamp difference is greater than {x}: {percentage_greater_than_x:.2f}%") # Total number of frames received total_frames_received = len(lines) summary_results.append(f"Total number of frames received: {total_frames_received}") return summary_results # Main function to handle file reading and processing def main(): input_file = 'data.txt' path_for_files = 'D://YOUR//PATH//' input_file = path_for_files + input_file malformed_packet = 0 try: with open(input_file, 'r') as file: lines = file.readlines() except FileNotFoundError: print("Input file not found") return # Group lines by device ID device_logs = defaultdict(list) for line in lines: if line.strip() == "": continue # if len(line.strip().split(';')[0]) == 34 and len(line.strip().split(';')[1]) == 9 and ';' in line: if ';' in line and len(line.strip().split(';')[0]) == 34 and len(line.strip().split(';')[1]) == 9: try: data, device_id = line.strip().split(';') device_logs[device_id].append(data) except ValueError: print(f"Malformed line: {line.strip()}") malformed_packet += 1 else: print(f"Malformed line: {line.strip()}") malformed_packet += 1 # Process each device's logs separately # x_value = 1000 # Example value for x # x_value = 10 # 10ms # x_value = 11 # x_value = 9 for device_id, device_lines in device_logs.items(): # Process timestamps and increments timestamp_results = process_timestamps(device_lines) increment_results = process_increments(device_lines) # Write timestamp results to file with open(f'{path_for_files}results_timestamp_difference{device_id}.txt', 'w') as file: file.write(f'\tFor device ID: {device_id}\n') for result in timestamp_results: file.write(result + '\n') # Write increment results to file with open(f'{path_for_files}results_counter_difference_{device_id}.txt', 'w') as file: file.write(f'\tFor device ID: {device_id}\n') for result in increment_results: file.write(result + '\n') # Calculate summary statistics summary_results = calculate_summary(device_lines, x_value) # Write summary results to file with open(f'{path_for_files}results_summary_{device_id}.txt', 'w') as file: file.write(f'\tFor device ID: {device_id}\n') for result in summary_results: file.write(result + '\n') print("Processing complete. Results have been written to respective files for each device.") print(f"Number of malformed packets: {malformed_packet}") if __name__ == "__main__": main()
Below therare is example outputs from analyzer program (10ms case and 8ms case)
Output from different logs 10ms case: 00B00FAE - 00B00FB9 = 11 = B 00B00FB9 - 00B00FC3 = 10 = A 00B00FC3 - 00B00FCD = 10 = A 00B00FCD - 00B00FD7 = 10 = A 00B00FD7 - 00B00FEA = 19 = 13 00B00FEA - 00B00FF5 = 11 = B 00B00FF5 - 00B00FFF = 10 = A 00B00FFF - 00B01009 = 10 = A 00B01009 - 00B01013 = 10 = A 00B01013 - 00B01026 = 19 = 13 00B01026 - 00B01031 = 11 = B 00B01031 - 00B0103B = 10 = A 00B0103B - 00B01045 = 10 = A 00B01045 - 00B0104F = 10 = A 00B0104F - 00B01062 = 19 = 13 00B01062 - 00B0106D = 11 = B 00B0106D - 00B01077 = 10 = A 00B01077 - 00B01081 = 10 = A 00B01081 - 00B0108B = 10 = A 00B0108B - 00B0109E = 19 = 13 00B0109E - 00B010A9 = 11 = B 00B010A9 - 00B010B3 = 10 = A 00B010B3 - 00B010BD = 10 = A 00B010BD - 00B010C7 = 10 = A 00B010C7 - 00B010DA = 19 = 13 00B010DA - 00B010E5 = 11 = B 00B010E5 - 00B010EF = 10 = A 00B010EF - 00B010F9 = 10 = A 00B010F9 - 00B01103 = 10 = A 00B01103 - 00B01116 = 19 = 13 00B01116 - 00B01121 = 11 = B 00B01121 - 00B0112B = 10 = A 00B0112B - 00B01135 = 10 = A 00B01135 - 00B0113F = 10 = A 00B0113F - 00B01152 = 19 = 13 00B01152 - 00B0115D = 11 = B 00B0115D - 00B01167 = 10 = A 00B01167 - 00B01171 = 10 = A 00B01171 - 00B0117B = 10 = A 00B0117B - 00B0118E = 19 = 13 00B0118E - 00B01199 = 11 = B 00B01199 - 00B011A3 = 10 = A 00B011A3 - 00B011AD = 10 = A 00B011AD - 00B011B7 = 10 = A 00B011B7 - 00B011CA = 19 = 13 00B011CA - 00B011D5 = 11 = B 00B011D5 - 00B011DF = 10 = A 00B011DF - 00B011E9 = 10 = A 00B011E9 - 00B011F3 = 10 = A 00B011F3 - 00B01206 = 19 = 13 00B01206 - 00B01211 = 11 = B 00B01211 - 00B0121B = 10 = A 00B0121B - 00B01225 = 10 = A 00B01225 - 00B0122F = 10 = A 00B0122F - 00B01242 = 19 = 13 00B01242 - 00B0124D = 11 = B 00B0124D - 00B01257 = 10 = A 00B01257 - 00B01261 = 10 = A 00B01261 - 00B0126B = 10 = A 00B0126B - 00B0127E = 19 = 13 00B0127E - 00B01289 = 11 = B 00B01289 - 00B01293 = 10 = A 00B01293 - 00B0129D = 10 = A 00B0129D - 00B012A7 = 10 = A 00B012A7 - 00B012BA = 19 = 13 00B012BA - 00B012C5 = 11 = B 00B012C5 - 00B012CF = 10 = A 00B012CF - 00B012D9 = 10 = A 00B012D9 - 00B012E3 = 10 = A 00B012E3 - 00B012F6 = 19 = 13 00B012F6 - 00B01301 = 11 = B 00B01301 - 00B0130B = 10 = A 00B0130B - 00B01315 = 10 = A 00B01315 - 00B0131F = 10 = A 00B0131F - 00B01332 = 19 = 13 00B01332 - 00B0133D = 11 = B 00B0133D - 00B01347 = 10 = A 00B01347 - 00B01351 = 10 = A 00B01351 - 00B0135B = 10 = A 00B0135B - 00B0136E = 19 = 13 00B0136E - 00B01379 = 11 = B 00B01379 - 00B01383 = 10 = A 00B01383 - 00B0138D = 10 = A 00B0138D - 00B01397 = 10 = A 00B01397 - 00B013AA = 19 = 13 00B013AA - 00B013B5 = 11 = B 00B013B5 - 00B013BF = 10 = A 00B013BF - 00B013C9 = 10 = A 00B013C9 - 00B013D3 = 10 = A 00B013D3 - 00B013E6 = 19 = 13 00B013E6 - 00B013F1 = 11 = B 00B013F1 - 00B013FB = 10 = A 00B013FB - 00B01405 = 10 = A 00B01405 - 00B0140F = 10 = A 00B0140F - 00B01422 = 19 = 13 00B01422 - 00B0142D = 11 = B 00B0142D - 00B01437 = 10 = A 00B01437 - 00B01441 = 10 = A 00B01441 - 00B0144B = 10 = A 00B0144B - 00B0145E = 19 = 13 00B0145E - 00B01469 = 11 = B 00B01469 - 00B01473 = 10 = A 00B01473 - 00B0147D = 10 = A 00B0147D - 00B01487 = 10 = A 00B01487 - 00B0149A = 19 = 13 00B0149A - 00B014A5 = 11 = B 00B014A5 - 00B014AF = 10 = A 00B014AF - 00B014B9 = 10 = A 00B014B9 - 00B014C3 = 10 = A 00B014C3 - 00B014D6 = 19 = 13 8ms case: 01548F1F - 01548F3B = 28 = 1C 01548F3B - 01548F43 = 8 = 8 01548F43 - 01548F4B = 8 = 8 01548F4B - 01548F54 = 9 = 9 01548F54 - 01548F5C = 8 = 8 01548F5C - 01548F77 = 27 = 1B 01548F77 - 01548F7F = 8 = 8 01548F7F - 01548F87 = 8 = 8 01548F87 - 01548F90 = 9 = 9 01548F90 - 01548F98 = 8 = 8 01548F98 - 01548FB3 = 27 = 1B 01548FB3 - 01548FBB = 8 = 8 01548FBB - 01548FC3 = 8 = 8 01548FC3 - 01548FCC = 9 = 9 01548FCC - 01548FD4 = 8 = 8 01548FD4 - 01548FEF = 27 = 1B 01548FEF - 01548FF7 = 8 = 8 01548FF7 - 01548FFF = 8 = 8 01548FFF - 01549008 = 9 = 9 01549008 - 01549010 = 8 = 8 01549010 - 0154902B = 27 = 1B 0154902B - 01549033 = 8 = 8 01549033 - 0154903B = 8 = 8 0154903B - 01549044 = 9 = 9 01549044 - 0154904C = 8 = 8 0154904C - 01549067 = 27 = 1B 01549067 - 0154906F = 8 = 8 0154906F - 01549077 = 8 = 8 01549077 - 01549080 = 9 = 9 01549080 - 01549088 = 8 = 8 01549088 - 015490A3 = 27 = 1B 015490A3 - 015490AB = 8 = 8 015490AB - 015490B3 = 8 = 8 015490B3 - 015490BC = 9 = 9 015490BC - 015490C4 = 8 = 8 015490C4 - 015490DF = 27 = 1B 015490DF - 015490E7 = 8 = 8 015490E7 - 015490EF = 8 = 8 015490EF - 015490F8 = 9 = 9 015490F8 - 01549100 = 8 = 8 01549100 - 0154911B = 27 = 1B 0154911B - 01549123 = 8 = 8 01549123 - 0154912B = 8 = 8 0154912B - 01549134 = 9 = 9 01549134 - 0154913C = 8 = 8 0154913C - 01549157 = 27 = 1B 01549157 - 0154915F = 8 = 8 0154915F - 01549167 = 8 = 8 01549167 - 01549170 = 9 = 9 01549170 - 01549178 = 8 = 8 01549178 - 0154919A = 34 = 22 0154919A - 015491A2 = 8 = 8 015491A2 - 015491AB = 9 = 9 015491AB - 015491B3 = 8 = 8 015491B3 - 015491D6 = 35 = 23 015491D6 - 015491DE = 8 = 8 015491DE - 015491E7 = 9 = 9 015491E7 - 015491EF = 8 = 8 015491EF - 0154920B = 28 = 1C 0154920B - 01549213 = 8 = 8 01549213 - 0154921B = 8 = 8 0154921B - 01549224 = 9 = 9 01549224 - 0154922C = 8 = 8 0154922C - 01549247 = 27 = 1B 01549247 - 0154924F = 8 = 8 0154924F - 01549257 = 8 = 8 01549257 - 01549260 = 9 = 9 01549260 - 01549268 = 8 = 8 01549268 - 01549283 = 27 = 1B 01549283 - 0154928B = 8 = 8 0154928B - 01549293 = 8 = 8 01549293 - 0154929C = 9 = 9 0154929C - 015492A4 = 8 = 8 015492A4 - 015492BF = 27 = 1B 015492BF - 015492C7 = 8 = 8 015492C7 - 015492CF = 8 = 8 015492CF - 015492D8 = 9 = 9 015492D8 - 015492E0 = 8 = 8 015492E0 - 015492FB = 27 = 1B 015492FB - 01549303 = 8 = 8 01549303 - 0154930B = 8 = 8 0154930B - 01549314 = 9 = 9 01549314 - 0154931C = 8 = 8 0154931C - 01549337 = 27 = 1B 01549337 - 0154933F = 8 = 8 0154933F - 01549347 = 8 = 8 01549347 - 01549350 = 9 = 9 01549350 - 01549358 = 8 = 8 01549358 - 01549373 = 27 = 1B 01549373 - 0154937B = 8 = 8 0154937B - 01549383 = 8 = 8 01549383 - 0154938C = 9 = 9 0154938C - 01549394 = 8 = 8 01549394 - 015493AF = 27 = 1B 015493AF - 015493B7 = 8 = 8 015493B7 - 015493BF = 8 = 8 015493BF - 015493C8 = 9 = 9 015493C8 - 015493D0 = 8 = 8 015493D0 - 015493EB = 27 = 1B 015493EB - 015493F3 = 8 = 8 015493F3 - 015493FB = 8 = 8 015493FB - 01549404 = 9 = 9 01549404 - 0154940C = 8 = 8 0154940C - 01549427 = 27 = 1B
Can you help me resolve this problem?
Best Regards