PWM generera en sinusspänning som har justerbar amplitud

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
Pajander
Inlägg: 223
Blev medlem: 25 april 2005, 15:04:26

PWM generera en sinusspänning som har justerbar amplitud

Inlägg av Pajander »

Hej, sitter och funderar på att göra ett litet projekt där jag behöver ha tillgång till en sinusspänning som är reglerbar i frekvens och amplitud från en microkontroller.

När jag söker runt på nätet så hittar jag många förslag på hur man genererar sinusen och justerar dess frekvens, men inte hittat något som även justerar amplituden.

Förutsättningar:
En fast DC spänning som ej är justerbar.
En liten 8bit MCU av valfri sort, AVR eller PIC troligtvis.
Drivkrets för H-brygga alt 2x halvbryggsdrivare
En h-brygga bestående av 4 transistorer
Eventuellt filter på utgången för att bli av med övertoner om de är för störande.

Jag vill kunna justera frekvensen och amplituden genom att sätta 2 register i mcun där den ena då styr vilken frekvens som är önskad och den andra vilken amplitud som är önskad. Jag vill inte lösa det genom att introdusera en extra reglerbar dc-dc omvandlare innan h-bryggan.

Är det någon som gjort något liknande eller har något tips på vart jag kan hitta sådanna projekt alternativt litteratur på området? Väldigt gärna med exempelkod då jag inte tycker programmering är särskilt kul.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Du kan ju testa att ge lite viktig upplysning:
* Vilka frekvenser rör det sig om?
* Hur stora steg ska amplituden stega?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> då jag inte tycker programmering är särskilt kul.

Där har du sannolikt det största problemet...

Och varför en H-brygga ?
Pajander
Inlägg: 223
Blev medlem: 25 april 2005, 15:04:26

Inlägg av Pajander »

Frekvenser säg 10Hz-1kHz (edit: till 250Hz räcker)

säg att frekvensen ska stega i steg om 1% av huvudspänningen dvs ca en kvarts volt vid en 24volt matningspänning.

sodjan: vilka alternativ till H-brygga tycker du man kan använda?
Senast redigerad av Pajander 7 oktober 2008, 12:55:01, redigerad totalt 1 gång.
Användarvisningsbild
psynoise
EF Sponsor
Inlägg: 7226
Blev medlem: 26 juni 2003, 19:23:36
Ort: Landvetter

Inlägg av psynoise »

En spänningstyrdförstärkare kan du antingen bygga med transkonduktansoperationsförstärkare (en. ota) eller fet-transistor. Sen finns det ju även en uppsjö digitalapotentiometrar som du kan använda som spänningsdelare, kräver säkert en buffer efter. Men detta lämpar väl sig bäst för LF och kanske inte allt för stor dynamik.
Senast redigerad av psynoise 7 oktober 2008, 12:53:11, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

OK, ca 100 steg.
Tja, en effekt-opamp kanske ?
Med förstärkningen styrd av en digital-pot (styrd av processorn).
Men det beror lite på vad sinussignalen ska driva.
Senast redigerad av sodjan 7 oktober 2008, 12:54:15, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

En annan sak är hur "ren" sinus du vill ha.
Skulle kanske ockå ha varit med i första inlägget... :-)
Pajander
Inlägg: 223
Blev medlem: 25 april 2005, 15:04:26

Inlägg av Pajander »

Psynoise: hm där hängde jag inte med så mkt
sodjan: så ren som möjligt utan att det sticker för mkt i kostnad att realisera, för enkelhetens skull kan vi ta en motor som last, ingen spec tillgänglig.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Alltså, "så xxx som möjligt" är inget bra designkriterium !!

Det är ju en jäkla skillnad på krav på en signal signal för t.ex
mätning av Hi-Fi utrustning mot drivning av t.ex en motor !!
Pajander
Inlägg: 223
Blev medlem: 25 april 2005, 15:04:26

Inlägg av Pajander »

sodjan: jo jag förstår det, men har inga mätningar eller data att bassera ett svar på, det jag är ute efter är att ha så lite energiinnehåll i övertornerna som möjligt.

Det jag nu är intresserad av först och främst är att få till styrningen av H-bryggan så jag kan variera frekvens och amplitud.

Så just nu är funktion jag är ute efter, så för labbändamål sätter jag en resistans på utgången så jag kan mäta vilken prestanda och renhet jag kan få på signalen i det läget.

edit: tack föresten, helt sjukt snabba ni är på o svara och komma med feedback. :)
Användarvisningsbild
psynoise
EF Sponsor
Inlägg: 7226
Blev medlem: 26 juni 2003, 19:23:36
Ort: Landvetter

Inlägg av psynoise »

Mm, en sinusvåg är väl inte det lättaste att ta fram, från en mikrokontroller är det väl bara datatabeller som gäller?

Med en spänningsstyrdförstärkare kan du ändra förstärkningen (dvs amplituden) via en yttre spänning. För att få fram styrspänningen får du väl använda en DAC, annars finns analogdevices ssm-kretsar (förr solid state music) där det finns digitaltstyrda volymkontrollers. Annars funkar sodjans föreslag utmärkt, begränsningen är upplösningen hos den digitalapotentiometern.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Men, vad är det för motor som bryr sig så mycket om övertoner ?

Och självklart så kan "som möjligt" alltid uppnås, med obegränsat med pengar,
och det har du ju inte satt någon gräns för...
limpan4all
Inlägg: 8448
Blev medlem: 15 april 2006, 18:57:29
Ort: Typ Nyköping

Inlägg av limpan4all »

Tja, med en duktigt snabb CPU så räcker det ju med PWM med individuelle styrning av transistorerna i H-Bryggan och något filter därefter.
Men det blir inte någon särskilt kul programmering.

Den riktigt simpla varianten är dyrare men mycket enklare.
En DDS (http://www.analog.com/en/rfif-component ... index.html) och en analog multiplikator.
Jag har använt den metoden (AD9831) för att skapa en styrbar (ca 150kHz) och modulerbar signalkälla.
Kom på att jag faktiskt använt AD9850 till ett annat projekt också, praktiska små krabater dom där...
Rekommenderar AD9832 för ditt ändamål.
EDIT: Fel rekomendation, fixat.
Senast redigerad av limpan4all 7 oktober 2008, 13:32:20, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Att ha en tabell att slå upp i är inte så svårt, att ha en "uträknat" tabell är inte så svårt heller, man kan t.ex. ha en "sinustabell" med fullt utslag liggande i programmet och sedan skala den vid att kopiera den till RAM och multiplicera med en faktor som avgör amplituden.

Nackdelen är att man med låga nivåer har färre bits att återge en sinus med och det blir aldrig bra så har man något i närheten av krav på "renhet" är detta en usel lösning.

Och för att filtrera enkelt måste PWM-frekvensen vara >> Fout, alltså minst 100x 250Hz och för att få en skaplig upplösning på sinuskurvan bör den vara på minst 256 steg, detta betyder att den "uträknade" tabellen ska kunde "spelas upp" med minst 256*250Hz = 64kHz. För att PWM-funktionen ska fungera ordentligt bör den vara minst 10x denna frekvens, alltså 640kHz, lite ovetenskapligt.

Är det 1kHz som gäller blir det "bara" en uppspelning med 256kHz och en PWM-frekvens på 2,56MHz...
SvenW
Inlägg: 1156
Blev medlem: 24 april 2007, 16:23:10
Ort: Göteborg

Inlägg av SvenW »

Här är en motorstyrning som lite grann liknar det som efterfrågas:

Ersätt 'motor_current' med amplitud och 'phase
-uppdatering' med frekvens.
Den duger inte till hifi, dessvärre!
Körs i interrupt-service-rutinen i 20 KHz, synkront med PWM-frekvensen.

ISR (TIMER1_OVF_vect)
{
}


inline void
commutator (void)
{
uint16_t pha, phb, phc;
int8_t phase_a, phase_b, phase_c;

pha = phase0;
phb = (phase0 + 128); /* + 120 degrees */
phc = (phase0 + 256); /* + 240 degrees */

phase_a = pgm_read_byte (&sintab_full[pha]);
phase_b = pgm_read_byte (&sintab_full[phb]);
phase_c = pgm_read_byte (&sintab_full[phc]);

pwm_a = (motor_current * phase_a) >> 7;
pwm_b = (motor_current * phase_b) >> 7;
pwm_c = (motor_current * phase_c) >> 7;
}


inline void
set_pwms (void)
{
#ifdef ATMEGA8
OCR1AL = (0x80 + pwm_a);
OCR1BL = (0x80 + pwm_b);
OCR2 = (0x80 + pwm_c);
#endif


#ifdef ATMEGA48
OCR1AL = (0x80 + pwm_a);
OCR1BL = (0x80 + pwm_b);
OCR2A = (0x80 + pwm_c);
#endif
}
Skriv svar