Problem med PWM och triangel/sinusvåg

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Problem med PWM och triangel/sinusvåg

Inlägg av sodjan »

Ja, jo... :-)

Den där lösningen är nog i alla fall snabbare än att anropa sin() varje gång.
Men det är *inte* en lösning med en lookup tabell... :-)

Det är en "PC-lösning" intryckt i en PIC, vilket kanske "fungerar" men det har
inte speciellt mycket med programmering av mikrokontrollers att göra, och du
har inte lärt dig speciellt mycket på det heller.

Sen så bör du nog tänka till lite. vilket upplösning har det register som du ska skriva till ?
D.v.s CCPR1L ? Är det ens i närheten av "double" eller t.ex "0.2902846773" ??
Det ser ju minst samt löjligt ut med 10 decimaler... :-)
Och du har alltså 16 värden per kvarts-cykel.

Och du har ju fortfarnde en hel del beräkningar i varje steg. Kom du aldrig på tanken
att lägga de värden som ska in i CCPR1L direkt i din "tabell" ? Då slipper du
ju i princip alla beräkningar helt och hållet. Alltså något i stil med :

Kod: Markera allt

#include <pic16F887.h>

unsigned char Sinus(int b);
void Delay(int a);

int x = 0, i = -1.0;


void main(){
...
...

      while(1){
            while(x<=16){
               CCPR1L = 1+Sinus(x);
               x++;
            }
...
...
      }
}

unsigned char Sinus(int b){
...
...

   else
   if (b == 2){
      return 24;
   }
...
...
   }
}
Direkt på rak arm, otestat...
Användarvisningsbild
stekern
Inlägg: 453
Blev medlem: 2 november 2008, 08:24:18
Ort: Esbo, Finland

Re: Problem med PWM och triangel/sinusvåg

Inlägg av stekern »

Sodjan hann skriva medans jag skrev detta, men jag postar ändå:

Lägg sinusvärderna i en array i stället för att ha en "enorm" nästlad if-sats.
Sen kan du ju ha värdena sinus(x)*127 i tabellen så slipper du säkert att köra med flyttal och kan även ta bort en multiplikation.
Senast redigerad av stekern 6 februari 2010, 13:13:45, redigerad totalt 1 gång.
Användarvisningsbild
E85
Inlägg: 1274
Blev medlem: 29 maj 2007, 16:24:19
Ort: Övik

Re: Problem med PWM och triangel/sinusvåg

Inlägg av E85 »

Du kan göra en array istället för Sinus() som ovanstående hann skriva men jag postar ändå.

const unsigned char sine_table[4] = {10,15,20,25};
y = sine_table[x];


Men det finns som sagt en massa att fixa där när det gäller doubles m.m.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Problem med PWM och triangel/sinusvåg

Inlägg av sodjan »

Och jag skulle skriva det i assembler... 8)

Och en array är naturligstvis mycket bättre än en nestlad if.
Det är väl det närmaste man kommer en "lookup table" i C... :-)
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Problem med PWM och triangel/sinusvåg

Inlägg av jesse »

Och jag skulle skriva det i assembler... 8)
kom igen nu... var lite snälla.... det blev ju snyggt ju , superfin sinuskurva! :bravo:
Det var bra gjort för en nybörjare. Man kan inte vara proffs första gången.
Användarvisningsbild
sebgus
Inlägg: 408
Blev medlem: 11 december 2007, 09:51:17
Ort: Göteborg

Re: Problem med PWM och triangel/sinusvåg

Inlägg av sebgus »

Naturligtvis, att man inte tänkte på det! Klart allt ska vara färdigberäknat så det bara är att hämta!

sodjan:

Kanske tog i med decimalerna där, orkade aldrig kolla efter var den "högg" av. :)

Array försökte jag få till förut, men det funkade inte. Men nu funkar det! Knepigt :humm:

Lyckades höja frekvensen ytterligare med era fina tips, tackar! :)

Här kommer den optimerade koden:

Kod: Markera allt

#include <pic16F887.h>

double y = 0;
int x = 0;

const unsigned char sine_table[64] = {127, 139, 152, 164, 176, 187, 198, 208, 217, 225, 233, 239, 244, 249, 252, 253, 254, 253, 252, 249, 244, 239, 233, 225, 217, 208, 198, 187, 176, 164, 152, 139, 127, 115, 102, 90, 78, 67, 56, 46, 37, 29, 21, 15, 10, 5, 2, 1, 0, 1, 2, 5, 10, 15, 21, 29, 37, 46, 56, 67, 78, 90, 102, 115};

void main(){
	OSCCON = 0x75;
	PWM1CON = 0x07;
	TRISD = 0xFF;
	TRISC = 0x00;
	PR2 = 0xFF;
	CCP1CON = 0x0C;
	TMR2ON = 1;
	T2CKPS0 = 0;
	T2CKPS1 = 0;
	ADCON0 = 0xC1;

		while(1){
				x = 0;
				while(x<64){
					y = sine_table[x];
					CCPR1L=(unsigned char)y;
					x++;
				}
		}
}
Någon som har ytterligare tips? :D

Fasen vad man lär sig idag!

EDIT: En bild på det hela, snyggare&snabbare än förra!
Bild
Senast redigerad av sebgus 6 februari 2010, 17:35:56, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Problem med PWM och triangel/sinusvåg

Inlägg av sodjan »

Nja, nu börjar det väl närma sig vad man kan åstkomma med
de verktygen och metoderna. Frekvensen blir ju "vad den blir"
så att säga, men det verkar ju som att det var OK...

Är det någon speciell anledning att du inte har gjort double y = 0;
till unsigned char y = 0; ?

Sen så tror jag att du kan hoppa över "y" helt och skriva
CCPR1L=sine_table[x]; direkt. Sannolikt ligger väldigt stor
del av processortiden i att hantera din double. Jämför gärna den
genererade koden i båda fallen så får du se ! :-)
Användarvisningsbild
sebgus
Inlägg: 408
Blev medlem: 11 december 2007, 09:51:17
Ort: Göteborg

Re: Problem med PWM och triangel/sinusvåg

Inlägg av sebgus »

Ja, det blir konstigt om jag använder något annat än double på y.

Låter bilder förklara problemet:

Så som koden är nu:
Bild

Samma kod fast med CCPR1L=sine_table[x];:
Bild

Ursprungskoden med unsigned char y = 0;:
Bild

Någon teori om det hela? Har själv ingen aning. Omvandlingsfenomen?

EDIT: Samma inställningar på oscilloskopet hela tiden. Amplituden minskar ju till i princip noll, inget jag vill ha...
Senast redigerad av sebgus 6 februari 2010, 17:51:04, redigerad totalt 1 gång.
Användarvisningsbild
E85
Inlägg: 1274
Blev medlem: 29 maj 2007, 16:24:19
Ort: Övik

Re: Problem med PWM och triangel/sinusvåg

Inlägg av E85 »

Det beror möjligtvis på att den blir för snabb för PWM-frekvensen/filtret helt enkelt.
Användarvisningsbild
sebgus
Inlägg: 408
Blev medlem: 11 december 2007, 09:51:17
Ort: Göteborg

Re: Problem med PWM och triangel/sinusvåg

Inlägg av sebgus »

Tänkte precis på det, haha! Bytte RC-nät, och då blir det ju förstås mycket bättre.

Får tänka lågpassfilter i fortsättningen och inte bara integrator...

Tackar :)

EDIT: Implementerade min gamla ad8bit()-funktion (för A/D-omvandlaren) och justerade frekvensen med en pot. Slipper man skaffa en frekvensgenerator för att testa filter :D :lol:
Användarvisningsbild
4kTRB
Inlägg: 20838
Blev medlem: 16 augusti 2009, 19:04:48

Re: Problem med PWM och triangel/sinusvåg

Inlägg av 4kTRB »

En bra bok i ämnet (och på labbänken) är aldrig fel.
Den här är som gjuten för dina projekt...

"Analog Test Signal Generation Using Periodic S-Encoded Data Streams"
  • Hardcover: 148 pages
    Publisher: Springer; 1st edition (January 15, 2000)
    Language: English
    ISBN-10: 0792372115
    ISBN-13: 978-0792372110

http://www.amazon.com/Generation-Period ... r=1-1#noop
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Problem med PWM och triangel/sinusvåg

Inlägg av sodjan »

> Ja, det blir konstigt om jag använder något annat än double på y.

Men när du skriver :

> Samma kod fast med CCPR1L=sine_table[x]

så använder du väl inte y alls !? Och det ser ju OK ut.
Returnerar sine_table fortfarande en double ? (Onödigt, så klart).
Det är inte heller osannolikt att kompilatorn gör någon optimering, det
finns ju ingen anledning att returnera en double till CCPR1L.

> Ursprungskoden med unsigned char y = 0;

Och hur en sine_table() definierad *då* då ?
Fortfarnde som en double ? (ockå fel/onödigt i så fall).

Hur som helst, det kanske viktigaste du har lärt dig på detta är
att du ska undvika float/double. Nästan alltid då det finns med
så beror på det på att man inte har förstått eller undersökt problemet
som ska lösas ordentligt. Om det däremot därefter fortfarade behövs
så är det ju bra att det finns... :-)
Användarvisningsbild
sebgus
Inlägg: 408
Blev medlem: 11 december 2007, 09:51:17
Ort: Göteborg

Re: Problem med PWM och triangel/sinusvåg

Inlägg av sebgus »

4kTRB:

Tack för tipset! Får köpa den fram emot sommaren, skolans kurslitteratur gjorde ett stort hål i plånboken nu... :/

sodjan:

Stämmer, använder inte y där. Sine_table är definierad som en unsigned char.

Med ursprungskoden menade jag den koden i min senaste post som innehöll kod och där är sine_table en unsigned char.

Ja man har märkt nu att double verkligen inte är smidigt, bra lärdom för fortsatt pic-programmering!

Haha man kanske ska sluta civ. ing. utbildningen och plugga ElektronikForumet på heltid! Vet någon hur det är med CSN och sånt isåfall?
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Problem med PWM och triangel/sinusvåg

Inlägg av jesse »

försök att göra en matematisk modell av vad ditt program gör så behöver du inte gissa varför det blir som det blir - då förstår du exakt. Och så lär du dig massor.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 47013
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Problem med PWM och triangel/sinusvåg

Inlägg av TomasL »

project_x skrev:Ja man har märkt nu att double verkligen inte är smidigt, bra lärdom för fortsatt pic-programmering!
Beror helt och hållet på hur handikappad din kompilator är, har inget med PIC att göra.
Skriv svar