There’s how to install the tools, how to use REPL, and a bunch of material on libraries. But nothing about building in VS Code or flashing an application (can you debug from VS Code or have to flash from Cyberbrick application?). Am I missing something obvious?
This may not be what you’re looking for, but my understanding is that you can only paste your code snippets into the field in CyberBrick PC app the so that it will be included when applying your configuration.
I don’t think that is correct. Application code would be called by rc_main.py, which is called by boot.py. Messing with boot.py would be risky unless you KNOW what you’re doing.
Based on what are you saying it? Can You link us new to this to any kind of documentation? I understand, that it’s still early days and we’re just out of kickstarter, but having a basic “make LED blink” step-by-step tutorial would be one of the first things to focus on, don’t you think?
I think their primary focus is getting people making simple things using the GUI editor for PC/Mac. From there you can achieve “LED blink” by playing around with the (imo) fairly intuitive interface. It’s drag-and-drop for the transmitter and receive with limited but fairly obvious options.
For many actions, using the GUI will be the most straightforward approach. If you’d like to add some custom code snippets, you can do so following this process:
In the CyberBrick desktop app, after pairing your devices, select “Code” under your receiver.
Click “Add” to add a new code snipped.
Write and save your code. If you use an external editor, there’s an issue on some platforms with pasting code into this field. If that happens, you may be able to drag the text and drop it into this field.
Under the Receiver, select the component that will be used to trigger your code snippet.
Click “Add”’ to add an event.
Change the Module to “Code” and the change the value to your code snippet.
After doing this, you can save and send your config to test on the device or click the “Test” button next to the event.
Given the kinds of failures that have been reported (motors turning without ‘cause’, peripherals not responding to changes in controls, failed attempts to connect, etc) it seems to me that some simple guidance on how to:
enable the logging that’s already included in the code,
how and where to retrieve the resulting logs,
a means to print both the raw and parsed data values received.
This little bit of info would go a long way toward debugging these failures. These SHOULD be within the capabilities of the code, but sorely lacking in any ‘how to’ do it. Where are the developers? Where are the support people?
And to pre-answer those who say it’s still early in their development cycle, I firmly disagree. This is a product that claims to be usable by anyone with a 3D printer. That COULD be true IFF there was some modicum of support.
Here are the documents on MicroPython, but please do not use third-party tools for firmware upgrade operations, as this will cause device security verification to fail and cannot be recovered :https://makerhub-dev.bambulab.net/en/cyberbrick/api-doc/
You can hook up the CyberBrick core e.g. to Arduino MicroPython IDE (that uses also the REPL). By browsing the files, one can see that the stock CyberBrick code has 3 folders and a boot.py file, whereas the boot.py can be extracted and opened in a text editor. If a configuration has been added to CyberBrick core with CyberBrick app, you also have a file rc_config at the root next to boot.py. rc_config (w/o extension) is the same *.json configuration file that you can download from MakerWorld together with CyberBrick models or that you can create with CyberBrick app.
In the app subfolder there are two precompiled binary Python files: control.mpy and parser.mpy. In addition there is rc_main.py. The latter contains 198 lines of Python instructions that once again can be read with the help of a text editor. control.py and parser.py are both available in source form in the Cyberbrick official GitHub repository: CyberBrick_Controller_Core/src/app_rc/app at master · CyberBrick-Official/CyberBrick_Controller_Core · GitHub
The folder bbl contains 6 files: buzzer.py, executor.py, leds.py, motors.py, servos.py and __init__.py
All are extractable and human readable.
The last folder log contains by default an empty file logging.0.log.
The RF communication between the CyberBrick modules and also the Bluetooth configuration interfaces seems to be in the frozen module(s). I wonder if ESPNow is being used for the communication between the CyberBricks in normal usage. Anyone with a logging RF spectrum analyzer, like Aaronia, who could have a look at this?
This is what I was suspecting / expecting also, but ESP-NOW is readily detectable with another ESP32 if it is present since it is an open broadcast protocol…
i.e. this is some simple code that will step through all 13 ESP-NOW channels and listen for any packets. It detects absolutely nothing with a setup where there is a remote and sockerbot program active and controls being moved. But does if I start up another ESP32 running some simple “Hello world” ESPNOW code.
Also, given the cyberbrick modules are still broadcasting Bluetooth the whole time they are talking to each other, and ESP32s have a single radio (so while actively switching between WiFi and Bluetooth is possible… it isn’t really recommended - i.e. because some activities like ble scan are effectively blocking) … I’m thinking at the moment this may actually communicate over Bluetooth, not ESP-NOW… Although having said that… I have also just noticed that they are broadcasting a detectable WiFi AP (but apparently not connectable)… i.e. ESP_B2AEAD is one of them, Curioser and Curioser!
#include "esp_now.h"
#include "WiFi.h"
#include "esp_wifi.h"
// Channel scanning variables
int currentChannel = 1;
const int maxChannel = 13;
const unsigned long channelScanTime = 5000; // 5 seconds per channel
unsigned long lastChannelChange = 0;
unsigned long packetCount = 0;
// Callback function for received ESP-NOW data
void onDataReceived(const uint8_t *mac, const uint8_t *data, int len) {
packetCount++;
Serial.printf("\n[CH %d] ESP-NOW packet #%lu detected from: ", currentChannel, packetCount);
for(int i = 0; i < 6; i++) {
Serial.printf("%02X", mac[i]);
if(i < 5) Serial.print(":");
}
Serial.printf("\nPayload length: %d bytes\n", len);
// Print payload in hex
Serial.print("Payload: ");
for(int i = 0; i < len; i++) {
Serial.printf("%02X ", data[i]);
}
Serial.println();
// Also try to print as ASCII (if printable)
Serial.print("ASCII: ");
for(int i = 0; i < len; i++) {
if(data[i] >= 32 && data[i] <= 126) {
Serial.print((char)data[i]);
} else {
Serial.print(".");
}
}
Serial.println();
Serial.println("---");
}
void changeChannel(int channel) {
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
currentChannel = channel;
Serial.printf("\n>>> Scanning Channel %d <<<\n", channel);
}
void setup() {
Serial.begin(115200);
// Wait for serial port to connect, with timeout
unsigned long startTime = millis();
while (!Serial && (millis() - startTime < 5000)) {
delay(100);
}
Serial.println("ESP-NOW Channel Scanner Starting...");
Serial.println("Will scan channels 1-13, spending 5 seconds on each");
WiFi.mode(WIFI_STA);
// Disable power saving for better reception
esp_wifi_set_ps(WIFI_PS_NONE);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(onDataReceived);
// Start on channel 1
changeChannel(1);
lastChannelChange = millis();
Serial.println("ESP-NOW initialized. Scanning for packets...");
}
void loop() {
// Check if it's time to change channels
if (millis() - lastChannelChange >= channelScanTime) {
currentChannel++;
if (currentChannel > maxChannel) {
currentChannel = 1; // Loop back to channel 1
Serial.println("\n=== Completed full scan, restarting from channel 1 ===");
}
changeChannel(currentChannel);
lastChannelChange = millis();
}
// Show scanning progress every second
static unsigned long lastProgress = 0;
if (millis() - lastProgress >= 1000) {
unsigned long timeOnChannel = millis() - lastChannelChange;
unsigned long timeRemaining = channelScanTime - timeOnChannel;
Serial.printf("Channel %d: %lu/%lu ms (packets: %lu)\n",
currentChannel, timeOnChannel, channelScanTime, packetCount);
lastProgress = millis();
}
delay(100);
}
Interesting point regarding the WiFi AP. I do see ESP_XXXXXX named AP broadcast as well and WAS able to connect to it (from a Win11 laptop), while being connected via Bluetooth/BLE? at the same time to an Android mobile phone running CyberBrick app.
No DHCP seems to be running, or at least no IP was offered to my laptop MAC.
It seems to me that WiFi and BT (or BLE?) do run at the same time on CyberBrick ESP32-C3 w/o problems?
For experimentation, I renamed the boot.py - I still see the CyberBrick Core in the Android CyberBrick App, but the LED does not blink anymore, when controlled via app (app is happy and does not complain about connection though) and the ESP WiFi AP does not show up anymore. REPL still connects, as before. What I can gather from this is that the WiFi AP is created by one of the loaded (frozen) modules that are imported via app/rc_main.py.
import socket
import network
import gc
gc.collect()
ssid = 'MicroPython-AP'
password = '123456789'
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid=ssid, password=password)
while ap.active() == False:
pass
print('Connection successful')
print(ap.ifconfig())
def web_page():
html = """<html><head><meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body><h1>Hello, World!</h1></body></html>"""
return html
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('', 80))
s.listen(5)
while True:
conn, addr = s.accept()
print('Got a connection from %s' % str(addr))
request = conn.recv(1024)
print('Content = %s' % str(request))
response = web_page()
conn.send(response)
conn.close()
and let it run with exec(open("netw.py").read()) and this creates a new AP MicroPython-AP. While connecting to it and opening a web-browser pointed to 192.168.4.1, I can see that it works just fine, as I get Hello World string output in the browser. From this I can take that it is pretty easy to make a custom WiFi AP running on CyberBrick Core, w/o having to flash-erase/wipe the original CyberBrick MicroPython setup.
Note I didn’t say it wasn’t possible… but wasn’t recommended. If the ESP32 code is done well, and they avoid any blocking functions it will probably be fine… time will tell. It may not be BLE since BLE is blocking (blocking, as in, you can’t use the radio for anything else, so no wifi while BLE scanning).
Very nice… definitely one step closer to changing this over to CRSF RC control AND preserving the bluetooth app functionality.