Professor Mark Csele


A basic oscilloscope was developed for a workshop project at the college in which students solder various components onto a PCB to build the scope including through-hole and SMT parts. In the usual fabrication technique for embedded projects, the MCU is soldered onto the PCB first and then programmed using an in-circuit programmer such as Microchip’s PicKit 3

The oscilloscope is pictured here completely packaged. The coloured wires at the bottom connect the external PicKit3 debugger/programmer to the chip already in the circuit (The MCU is SMT and was soldered to the PCB then programmed in-circuit).


In the current prototype, the following are supported:

  • Timebase (seconds/div): 10μ, 20μ, 50μ, 100μ, 200μ, 500μ, 1m, 2m, 5m, 10m, 20m, 50m, 100m
  • Vertical (Volts/div): 50, 20, 10, 5, 2, 1, 500m, 200m, 100m
  • Vertical position adjustment
  • Trigger Mode: Free Running, Rising Edge, Falling Edge
  • Trigger position adjustment

The oscilloscope is usable to approximately 200KHz (a sampling filter eliminates any signal above 500KHz), with good waveshape rendition up to about 100KHz making it ideal for use in the audio range.


The basic scope employs a Microchip dsPIC33FJ64GS606 microcontroller which has a high-speed (1MS/s) on-chip ADC. The analog input signal first passes through a 100:1 voltage divider to reduce the voltage range – an input signal of 300V would be hence be reduced to 3V. That signal then passes through three sets of amplifiers which scale the voltage range appropriately: the amplifiers in the prototype version have a gain of 1, 10, and 100. On the *100 range, for example, an input signal of 1Vp-p is presented to the ADC channel as 1Vp-p. Each input is then biased by a summing amplifier so that the bipolar signal becomes a unipolar signal with the range 0 to 3V (with a “zero” value of +1.5V). So, for an input range of -1.5V to +1.5V, the “*100” ADC is presented with a signal which has a range 0V to 3V (with +1.5V being “zero” on the input). By selecting the appropriate ADC input, a different analog range may now be selected. Regardless of the range, though, the input of the ADC is restricted to the range 0V to +3V. Since the LCD (which has a vertical resolution of 64 pixels) is divided into six divisions of ten pixels each, the aforementioned example results in a vertical display of 500mV/division. Ranges of 200mV/div and 100mV/div are accomplished by multiplying the input values in the same manner as “digital zoom” on a camera.

Rotary encoders are used to select most user parameters. These encoders produce two pulses, the order depending on the direction of rotation. Inexpensive D flip-flops process these signals which are connected to change-interrupt inputs allowing detection of the change of parameters even while the scope is in, say, a loop waiting for signals to acquire. Aside from six encoders (five are currently assigned to Vertical, Vertical Position, Timebase, Trig Mode, and Trig Position), eight small pushbuttons are also used for user interface. Currently, only two pushbuttons are used for backlight control (important with battery power since the backlight LEDs draw almost as much as the rest of the circuitry) and the Auto Calibrate function.

Complete Schematic of the oscilloscope.

The actual hardware was developed by a colleague, Professor Stefane Filion of the Electronics Department at the college where I teach.


The LCD display is an inexpensive graphical unit from New Haven Display and features a resolution of 128 by 64 pixels. The left half of the screen is the actual scope grid and is divided into divisions of ten pixels square. The resulting display is six divisions high by ten divisions long. The remaining right side of the screen is used to display the timebase, Volts/division, and trigger mode.

The majority of the code is used for graphical display: it consists of a plot system to graph points and draw lines between adjacent points, and a character generator allowing text to be displayed. Since this is a graphics-only LCD, text must be generated as a series of dot-patterns for display (via a large look-up table in the code).

Another interesting feature is the auto-calibrate feature which compensates for the DC offset of the OP-Amps used in the analog front-end. When selected, AutoCalibrate prompts the user to ground the input, then, one channel at a time, ramps to voltage on an internal DAC until the ADC input reaches the midpoint (“zero volts” or 0x200 on the 12-bit ADC used). These offset values are then written directly to the last page of flash program memory using RTSP since the MCU chosen lacks a “user” flash area as many low-end devices (e.g. the 18F452) have.

Complete Code of the oscilloscope written in assembly language. Build under MPLAB 8.xx.

An actual display screen. Shown is a 10KHz sine wave – the “fuzziness” around the wave is caused by the display of multiple traces as the shutter speed was slow during the photograph. Note the calibration: as expected, a 10KHz wave has a 100μs period as reflected here.