|
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
tadejcl Neznanec
Pridružen-a: Sre 14 Okt 2020 15:58 Prispevkov: 3 Aktiv.: 0.07
|
Objavljeno: Sre Okt 14, 2020 4:11 pm Naslov sporočila: Arduino-generiranje sinusa |
|
|
Pozdravljeni
Sem čisto nov na forumu in imam problem z enim projektom, ki sem se ga lotil. Upam, da si bo kdo vzel čas in mi lahko pomagal.
Z arduinom želim generirati tri signale s faznim zamikom 120°. Se pravi neka simulacija trifaznega generatorja. Signale na izhodu dobim na osciloskopu (za prikaz/simulacijo uporabljam Proteus 8). Iz arduina dobim PWM signale (pin9, pin10 in pin11). Problem se pojavi, ko želim uporabiti low pass filter. Ko priklopim na osciloskop je signal trikoten.
Kaj moram spremeniti, da bom dobil dokaj lep sinus ker vem da čistega nebom dobil vendar vsaj približek? Moram spremeniti kodo? Vrednosti RC filtra? Ali tabelo z izračuni funkcije?
Že v naprej hvala za pomoč.
Lep pozdrav |
|
Nazaj na vrh |
|
|
rplink3r Član
Pridružen-a: Tor 06 Feb 2007 20:02 Prispevkov: 480 Aktiv.: 2.29 Kraj: Levec
|
Objavljeno: Sre Okt 14, 2020 4:47 pm Naslov sporočila: |
|
|
Tule je primer za eno fazo, ko ti to dela greš naprej,
https://www.instructables.com/Arduino-Sinewave-for-Inverters/
Sicer je primerov veliko, bolj kot ne za eno fazo, pa tudi za tri faze bi znalo bit kaj.
Če po filtriranju dobiš trikot, bo nekaj narobe z generacijo pwm-a, napačne vrednosti v lookup tabeli, ali pa napake v programu.
Priloži kodo, da se vidi kaj dejansko imaš. _________________ "The statement below is false."
"The statement above is true." |
|
Nazaj na vrh |
|
|
tadejcl Neznanec
Pridružen-a: Sre 14 Okt 2020 15:58 Prispevkov: 3 Aktiv.: 0.07
|
Objavljeno: Sre Okt 14, 2020 5:56 pm Naslov sporočila: |
|
|
Kodo imam tako:
/**
Arduino IDE project assembly
Name: Fequency generator (3-phase)
Purpose: Testing
@author Tadej Zupančič
@version 1.0 30/09/20
*/
// CONSTANTS
const int f = 50; // frekvenca signala
const float fs = 500.0; // respond(odziv) bo 2 ms
const int t_delay = 2; // zakasnitev spremembe izhoda
// PUBLIC VARS
byte sig_phase1[500]; // signal faze 1: +0°
byte sig_phase2[500]; // signal faze 2: +120°
byte sig_phase3[500]; // signal faze 3: +240°
int i = 0; // stevec pozicije tabele
float t;
long timestamp_phase_correct = 0; // casovnik signala faze 1: +0°
void setup() {
pinMode(10, OUTPUT);
// Generiranje graf sinusne funkcije za - FAZA 1
for (int i = 0; i < 500; i++) // i je array številka(0, 1, 2, 3,...) GRE OD 1 - 500 SIGNALOV
{
t = (float)i / fs;
sig_phase1[i] = (byte)(127.0 * (sin(2 * 3.14 * f * t))); // +1 da dobis signal nad 0!, formula za generiranje katerekoli frekvence
}
// Generiranje graf sinusne funkcije za - FAZA 2
for (int i = 0; i < 500; i++) // i je array številka(0, 1, 2, 3,...) GRE OD 1 - 500 SIGNALOV
{
t = (float)i / fs;
sig_phase2[i] = (byte)(127.0 * (sin((2 * 3.14 * f * t)-90))); // +1 da dobis signal nad 0!, formula za generiranje katerekoli frekvence
}
// Generiranje graf sinusne funkcije za - FAZA 3
for (int i = 0; i < 500; i++) // i je array številka(0, 1, 2, 3,...) GRE OD 1 - 500 SIGNALOV
{
t = (float)i / fs;
sig_phase3[i] = (byte)(127.0 * (sin((2 * 3.14 * f * t)-180))); // +1 da dobis signal nad 0!, formula za generiranje katerekoli frekvence
}
}
void loop() {
if(micros() - timestamp_phase_correct > t_delay)
{
analogWrite(9, sig_phase1[i]); //Change output value phase 1 ob Do:9 (PWM)
analogWrite(10, sig_phase2[i]); //Change output value phase 2 ob Do:10 (PWM)
analogWrite(11, sig_phase3[i]); //Change output value phase 3 ob Do:11 (PWM)
i++;
i = (i < 500)? i : 0; // counter reset after 500 times (0-499)
timestamp_phase_correct = micros(); // sampling interval time stamp
}
} |
|
Nazaj na vrh |
|
|
igo Član
Pridružen-a: Sre 11 Okt 2006 19:11 Prispevkov: 3638 Aktiv.: 17.06
|
Objavljeno: Sre Okt 14, 2020 8:38 pm Naslov sporočila: |
|
|
Najlažje je vzeti 3 števce
byte kot000; // 0...255
byte kot120;
byte kot240;
Potem na roke izračunaš vrednost celotne periode sinusa v 256 točkah (vsakih 360/256 stopinje) in jih shraniš v programski prostor, ne pa v RAM.
Sinusoida[]={ 127, ... 255, ..., 127, ... 0, ... 125}; // dvignjena za 127
To so vrednosti v točkah i = 0, 63, 127, 195, 255, ostale so pač vmes.
Nato v setup nastaviš 3 števce:
kot000 = 0;
kot120 = 85;
kot240 = 170;
V loop() pa samo s ++ povečuješ vse 3 števce in se bodo sami obrnili iz 255 v 0, ko bo treba.
Še ena malenkost glede hitrosti:
void loop()
{
GlavnaZ: // GlavnaZanka: DVOPIČJE
...
... program
...
kot000++;
kot120++;
kot240++;
goto GlavnaZ; // goto skok je 11 ciklov hitrejši od loop
} // void loop()
Upoštevaj, da pri 50 Hz ena perioda traja 20 ms, en korak kota pa
20/256 = 78 us .
To hitro mine zato ne izgubljaj nepotrebnih ciklov.
Ni dvakrat za reči, da ne bi bilo hitreje direktno brati 3 timerje in v kar brez prekinitve direktno računati vrednosti ob katerih mora posamezen pin spremeniti trenutno stanje. _________________ Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor |
|
Nazaj na vrh |
|
|
tadejcl Neznanec
Pridružen-a: Sre 14 Okt 2020 15:58 Prispevkov: 3 Aktiv.: 0.07
|
Objavljeno: Čet Okt 15, 2020 1:18 pm Naslov sporočila: |
|
|
[quote="igo"]Najlažje je vzeti 3 števce
byte kot000; // 0...255
byte kot120;
byte kot240;
Potem na roke izračunaš vrednost celotne periode sinusa v 256 točkah (vsakih 360/256 stopinje) in jih shraniš v programski prostor, ne pa v RAM.
Sinusoida[]={ 127, ... 255, ..., 127, ... 0, ... 125}; // dvignjena za 127
To so vrednosti v točkah i = 0, 63, 127, 195, 255, ostale so pač vmes.
Nato v setup nastaviš 3 števce:
kot000 = 0;
kot120 = 85;
kot240 = 170;
V loop() pa samo s ++ povečuješ vse 3 števce in se bodo sami obrnili iz 255 v 0, ko bo treba.
Še ena malenkost glede hitrosti:
void loop()
{
GlavnaZ: // GlavnaZanka: DVOPIČJE
...
... program
...
kot000++;
kot120++;
kot240++;
goto GlavnaZ; // goto skok je 11 ciklov hitrejši od loop
} // void loop()
Upoštevaj, da pri 50 Hz ena perioda traja 20 ms, en korak kota pa
20/256 = 78 us .
To hitro mine zato ne izgubljaj nepotrebnih ciklov.
Ni dvakrat za reči, da ne bi bilo hitreje direktno brati 3 timerje in v kar brez prekinitve direktno računati vrednosti ob katerih mora posamezen pin spremeniti trenutno stanje.[/quote]
Pozem obdrzim tako kodo kot je in jo le popravim kot si omenil? |
|
Nazaj na vrh |
|
|
int47 Član
Pridružen-a: Pon 15 Dec 2003 0:10 Prispevkov: 2066 Aktiv.: 9.28 Kraj: Ljubljana
|
Objavljeno: Pet Okt 16, 2020 10:12 am Naslov sporočila: |
|
|
Tako na hitro :
tadejcl je napisal/a: |
sig_phase2[i] = (byte)(127.0 * (sin((2 * 3.14 * f * t)-90))); // +1 da dobis signal nad 0!, formula za generiranje katerekoli frekvence
|
Mislim, da sin() računa v radianih. _________________ Kdor ni skregan, ni Slovenc ! |
|
Nazaj na vrh |
|
|
igo Član
Pridružen-a: Sre 11 Okt 2006 19:11 Prispevkov: 3638 Aktiv.: 17.06
|
Objavljeno: Ned Okt 25, 2020 9:58 am Naslov sporočila: |
|
|
Tisti timestamp_phase_correct je dokaj ponesrečeno uporabljen, saj 2 mikrosekundi mineta zelo hitro.
Že tako računanje (+, -) z long spremenljivkami dolgo traja, zato se znotraj if pogoja uporablja le primerjanje (<, >).
byte Sinusoida[]= ... izračunaj sinusoido v 256 točkah
Setup()
{
kot000=0;
kot120=85;
kot240=170;
}
void loop()
{
GlavnaZ:
microzdaj = micros();
if(microzdaj > micronext)
{
micronext = microzdaj + microsinhron; // if pogoj bo naslednjič (next) izpolnjen čez microsinhron mikrosekund
analogWrite(9, Sinusoida[kot000]);
analogWrite(10, Sinusoida[kot120]);
analogWrite(11, Sinusoida[kot240]);
kot000++;
kot120++;
kot240++;
}
goto GlavnaZ;
}
Nisem preverjal, ampak vsak analogWrite mora uporabljati svoj Timer.
Vsak timer je povezan z dvema izhodnima pinoma, zato ni nujno, da smeš uporabiti pine 9, 10 in 11.
Za povrhu analogWrite vrže ven zelo počasno frekvenco 480 ali 960Hz in ni nujno, da bo kaj pametnega prilezlo ven na izhode, če jo boš v loop stalno spreminjal.
Naštudiraj registre, ki so povezani s Timerji, in vanje direktno vpisuj vrednosti ob katerih naj izhodni pini spremenijo stanje. To je v datasheetu od mikrokontrolerja. _________________ Teoretično je praksa posledica teorije, praktično je pa ravno obratno. (igo 2001)
LP, Igor |
|
Nazaj na vrh |
|
|
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 68 dni
Powered by phpBB © 2001, 2005 phpBB Group
|