Generare una sinusoide 50 hz con arduino

Salve a tutti.

chiedo info per generare una sinusoide con arduino, ho letto di sinth.h che permette di generare appunto una sinusoide.
dovrebbe essere in una libreria per arduino.
qualcuno può dirmi quale? Non so se questo argomento è stato già trattato.

grazie

Che Arduino? Perché i classici Arduino basati su MCU AVR NON hanno un DAC (Digital to Analog Converter) e quindi ... la vedo difficile generare veramente dei segnali analogici ... al massimo degli aborti fatti integrando un segnale PWM ... :roll_eyes:

Guglielmo

EDIT: Ho guardato quella libreria e, come immaginavo:

Output audio as PWM on pin 11, pin 3 or ad differential signal on both.

... una porcheria fatta usando il PWM. Se vuoi generare dei segnali in modo abbastanza pulito orientati verso MCU Arduino che abbiano a bordo almeno un DAC così crei un vero segnale analogico (es. Arduino MKR ZERO che ha un DAC a 10 bit) :wink:

Ho arduino 1 rev 3 ... non un granchè per applicazioni di questo tipo , ma ho visto che con questa funzione è possibile generare una sinusoide "approssimativa" (si vede che è un segnale digitale) e ho diverse resistenze e condensatori ... magari potevo aggiungere un filtro passa basso per smussarla... ma sono aperto ad alternative a questa soluzione, non troppo elaborate se possibile. l'obiettivo è comunque generare un segnale che possa essere letto da un voltmetro in AC... niente altro

AD9833 o AD9850 controllato da Arduino Uno. Li trovi da Amazon, Ebay, Aliexpress.

Beh, anni fa realizzai una interfaccia "Covox" (non dirmi che a fine anni '80 e primi anni '90 non l'hai mai sentita nominare... :sunglasses:) su connettore parallelo della stampante (sic!), quindi avendo a disposizione almeno 8 bit in uscita teoricamente con un partitore R/2R si può generare un segnale audio "decente". :wink: Ovviamente a patto di settare contemporaneamente le uscite.

50 hz li generi come vuoi

Anche solo un Onda quadra alla frequenza di 500hz (non a caso il pwm di arduino) con un filtro del primo ordine sembra quasi bella

Mettiamo un filtro del terzo ordine a siamo a posto

La questione è:

Va regolata?
Va modulata?
Che intensità?
Che potenza ?

Su queste cose si gioca la scelta dell hardware

Io sono pronto a scommettere che si sta cercando un inverter dc-ac

Ovvero, seppur solo ad 8 bit, un DAC :grinning:

L'avevo realizzata anche io negli anni '70, quando avevo cominciato a giocare con gli i8080, per realizzare semplicissime immagini sull'oscilloscopio :grin:

Guglielmo

L'ampiezza magari arrivassi in valore efficace a 10 V, ma già se sto a 1,5 V (sempre valore efficace) andrebbe bene per diverse cose, mi accontenterei... e per questo Arduino andrebbe già bene.
potenza... quella che può essere misurata con un voltmetro standard.
frequenza solo 50 Hz.
Forse mi sto fissando sulla soluzione arduino perchè ce l'ho e ho resistenze e condensatori e avevo visto in rete questa funzione sinth.h, ma magari esistono soluzioni più semplici.

Oscillatore a ponte di Wien?... Dipende da quello che ci devi fare (che ancora non si è capito!). Puoi anche generare un segnale con il computer e mandarlo a un amplificatore, così come puoi prendere un alimentatore a corrente alternata...

Se, invece, ti serve un calibratore di tensione alternata, il discorso è un po' diverso...
https://www.google.com/search?q=calibratore+tensione+alternata&tbm=isch

E se si porta il PWM a lavorare nei dintorni dei 20 kHz, e si varia il suo duty esattamente una volta al millisecondo secondo una tabellina di 20 punti?

Ce la calcola Arduino stesso :wink:

uint8_t tabe[20] = {};

void setup() 
{
    Serial.begin(115200);
    for (uint8_t ms=0; ms<=19; ms++)
    {
        float angle = 2.0 * M_PI * ms / 20.0;
        float value = (1.0 + sin(angle)) * 127.5;
        tabe[ms] = int(value + 0.5);
        Serial.println(tabe[ms]);
    }
}

void loop() {}
128, 167, 202, 231, 249, 255, 249, 231, 202, 167,
127, 88, 53, 24, 6, 0, 6, 24, 53, 88

Poi basta un operazionale che fa sia da amplificatore per arrivare ai Veff voluti, sia da filtro passa basso.

ci devo tarare (taratura interna, non serve mandare a un laboratorio di taratura, ma deve essere una procedura valida) dei voltmetri che usiamo per delle verifiche elettriche sul campo... non sono strumenti di laboratorio ma devono essere affidabili per quello che ci serve ... le tensioni che ci misuro vanno da 0,1 a 10 V, non oltre. abbiamo uno strumento campione di riferimento (tarato LAT) ... la taratura è per confronto della misura ottenuta con lo strumento in taratura con quella ottenuta con lo strumento campione.
basterebbero 3 o 4 punti in questo intervallo (0,1 - 10 V) se poi non si riece più di 1,5V già mi accontenterei

Allora prendi un trasformatore da 9V, come quelli al #9, misura con lo strumento campione e regola l'altro...

ma per i valori bassi? potrei fare un partitore di tensione con un set di resistenze

Sì...

in effetti così mi semplifico le cose... volevo cogliere l'occasione per fare e imparare qualcosa con arduino.. come in un altro thread che ho già discusso con voi in passato (e ho risolto con mia soddisfazione anche grazie a voi), ma tutto sommato...

Devi solo tenere i due strumenti collegati contemporaneamente per non avere variazioni di tensione al variare del carico, se i due strumenti hanno resistenze d'ingresso diverse.

questo è certo, ho già fatto prove simili... la misura deve essere simultanea

1 Like

Beh... Il giochetto con Arduino lo fai a parte, indipendentemente dagli strumenti da tarare! :slight_smile:

1 Like

Responso:

uint8_t   tabe[20] = {};
uint8_t   i;
uint32_t  t;

void setup() 
{
    for (uint8_t ms=0; ms<=19; ms++)
    {
        float angle = 2.0 * M_PI * ms / 20.0;
        float value = (1.0 + sin(angle)) * 127.5;
        tabe[ms] = int(value + 0.5);
    }

    // Pins D9 and D10 - 31.4 kHz
    TCCR1A = 0b00000001; // 8bit
    TCCR1B = 0b00000001; // x1 phase correct

    i = 0;
    t = micros();
}

void loop() 
{
    if (micros()-t >= 1000)
    {
        t += 1000;
        analogWrite(9, tabe[i]);
        i = (i + 1) % 20;
    }
}

7498746

168498416

1 Like

i = (i + 1) % 20;
è molto elegante, ma sicuramente è molto più veloce senza il modulo:

i+=1;
if (i>19) i=0;