RT1062 trouble with "save open script as main.py"

Hi,

I’m having serious problems when trying to upload code on our new RT1062 cameras.

First element of weirdness is that the LED just stays solid green all the time. Maybe that’s a clue as to what’s going on?

Nevertheless, I can connect to it in the IDE and successfully run both example code and code I’ve customized (based on one of the AprilTag examples). I get beautiful, tantalizing data in the serial monitor of the IDE. :slight_smile:

The trouble starts when I try to save the code to the camera to use it outside of the IDE. Then the following happens:

  1. It kills my computer’s keyboard. I have to unplug the camera to get the computer to register keystrokes. (This is macOS 13.3 on an M2 Mac mini, IDE version 4.1.3.)
  2. It bricks the camera. Then, when I try to use the IDE’s automatic un-bricking routine, it gives me this error: “UsbHidPeripheral() cannot open USB HID device”. There is no way to connect to the camera at this point.
  3. If I do the trick of connecting SBL to 3.3V, I can connect to the camera again and reinstall the firmware that kwagyeman posted here. So, back to normal.
  4. But the cycle repeats exactly if I try to upload new code. I even just tried uploading helloworld as a test, and that caused the same behavior.

I’ve tried it on both copies of the RT1062 that we have, and the behavior is the same.

Thank you for any help!

Hi, can you send me the script? I’ll give it a try and see if I can spot the issue. It sounds like there’s a bug.

I tested it just using helloworld_1.py from the examples:

# This work is licensed under the MIT license.
# Copyright (c) 2013-2023 OpenMV LLC. All rights reserved.
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# Hello World Example
#
# Welcome to the OpenMV IDE! Click on the green run arrow button below to run the script!

import sensor
import time

sensor.reset()  # Reset and initialize the sensor.
sensor.set_pixformat(sensor.RGB565)  # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA)  # Set frame size to QVGA (320x240)
sensor.skip_frames(time=2000)  # Wait for settings take effect.
clock = time.clock()  # Create a clock object to track the FPS.

while True:
    clock.tick()  # Update the FPS clock.
    img = sensor.snapshot()  # Take a picture and return the image.
    print(clock.fps())  # Note: OpenMV Cam runs about half as fast when connected
    # to the IDE. The FPS should increase once disconnected.

Yeah, I’m noticing USB lockup with the latest firmware on it…

Okay, there’s some issue with the LED control code. Direct Pin control still appears to work. However, the machine.LED module is broken. I will debug this too.

I noticed that saving a script which does not use the camera module does not break USB.

Okay, fixed one issue: ports/mimxrt: Service TinyUSB while waiting for sensor frames. by kwagyeman · Pull Request #2052 · openmv/openmv (github.com). This stops the system from crashing when you save main.py to it.

Working on the LED fix now.

Here’s a working binary:
firmware.zip (1.3 MB)

Fixed the default LED issue: boards/OPENMV_RT1060: Fix default script LED pin name. by kwagyeman · Pull Request #2053 · openmv/openmv (github.com)

Unfortunately, it’s still having problems. Now it seems to not crash while running helloworld_1.py, but it does crash (after about 30 seconds or so) when running my code. (And it’s still taking the keyboard with it, until I unplug the camera.)

Here’s my code:

import sensor, image, time, math

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.set_hmirror(True)
sensor.set_vflip(True)
# sensor.set_windowing(0,0,160, 200)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)  # must turn this off to prevent image washout...
sensor.set_auto_whitebal(False)  # must turn this off to prevent image washout...

# Note! Unlike find_qrcodes the find_apriltags method does not need lens correction on the image to work.

# The apriltag code supports up to 6 tag families which can be processed at the same time.
# Returned tag objects will have their tag family and id within the tag family.

tag_families = 0
#tag_families |= image.TAG16H5 # comment out to disable this family
#tag_families |= image.TAG25H7 # comment out to disable this family
#tag_families |= image.TAG25H9 # comment out to disable this family
#tag_families |= image.TAG36H10 # comment out to disable this family
tag_families |= image.TAG36H11 # comment out to disable this family (default family)
#tag_families |= image.ARTOOLKIT # comment out to disable this family

# What's the difference between tag families? Well, for example, the TAG16H5 family is effectively
# a 4x4 square tag. So, this means it can be seen at a longer distance than a TAG36H11 tag which
# is a 6x6 square tag. However, the lower H value (H5 versus H11) means that the false positve
# rate for the 4x4 tag is much, much, much, higher than the 6x6 tag. So, unless you have a
# reason to use the other tags families just use TAG36H11 which is the default family.

def family_name(tag):
    if(tag.family() == image.TAG16H5):
        return "TAG16H5"
    if(tag.family() == image.TAG25H7):
        return "TAG25H7"
    if(tag.family() == image.TAG25H9):
        return "TAG25H9"
    if(tag.family() == image.TAG36H10):
        return "TAG36H10"
    if(tag.family() == image.TAG36H11):
        return "TAG36H11"
    if(tag.family() == image.ARTOOLKIT):
        return "ARTOOLKIT"

while(True):
    print("Z")
    track = 0
    index = 0
    img = sensor.snapshot()
    for tag in img.find_apriltags(families=tag_families): # defaults to TAG36H11 without "families".
        print_args = (track, index, tag.id(), tag.cx(), tag.cy(), (180 * tag.rotation()) / math.pi)
        print("%d,%d,%d,%d,%d,%f," % print_args, end="")
        index=index + 1

Thank you!

I think I know what the problem is.

Can you try this firmware:

firmware.zip (1.3 MB)

That appears to have done it! Hooray! Thank you, Kwabena!

Yeah, the problem is that we are not servicing Tiny USB enough. When the camera is connected to the IDE we service it via print().

I added code to service it while snapshot is waiting for frames. However, once you add processing overhead the processor is rarely waiting anymore since the DMA system will always have a new frame… so, I add more serving code to handle that.

However, if you were just calling while(True) in a loop you’d have the crash still since nothing would service TinyUSB.

Ibrahim made a better fix that will come soon: misc: Fix TinyUSB polling. by iabdalkader · Pull Request #2054 · openmv/openmv (github.com)