Oscilloscope and Function Generator Using Teensy 3.1

Status
Not open for further replies.

jomac

Member
Im on the lookout for two projects (initially) for the workshop, the first is an oscilloscope that outputs its display to a LCD and not via USB to a PC, something that can be stand alone. The second is a function generator that will output a signal in Sine, Square and triangular waveforms, the more advanced the better in either case. Has anyone any suggestions or pointers with this?

And also a small question, i read that the Teensy 2 can measure a signal up to 5Mhz, can anyone tell me what the Teensy 3.1 is capable of?

Thanks in advance.

John
 
For the function generator you could use the 12bit DAC, but you only have 1 pin that can do that. You could also filter PWM output but it wouldn't be ideal.

The oscilloscope may be more difficult - pushing data to an LCD takes a lot of cycles, but interrupts would help you out heaps here. You'd have to see whether the impact is going to ruin your data. As for ADC sampling speed, the datasheet has some more info, but it seems fairly fast. Page 680 of the datasheet has the info you need.
 
If you are interested in a project with excellent learning experience, go ahead and try to build an logic analyzer or oscilloscope using a Teesny ETC. Most real digital oscilloscopes contain FPGA's for a reason ;-)

However, should you be interested in a functioning, precision measuring instrument i'd suggest you listen to the expert advice given by people with a couple decades experinece. Pauls advice hads been very consistent in advising to get a real Oscilloscope, not a questionable $50 piece of electronics.

If you are not sure what to look for in an Oscilloscope then watch some of the many reviews on Dave Jones EEVBlog and some of the videos where Dave uses the oscilloscope to measure a whole varity of things with the oscilloscope. That will provide you with a very good starting point of what to look for.
A used analog oscilloscope for $50-$100 from a brand name such as tektronics is much better tha one of those cheap Chinese $50 contraptions.
 
Function Generator

I took a sine wave generator from Paul tweaked it and tested it. This produces a signal at exactly 100 Hz as tested with my HP 3561A spectrum analyzer. I trust it. You should be able to use it to create other functions. If you do it would be interesting to post back here.

I found some idiosyncrasies since posting the code initially. They are in the comments of the code. Basically I cannot output a signal above an integer value of 2733 though in theory with it being a 12 bit DAC, I should be able to output 4096. In practice everything about 2733 gets clipped to 2.151 Volts.

Can anyone see a reason for this?

Code:
// Simple DAC sine wave test on Teensy 3.1
// DAC is 12 bit using stable reference voltage
// deltaTime of 90 for N=6 @ 96 MHz -0 or -O3 gives precise frequency
// deltaTime of 50 for N=1 @ 96 MHz -O gives precise frequency
// smaller deltaTimes not necessarily precise
// maximum output integer on analogWrite function is 2733 without clipping
// maximum output voltage from Teensy 3.1 is 2.252 Volts
// when subsequent points are viewed on an oscillascope, on a generally downward
//    trending portion of the graph, the line is jagged, meaning that the next point 
//    that you expect should be lower than the previous one will actually be higher
//    Thus the output signal should be filtered.

int ledPin = 13;
int led = 0;     // use to toggle led
int analogBits = 1350;
boolean output;
byte n, N = 6;     // number of harmonics (1 to 6)
float A[6] = {0.008, 1.0,0.007, 0.006, 0.005, 0.004};
float phase[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
float amplitude;
float twopi = 3.1415926535 * 2;
elapsedMicros usec = 0;
elapsedMicros time = 0;
// I started with the eq'n 50 + (N-1)*40/5, but frequencies were wrong for intermediate N
uint deltaTime = 65 + (N-1)*25/5;   // microseconds
float Fw = 100;

void setup() {
  analogWriteResolution(12);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  delay(800);

  // normalize sum of amplitudes to one
  float sum  = 0.0f;
  for (n=0; n<N; n++)
    sum += A[n];
  for (n=0; n<N; n++)
    A[n] = A[n]/sum;
}

void loop() {
  time = 0;
  amplitude = 0.0f;
  for (n=0; n < N; n++)
    amplitude += A[n] * sinf(phase[n]);
  analogWrite(A14, analogBits + (int) (analogBits * amplitude));
  for (n = 0; n < 2; n++) {
    phase[n] += twopi * (n + 1) * Fw * deltaTime * 1e-6;
    if (phase[n] >= twopi) {
      phase[n] = phase[n] - twopi;
    }
  }

  led = led + 1;   // toggles the LSB
  output = ((1 << 14) & led); // value of shifted bit
  digitalWrite(ledPin, output);

  while (usec < deltaTime);  // wait
  
  usec = usec - deltaTime;
  
  //Serial.println(time);
  //time = 0;
  //Serial.println(output);
}
 
Last edited:
Status
Not open for further replies.
Back
Top