Skip to content
This repository was archived by the owner on Nov 7, 2026. It is now read-only.

Commit 94c8841

Browse files
Web 0.7.0: VisuBot-Programm auf den mBot2 übertragen, Start mit Taste A (#164)
Claude-Session: https://claude.ai/code/session_01K8C1HvVqFVDDiMJ5WasFzi Co-authored-by: Claude <noreply@anthropic.com>
1 parent eba9775 commit 94c8841

30 files changed

Lines changed: 2363 additions & 1387 deletions

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is loosely inspired by Keep a Changelog.
88

99
### Added
1010

11+
- **Web 0.7.0, VisuBot upload to the mBot2:** a new button “⬆ Upload” (Chrome/Edge, USB) saves the finished program on the mBot2, like uploading in mBlock. Then it drives without a cable, for example through a maze: after switching on, the screen shows “A = Start”, and button A starts the program. VisuStruct translates the structogram or Java code into MicroPython for the CyberPi in the background (case selection as if/elif, Java string concatenation with numbers). The upload frames are identical to mBlock 5's (protocol from cyberpi-uploader, MIT). New step “Driving without a cable” in VisuBot lesson 2 and in the reference.
1112
- **Web 0.6.3, elements width:** the line between the elements and the structogram can be dragged (also with the arrow keys); a double-click resets it. Narrow elements show their name small below the symbol, wide ones next to it. The width is remembered.
1213
- **Web 0.6.2, programming large:** a ⇄ button in Programming and in the structogram toolbar makes Programming the large main area and the structogram narrow; another click swaps back. Both widths can be dragged at the line between them, and the choice is remembered.
1314
- **Web 0.6.1, VisuBot reference in plain words:** the mBot2 commands and sensors in the reference use the same groups as the elements (driving and turning, wheels separately, light/sound/screen, emotions, waiting and stopwatch; distance, line, colours, buttons and joystick, light and loudness, tilt and shaking, stopwatch and battery) and are explained in short, simple sentences for beginners (de/en): what a command and a sensor is, every line says what the mBot2 does, LEDs, tones and angles explained.

‎web/lessons/de/visubot/01-der-mbot2.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ Jetzt fährt der mBot2 bei jedem Schritt der Simulation mit. Stell ihn auf den B
292292

293293
> Fertig? Klick noch einmal auf **🟢 mBot2**. Dann hält er an, zeigt „Bis bald!“ und gibt den Anschluss frei. Erst danach das Kabel ziehen.
294294
295+
> Ganz ohne Kabel fahren? Das lernst du in Lektion 2 bei **Ohne Kabel fahren**.
296+
295297
## Den mBot2 testen
296298

297299
Ist der mBot2 verbunden, erscheint unter der Welt **🔧 mBot2 testen**. Klapp es auf:

‎web/lessons/de/visubot/02-das-quadrat.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,30 @@ lösung: vb-vier-quadrate-loesung.visustruct
9595
> 4 Quadrate · 4 Seiten · 5 Schritte = 80. Ohne Schleifen wären das 80 Kästen.
9696
:::
9797

98+
## Ohne Kabel fahren
99+
100+
::: mbot2
101+
fokus: cyberpi, buttons
102+
ansicht: oben
103+
:::
104+
105+
Bisher hängt der mBot2 am Kabel, solange er fährt. Du kannst dein Programm aber auch **auf den mBot2 übertragen**. Dann merkt er es sich und fährt ganz allein, zum Beispiel durch ein Labyrinth auf dem Boden.
106+
107+
1. Schließ den mBot2 mit dem USB-Kabel an und schalte ihn ein, wie in Lektion 1. Das geht nur in **Chrome** oder **Edge**.
108+
2. Öffne dein Programm, zum Beispiel die vier Quadrate.
109+
3. Klick oben auf **⬆ Übertragen** und dann auf **Jetzt übertragen**. Wähle wieder **USB Serial**.
110+
4. Warte, bis „Fertig!“ dasteht. Der mBot2 startet neu und zeigt **A = Start**.
111+
5. Zieh das Kabel ab und setz den mBot2 an den Start.
112+
6. Drück **Taste A**, das ist die [Taste mit dem Quadrat]{teil=buttons}. Jetzt fährt dein Programm los.
113+
114+
Das Programm bleibt gespeichert, auch wenn du den mBot2 aus- und wieder einschaltest. Erst das nächste Übertragen ersetzt es.
115+
116+
> Fährt er los, bevor du bereit bist? Keine Sorge: Er wartet immer auf Taste A. Drückst du A noch einmal, während er fährt, passiert nichts. Ist er fertig, startet A das Programm von vorn.
117+
98118
::: checkliste
99119
- Ich kann einen Ablauf erst ohne Schleife bauen. → Ein Quadrat fahren
100120
- Ich erkenne Wiederholungen und ersetze sie durch eine For-Schleife. → Immer das Gleiche
101121
- Ich kann zwei Schleifen ineinander schachteln. → Schleife in der Schleife
102122
- Ich kann drei Schleifen ineinander schachteln. → Vier Quadrate
123+
- Ich kann mein Programm auf den mBot2 übertragen und ohne Kabel mit Taste A starten. → Ohne Kabel fahren
103124
:::

‎web/lessons/de/visubot/nachschlagen.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,7 @@ mbot.getBattery() wie voll ist der Akku? (in Prozent)
146146
### Echter mBot2
147147

148148
Mit **🔌 mBot2** neben „Simulation starten“ verbindest du den echten Roboter mit dem USB-Kabel. Das geht nur in Chrome oder Edge. Dann fährt er jeden Schritt der Simulation mit, und die Sensoren messen echte Werte. Ein zweiter Klick trennt ihn wieder.
149+
150+
### Ohne Kabel fahren
151+
152+
Mit **⬆ Übertragen** speicherst du dein Programm fest auf dem mBot2. Danach Kabel ab, mBot2 an den Start und **Taste A** drücken: Er fährt dein Programm allein. Es bleibt gespeichert, bis du ein neues überträgst. Eingaben mit der Tastatur gehen am mBot2 nicht.

‎web/lessons/en/visubot/01-der-mbot2.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ Now the mBot2 drives along with every step of the simulation. Put it on the floo
292292

293293
> Finished? Click **🟢 mBot2** once more. It stops, shows “Bis bald!” and releases the port. Only then pull out the cable.
294294
295+
> Want to drive with no cable at all? You learn that in lesson 2 under **Driving without a cable**.
296+
295297
## Testing the mBot2
296298

297299
When the mBot2 is connected, **🔧 Test the mBot2** appears below the world. Open it:

‎web/lessons/en/visubot/02-das-quadrat.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,30 @@ lösung: vb-vier-quadrate-loesung.visustruct
9595
> 4 squares · 4 sides · 5 steps = 80. Without loops that would be 80 boxes.
9696
:::
9797

98+
## Driving without a cable
99+
100+
::: mbot2
101+
fokus: cyberpi, buttons
102+
ansicht: oben
103+
:::
104+
105+
So far the mBot2 hangs on the cable while it drives. But you can also **upload your program to the mBot2**. Then it remembers it and drives all by itself, for example through a maze on the floor.
106+
107+
1. Connect the mBot2 with the USB cable and switch it on, as in lesson 1. This only works in **Chrome** or **Edge**.
108+
2. Open your program, for example the four squares.
109+
3. Click **⬆ Upload** at the top and then **Upload now**. Choose **USB Serial** again.
110+
4. Wait until it says “Done!”. The mBot2 restarts and shows **A = Start**.
111+
5. Unplug the cable and put the mBot2 at the start.
112+
6. Press **button A**, that is the [button with the square]{teil=buttons}. Now your program starts.
113+
114+
The program stays saved, even when you switch the mBot2 off and on again. Only the next upload replaces it.
115+
116+
> Afraid it drives off before you are ready? Don't worry: it always waits for button A. If you press A again while it drives, nothing happens. When it has finished, A starts the program again from the beginning.
117+
98118
::: checkliste
99119
- I can build a sequence without a loop first. → Driving a square
100120
- I spot repetitions and replace them with a for loop. → Always the same
101121
- I can nest two loops. → A loop in a loop
102122
- I can nest three loops. → Four squares
123+
- I can upload my program to the mBot2 and start it with button A without a cable. → Driving without a cable
103124
:::

‎web/lessons/en/visubot/nachschlagen.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,7 @@ mbot.getBattery() how full is the battery? (in percent)
146146
### Real mBot2
147147

148148
With **🔌 mBot2** next to "Start simulation" you connect the real robot with the USB cable. This only works in Chrome or Edge. Then it drives every step of the simulation along, and the sensors measure real values. A second click disconnects it again.
149+
150+
### Driving without a cable
151+
152+
With **⬆ Upload** you save your program on the mBot2. Then unplug the cable, put the mBot2 at the start and press **button A**: it drives your program on its own. It stays saved until you upload a new one. Keyboard inputs do not work on the mBot2.

‎web/package-lock.json‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎web/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "visustruct-web",
33
"private": true,
4-
"version": "0.6.3",
4+
"version": "0.7.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

‎web/src/core/codeGenerator.ts‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export interface CodeOptions {
2222
arrayElementTypes?: Map<string, string>
2323
/** Text-Variablen: In Python ohne `str(…)` verketten. */
2424
stringVariables?: Set<string>
25+
/** Python ohne `match` (MicroPython auf dem mBot2 kennt es nicht): Fallauswahl als `if`/`elif`/`else`. */
26+
pythonWithoutMatch?: boolean
2527
/** Nur für die Ansicht „Code live“: graue Platzhalter statt `true`/„empty element“, Zeilen je Element. */
2628
live?: LiveContext
2729
}
@@ -1294,6 +1296,18 @@ function emitElement(element: VSElement, target: CodeTarget, options: CodeOption
12941296
case ElementType.fallauswahl: {
12951297
const cases = element.cases
12961298
if (!cases || cases.length === 0) return
1299+
if (py && options.pythonWithoutMatch) {
1300+
const choice = `wahl${indent / step + 1}`
1301+
emitConditionHeader(choice + ' = ', '\n', element.textLines, target, options, indent, sink)
1302+
cases.forEach((c, i) => {
1303+
const isLast = i === cases.length - 1
1304+
if (isLast && i === 0) sink.out += sp(indent) + 'if True:' + forcedCaseComment(c.name, target) + '\n'
1305+
else if (isLast) sink.out += sp(indent) + 'else:' + forcedCaseComment(c.name, target) + '\n'
1306+
else sink.out += sp(indent) + (i === 0 ? 'if ' : 'elif ') + choice + ' == ' + caseLabelToken(c.name, target) + ':\n'
1307+
body(c.elements, indent + step)
1308+
})
1309+
return
1310+
}
12971311
emitConditionHeader(
12981312
py ? 'match ' : 'switch (',
12991313
py ? ':\n' : ') {\n',

0 commit comments

Comments
 (0)