Sending and Receiving Data over Bluetooth via Nicla Vision Camera and Raspberry Pi 4

Hello,
The following code in OpenMV will send the outputs to the Raspberry Pi over Bluetooth but the Raspberry Pi (Central Device) is only reading the last output. Is this a timing issue or an issue in the code? Any thing will help. The code used for the transmission is below.


def _encode_dist(dist):
    return struct.pack("<h", int(dist))

def _decode_data(data):
    try:
        print(f"Raw data: {data}, Type: {type(data)}")
        if data is None or not isinstance(data, bytes):
            print("No valid data received or data is not bytes")
            return None
        decoded_data = struct.unpack("<h", data)[0]
        print(f"Decoded data: {decoded_data}")
        return decoded_data
    except Exception as e:
        print(f"Error decoding data: {e}")
        return None
async def send_ack():
    print("Sending acknowledgement")
    ack_value = 1
    ACK_characteristic.write(_encode_dist(ack_value))
    await asyncio.sleep(0.1)
    print("ACK sent")

elif case_select == 2:
        print('Executing case 2: Scan for elevator buttons')
        #measure distance away, send (x,y,z)')
        detected_buttons = ScanForButtons()
        z_coord = MeasureDistance()
        print(f"z coord data:{z_coord}")
        dist_characteristic.write(_encode_dist(z_coord))



        if detected_buttons:
            number_labels = len(detected_buttons)
            print(f"number: {number_labels}")
            
            numlabels_characteristic.write(_encode_dist(number_labels))
            await asyncio.sleep(0.2)
            await wait_for_ack()
           

            await wait_for_ack()
            for buttons in detected_buttons:
                center_x, center_y, label, score = buttons
                print(f"Center X: {center_x}, Center Y: {center_y}, Label: {label}, Score: {score}")

                if isinstance(label, str):
                    if label == "down":
                        label = 100
                    elif label == "up":
                        label = 101

                
                encoded_label = _encode_dist(label)
                print(f"Sending Label: {label}, Encoded: {encoded_label.hex()}")
                labels_characteristic.write(_encode_dist(label))
                await wait_for_ack()
                
                delta_x, delta_y = check_tight_centering(center_x, center_y)
                print(f"delta_x: {delta_x}, delta_y: {delta_y}")



                delta_x_characteristic.write(_encode_dist(delta_x))
                await asyncio.sleep(0.2)
                await wait_for_ack()
                
                delta_y_characteristic.write(_encode_dist(delta_y))
                await asyncio.sleep(0.2)
                await wait_for_ack()
                
        else:
            print("No buttons detected.")

Hi Trent,

I understand you are having trouble getting something working. These things happen when you are writing code. However, you cannot post a massive code dump of your program and ask us to debug where the issue is. Additional, you have code running on the pi too which means a bug could be on that also… I’m also noticing that you are calling a sync functions which are not in the code dump you posted.

However, I can potentially provide help for how to structure your protocol. Can you describe what you are trying to do?

Yeah I completely understand. I tried to only include the relevant code, although it is a lot and doesn’t account for some of the functions used. Also regarding the Rasp Pi code I do not believe that the issue is there. I wanted to see if there was a potential problem with the await asyncio.sleep() being used. Could they be too quick or too slow? I just got the code to work properly but the time it takes for total transmission is ~5 seconds which seems too slow for Bluetooth’s capabilities. If there is nothing you can do with the limited code that is understandable. Thanks

Hi, you shouldn’t use timeouts. This is unreliable.

Do this:

  1. Set your new value
  2. Increment the ack flag.
  3. The other side checks the incremented number.
  4. The other side replies with another ack flag that increments.
  5. You check the incremented value.

That’s your hand shake. No need to wait and delay. The counters can roll over and/or just be 0/1 each. The trick is that you are synced and can’t leave lock step.

Each side when checking needs to wait for the incremented number by the way. Also, you’ll want to handle timeouts if the increment doesn’t happen in a reasonable time.