Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple MCU Capability #186

Open
rcwilcox opened this issue Sep 21, 2021 · 21 comments
Open

Multiple MCU Capability #186

rcwilcox opened this issue Sep 21, 2021 · 21 comments
Assignees
Labels
enhancement New feature or request open for vote Vote at https://wokwi.com/features

Comments

@rcwilcox
Copy link

rcwilcox commented Sep 21, 2021

Add capability to simulate multiple MCUs in a single simulation diagram.

Possible Use Cases:

  • Prototype multi-processor systems - e.g. Multiple Slave MCUs processing sensor data (DSP algorithms, predictive filters for raw IMU inputs etc.) that would provide preprocessed data back to the Master MCU.
  • Simulate H/W not (yet) available as a Wokwi part. e.g. a MAX7219 could be simulated with a MCU board (or a bare bones MCU chip if that were available) to scan and decode LED outputs.
@urish urish added enhancement New feature or request open for vote Vote at https://wokwi.com/features labels Sep 21, 2021
@urish
Copy link
Contributor

urish commented Sep 21, 2021

This one seems quite popular already, so I'm sharing some thoughts about the implementation challenges:

  • Performance - right now, we can a single-core 16MHz AVR MCU simulation usually runs at 100% on modern hardware. RP2040 (at 125MHz) runs at about 33% on my hardware here, which is pretty powerful. Running multiple MCUs simultaneously will drop the performance even further. This can be mitigated by carefully writing the user code - putting the MCU to sleep when idle, or by dropping the MCU speed (e.g. using the clock prescaler on AVR).
  • Code - I assume that for most use cases, you want different code to run on each MCU. We need to come up with a way to define several "subprojects" in each project, and associate each to a microcontroller. Any proposals here?

For "Simulate H/W not (yet) available as a Wokwi part" - multiple MCUs is one way to achieve this. Another approach I'm looking at is using Web Assembly (perhaps together with AssemblyScript). It'll be more performant, but comes with its own set of challenges. So perhaps multiple MCUs support can give us a quick win here.

@dommilosz
Copy link

We can create option in diagram.json to configure the MCU speed. I think even 20MHz for RP2040 would be enough for most applications and maybe we can go even slower. For the code problem it can be also set in diagram.json as entry point file. Adding directiories could also help. In single MCU system code would be compiled like it is already. If we add more MCUs the ones with other IDs would have to have code in folder mentioning their id.

diagram.json approach

{
      "type": "wokwi-pi-pico",
      "id": "pico",
      "top": -1.33,
      "left": 6.67,
      "attrs": { "env": "arduino-community" },
      "speed": 10000000 (10MHz)
      "code": "sketch.ino" (optional, without it behaves like it is now)
},
{
      "type": "wokwi-pi-pico",
      "id": "pico2",
      "top": -1.33,
      "left": -100.67,
      "attrs": { "env": "arduino-community" },
      "speed": 10000000 (10MHz)
      "code": "sketch2.ino"
}

directories approach (speed still in diagram.json)
1 MCU:

/sketch.ino
....

N MCU:

/sketch.ino (code of the first MCU with id: pico)
/mcu/pico2/sketch.ino (code of MCU with id:pico2)
....

It would be great to have multi MCU simulation. It would greatly increase speed of prototyping various multiple MCU systems. Like testing I2C between MCUs. Compilation time on wokwi is faster than on my pc for rp2040 and also not including time to restart every one of them to bootloader and compile each separately.

@urish
Copy link
Contributor

urish commented Jun 18, 2022

Thanks for the feedback and suggestions!

Directories probably make more sense, as projects often consist of multiple source files (e.g. the libraries.txt / library manager tab). Some of the projects use Python or non-Android SDKs (like the Pi Pico SDK), so they require different kind of treatment.

As far as slowing down the clock - unfortunately, it is not as simple. The code that is running inside the simulation has also to be aware of the slower clock, otherwise things like delay() will take longer than expected.

In the meanwhile, custom chips (#301) should provide a way to create custom I2C devices (also SPI, UART), so they may be useful for certain scenarios. And they have good performance too.

Great to hear you are happy with the developer experience on Wokwi.com :-)

@dommilosz
Copy link

In Arduino IDE there is option to change the clock. Also F_CPU define may help. Other option is to inject code changing cpu speed. In rp2040 you can do it and delays still work fine I think.

@leftCoast
Copy link

leftCoast commented Jun 20, 2022

Leave the project & window as a single , as it is now. Just add a "connector" item that allows you to connect to another project in another browser tab/window. This would cause that other window to be able to run in the background.

The connector would just connect wires.

@urish
Copy link
Contributor

urish commented Jun 21, 2022

The connector would just connect wires.

It's a creative idea, but "just connecting wires" is unfortunately not feasible. To find the voltage on the wire (high/low), the simulator has to look at everything connected to this wire. Different browser tabs communicating by passing messages, which has high latency (we can get around 100 messages per second, often even less). So the simulation will be very very very slow if it'll have to wait for the two tabs to talk every time it has to figure out the state of the wire (imagine driving an Uno down from 16MHz to 100Hz... that kind of slow)

@leftCoast
Copy link

could we just bounce a couple bytes off a server?

@urish
Copy link
Contributor

urish commented Jun 22, 2022

could we just bounce a couple bytes off a server?

How exactly?

@leftCoast
Copy link

leftCoast commented Jun 23, 2022

How? Err..

The "connector" stores a URL, login, password & ID to its mate from another simulation. It uses this to store any changes on its input pins to that file. Then reads the matching file for changes and stores them locally.

It would probably be slow, yes. But, it would be a start. And it's not limited to 2 processors. Heck, it could be any amount if them on any machine. It might be a fun thing to play around with.

-jim

@dommilosz
Copy link

I think using http request would be very very slow like few requests/s. Websockets may be better solution. But still uses tcp which is not great for very quick message system.

@chrisisbeef
Copy link

Just wanted to pop in here with a few of my own thoughts on this --

  1. Connecting projects together seems to me to be the best way to do this, however it would be meaningful to allow multiple "instances" of a single project to be connected - for instance, if I built some kind of sensor assembly and I wanted to allow multiple instances of that sensor to communicate with the master unit - I wouldn't want to create the same project multiple times. This also comes into play in my suggestion around how to implement the connections
  2. Modeling connections around any type of TCP request (HTTP, WebSockets, etc) will introduce some latency, yes - but let's be honest - for the simulation, what kind of sampling rate are you really trying to get on those MCU to MCU connections?

Now let's talk about the connections themselves, there's several different approaches one could take (and I'll use the ESP32 stuff for this, since I'm right now working in that and looking into this very things from a usability perspective for my project)

  1. Serial I/O -- You can use either a UART port of SoftwareSerial library in your code to connect two MCUs together
  2. BLE -- You can use Bluetooth to communicate between two devices
  3. MQTT / Network / WiFi -- Use a server-side component (MQTT) to facilitate communication between MCUs
  4. ESP-Mesh / ESP-BLE-Mesh -- Use a mesh network
  5. ESP-Now -- Use a direct protocol over wifi

In all of these scenarios, some latency will be added in a real implementation depending on which you choose, so that being said which of these would be the easiest to implement? Well, The MQTT solution can literally do this right now without any changes. Almost every other solution (imo) would be pretty simple to implement using websockets and would provide a balance between being able to simulate how this would work in reality (thus eliminating the amount of code changes between the simulation and the dev board and then the pcb) and an implementation that doesn't "break the bank" and proves to be incredibly unscalable from a simulation perspective (i.e. physically modeling multiple MCUs in the same simulator instance, which is I believe what @urish was getting at above)

TLDR; leave projects alone, allow projects to be linked with multiple instances of a project created on the master or linker side - each instance of a linked project prompts the user to open that instance in a new browser tab; and use websockets for the node to node configuration allowing pretty much any of BLE, Serial, Mesh, ESP-Now as the implementation type - for anything requiring a physical wire (Serial) you would probably want to force the link to reference which pins to connect for TX/RX on both sides and "disable" those pins in the simulator (or maybe not, idk?)

@ForrestErickson
Copy link

For an application on which I am volunteering, we would like to have multiple MCU capability. We have an SPI Controller (an UNO) connecting to an SPI Peripheral (a second UNO).

Our application we call the General Purpose Alarm Device. aka GPAD.
https://github.com/PubInv/general-alarm-device
The GPAD is an SPI Peripheral and we would benefit if w could simulate two UNOs connected as Controller and Peripheral so we can develop both the controller side and peripheral side firmware.

@EpicLPer
Copy link

This would help us with a current ongoing project quite a lot! :)

@urish
Copy link
Contributor

urish commented Oct 18, 2022

This would help us with a current ongoing project quite a lot! :)

@EpicLPer can you please explain how it will be helpful for you?

@EpicLPer
Copy link

This would help us with a current ongoing project quite a lot! :)

@EpicLPer can you please explain how it will be helpful for you?

We're currently working on a somewhat technical fursuit for a friend, which uses multiple Xiao ESP32C3's from Seeedstudio as "Slaves" and one ESP32 as the main unit.
We want to test SPI/I2C communication amongst all those units to see, check and test various things before implementing them IRL or building them on a breadboard, which includes various temperature readings, monitoring of failing Slaves, error outputs, audio output to a 600 Watt DAC, communication via Bluetooth on a Smartphone and many more small things by the end of our project :)

So quite a project indeed :)

@urish
Copy link
Contributor

urish commented Oct 18, 2022

Quite a project indeed! How many C3 "slaves" do you need to have in order for the simulation to be useful for you?

@EpicLPer
Copy link

EpicLPer commented Oct 18, 2022

Quite a project indeed! How many C3 "slaves" do you need to have in order for the simulation to be useful for you?

So far everything's just a rough sketch, but by the end we'd at minimum need 5 to communicate to each other.
However, less is also okay since we could just split things up, I'm not even a programmer myself (yet), and this would help immensely to get me motivated to look further into things instead of having to flash onto real hardware, deal with god knows how many wires and potential wonky connections, waiting multiple minutes for firmware flashes to update on each Slave and/or the main ESP, etc. etc. etc. :)

@ForrestErickson
Copy link

The recent traffic by "urish" and "EpicLPer" had me thinking I could also be more specific.
For our GPAD device we envision only one SPI Controller and one SPI Peripheral for our use case. Each is an UNO (or equivalent). See: https://github.com/PubInv/general-alarm-device

However, in general, SPI systems might have one controller and many peripherals and so for the use case where the peripheral is something like an UNO or an ESP32 an elaborate systems could have as many peripherals attached as the controller can support the nCS (Chip Select low) pins.

For systems with multi master I2C bus it gets even more, interesting.

Simulating both SPI and I2C systems before breadboarding / prototyping or PCB fabrication would be an ideal use case to demonstrate Wokwi utility.

@c1570
Copy link

c1570 commented Jan 30, 2023

If anyone needs multiple MCUs now and programming JavaScript/TypeScript is an option, wokwi/rp2040js#117 includes a demo program that wires up two RP2040s and simulates a pullup/open collector bus between them. Probably this can be done in a similar way for ESP32 and Arduino, too.

@urish
Copy link
Contributor

urish commented Feb 5, 2023

wokwi/rp2040js#117 includes a demo program that wires up two RP2040s and simulates a pullup/open collector bus between them.

Thanks, very interesting to see this implementation. As far as I can see, the SRAM and peripherals are not shared between the cores? Or did I miss anything?

@urish
Copy link
Contributor

urish commented Feb 5, 2023

Oh, my bad - it's simulating two RP2040 MCUs and not both cores. Then obviously you don't need/want to share the peripherals between the cores. Cool demo!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request open for vote Vote at https://wokwi.com/features
Projects
None yet
Development

No branches or pull requests

8 participants