Simulating a 555 timer in JavaScript with p5.js

The 555 timer is the most popular integrated circuit ever produced – in 2003 it was estimated that a billion units are manufactured every year. It is used for many applications involving oscillating, pulse generation and timing.

Recently I was set the challenge of simulating a 555 timer circuit using JavaScript. this is what I ended up with:

On the top of the screen is a graph showing the voltage level on the output pin of the 555 IC and the voltage level on the anode of the capacitor (relative to ground).

On the left are sliders that allow you to adjust the resistances of the two resistors and the capacitance of the capacitor. There are also labels showing the duty cycle and frequency of the output square wave. Additionally, you can adjust the milliseconds per division of the graph.

On the right is a diagram of the circuit, showing all of the internal components within the IC. The wires between components change colour depending on the voltage on them (relative to ground), where green is 9v and red is 0v.

I used p5.js for the graphics because it’s extremely easy to use and is compatible with most browsers.

If you’d like to try out the simulation you can access it here: https://brychanthomas.github.io/555/. Although it seems to work on mobile devices it is better on computers with bigger screens and better processors. I found that Chrome was the best web browser for it.

Design

Instead of just using the equations that describe the behaviour of the 555 timer as a black box, I thought that I’d simulate the individual components inside the IC in order to learn more about how it works. I based my circuit upon this diagram:

As you can see, to implement this circuit I had to create objects representing resistors, comparators, SR flip-flops and transistors. I didn’t include the reset and control voltage pins because they weren’t necessary for the circuit I was planning to build, although adding them could be a future improvement.

When I first implemented this circuit the output pin was low when the capacitor was charging and high when it was discharging, when it should be the other way round. Looking at the datasheet for the NE555 I saw that there is supposed to be a NOT gate between the complement of Q on the flip flop and the output pin – I think this is represented by the ‘Output Driver’ in the above diagram. Instead of having to fit in a NOT gate I decided to just connect the output pin to the Q pin instead of the Q complement pin, as in this diagram.

Then, in order to create the circuit, I added the external components by following the below diagram:

This sets up the IC as an astable multivibrator, which means that it continually oscillates between two states where the output is either high or low. I had to simulate a capacitor to do this. I used this equation to simulate the charging of the capacitor and this equation to simulate its discharging.

I implemented each electrical component as a class in order to make it easier to re-use the code in any other projects I do. It also made it easy to have multiple instances of one type of component. As well as these classes I needed a class that handled the graph, a class that handled drawing the circuit components each frame, a class that handled drawing the coloured lines between components each frame and a class for the overall 555 timer IC that depended on the component classes.

Simplification

I stuck to simulating voltages without calculating currents. All of the equations and logic I used to simulate the components were based on voltages and, for the capacitor, time, so there was no need to calculate the current in different parts of the circuit. I stored all of the voltages in a dictionary called ‘voltages’, where each point in the circuit is stored as a key:value pair with a string key such as ‘b+’ or ‘TriggerPin’.

Some of the components were heavily simplified to make them easier to implement and allow the program to execute faster. The transistor is the component that suffered the most. It turns out that simulating bipolar junction transistors is very complex. I considered swapping it for a MOSFET, but this also turned out to be complex.

As the signals connected to the transistor were essentially digital, being either 0v or 9v, I decided that there was no point trying to simulate all of the analogue behaviours of the transistor and settled on an incredibly naive and stupid model that would probably disgust any electronic engineer. If the voltage between the emitter and base is greater than 3v, the transistor is saturated. Otherwise it is completely off. What makes it worse is that BJTs are current controlled not voltage controlled but it works well enough for this purpose.

I also simplified the resistors by simulating each group of them as a single object which I called ‘Voltage_divider’. For example, the three 5 kiloohm resistors in the IC are actually simulated as a single component made up of three 5 kiloohm resistances.

The light emitting diode is also very simplified. Instead of following the diode characteristic curve, as it is also essentially in a digital system, I made it turn on (and colour blue) if the voltage across it is more than 3v and turn off otherwise.

Accuracy

To my surprise, the simulation is actually fairly accurate in predicting the duty cycle and frequency of the output. At first the values jump around a bit but they soon settle down. With R1 = 1000 ohms, R2 = 4000 ohms and C1 = 500 uF it says that the duty cycle is 56% and the frequency is 0.32 Hz:

This image has an empty alt attribute; its file name is image-3.png

This calculator says that the frequency should be 0.321 Hz and the duty cycle should be 55.6%. I’m pretty surprised that it matches up so well with the theoretical predictions when I made it out of individual components.

However, the accuracy does decrease a lot at higher frequencies. For example, when R1 = 1000 ohms, R2 = 1150 ohms and C1 = 33 uF the calculator says it should be a frequency of 13.251 Hz and a duty cycle of 65.15, while the simulation reports a frequency of 6.82 Hz and a duty cycle of 61%:

You can see in the graph that the sample rate at which the voltage level of the capacitor is updated and measured (every 10ms) is having a big impact – from one sample to the next the voltage across the capacitor changes a lot, and the comparators and transistor cannot react until the voltage is updated. This means that the voltage of the capacitor can go higher and lower before the output pin is toggled, decreasing the frequency.

To combat this we can increase the sample rate. For example, when I increased the sample rate from every 10ms to every 1ms the frequency was reported as 11.86 Hz and the duty cycle as 64%, which are much closer to the true theoretical values:

However, the downside of increasing the sample rate like this is that the simulation runs more slowly and uses more processing time – it has to update all of the voltages 1000 times a second instead of 100 times a second. However, I am still happy with the model because it was designed more as an educational tool so that I could learn a bit about the 555 IC rather than for predicting the output waveforms accurately.

Improvements

One of the main improvements I could make is improving the graphical design in order to make the simulation easier to use. The line colours are somewhat confusing and the diagram is a little cramped. I’m not a brilliant interface designer but I’m sure that there must be a better way to lay it out.

Another improvement that I could make is in the way I’ve implemented the lines. At the moment I have to specify the voltage connection for the colour and two (X, Y) coordinates for every line. For example, here are all of the lines outside of the IC:

As you can see this is confusing and difficult to set up. I’m sure that there must be an algorithm that can automatically plot right angled lines that cross over as little as possible, but I haven’t found one yet. Alternatively I could create another application that allows you to drag and drop lines and arrange them graphically and then outputs all of the values needed for the configuration you have created, which you can then copy and paste into the program.

Overall I have found this an interesting project and have learned a lot.

Leave a comment

Design a site like this with WordPress.com
Get started