Skip to main content

FAQ

This page is organized around the current CoCube MicroPython workflow. When something goes wrong, check "Connection and Flashing" first, then "Running and Files," and only then move on to the specific modules.

Connection and flashing

Thonny cannot see CoCube, or there is no serial port to select

Check these items first:

  • Make sure CoCube is powered on. Hold the bottom power button for about 3 seconds before connecting.
  • Make sure the USB cable supports data transfer. Some cables are charge-only and the computer will never see a serial port.
  • Check whether the port changed after reconnecting the cable. Open Thonny's interpreter settings again and reselect the port manually.
  • Make sure the computer has the serial driver it needs. On Windows, or on some macOS setups, you may need the CH343 driver.

If it still does not work, try a different cable first, then a different USB port. That is usually more effective than repeatedly restarting everything.

Flashing finished, but the Shell still does not show >>>

Check in this order:

  1. Make sure Thonny is still set to the correct port and the MicroPython (ESP32) interpreter in the lower-right corner.
  2. Click the red stop button in the toolbar to restart the interpreter.
  3. Unplug and reconnect CoCube, then select the port again in Thonny.

If you used the lower-level Flash Download Tool, also double-check:

  • whether the chip model is correct
  • whether the firmware file matches CoCube
  • whether the flash address is correct

If any one of those is wrong, the device may fail to boot normally.

Firmware flashing requires the highest stability, and a wired USB connection is still the safest option.

For the current MicroPython docs, it is also helpful to think of "flashing firmware" and "uploading .py files" as two separate things:

  • Firmware flashing: prefer wired USB
  • Daily development: then use Thonny to connect, run, and save scripts

Running and files

I saved the code to the device. Why does it not auto-run after reboot?

The most common reason is the filename.

MicroPython only auto-runs a file named main.py when the device powers on.
Files such as test.py or demo.py are saved on the device, but they do not start automatically.

If you want CoCube to keep running the program after it is disconnected from the computer, save the script as main.py.

main.py is already there. Why does it look like it stopped running as soon as I connect Thonny?

That is Thonny's default behavior. It does not necessarily mean the program is broken.

When Thonny connects, it usually interrupts the currently running program and enters the REPL.
That is why you can see this pattern:

  • When the device powers on by itself, main.py starts automatically
  • As soon as Thonny connects, the program is interrupted and the Shell only shows >>>

In that case you can:

  • press Ctrl + D in the Shell to soft reboot and watch the full startup sequence again
  • or change the related Thonny setting so that connecting does not interrupt the running program

The upload succeeded, but the screen does not respond

Do not assume the whole board is broken. Check these first:

  • Does the program actually call display.init()?
  • Are the text color and background color too similar?
  • Does the code only use print(...) in the Shell instead of drawing on the screen?

If you only want to verify that the screen works, start with the smallest possible example. The current firmware already includes a default Chinese font, so display.write() is enough:

import display

tft = display.init()
tft.fill(display.BLACK)
display.write("Hello, CoCube", 24, 40, display.YELLOW, display.BLACK)

Once the program enters while True, I cannot do anything in Thonny

That is normal. An infinite loop keeps the interpreter busy.

You can stop it by:

  • clicking the red stop button in the Thonny toolbar
  • or pressing Ctrl + C in the Shell

If you see KeyboardInterrupt in the Shell, that usually means the program was interrupted successfully, not that a new error has appeared.

Motion and positioning

Why does the robot not move as expected?

Time-based control is affected by many real-world factors, for example:

  • the floor may be too slippery or too rough
  • the battery level may be different
  • the two tracks may have slightly different friction

So the same move_ms(...) or rotate_ms(...) code can produce slightly different paths on different surfaces.

A safer tuning order is:

  1. Keep the speed around 20~30 first
  2. Confirm the direction first
  3. Then adjust the timing values gradually

move_to(), rotate_to(), or cocube.pos.x does not look right

Check cocube.pos.state first.

  • If cocube.pos.state is true, the position and angle data are reliable
  • If cocube.pos.state is false, do not continue relying on coordinate-based APIs

Common reasons include:

  • CoCube is not on CoMaps
  • it has moved outside the valid positioning area
  • the current position is not updating stably

If positioning is invalid, move the robot back into the normal CoMaps area before testing further.

Expansion modules

The external module is attached, but nothing responds in the program

Check the easiest step to miss first: did you call cm.power_on()?

With the current firmware, many external modules should begin like this before you read from or control them:

import cocube_module as cm

cm.power_on()

Then test the smallest possible interface, for example:

  • ToF: cm.tof_connected() and cm.tof_distance()
  • Light sensor: cm.dlight_level()
  • Voice: cm.asr_get_command()
  • Gripper: cm.gripper_open()

If even the smallest interface does not respond, then check whether the magnetic connection is secure.

The first ToF reading is false, -1, or -2

This is common. In many cases the module has just powered on and is not ready yet.

Use this order:

  • after cm.power_on(), wait a short moment first
  • if the first read fails, read again instead of assuming the module is broken
  • treat negative values as invalid data first

Common return values in the current firmware are:

  • a normal millimeter value: read succeeded
  • -1: invalid data
  • -2: measurement timeout

Why does the gripper not move, or why does its angle look strange?

Check these items first:

  • whether cm.power_on() has been called
  • whether the angle is inside the 0~70 range
  • whether gripper_open(), gripper_close(), and gripper_degree(...) each work by themselves

In the current firmware:

  • 0 is closer to fully open
  • 70 is closer to fully closed

If you mix base motion, gripper control, and coordinate control all at once from the start, it becomes much harder to tell which step is actually wrong.

Voice recognition

Why does the voice module never respond?

The most common reasons fall into four groups:

  • the module has just powered on and is not ready yet
  • the environment is too noisy
  • the wake phrase was not spoken first
  • the action logic was written too early before confirming the command ID

A safer test order is:

  1. Call cm.power_on()
  2. Wait a moment
  3. Speak a wake phrase first, such as 你好小智
  4. Then speak the command phrase
  5. In the program, only print the result of cm.asr_get_command()

Once the command IDs are stable, then map them to actions.

Why do my learned custom commands not work?

Confirm these two things first:

  • learned command IDs start from 4
  • you have actually printed and confirmed the returned ID in code

Do not guess the number just because "this was the first command I recorded."
The safest way is still to print it first:

import time
import cocube_module as cm

cm.power_on()
time.sleep_ms(500)

while True:
print(cm.asr_get_command())
time.sleep_ms(50)

Also, before relearning commands, it is best to delete the old learned wake phrase or commands first, keep the environment quiet, and speak clearly.

AI camera

Why do read_card(), read_color(), or get_line() throw an error immediately?

That usually means the order is wrong, not that the camera is broken.

Camera APIs must be used in this order:

  1. init()
  2. change_algo(...)
  3. call the read function that matches the current algorithm

For example:

  • read_card() requires Card Recog
  • read_color() requires Color Recog
  • get_line(...) requires Line Detect

If the algorithm does not match, the firmware throws an error directly instead of quietly returning an empty result.

The camera recognition result is unstable. What should I tune first?

Tune the environment and target before the code.

The best things to check first are:

  • whether the target stands out clearly from the background
  • whether line following uses a high-contrast scene such as black on white
  • whether the line thickness is appropriate
  • whether the card or target is too far away, making w and h too small
  • whether multiple vision tasks are being mixed at the same time

The safest workflow is still:

  • test one algorithm at a time
  • print the result first
  • only map it to chassis actions after the result is stable

Why do other peripherals behave differently as soon as the camera is initialized?

That is a resource-sharing characteristic of the current firmware, not a random bug.

After camera init():

  • cocube_module enters camera mode
  • the gripper control path changes
  • the resources used by NeoPixel are occupied

So at the beginning of debugging, do not mix the camera, gripper, and NeoPixel all at once.

A safer order is:

  1. Get the camera working by itself
  2. Get the peripherals working by themselves
  3. Only then build a combined program

Still not solved?

Review the docs in this order:

  1. Set Up the Development Environment
  2. Basic Concepts
  3. The "Common issues / reminders" section in the related lesson page
  4. cocube core reference
  5. cocube_module reference
  6. Camera modules

If you can narrow the issue down to a more specific symptom such as "cannot connect," "no >>>," "cannot read data," or "has an ID but no action," troubleshooting usually becomes much faster.