Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 13 of 13

Thread: Frequency generator

  1. #1
    Junior Member
    Join Date
    Mar 2020
    Posts
    7

    Frequency generator

    Hi.

    I need your help (I'm sorry for my English).

    I have bought a Tripple CAN board with a Teensy 4.0 and a display from skpang.

    This is a very good board and the CAN connectivity is great and function very good.

    But now I need an SPI port to connect an AD9833 frequency generator. This board uses the SPI for the display.

    For my project I need a frequency from 0 to 350 hz with a 50/50 frequency length.

    Is there an option to get an frequency generator on the software way?

    I have searched in Internet but I found nothing..

    Greetings

    Gary

  2. #2
    Is this what you are looking for:

    https://www.pjrc.com/teensy/td_pulse.html

    The correct English Internet search term for an Arduino requency generator is called PWM, which stands for Pulse Width Modulation.

  3. #3
    Junior Member
    Join Date
    Mar 2020
    Posts
    7
    Good morning.

    I have taken a look on this site days before. But this isn't a good way. I need a square signal with a length from 50/50. PWM hasn't this length.

    Thanks for your idea and reply

    Gary

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,979
    If Resolution is set to 8 bits - values range 0-255. Setting an AnalogWrite( pin, 127 ) will give a 50/50 wave.

    Something like this should work - picking a higher Resolution ( up to 16 bits ) will work better at low frequencies indicated - the value to write changes accordingly.
    Code:
      #define PINx  4  // your pin here
      void setup() {
          analogWriteResolution(8);
          analogWriteFrequency(PINx, 350); // Use this to write the desired frequency
          analogWrite(PINx, 127);
      }

  5. #5
    Junior Member
    Join Date
    Mar 2020
    Posts
    7
    Thanks defragster

    Just I have tried to take the Teensy from this board. It was possible. I thought that the Teensy was soldered.

    Now there is an option to use the SPI port 2 on the backside.

    I have not much knowledge in this boards. Is it possible to use the second port, if the first one is already used? In this case I could use the AD9833.

    Nevertheless I will try your code.

    Greetings

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,979
    If you have software library that allows specifying the SPI port it should work.

  7. #7
    Junior Member
    Join Date
    Mar 2020
    Posts
    7
    Hi defragster.

    Sorry for the late reply. We have a lot of problems with the Corona virus in my federal state of Germany.

    I have tried your code and this runs well with your frequency. But if I try other frequencies like for example 20, I dont have a duty about 50/50.
    This is very difficult for me. ;-)

    Thanks

    Gary

  8. #8
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,363
    Yep it works better if you go to higher resolution... Here is a quick and dirty that verified using Logic Analyzer:
    Code:
    #define PINx  12  // your pin here
    void setup() {
      while (!Serial && millis() < 4000) ;
      Serial.begin(115200);
      Serial.println("Will start at 350, enter new if desired...");
    
      analogWriteResolution(10);
      analogWriteFrequency(PINx, 350); // Use this to write the desired frequency
      analogWrite(PINx, 511);
      pinMode(13, OUTPUT);
    }
    
    void loop() {
      int ch;
      if (Serial.available()) {
        uint16_t val = 0;
        while ((ch = Serial.read()) != -1) {
          if (ch >= '0' && ch <= '9') val = val * 10 + ch - '0';
        }
        digitalWriteFast(13, !digitalReadFast(13));
        analogWriteFrequency(PINx, val); // Use this to write the desired frequency
        analogWrite(PINx, 511);
      }
    }
    And you can see the change with the entering in 20...
    Click image for larger version. 

Name:	screenshot.jpg 
Views:	6 
Size:	70.0 KB 
ID:	19422

    At the 8 bit resolution, the value 20hz gave a value of maybe 40% duty due to limitations of rounding and the like. You can also go up to 12 bit resolution,
    Again would need to change the analogWrite to something like 2047...

  9. #9
    Junior Member
    Join Date
    Mar 2020
    Posts
    7
    Thank KurtE.

    I haved tried to use your code. The frequencies between 18 and 350 are ok. But the lower frequencies are not possible.

    The 40% daty are ok. But I Need a frequency near by 0.

    Greetings and thanks

  10. #10
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,363
    Again it may depend on all of your other requirements and how exactly you need it. You could simply use an intervalTimer to do it. Or you could use the timerTools by @luni...

    Example: hacked up previous example:
    Code:
    #define PINx  12  // your pin here
    IntervalTimer it;
    
    void it_handler() {
      digitalWriteFast(PINx, !digitalReadFast(PINx));
      asm("dsb");
    }
    
    void setup() {
      while (!Serial && millis() < 4000) ;
      Serial.begin(115200);
      Serial.println("Will start at 350, enter new if desired...");
    
      //analogWriteResolution(10);
      //analogWriteFrequency(PINx, 350); // Use this to write the desired frequency
      //analogWrite(PINx, 511);
      pinMode(PINx, OUTPUT);
      it.begin(&it_handler, 500000l/350);
      pinMode(13, OUTPUT);
    }
    
    
    void loop() {
      int ch;
      if (Serial.available()) {
        uint16_t val = 0;
        while ((ch = Serial.read()) != -1) {
          if (ch >= '0' && ch <= '9') val = val * 10 + ch - '0';
        }
        digitalWriteFast(13, !digitalReadFast(13));
        //analogWriteFrequency(PINx, val); // Use this to write the desired frequency
        //analogWrite(PINx, 511);
        it.update(500000l/val);
    
      }
    }

  11. #11
    At low frequencies, just running an interval timer can be quite accurate enough.

    https://www.pjrc.com/teensy/td_timin...rvalTimer.html

    Use a high priority if you need very good precision. It is capable of microsecond precise at highest priority levels, if you manage/design correctly.

  12. #12
    Junior Member
    Join Date
    Mar 2020
    Posts
    7
    Thanks a lot

    At this time it is too much for my brain. I will test the new code in the evening.

    I dont need an exact square wave but it should be nearly 50/50. 60/40 isn't a problem. The first zulignal should be near 0 and it's not important that the signals are exactly for example 5.0 Hz.

    Thanks for helping me...

    Greetings

  13. #13
    Junior Member
    Join Date
    Mar 2020
    Posts
    7
    Thanks KurtE

    This runs perfectly. I dont know why but it works. ;-)

    Now I go a big step to the end of my Project.

    Your help is great…. Thanks also to the rest of this forum.


    Greetings

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •