PWM Signaal van 1Hz

Hallo Allen

ik ben een schakeling aan het maken waarbij een een PWM signaal nodig heb. Ik gebruik nu een Arduino UNO en krijg via Tone() nu een mooi PWM signaal.

alleen heb ik een frequentie van 1Hz tm 300Hz nodig, zover ik heb kunnen vinden kan de Tone() functie niet lager dan 31Hz.

weet iemand misschien een andere oplossing om toch lager te kunnen!?

je zou het helemaal zelf kunnen programmeren? Maar heb je nu een tone generator van 1-300 Hz nodig of een PWM van 1-300Hz en een duty cycle van 0-100%.

Dank voor je reactie.

ik gebruik nu de tone generator die werkt goed. ik heb uiteindelijk een blokgolf van 12v nodig om een toerenteller aan te sturen. probleem is hiermee dat hij niet lager van 31 hz gaat.

PWM signaal met 50% duty cycle is hiermee vergelijkbaar toch of zie ik dit verkeerd?

Hoi Jeroen, welkom.

Het is niet duidelijk wat je wil met die PWM. Ik zie de relatie niet tussen 0 tot en met 32 Hz en 50 % duty cycle. Ik zie ook niet hoe je een 1 Hz signaal voor een toerenteller nodig zou hebben.

Als je 1 keer per seconde een bepaalde pulsbreedte moet maken die relatief is aan je toerental, dan is dat een heel vreemd signaal waar ik me geen andere toepassing van kan voorstellen (ik geloof dus niet dat dat op een of ander dashboard zo verwerkt zou worden).

Wellicht dat je nog eens kunt beschrijven wat je wil, maar dan zonder de termen PWM, pulsbreedte of frequentie/Hz te gebruiken ?

Ik zit denk ik verkeerd te denken ja :slight_smile:

de teller heeft een 12v puls signaal nodig
ik gebruik nu de Tone() en hierbij komt 200hz overeen met 4000 RPM de minimale 31Hz is dan 620 RPM

Okee, dan heb je dus alleen een frequentie nodig. Die frequentie zal bij benadering een duty cycle (niet te verwarren met PWM) van 50 Hz hebben, maar dat zal verder van weinig belang zijn. Wil je de Arduino nog voor andere zaken gebruiken, of is het genereren van deze frequentie het enige doel ? Dat vraag ik omdat andere functies het genereren van zo'n frequentie zou kunnen beïnvloeden. De laagste frequentie kennen we inmiddels. Is die 300 Hz het maximum; 6000 RPM, of heb je behoefte aan een hogere frequentie ?

ff een simpel programmatje voor je. 0-300 Hz (instelbaar via de defines). Zit genoeg commentaar in om je verder te helpen.

@edit: Zat nog een klein foutje in de tijdsduur. Die moet door 2 gedeeld worden. aangepast.

#include "Arduino.h"

//
// Pin definitions
//
#define PULS_PIN    3                 // stel puls komt eruit op pin 3
#define POTMETER    A0                // zet bijvoorbeeld een potmeter op Analoog 0
//
// global defines & parameters
//
#define MIN_FREQUENTIE    0           // laagste frequentie
#define MAX_FREQUENTIE    300         // hoogste frequentie
//
// global variables
//
uint32_t timer;                        // timer voor de puls generatie
uint32_t tijdsduur;                    // duur van een halve cycle
uint16_t oudeAnaloog = 0;              // vorige analoge waarde
/**
 * @name setup()
 * initialize the program
 */
void setup()
{
    pinMode(PULS_PIN, OUTPUT);
    digitalWrite(PULS_PIN, LOW);
}

/**
 * @name loop()
 * main loop of program and runs endlessly
 */
void loop()
{
    uint16_t    analoog;                 // huidige waarde van de analoge pin
    uint16_t    frequentie;              // gevraagde frequentie
    uint32_t    ditMoment = micros();    // huidige tijd volgens micros()
    //
    // lees analoge pin
    //
    analoog = analogRead(POTMETER);
    //
    // kijk of de waarde is veranderd
    //
    if (analoog != oudeAnaloog) {
        //
        // de waarde is veranderd dus de frequentie aanpassen
        //
        frequentie = map(analoog, 0,1023, MIN_FREQUENTIE, MAX_FREQUENTIE);
        //
        // bereken de tijdsduur in micro seconden (voor wat meer nauwkeurigheid).
        // formule normaal : f = 1 / T => T = 1 / f
        // daar we rekenen in microseconden wordt het T = 1000000 / f
        //
        if (frequentie != 0) {                // pas op voor delen door 0
            //
            // bereken de puls duur / 2 (50% duty cycle)
            //
            tijdsduur = (1000000 / frequentie) / 2;
            //
            // start de timer
            //
            timer = ditMoment;
        } else {
            //
            // er is nu geen puls duur omdat de frequentie gelijk aan 0 is
            //
            tijdsduur = 0;
            //
            // timer hoeft ook niet te lopen
            //
            timer     = 0;
            //
            // en zet het level gelijk op LOW
            //
            digitalWrite(PULS_PIN, LOW);
        }
        //
        // bewaar de analoge waarde
        //
        oudeAnaloog = analoog;
    }
    //
    // kijk of de puls van level moet veranderen
    //
    if (timer != 0) {
        //
        // de timer loopt
        //
        if ((ditMoment - timer) > tijdsduur) {
            //
            // de timer is verlopen dus flip de puls pin
            //
            digitalWrite(PULS_PIN, !digitalRead(PULS_PIN));
            //
            // en zet de timer voor de volgende keer
            //
            timer = ditMoment;
        }
    }
}

nico waar wordt ditmoment en timer gezet, en je moet de verlopen tijd aftrekken om een betere stabiliteit te maken. ik denk ook dat een interupt handig is, dan zijn hogere freqs goeedte doen.

als de analoge waarde wijzigt.... en er is geen vraag naar hogere frequenties...En waarom ingewikkelder maken dan nodig.... @edit: Maar het staat je altijd vrij om een ander voorstel te maken? Dan kan de TS kiezen.

jeroenveer: ik gebruik nu de tone generator die werkt goed. probleem is hiermee dat hij niet lager van 31 hz gaat.

PWM signaal met 50% duty cycle is hiermee vergelijkbaar toch of zie ik dit verkeerd?

Hoi,

Tone() is voornamelijk gericht op muziek/geluid, onder de 31 hz (B0) heb je bijv. ook wel tonen, maar die kom je in de meeste muziek vrijwel niet tegen en zijn voor de meesten onder ons lastig te horen.

In principe doet de Blinkwithoutdelay voorbeeldsketch van het Arduino-programma echter niet zoveel... anders en die kan je vrij instellen. (de blink-sketch zou ook kunnen, al is dat niet zo'n geweldige methode)

Zoals hij standaard ingesteld staat, 1sec lampje aan en 1 sec lampje uit, heb je bijv. al een toongenerator van een halve Herz.

Het lijkt me dat je met wat aanpassingen, schakelaartjes/potentiometers of andere methode om het interval langer/korter te maken er grotendeels bent.

Bedankt Nico ik ga dat stukje is proberen ziet er goed uit.

max toeren is 7000 dus de max Hz op 350.

ik gebruik de SPI met een CAN controller.

En wil er misschien nog een 2e OUTPUT in maken ook met een frequentie voor de snelheidsmeter. kan ik hiervoor een uint32_t timer2; erin zetten?

yep