Frequenza pwm arduino nano atmega328

Chi si ricorda qual'è la frequenza del segnale PWM?
Io ricordo 490Hz, ma su quale pin su tutti o c'è un PWM a circa 900Hz.

Ne ho bisogno per generare un impulso da basso ad alto di circa 10us, allora con PWM di 490 ho che:
p = 1/490 = 0,002040816 secondi, circa 2ms diviso 255 = 0,000008003
circa 8us con analogWrite(pin, 1) poi resta basso per tutto il resto del tempo cioè 2ms - 8us e ho tutto il tempo per fare digitalWrite(pin, LOW).

Sempre che i mie calcoli siano esatti.
Ciao.

Su ATmega328P il core Arduino imposta:

Timer0
Usato da millis() e delay() e per il PWM sui pin 5 e 6
fast hardware pwm
(default 976.5625 Hz)
Pin 5 è anche usato per il “pulse counting
Pin 8 è usato per il “input capture

Timer1
Usato dalla libreria Servo e per il PWM sui pin 9 e 10. Libreria e PWM mutuamente esclusivi.
8-bit phase correct pwm mode
(default 488.28125 Hz)

Timer2
Usato per il PWM sui pin 3 e 11
8-bit phase correct pwm mode
(default 488.28125 Hz)

Guglielmo

Il timer2 è usato anche da tone, che quindi interferisce con il PWM sui pin 3 e 11.

1 Like

Due digitalWrite high e una low. Avevo misurato che una digitalWrite dura circa 5µs.

E c'è sempre delayMicroseconds.

Ecco ero arrivato a 976.5625 pure io. Gli altri due sono la metà di 976.
Secondo te è corretto che:

analogWrite(5, 3); 

Sta alto per circa 12us

mentre:

analogWrite(9, 2);

Sta alto per circa 16us.

Mo provo con il simulatore collegandogli l'analizzatore.

Ciao.

La cosa è ovviabile, su AVR, usando un'altra libreria, la toneAC che può usare sia Timer1 che Timer2.

Poi c'è ancora in giro la vecchia tone() che non usava alcun timer o la TimerFreeTone che, come dice il nome, non usa anche lei alcun timer.

Guglielmo

Ok, vi ho letti tutti. Sembra funzionare, il sembra è dovuto al fatto che la mia vista non è buona specie quando messa alla prova da GTKwave che trovo scomodissimo da usare (sono io che non lo so usare) e mi devo calcolare a mano il tempo.

Che software usate per analizzare il .vcd fornito da wokwi?
Ho provato anche l'estensione di VSCODE ma anche lui non va bene.
Se non ho sbagliato i calcoli, attualmente ho un loop che gira alla velocità di 4us e ad intervalli regolari passa a 10us perché stampo.
In pratica ogni 50ms viene emesso un trigger al sensore sr-04, viene sollevato l'interrupt sul pin echo, la funzione agganciata sgancia il pin dal PWM con pinMode e poi digitalWrite ma basterebbe sganciarlo poiché è già LOW. L'interrupt su echo è CHANGE quindi vengono prese due letture di micros.

#include "US.h"

USPing usPing;

#define TRIGGER_PIN 6
#define ECHO_PIN 2

#define DEBUG_PIN   7
volatile uint8_t *portDebug;
uint8_t portDebugBitMask;

void setup() {
    pinMode(DEBUG_PIN, OUTPUT);
    portDebug = portOutputRegister(digitalPinToPort(DEBUG_PIN));
    portDebugBitMask = digitalPinToBitMask(DEBUG_PIN);
    usPing.begin(ECHO_PIN, TRIGGER_PIN);
    usPing.setTriggerInterval(50);
  
    Serial.begin(115200);
    attachInterrupt(digitalPinToInterrupt(ECHO_PIN), rxEcho, CHANGE);
  
}

void rxEcho() {
    usPing.noTrigger();
    usPing.rxEcho();
}


//Velocità del suono m/s = 331,4 + (0,606 * Temp) + (0,0124 * Umidità)
// https://www.michelediluca.it/sensore-ultrasuoni-hc-sr04-arduino/

void loop(void) {
    *portDebug |= portDebugBitMask;
    
    usPing.trigger();

    uint32_t echoTime = usPing.getEchoTime();
    if (echoTime) {
        //Serial.print("echoTime = ");
        Serial.print(echoTime);
        Serial.print('\t');
        
        Serial.println(usPing.usToCm(echoTime));
    } 
    *portDebug &= ~portDebugBitMask;
    
    
}

Sembra che il problema del ping bloccante sia risolvibile in modo efficiente e poco dispendioso, ora non resta che documentare il tutto.

Ciao.

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