# Frequency Square Wave

**URL:** <https://forum.arduino.cc/t/frequency-square-wave/1174045>\
**Category:** Programming\
**Created:** [October 1, 2023, 4:02pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045 "2023-10-01T16:02:20Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paulvlaar8](https://avatars.discourse-cdn.com/v4/letter/p/90db22/32.png) [@Paulvlaar8](https://forum.arduino.cc/u/Paulvlaar8)\
**Post date:** [October 1, 2023, 4:02pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/1 "2023-10-01T16:02:20Z")

</div>

I'm trying to get a square wave between 1000 HZ and 100000 HZ.  
I have the hardware all setup but the frequency doesn't go lower then 2000 HZ and above 4000 HZ it loses a couple hundred HZ.

This is my code:

```arduino
Const int PIN = 3;

int RPM = 8000;
int PPM;
int PPS;
int Microsecs;
int interval;

void setup(){
  pinMode(PIN, OUTPUT);
  Serial.begin(9600);
}

void loop(){
  PPM = RPM;
  PPS = PPM/60;
  interval = 1000000/PPS;
  Microsecs = interval/2;
  digitalWrite(PIN, HIGH);
  delayMicroseconds(Microsecs);
  digitalWrite(PIN, LOW);
  delayMicroseconds(Microsecs);
}

```

When i input a direct delay instead of the microsecs it works a lot better.  
Any idea What is going wrong here?

---

<div class="post-metadata">

**Author:** ![J-M-L](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/j-m-l/32/766245_2.png) [@J-M-L](https://forum.arduino.cc/u/J-M-L)\
**Post date:** [October 1, 2023, 4:11pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/2 "2023-10-01T16:11:01Z")

</div>

Well first you do lots of maths in the loop, so that will slow things down  
Then you are using an int which is only 16 bits on uno and the likes  
Last you are using digitalWrite which is notoriously "slow" (when you want really fast operations)

If you enter a fixed value for the delay, as the other variables are not used the compiler just get rid of them and you don’t have the math anymore at each loop

---

<div class="post-metadata">

**Author:** ![groundFungus](https://avatars.discourse-cdn.com/v4/letter/g/73ab20/32.png) [@groundFungus](https://forum.arduino.cc/u/groundFungus)\
**Post date:** [October 1, 2023, 4:13pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/3 "2023-10-01T16:13:07Z")

</div>

Have you tried[the **tone()** function?](https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/)

---

<div class="post-metadata">

**Author:** ![GolamMostafa](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/golammostafa/32/239011_2.png) [@GolamMostafa](https://forum.arduino.cc/u/GolamMostafa)\
**Post date:** [October 1, 2023, 4:21pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/4 "2023-10-01T16:21:36Z")

</div>

If you want accurate sqaure wave frequency at DPin-9 (1 kHz to 100 kHz), you may go with CTC-4 Mode of TC1 (Timer/Counter 1) of the MCU of UNO Board.

**Sample Sketch:**

```arduino
void setup()
{
  pinMode(9, OUTPUT); //output is at DPin-9  
  
  TCCR1A = 0x00;
  TCCR1B = 0x00;

  bitClear(TCCR1B, WGM13);
  bitSet(TCCR1B, WGM12);
  bitClear(TCCR1A, WGM11);
  bitClear(TCCR1A, WGM10);

  bitClear(TCCR1A, COM1A1);
  bitSet(TCCR1A, COM1A0);
 

  OCR1A = 7999; // f = 16 MHz/(2 x N (1+OCR1A); for 1000 Hz, OCR1A = 7999
  TCNT1 = 0x0000;

  bitClear(TCCR1B, CS12); //start TC1 with prescaler N = 1
  bitClear(TCCR1B, CS11);
  bitSet(TCCR1B, CS10);
}

void loop(){}

```

---

<div class="post-metadata">

**Author:** ![DVDdoug](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/dvddoug/32/671533_2.png) [@DVDdoug](https://forum.arduino.cc/u/DVDdoug)\
**Post date:** [October 1, 2023, 4:32pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/5 "2023-10-01T16:32:17Z")

</div>

**Yes, tone()** is the obvious solution. (It may not be absolutely perfect to 1Hz... There may be errors related to rounding, or remainders after frequency-division, or whatever it's doing. The CPU clock also as accuracy limits/tolerance.)

> [@J-M-L](#):
>
> Well first you do lots of maths in the loop, so that will slow things down

**Right...** Every instruction in the loop takes time and that gets added to the delay.

If you use micros(), similar to the Blink Without Delay Example, that's not a problem but there is still a limit to how fast you can loop.

---

<div class="post-metadata">

**Author:** ![groundFungus](https://avatars.discourse-cdn.com/v4/letter/g/73ab20/32.png) [@groundFungus](https://forum.arduino.cc/u/groundFungus)\
**Post date:** [October 1, 2023, 4:37pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/6 "2023-10-01T16:37:58Z")

</div>

The tone() function uses timers.

This from B[rett Hagman's notes on the tone() function](https://github.com/bhagman/Tone#ugly-details):

The range of frequencies that can be produced depends on the microcontroller clock frequency and the timer which is being used:

| _MCU clock_ | _8 bit timer Flow_ | _16 bit timer Flow_ | _Fhigh_ |
| --- | --- | --- | --- |
| 8 MHz | 16 Hz | 1 Hz (1/16 Hz) | 4 MHz |
| 16 MHz | 31 Hz | 1 Hz (1/8 Hz) | 8 MHz |

---

<div class="post-metadata">

**Author:** ![JCA34F](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jca34f/32/340148_2.png) [@JCA34F](https://forum.arduino.cc/u/JCA34F)\
**Post date:** [October 1, 2023, 4:47pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/7 "2023-10-01T16:47:53Z")

</div>

I believe the Tone function maxes out at 65535 Hz (uint16\_t)?

---

<div class="post-metadata">

**Author:** ![J-M-L](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/j-m-l/32/766245_2.png) [@J-M-L](https://forum.arduino.cc/u/J-M-L)\
**Post date:** [October 1, 2023, 4:52pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/8 "2023-10-01T16:52:28Z")

</div>

Yes on 8 bit architecture as it’s using an unsigned int so 16 bits (but would be 32 bits on a MKR or ESP)

> <https://github.com/arduino/ArduinoCore-avr/blob/63092126a406402022f943ac048fa195ed7e944b/cores/arduino/Tone.cpp#L243-L243>

---

<div class="post-metadata">

**Author:** ![JCA34F](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jca34f/32/340148_2.png) [@JCA34F](https://forum.arduino.cc/u/JCA34F)\
**Post date:** [October 1, 2023, 5:06pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/9 "2023-10-01T17:06:21Z")

</div>

Well, the OP didn't say which Arduino, so...

---

<div class="post-metadata">

**Author:** ![J-M-L](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/j-m-l/32/766245_2.png) [@J-M-L](https://forum.arduino.cc/u/J-M-L)\
**Post date:** [October 1, 2023, 5:21pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/10 "2023-10-01T17:21:44Z")

</div>

Yes indeed

My point was that the function does not use the fixed width type (uint16\_t)

---

<div class="post-metadata">

**Author:** ![ruilviana](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ruilviana/32/722429_2.png) [@ruilviana](https://forum.arduino.cc/u/ruilviana)\
**Post date:** [October 1, 2023, 5:49pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/11 "2023-10-01T17:49:53Z")

</div>

Which Arduino are you using?

If you use the ESP32, you can generate frequencies from 1 HZ to 40 Mhz regardless of the code running.  
Using the LEDC feature of the ESP32.

---

<div class="post-metadata">

**Author:** ![Paulvlaar8](https://avatars.discourse-cdn.com/v4/letter/p/90db22/32.png) [@Paulvlaar8](https://forum.arduino.cc/u/Paulvlaar8)\
**Post date:** [October 7, 2023, 4:06pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/12 "2023-10-07T16:06:18Z")

</div>

I'm using the Arduino Nano Every.  
I've tried to use the Tone() function which does work.  
But i still can't get a higher frequency then 500HZ.  
I doubt its because i'm on the limit of what frequency the transistor and optocoupler can manage.  
I do see that there is an additional wire in my gauge which is what i need to control.  
It says it needs to be pulled up in case of a "Open collector ECU output", no idea what this means.  
Any suggestions?

---

<div class="post-metadata">

**Author:** ![cattledog](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cattledog/32/217816_2.png) [@cattledog](https://forum.arduino.cc/u/cattledog)\
**Post date:** [October 7, 2023, 4:18pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/13 "2023-10-07T16:18:19Z")

</div>

Please post a circuit diagram of what you have, and a link to the gauge you are trying to drive.

---

<div class="post-metadata">

**Author:** ![Paulvlaar8](https://avatars.discourse-cdn.com/v4/letter/p/90db22/32.png) [@Paulvlaar8](https://forum.arduino.cc/u/Paulvlaar8)\
**Post date:** [October 7, 2023, 4:53pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/14 "2023-10-07T16:53:36Z")

</div>

![20231007_185116](https://europe1.discourse-cdn.com/arduino/original/4X/7/1/5/71583556fd9c3f4f35ad15b68efd6ba484bfc995.jpeg)  
 ![20231007_185132](https://europe1.discourse-cdn.com/arduino/original/4X/d/6/e/d6e0a5d8f7c3c420037b7b9f68ed7503e368fc71.jpeg)  
This is the gauge and the circuit i use

---

<div class="post-metadata">

**Author:** ![cattledog](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cattledog/32/217816_2.png) [@cattledog](https://forum.arduino.cc/u/cattledog)\
**Post date:** [October 7, 2023, 5:32pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/15 "2023-10-07T17:32:34Z")

</div>

I would certainly try a 10K pullup to 12v on the Brown/state wire of the tachometer.

---

<div class="post-metadata">

**Author:** ![Paulvlaar8](https://avatars.discourse-cdn.com/v4/letter/p/90db22/32.png) [@Paulvlaar8](https://forum.arduino.cc/u/Paulvlaar8)\
**Post date:** [October 7, 2023, 6:32pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/16 "2023-10-07T18:32:00Z")

</div>

Sadly when i put a 10K resistor between the brown wire and 12V nothing works.

---

<div class="post-metadata">

**Author:** ![cattledog](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cattledog/32/217816_2.png) [@cattledog](https://forum.arduino.cc/u/cattledog)\
**Post date:** [October 7, 2023, 7:09pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/17 "2023-10-07T19:09:38Z")

</div>

What transistor are you using on the high side of the gauge?

If its an NPN it should be between the gauge and ground.

Do you have a scope to look at the signals?

---

<div class="post-metadata">

**Author:** ![Paulvlaar8](https://avatars.discourse-cdn.com/v4/letter/p/90db22/32.png) [@Paulvlaar8](https://forum.arduino.cc/u/Paulvlaar8)\
**Post date:** [October 7, 2023, 7:43pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/18 "2023-10-07T19:43:26Z")

</div>

I'm using the 2N5401 which is a PNP transistor.  
I might be able to use a mosfet, i have one laying around, do you think that would work?  
I don't have a scope as i normally only use thing that are either constantly on or off.

---

<div class="post-metadata">

**Author:** ![cattledog](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/cattledog/32/217816_2.png) [@cattledog](https://forum.arduino.cc/u/cattledog)\
**Post date:** [October 7, 2023, 8:07pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/19 "2023-10-07T20:07:58Z")

</div>

> mosfet, i have one laying around, do you think that would work?

I'm not a hardware guy, but I'm not certain there would be any advantage over what you are using.

The guide shows six wires. Can you provide the complete information of what you have connected to where?

---

<div class="post-metadata">

**Author:** ![JCA34F](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/jca34f/32/340148_2.png) [@JCA34F](https://forum.arduino.cc/u/JCA34F)\
**Post date:** [October 7, 2023, 8:29pm UTC](https://forum.arduino.cc/t/frequency-square-wave/1174045/20 "2023-10-07T20:29:26Z")

</div>

Connect green wire to +12V supply, black wire to 12V ground ( - ), red / blue wire to Arduino output pin, 12V ground to Arduino GND. Use the Tone function to apply a 500Hz signal to the output pin.

[Next page](https://forum.arduino.cc/t/frequency-square-wave/1174045.md?page=2)
