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

Create new parts (chips, sensors, etc.) with custom logic #301

Open
urish opened this issue Feb 3, 2022 · 36 comments
Open

Create new parts (chips, sensors, etc.) with custom logic #301

urish opened this issue Feb 3, 2022 · 36 comments
Assignees
Labels
enhancement New feature or request open for vote Vote at https://wokwi.com/features

Comments

@urish
Copy link
Contributor

urish commented Feb 3, 2022

Make it possible to create custom parts and program your own logic:

  1. Define the pins for the part (e.g., for an I2C sensor: GND, VCC, SCL, SDA, INT)
  2. Write some code to implement the logic for the part
  3. Load this part into Wokwi and use it in the simulation.

I've done some prototyping, and one way to implement this in a secure and performant way is to use AssemblyScript together with Web Assembly.

Initial thoughts about the API for creating custom parts:

  1. Keep the function names similar to Arduino (e.g. digitalRead/digitalWrite/pinMode)
  2. Make it easy to include standard protocols (such as UART, I2C, SPI)
  3. The first version should focus in digital simulation, as the Analog part of the simulator is not very mature at this time.

Here's a proposal of what the code for a simple part (pulse counter with an I2C interface) might look like:

import { createI2CDevice, digitalWatch, I2CDevice, I2CPins, registerChip } from 'wokwi-api';

export enum Pins {
  GND,
  VCC,
  SCL,
  SDA,
  PULSE,
}

enum Events {
  PulseIn,
}

const ADDRESS: u8 = 0x22;

export class CounterChip implements I2CDevice {
  private counter: u32;
  private byteIndex: u8;

  constructor() {
    this.counter = 0;
    this.byteIndex = 0;
    createI2CDevice(this, new I2CPins(Pins.SCL, Pins.SDA), ADDRESS);
    digitalWatch(Pins.PULSE, Events.PulseIn);
  }

  i2cConnect(): boolean {
    this.byteIndex = 0;
    return true; /* ack */
  }

  i2cReadByte(): u8 {
    const shiftAmount = this.byteIndex++ * 8;
    return u8(this.counter >> shiftAmount);
  }

  i2cWriteByte(value: u8): void {
    // Writing any value just resets the counter
    this.counter = 0;
  }

  i2cDisconnect(): void {
    // do nothing
  }

  onEvent(event: i32, data: i32): void {
    switch (event) {
      case Events.PulseIn:
        /* data holds the new pin value: 1 for rising edge */
        if (data) {
          this.counter++;
        }
        break;
    }
  }
}

registerChip('i2c-counter', CounterChip);

And another example - HC-SR04 Ultrasonic sensor (for now, with a fixed distance):

import { addClockEvent, digitalWatch, digitalWrite, HIGH, LOW, OUTPUT, pinMode } from './wokwi-api';

const distance = 300;

enum Pins {
  VCC,
  GND,
  ECHO,
  TRIG,
}

enum Events {
  TrigChanged,
  StartEcho,
  EndEcho,
}

export class UltrasonicSensor {
  constructor() {
    digitalWatch(Pins.TRIG, Events.TrigChanged);
    pinMode(Pins.ECHO, OUTPUT);
    digitalWrite(Pins.ECHO, LOW);
  }

  onTrigChanged(value: boolean): void {
    if (!value) {
      const us = 1000;
      const echoDelay = 300 * us;
      const echoTime = Math.round(distance * 58.82 * us);
      addClockEvent(echoDelay, Events.StartEcho);
      addClockEvent(echoDelay + echoTime, Events.EndEcho);
    }
  }

  onEvent(event: i32, data: i32): void {
    switch (event) {
      case Events.TrigChanged:
        this.onTrigChanged(bool(data));
        break;

      case Events.StartEcho:
        digitalWrite(Pins.ECHO, HIGH);
        break;

      case Events.EndEcho:
        digitalWrite(Pins.ECHO, LOW);
        break;
    }
  }
}
@urish urish added enhancement New feature or request open for vote Vote at https://wokwi.com/features labels Feb 3, 2022
@kartben
Copy link

kartben commented Feb 3, 2022

Yes please! ❤️

@urish
Copy link
Contributor Author

urish commented Mar 26, 2022

Started working on this and uploaded an early prototype so users can start playing around and share their feedback.

Here's a quick demo project: https://wokwi.com/projects/327144279206003284
Press "F1" and select "Create a custom C chip (alpha)", then run the simulation to see the Arduino sketch communicating with the custom I2C chip. The chip logic is defined in "i2c-counter.chip.c", and the pinout in "i2c-counter.chip.json".

And a google doc with further explanations: https://link.wokwi.com/custom-chips-alpha

@sjamesparsonsjr
Copy link

Can I suggest the new part creating uses the Fritzing images and pin maps to speed up device creation?

@urish
Copy link
Contributor Author

urish commented Apr 9, 2022

@sjamesparsonsjr that suggestion may fit better in #302

@Project487
Copy link

Hi,
This is great. I have successfully created a simple chip based on the i2c-counter example.
Is it possible to create more than one chip for each system model? Can a created chip be 'saved' to be used for other simulations?
I hope the development continues!

@urish
Copy link
Contributor Author

urish commented Jul 2, 2022

Thanks for the feedback!

It's possible to create multiple instance of each chip type. Here's a recent example with 2 copies of the same chip:

https://wokwi.com/projects/335750100024296020

What do you mean by "saving" custom chips for using in other simulation?

@Project487
Copy link

Hi,
Thanks for the reply.
The example given shows the chip defined as "chip-bounce"; where is this definition made? Can "chip-bounce" be saved as an entity to be used later, much like the the 'new parts' list on the simulation panel?
Diagram.json shows some interesting parts not shown in the 'new parts' drop down. Is there a list of these parts? (I came across an example using the Adafruit SSD1306 OLED display, wokwi-ssd1306, also not listed in the 'add new part' drop-down menu).
I would really like to use the chip creation feature and hope these questions aren't too naive. Thanks again.

@urish
Copy link
Contributor Author

urish commented Jul 7, 2022

The example given shows the chip defined as "chip-bounce"; where is this definition made? Can "chip-bounce" be saved as an entity to be used later, much like the the 'new parts' list on the simulation panel?

The definition is implicitly made whenever you have a pair of "whatever.chip.json" and "whatever.chip.c" files. Right now, the chips are saved along with the project, but we're looking into a way to make them separate entities that can be imported into a project (much like you can import Arduino libraries using the Library Manager).

The current solution we're looking into is hosting custom chips on GitHub - you create a github repo with the custom chip source code and definition, and then you'll be able to submit the repo to a central Wokwi Chip registry, and users will be able to pull chips from this registry. Still working out the details.

Diagram.json shows some interesting parts not shown in the 'new parts' drop down. Is there a list of these parts? (I came across an example using the Adafruit SSD1306 OLED display, wokwi-ssd1306, also not listed in the 'add new part' drop-down menu).

These parts aren't officially supported. Some are incomplete (e.g. wokwi-serial-port - see #149), or deprecated (like wokwi-ssd1306), and some just need some documentation and perhaps a bit of refactoring (e.g. #240).

I'm curious, what are you using the custom chips for?

@Project487
Copy link

Thanks for the information. A GitHub chip repository seems very reasonable. I will await developments.
The chips are sensors for a project (a model submarine!) I want to build; the sensors need to interact with one-another. For example a sensor determining the water level in ballast tanks needs to affect the output of (say) an MPU6050 accelerometer so feedback can adjust pitch (level) of the sub. Currently I think the outputs have to be provided independently with sliders. Is the code available for the officially supported chips?
Thanks again.

@urish
Copy link
Contributor Author

urish commented Jul 24, 2022

The chips are sensors for a project (a model submarine!) I want to build

Sounds like a cool use-case! Do you have some models?

Is the code available for the officially supported chips?

Only for a few of them, e.g. the ILI9163 Display Driver. I guess you are looking for the code of the MPU6050? Is there anything else?

@jaseinatl
Copy link

Not sure if this is the appropriate place to put this, but I was thinking that it would be cool to be able to select several predefined components and click a button that allowed you to make your own custom component. So , for example, If I m working with a lot of LEDs and their associated resistors, I would like to be able to generate an LED and connect it to a resistor, then with both items selected, define a custom component that would only show up locally in my dev. environment.

Then every time I needed one of these, I could grab it from my + button under My Custom Components and voila it would appear just how I had wired it. This would be super easy to code and the combined elements as their own custom component would have all of the attributes that were not already defined. In other words, it would have two pins (the two open pins) to connect to as well as the resistance on the resistor, the color on the LED. When I generate my custom component made of other components, that stuff would automatically be exposed. Maybe that's a different request, but just in case.

@urish
Copy link
Contributor Author

urish commented Sep 21, 2022

Maybe that's a different request, but just in case.

Yeah, that sounds like a new feature request - some kind of "modules" library. One way to sort-of achieve this now is to have a project with your common "modules", and then you can select several parts, copy them, and paste them into another projects. They'll be copied along with all the internal connections. Anyway, feel free to open a new feature request!

@urish urish self-assigned this Sep 28, 2022
@urish
Copy link
Contributor Author

urish commented Sep 28, 2022

Update: the Custom Chip API is now getting into a beta phase. There will probably be some minor changes, but I think we're already clear on the general direction.

You can view the current API reference here: https://gist.github.com/urish/f9129d3d34ffd557eccf354907663051, and we expect to shortly migrate it to https://docs.wokwi.com.

Here's a bunch of examples for custom chips, showing what you can do with the current API:

@bato3
Copy link

bato3 commented Oct 8, 2022

Nice work!

The API documentation is clear, but it lacks information about the chip.json structure (display, controls).
BTW: in doc is analog example, but not here.

And my propositions:

  • It should be possible to define the appearance of the element. For example:
    • by handling wokwi-elements format,
    • selecting an case (e.g .: DIP_n_, SOP_n_, TQFP_n_, TO-98, TO-225, TO-220),
    • uploading an SVG file,
  • Are you planning to create a custom-element library?

//edit:

You wrote:

It's possible to create multiple instance of each chip type. Here's a recent example with 2 copies of the same chip:

Is possibl eto create multiple different chips? (eg XOR CD4030 + NAND MC14093B )

@urish
Copy link
Contributor Author

urish commented Oct 8, 2022

Thanks for the feedback @bato3!

It should be possible to define the appearance of the element. For example:

Yeah, the details aren't clear yet, but this might be part of #302. Probably uploading an SVG file and defining the pins.

Are you planning to create a custom-element library?

There'll probably be some way to submit your custom chips and for other users to add them. Perhaps through GitHub. Still thinking of possible ways to accomplish this.

Is possibl eto create multiple different chips?

Yes, you can have many chip types in a single project, and multiple instances of each chip type.

@jaseinatl
Copy link

Are you planning to create a custom SVG element resource that WOKWI loads and all SVGS can simply reference? Like what you do with the "hole" symbol on your current SVG artwork?

Ideally, given a default library set, someone could create any svg and include your resources for "pins" or solder points or connectors of any sort and that SVG would be ready to be added to the layout, including accessibility to connections. The only thing it would require for simulation would be the underlying code which would benefit from the standardization of the connector SVG resources.

By standardizing every connector type and perhaps some common display types like (on board LEDs), simple hooks in the API would help with the logic part. But even before the logic part was not done, having the SVG with standardized components would enable layout and connections immediately. Upon adding a custom component all of the "pin" SVG symbols would be enabled for connections, for example. This might make it easier to debug upon running the simulation. Ill check out 302 to see if its covered there. Great work on custom elements. thanks

@urish
Copy link
Contributor Author

urish commented Oct 9, 2022

Probably for starters, the user will just provide the complete SVG. To make things simple. Then we'll see how to evolve it based on how users will use it and the feedback we get (that's how Wokwi goes in general)

@urish
Copy link
Contributor Author

urish commented Nov 22, 2022

Update: We have a proof-of-concept of creating custom chips using the Rust language. Here's an example of an inverter:

https://wokwi.com/projects/346597452510397012

@urish
Copy link
Contributor Author

urish commented Dec 6, 2022

New docs for custom chips: https://docs.wokwi.com/chips-api/getting-started

Also, a new example of a chip hosted in GitHub repo: https://github.com/wokwi/inverter-chip

@alextrical
Copy link

Thank you for the progress on this amazing addition,
Can I confirm that the custom chip functionality isn't currently supported in Visual Studio?
(or do i need to put the chip definitions somewhere other than root)

@urish
Copy link
Contributor Author

urish commented Feb 12, 2023

Can I confirm that the custom chip functionality isn't currently supported in Visual Studio?

It is supported in Visual Studio Code. Please take a look at the documentation: https://docs.wokwi.com/vscode/project-config#custom-chips

Is the documentation about this clear or does it need any improvements?

@alextrical
Copy link

Ah, perfect, it seems that once again I failed to locate the relevant documentation.

It took me a second to work out that its possible to replace the 'wasm' with the 'c' file, and now it works perfectly. I think the thing that tripped me up was the requirement to define the chip in the '.toml' file, instead of the web version auto detecting, though its added ability to add the chip definitions to sub folders is really neat.

Keep up the amazing work

@alextrical
Copy link

I may have spoke too soon on it working with a *.chip.c file, it seems to hang on the 'Loading project...' message.
I will convert the chips over to a wasm and load them instead :)

@urish
Copy link
Contributor Author

urish commented Feb 12, 2023

Yeah, it doesn't know how to compile things - you have to feed it with binaries :)

Do you need any assistance in converting the chips to wasm?

@alextrical
Copy link

I will see what I can do for a little bit, using the existing examples, and try to convert the 'eeprom_custom_chip_test' example into wasm.

I will let you know in an hour if i'm stuck. :)

@alextrical
Copy link

alextrical commented Feb 12, 2023

Ive had some luck using your example for an inverter and the EEPROM example, to compile the wasm at the following repo https://github.com/alextrical/wokwi-24C01-custom-chip
Oddly i had issues getting the Build part of the Workflow to trigger ("github.event_name == 'push'" wasn't triggering when pushing from GitHub Desktop) and then the "ncipollo/release-action" failed with the following error 'Error undefined: No tag found in ref or input!'

Ive managed to force it through to a release, and can now see the desired chip.zip file :)

edit: all fixed, I wasn't using "tags" in the push, now I have done that it works without having to edit the Workflow. The error was pretty clear

@urish
Copy link
Contributor Author

urish commented Jul 28, 2023

New UI to easily create custom chips and add them to your project:

image

image

Also, updated the documentation:

@urish
Copy link
Contributor Author

urish commented Aug 12, 2023

New video tutorial - how to create custom chips, 3 examples in 15 minutes

https://youtu.be/yzdCS3A4DvU

@urish
Copy link
Contributor Author

urish commented Sep 26, 2023

Another video tutorial: Creating an I2C I/O expander chip from scratch in Wokwi, using the Custom Chips API

@InRiPa
Copy link

InRiPa commented Nov 14, 2023

This is really great! One question, is or will there be a searchable part library, where i can checkout what other users did? Just so I don't have to reinvent the wheel when it comes to common chips.

@urish
Copy link
Contributor Author

urish commented Nov 14, 2023

We plan to have some list soon - probably in a public GitHub repo. For now, you can find the most comprehensive list here: https://docs.wokwi.com/chips-api/getting-started#chip-examples

@Crispkreme
Copy link

hello, i would like to ask if there is a component like bluetooth module and nrf module in wokwi?

@apollolabsdev
Copy link

Is an icon/image editor for the custom components something planned for?

@urish
Copy link
Contributor Author

urish commented Mar 31, 2024

Is an icon/image editor for the custom components something planned for?

Can you elaborate on what would you like to see?

@apollolabsdev
Copy link

It's more of an aesthetic thing really. Rather than just the default green block look, maybe users can have the option to upload or edit an image replicating the actual component being modeled. Like all other built-in components in the library.

@mohdrais
Copy link

Can somebody create a module sensor with RS485? Maybe the sensor can read only one input such as temperature. Those who would like to expand the sensor with more than one input can modify the basic module to include, may be humidity, oxygen concentration and so on.

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