Signal Generator in a PIC16F1829–Part 1

signal_generator_sig3

 

I recently completed a software design  to control a Keysight digital storage oscilloscope (DSO).  The end goal of the software was to initialize oscilloscope settings,

set a trigger, and then make timing measurements from a trigger on one scope channel to an undefined point of a signal on a second scope channel.

The second signal I had to measure was not something that would be available to me during development.  This posed a bit of a problem.  I knew the signal would be a rising signal between 0-5V,  but did not know how complex the signal might be.  It could be exponential, a simple ramp, sinusoidal, or some weird combination.

 

To test my software I decided to implement a waveform generator in a small microcontroller on the design.  The concept is about as simple as you can get.  I fed the pulse-width modulated (PWM) output of a Microchip PIC16F1829 into an RC filter, with an op-amp voltage-follower to isolate the signal from the scope.  The 270 ohm resistor on the output is protection against the user shorting the signal, as it also feeds to a terminal block on the design.

pwm_signal

 

I wanted to have the option of selecting between four different test signals whose “timebase” was determined by a potentiometer.  I would generate a trigger and the test signals with a button press.  The adjustable timebase combined with fixed PWM frequency/RC filter (R7 and C10) would cause the signal to get squeezed or stretched depending on the potentiometer setting, but that was okay for this design.

The first step was to come up with test signals.  So for starters I used Microsoft Excel to create some funky equations that would give me interesting waveforms.  One of the signals (signal 4)  is shown below.  A benefit of using  Excel is that I could quickly change the equations and track the result was in an associated chart.

signal_generator_excel

 

Once I had the equations defined I  wrote a Visual Basic (VB) program to generate C code structures/arrays that I could use in the microcontroller’s firmware.  This was a lot faster than transcribing the values from the spreadsheet directly into C.

The VB program was written to generate appropriately formatted text in a text box on the VB form.   This resulting text was  then copied/pasted into my firmware.  The form is shown below.   You can see how the byte values in the character array for “sig4.PWM[]” below match the Excel spreadsheet values above (although rounded to integers, and limited to 0-255).

image

 

In part two I’ll cover some of the firmware that was used to generate the signals.  But you can see from the scope capture below that I was able to approximate the waveform using the PWM output and the sig4.PWM[] character array.  The yellow signal (channel 1) is a trigger signal generated by the microcontroller.  Green (channel 2) is the waveform generated by the PWM-RC filter combo.  The distorted nature of the signal has to do with the PWM frequency, RC circuit component values, and the time between PWM output changes (established by a potentiometer voltage).

sig_4

 

Here’s the text of the VB code…

Imports System.Math

Public Class Form1

    Private Sub Button_Generate_Click(sender As Object, e As EventArgs) Handles Button_Generate.Click

        TextBox_Output.Text = ""
        For j = 1 To 4

            Dim result As Double = 0
            Dim Output_String = "const struct " + TextBox_StructureName.Text + j.ToString + " {" + vbCrLf
            Output_String += vbTab + "unsigned char Size;" + vbCrLf
            Output_String += vbTab + "unsigned char PWM[" + TextBox_Size.Text + "];" + vbCrLf
            Output_String += vbTab + "} " + TextBox_StructureName.Text + j.ToString + " = " + vbCrLf
            Output_String += vbTab + vbTab + "{ " + TextBox_Size.Text + ", {" + vbCrLf + vbTab + vbTab

            For i = 1 To Val(TextBox_Size.Text)
                Select Case (j)

                    Case 1
                        result = Sin(i / 90) * 255
                        If result < 0 Then result = 0
                        If result > 255 Then result = 255
                        Output_String += result.ToString("0")
                        If (i <> Val(TextBox_Size.Text)) Then Output_String += ", "
                        If i Mod 10 = 0 Then Output_String += vbCrLf + vbTab + vbTab

                    Case 2
                        result = 5 * (2.2 - Exp(i)) / -Sin(i / 90) * Exp(-i)
                        If result < 0 Then result = 0
                        If result > 255 Then result = 255
                        Output_String += result.ToString("0")
                        If (i <> Val(TextBox_Size.Text)) Then Output_String += ", "
                        If i Mod 10 = 0 Then Output_String += vbCrLf + vbTab + vbTab

                    Case 3
                        result = (Sin(i / 90) + Sin((8 * i) / 90) + 0.5) * 100
                        If result < 0 Then result = 0
                        If result > 255 Then result = 255
                        Output_String += result.ToString("0")
                        If (i <> Val(TextBox_Size.Text)) Then Output_String += ", "
                        If i Mod 10 = 0 Then Output_String += vbCrLf + vbTab + vbTab

                    Case 4
                        result = (Sin(i / 90) + Sin(8 * (i + 45) / 90) - 0.5 * (Sin(22 * i / 90)) + 1.5) * 75
                        If result < 0 Then result = 0
                        If result > 255 Then result = 255
                        Output_String += result.ToString("0")
                        If (i <> Val(TextBox_Size.Text)) Then Output_String += ", "
                        If i Mod 10 = 0 Then Output_String += vbCrLf + vbTab + vbTab

                End Select

            Next

            Output_String += "} };" + vbCrLf + vbCrLf

            TextBox_Output.Text += Output_String

        Next


    End Sub
End Class

Trackbacks

  1. […] waveform equations and Visual Basic (VB) code to convert the equations into C coded look-up tables (that post is here).  The output of the VB program is copy/pasted into firmware for a Microchip […]

Speak Your Mind

*