Square wave with 1kHz

I am using this loop code to generate square with 1kHz:

void loop() {
    for (int i = 0; i < 128; i++) {
      digitalWrite(pin_LED, HIGH);
      delayMicroseconds(500);
      digitalWrite(pin_LED, LOW);
      delayMicroseconds(500);
    }
}

response is:
image
128 pulses with delay of 80ms (12,5Hz), but when I put a delay of 1s this wave is generated:
image

void loop() {
    for (int i = 0; i < 128; i++) {
      digitalWrite(pin_LED, HIGH);
      delayMicroseconds(500);
      digitalWrite(pin_LED, LOW);
      delayMicroseconds(500);
    }
    delay(1000);
}

Congratulations.

In principle, this approach works, but it's not very dependable. You're better off using a Timer to generate a waveform like this. There are many tutorials out there about configuring Timers for waveform generation.

A partial solution for this was to use noInterrupts(); and I have I better results, but no perfect. I will search how to use timer for this. thank you.

1 Like

The waveform that is displayed on the first trace is not a true representation of what is actually happening.

You are generating a frequency of 1kHz.
The oscilloscope is on a slow timebase, and is only taking 500 samples per second.
500 Samples per second
This means that it is only taking one sample for every two cycles of the actual waveform.

The only reason that the waveform looks like a square wave is that the frequency generated is not exactly 1kHz, and that each sample gets taken earlier (or later) on in the cycle.

The waveform displayed is an artifact of sampling below the Nyquist frequency.

That is also the reason why the frequency is displayed as 12.2Hz, and not 1kHz.

Is there some setting on the oscilloscope that can increase the sampling rate?

The timebase is on 100ms/division, try increasing the timebase to say 1ms/division to see the true waveform - that's turn the timebase knob 6 clicks clockwise.

1 Like

I tried turning down the memory depth on my oscilloscope to see if I could recreate what you were seeing.
I couldn't get anywhere near 500 samples per second, with the timebase on 100ms/division.
The lowest my oscilloscope would do was 10kSa/s.

Then I had an idea - use a second Arduino to make an oscilloscope.
500 samples per second is easy to achieve, and the serial plotter displays 500 points.

This should be exactly the same as victorioroque1's oscilloscope settings.

Here is the sketch that I came up with:

int inputPin = A0;
unsigned int raw = 0 ;
unsigned long previousMicros = 0;
const long interval = 2000;         // sampling period in microseconds

void setup() {
  Serial.begin(115200);
}

void loop() {
  unsigned long currentMicros = micros();
  if (currentMicros - previousMicros >= interval) {
    previousMicros = previousMicros + interval;
    raw = analogRead(inputPin);
    Serial.print(raw);
    Serial.print(", ");
    Serial.print(1200);     // prevents serial plotter autoscaling
    Serial.print(", ");
    Serial.println(-400);   // sets y axis scale
  }
}

I used this second Arduino Uno R3 to monitor the output of a Uno R3 running victorioroque1's code.
Here are the results on the serial plotter:

An almost perfect re-creation of victorioroque1's traces.

1 Like

The total width of the two apparent pulses in the second trace is 128 real pulses x 1ms period = 128ms.

victorioroque1, I think you need to find the way to turn up your sample rate.
It is the memory depth that needs increasing.

I like to have the memory depth set as high as possible, that way you can zoom in on a saved trace and still have good resolution.

The following traces are all from a single acquisition:


100ms per division - shows 2 bursts of 128 pulses.


zoomed in to 10ms per division - just possible to count 128 pulses.


zoomed in to100µs per division - single pulse.

This code has the additional limitation that the execution time of the code is not accounted for; each delay would need to be tuned to more closely arrive at 500 us per pulse width, high and low.
It could be improved significantly by simply using fastDigitalPin library, available through the IDE Library Manager.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.