Using Simulink    

Zero-Crossing Detection

When simulating a dynamic system, Simulink checks for discontinuities in the system's state variables at each time step, using a technique known as zero-crossing detection. If Simulink detects a discontinuity within the current time step, it determines the precise time at which the discontinuity occurs and takes additional time steps before and after the discontinuity. This section explains why zero-crossing detection is important and how it works.

Discontinuities in state variables often coincide with significant events in the evolution of a dynamic system. For example, the instant when a bouncing ball hits the floor coincides with a discontinuity in its position. Because discontinuities often indicate a significant change in a dynamic system, it is important to simulate points of discontinuity precisely. Otherwise, a simulation could lead to false conclusions about the behavior of the system under investigation. Consider, for example, a simulation of a bouncing ball. If the point at which the ball hits the floor occurs between simulation steps, the simulated ball appears to reverse position in midair. This might lead an investigator to false conclusions about the physics of the bouncing ball.

To avoid such misleading conclusions, it is important that simulation steps occur at points of discontinuity. A simulator that relies purely on solvers to determine simulation times cannot efficiently meet this requirement. Consider, for example, a fixed-step solver. A fixed-step solver computes the values of state variables at integral multiples of a fixed step size. However, there is no guarantee that a point of discontinuity will occur at an integral multiple of the step size. You could reduce the step size to increase the probability of hitting a discontinuity, but this would greatly increase the execution time.

A variable-step solver appears to offer a solution. A variable-step solver adjusts the step size dynamically, increasing the step size when a variable is changing slowly and decreasing the step size when the variable changes rapidly. Around a discontinuity, a variable changes extremely rapidly. Thus, in theory, a variable-step solver should be able to hit a discontinuity precisely. The problem is that to locate a discontinuity accurately, a variable-step solver must again take many small steps, greatly slowing down the simulation.

How Zero-Crossing Detection Works

Simulink uses a technique known as zero-crossing detection to address this problem. With this technique, a block can register a set of zero-crossing variables with Simulink, each of which is a function of a state variable that can have a discontinuity. The zero-crossing function passes through zero from a positive or negative value when the corresponding discontinuity occurs. At the end of each simulation step, Simulink asks each block that has registered zero-crossing variables to update the variables. Simulink then checks whether any variable has changed sign since the last step. Such a change indicates that a discontinuity occurred in the current time step.

If any zero crossings are detected, Simulink interpolates between the previous and current values of each variable that changed sign to estimate the times of the zero crossings (e.g., discontinuities). Simulink then steps up to and over each zero crossing in turn. In this way, Simulink avoids simulating exactly at the discontinuity, where the value of the state variable might be undefined.

Zero-crossing detection enables Simulink to simulate discontinuities accurately without resorting to excessively small step sizes. Many Simulink blocks support zero-crossing detection. The result is fast and accurate simulation of all systems, including systems with discontinuities.

Implementation Details

An example of a Simulink block that uses zero crossings is the Saturation block. Zero crossings detect these state events in the Saturation block:

Simulink blocks that define their own state events are considered to have intrinsic zero crossings. If you need explicit notification of a zero-crossing event, use the Hit Crossing block. See Blocks with Zero Crossings for a list of blocks that incorporate zero crossings.

The detection of a state event depends on the construction of an internal zero-crossing signal. This signal is not accessible by the block diagram. For the Saturation block, the signal that is used to detect zero crossings for the upper limit is zcSignal = UpperLimit - u, where u is the input signal.

Zero-crossing signals have a direction attribute, which can have these values:

For the Saturation block's upper limit, the direction of the zero crossing is either. This enables the entering and leaving saturation events to be detected using the same zero-crossing signal.

If the error tolerances are too large, it is possible for Simulink to fail to detect a zero crossing. For example, if a zero crossing occurs within a time step, but the values at the beginning and end of the step do not indicate a sign change, the solver steps over the crossing without detecting it.

This figure shows a signal that crosses zero. In the first instance, the integrator steps over the event. In the second, the solver detects the event.

If you suspect this is happening, tighten the error tolerances to ensure that the solver takes small enough steps. For more information, see Error Tolerances.


It is possible to create models that exhibit high-frequency fluctuations about a discontinuity (chattering). Such systems typically are not physically realizable; a massless spring, for example. Because chattering causes repeated detection of zero crossings, the step sizes of the simulation become very small, essentially halting the simulation.

If you suspect that this behavior applies to your model, you can disable zero-crossing detection by selecting the Disable zero crossing detection option on the Advanced pane of the Simulation Parameters dialog box (see Zero-crossing detection). Although disabling zero-crossing detection can alleviate the symptoms of this problem, you no longer benefit from the increased accuracy that zero-crossing detection provides. A better solution is to try to identify the source of the underlying problem in the model.

Blocks with Zero Crossings

Description of Zero Crossing  
One: to detect when the input signal crosses zero in either the rising or falling direction.
Two: one to detect when the upper threshold is engaged, and one to detect when the lower threshold is engaged.
Dead Zone
Two: one to detect when the dead zone is entered (the input signal minus the lower limit), and one to detect when the dead zone is exited (the input signal minus the upper limit).
Hit Crossing
One: to detect when the input crosses the threshold.
If the reset port is present, to detect when a reset occurs. If the output is limited, there are three zero crossings: one to detect when the upper saturation limit is reached, one to detect when the lower saturation limit is reached, and one to detect when saturation is left.
One: for each element of the output vector, to detect when an input signal is the new minimum or maximum.
One: if the relay is off, to detect the switch on point. If the relay is on, to detect the switch off point.
Relational Operator
One: to detect when the output changes.
Two: one to detect when the upper limit is reached or left, and one to detect when the lower limit is reached or left.
One: to detect when the input crosses through zero.
One: to detect the step time.
For conditionally executed subsystems: one for the enable port if present, and one for the trigger port, if present.
One: to detect when the switch condition occurs.

  Solvers Algebraic Loops