Wokwi Simulator Custom Chips

This thread is for listing Wokwi Custom Chips. If you use or know of any interesting ones, please post them here.

I use a couple Wokwi "custom chips" to test code by posters on the forum.

Two of my favorites are:,

They are both demonstrated in:

I often pull up that simulation up as a testbed and drop a poster's code in to see how things run.

Frequency Counter

I've just written my own Frequency Counter custom chip, as demonstrated here:

image https://wokwi.com/projects/406518140295703553

but I haven't yet packaged it in Github. It is packaged in Github here:

The Frequency Counter can detect up to 8MHz from an simulated Uno, and the code in the sketch demonstrates a few methods of pulse generation.

code
/*
  Custom Frequency Counter chip example for Wokwi.
  https://wokwi.com/projects/406518140295703553 -- Using https://github.com/drf5n/Wokwi-Chip-FrequencyCounter
  https://wokwi.com/projects/406335146945275905 -- Using tabbed files
  built from https://wokwi.com/projects/327458636089524820

  Start the simulation. The green LED shows the output of the inverter.
  The frequency counts show up in the Serial monitor.

  For more information on custom chips: https://docs.wokwi.com/chips-api/getting-started
*/

#include "TimerHelpers.h" // https://gammon.com.au/timers // to configure PWM

const int scheme = 6; // 0..8 Choose one 0 is slowest range, 6 is fastest, 8 is variable
const unsigned long Period = 1000; // 0..? keep lower than 16k for delayMicrosecond() modes
unsigned long varPeriod = Period; // 
const byte PIN = 9;  // this is OC1A (timer 1 output compare A) for sharing with PWM modes

void setup() {
  pinMode(PIN, OUTPUT);
}

void loop() {
  switch (scheme) {
    case 0: // millisecond period with divided delay()
      digitalWrite(PIN, LOW);
      delay(Period / 2); // 50%
      digitalWrite(PIN, HIGH);
      delay(Period - Period / 2); // Compliment of 50% to deal with odd numbers and zeros
      break;
    case 1: // microsecond period with divided delayMicroseconds()
      digitalWrite(PIN, LOW);
      delayMicroseconds(Period / 2);
      digitalWrite(PIN, HIGH);
      delayMicroseconds(Period - Period / 2);
      break;
    case 2: // microsecond period direct port manipulation
      PORTB &= ~bit(1);
      delayMicroseconds(Period / 2);
      PORTB |= bit(1);
      delayMicroseconds(Period - Period / 2);
      break;
    case 3: // PINx toggle in loop()
      PINB = bit(1);
      break;
    case 4: // PINx toggle, one cycle unrolled per loop()
      PINB = bit(1);
      PINB = bit(1);
      break;
    case 5: // unrolled PINx toggle to reduce loop() overhead
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      PINB = bit(1);
      break;
    case 6: // PWM output
      static bool init6 = false;
      if (!init6 ) {
        init6 = true;
        set8MHz(0);
      }
      delay(10);
      break;
    case 7: // broken PWM output
      static bool init7 = false;
      if (!init7 ) {
        init7 = true;
        set8MHz(1); // alternate
      }
      delay(10);
      break;
    case 8: // variable 0-Period millis
      static int lastA0 = -1;
      int potVal = analogRead(A0);
      if (potVal != lastA0) { // change detect pot
        varPeriod = map(potVal, 1023, 0, 0, Period);
        lastA0 = potVal;
      }
      digitalWrite(PIN, LOW);
      delay(varPeriod / 2);
      digitalWrite(PIN, HIGH);
      delay(varPeriod - varPeriod / 2);
      break;
    default:
      static bool initDefault = false;
      if (!initDefault) {
        initDefault = true;
        Serial.begin(115200);
        Serial.print("unsuppored scheme: ");
        Serial.print(scheme);
      }
  }
}

void set8MHz(const byte scheme) {
  TCCR1A = 0;        // reset timer 1
  TCCR1B = 0;
  // set up Timer 1
  TCNT1 = 0;  // reset counter
  if (scheme == 0) { // 8MHz one way:
    OCR1A = 1;  // compare A register value //
    // WGM 15: FastPWM with TOP=OCR1A
    Timer1::setMode (15, Timer1::PRESCALE_1, Timer1::SET_A_ON_COMPARE);
  }
  else if (scheme == 1) { // 8MHz the other way // Doesn't work on Wokwi
    OCR1A = 0;  // compare A register value //
    // WGM 15: FastPWM with TOP=OCR1A
    Timer1::setMode (15, Timer1::PRESCALE_1, Timer1::TOGGLE_A_ON_COMPARE);
    /*
      Page 103 of https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf

      A frequency (with 50% duty cycle) waveform output in fast PWM mode can be achieved by setting OC1A to toggle its logical
      level on each compare match (COM1A1:0 = 1). This applies only if OCR1A is used to define the TOP value
      (WGM13:0 = 15). The waveform generated will have a maximum frequency of fOC1A = fclk_I/O/2 when OCR1A is set to zero
      (0x0000). This feature is similar to the OC1A toggle in CTC mode, except the double buffer feature of the output compare
      unit is enabled in the fast PWM mode.
    */
  }
}

The Wokwi custom chip API is documented in the:

...which has lots of examples. However, if you're looking for a non-official custom chip, it can be hard to find. Googling for them, you can often find broken implementations, or old implementations of them.

If you've written or use interesting Wokwi custom chips, feel free to post about them here.

See also:

1 Like

These are a straight cut and paste from Custom Chips Getting Started:

Basics

Communication

  • SPI Chip - A basic ROT13 cipher over SPI
  • UART Chip - A basic ROT13 cipher over UART
  • I2C Chip - Simple counter with interrupt output
  • EEPROM Chip - Simple I2C memory with 256 kbits by Benny Meisels

Displays

Sensors

Complex chips

1 Like

Up/Down counter limit switches

Here's a Wokwi custom chip with an up/down counter and upper/lower limit/threshold outputs:

  • Wokwi limitCounter -- up/down counter with NO/NC high/low limit outputs.

It isn't a custom chip, but I also learned that you can use the Wokwi stepper motor inputs or A4988 outputs as quadrature signals that work as an encoder:

Stepper quadrature output as encoder input

And another with an A4988 driver and clearer quadrature output/input signals.

(With that, you could read a couple of the motor's quadrature signals with an Arduino and with a function on the Arduino, simulate motor feedback.)

GPS

Luxometer BH1750

1 Like

Sample chips from this tutorial video: https://www.youtube.com/watch?v=yzdCS3A4DvU

And from the getting started, the plain hello-world chip:

I extended those examples to:

I hacked together a L298 4-channel driver chip in this simulation:

And another version:

https://github.com/drf5n/Wokwi-Chip-L298N

Also a Wokwi TB6612FNG (per Pololu Pololu - TB6612FNG Dual Motor Driver Carrier or per Datasheet)

https://github.com/drf5n/Wokwi-Chip-stepper-esc

I saw an interesting version of a diode custom chip by Maverick on Discord in:

Here's some discussion of a diode component: Diode component (for making a matrix of switches) · Issue #349 · wokwi/wokwi-features · GitHub

Here's a simulation of a DC motor with variable speed and inertial by using a Stepper with a custom stepper-esc chip:

The sim uses a chip-scope to show the input and output signals from the ESC, and you can vary the MaxSpeed and a Tau/Time constant variables to control the speed and inertia of the motor, while controlling the power to the motor with plain old PWM.

The development process of the DS18B20 custom chip from an idea to a (beta) component included in the Wokwi menu is here on Discord:

Welcome.
You can share your projects, so we can try them.
Do you have a Github account, then you can put them there.
Some custom parts can be more integrated in Wokwi.
There are a number of options, but I don't know much about it.

Have a look at the development of the DS18B20:
First it was a Custom Chip, just like any other.
Then a Custom Chip without its code in the project: Dallas DS18B20 Example - Wokwi ESP32, STM32, Arduino Simulator
Then a svg file for the shape: Rangkaian sensor suhu DS18B20 - Wokwi ESP32, STM32, Arduino Simulator
Then it was included in the menu for the parts in the Wokwi diagram.
And the code is on Github: GitHub - bonnyr/wokwi-ds1820-custom-chip

GPS Simulator chip

Found at Discord

Wokwi PN2222 transistor custom chip:

Found on Discord

Schmitt Trigger custom chip

This demo has an attribute for threshold and hysteresis:

Nice.

Add an LED that follows the output state.

I am curious though, given wokwi's limited analog capability, where you see this being used.

I haven't played much with the analog sensors they do have, so.

a7

1 Like

I added two LEDs, one upstream and one downstream of the Schmitt trigger, and also a digitalRead of the pot. I think I was playing with sensing an analog signal on a digital pin, and Wokwi wouldn't do it unaided. Arduino AVRs have schmitt triggers on their inputs, and if you do some switch debouncing with a cap, the hysteresis of the ST makes them pretty clean.

Resistor-ladder voltage divider as built into an 5-button LCD shield:

A BME280 humidity, pressure and temperature sensor:

With Adafruit_BME280 library:

With BME280 Library:

1 Like

I have created two projects with AHT25 Temperature and Humidity sensor (which I created for these projects) : [Wokwi - Online ESP32, STM32, Arduino Simulator](Nano - AHT25 Sensor) and this one for multiple I2C ports (with SoftwareWire library) : [Wokwi - Online ESP32, STM32, Arduino Simulator](Arduino Nano - Multiple AHT25 Sensor)
GitHub - fido974/wokwi-aht25-custom-chip: AHT25 sensors for Arduino simulated in Wokwi - SofwareWire library used to have multiple I2C buses

1 Like

Here are some custom chips I created.
LM35: https://wokwi.com/projects/361217548093868033
CD4026B: https://wokwi.com/projects/361123975583660033
MCP9808: https://wokwi.com/projects/379919046996397057
CD4094: https://wokwi.com/projects/412763780750064641
74HC164: https://wokwi.com/projects/409480203031581697

These others are potentially buggy, less useful or experimental.
DF_Robot ME007YS: https://wokwi.com/projects/380022336994774017 (Requires different custom chip code for different libraries.)
TXS0108E: https://wokwi.com/projects/348849371514667603 (Not really useful.)
Capacitive soil moisture sensor: https://wokwi.com/projects/348850059861819987 (It's just a generic analog sensor.)
DS1302 RTC: https://wokwi.com/projects/349506706856739410 (Requires different custom chip code for different libraries.)

1 Like

Here's the Up/Down counter limit switch packaged in github for use as a Wokwi custom chip dependency:

The chip could monitor the step/dir of a stepper motor and simulate positional feedback as limit switches or a potentiometer, such as in: