Zum Inhalt springen

Sinuskurve (war: brauche mal dringend hilfe)


Empfohlene Beiträge

Geschrieben

Servus. Ich habe da mal ein kleines Problem in C++

Wie gebe ich eine Sinuskurve (0..10V) aus??

Kann mir jemand da mal nen tipp geben?

Am besten wäre sogar ne Sintax damit ich das mal sehen kann.

Danke!!

Geschrieben


#include <math.h>
#include <stdio.h>


int main()
{

double sin_val=-0.1;

while(sin_val<9.9)
printf("Wert %5.3f bei %2.1f Volt \n",sin(sin_val),sin_val+=0.1);

return 0;

}
[/PHP]

So, oder grafisch ? Wenn ja, unter Konsole oder der GUI ?

Geschrieben

Also erstmal vielen Dank für die schnelle Hilfe.

Aber da ist leider noch was.

Ich habe das Signal mal auf nem Oszi ausgegeben und es erscheint nicht wirklich eine Kurve.

Also eigentlich ist es gar keine Kurve sondern nur eine Pyramide.

Komme mir vor wie Ramses in Ägypten.

Kann mir da jemand helfen?

MFG

Excalibur

" Bitte vergebt mir meine Unwissenheit, doch bin ich lernfähig! "

Geschrieben

int main ()

{

outport (0x300,0);

inportb (0x300);

clrscr ();

double sin_val=-0.1;

do

{

if ( kbhit() )

{

abbruch=getch();

if (abbruch==27)

goto beenden;

}

while ( sin_val<=9.9 )

{

gotoxy (7,15);

printf ("Wert %5.3f bei %2.1f Volt \n", sin(sin_val),sin_val+=0.1);

ausgabe=(sin_val*4095)/10;

outport (0x300,ausgabe);

inportb (0x300);

}

while ( sin_val>=0.01 )

{

gotoxy (7,16);

printf ("Wert %5.3f bei %2.1f Volt \n", sin(sin_val),sin_val-=0.1);

ausgabe=(sin_val*4095)/10;

outport (0x300,ausgabe);

inportb (0x300);

}

}

while (!kbhit());

Geschrieben

Das was Klotzkopp meinte ist korrekt, aber auch woanders könnte es noch Probleme geben:

Ist das korrekt, daß der Port doubles annimt? Muß man da nicht auf ein kleineres Format runtercasten? (char/short/int/float)

Damit das Ergebnis der Sin/Cos/Tan-Funktionen stimmt muß man das ganze u.U. in Radians umrechenen: Sin(sin_val*M_PI/180).

Geschrieben

Erstmal danke für die Hilfe.

Also so langsam zweifle ich an mir selbst.

Ich bekomms einfach net hin.

Entweder Pyramiden oder Signale mit zwei High-Werten hintereinander.

Wird Zeit das es WE wird. Wußte garnet dass es so schwierig ist ne Sinuskurve auszugeben.

Aber wenn ihr noch ein paar Ratschläge habt. Immer her damit

Geschrieben

*lach* Also wenn ich Sinus waere, wuerde ich auch Pyramiden ausgeben.

Du musst das Sinusargument von 0 bis 2*PI laufen lassen, um die ganze Kurve zu bekommen und den Sinuswert mit 10 Multiplizieren, wenn er zwischen -10 und +10 pendeln soll. (Soll er von 0 bis 10 laufen, mit 5 multiplizieren und 5 aufaddieren.)

Geschrieben

Also erstmal danke für die Hilfe.

Nur verstehe ich nicht wie ich das ansstellen soll. Bin halt momentan schwer von Begriff.

Kannste mir das als Sintax schicken. Damit ich das mal sehe.

Glaube momentan das ich besser zur Pharaonenzeit geboren wäre. Sehe über all Pyramiden.*lach*

Geschrieben

Also vielleicht ist da die Fragestellung etwas komisch. Erst mal wie wird der Sinus vom entsprechenden Volt berechnet? Gib mal ´ne Formel, dann könnte man mehr damit anfangen.

Ich verstehe das so, daß Du die Sinuswerte bei entsprechenden Graden berechnet haben möchtest und zwar auf einen Wertebereich, der vermutlich den Volt entsprechen soll.

Seltsam ist noch, daß Du den Port gleich nach dem Schreiben wieder liest und zwar ohne das Ergebnis abzuspeichern oder zu verarbeiten - erscheint mir sinnlos.

Vielleicht bringt Dich das Beispiel weiter:


	{

#define sin_start	0

#define sin_end		360

#define schrittweite	20

#define amplitude 10

#define m_pi		3.14159265358979323

#define rad2deg(R)	R/(m_pi*180.)

#define rad(R)		R*(3.14159265358979323/180.)

#define grad(R)		R*(180.0/3.14159265358979323)

#define m_rad		3.14159265358979323/180.

#define m_grad		180./3.14159265358979323


	double sin_val; 


	for (sin_val=sin_start ; sin_val<=sin_end ; sin_val+=(sin_end-sin_start)/schrittweite)

	printf ("Wert %5.3f bei %2.1f Grad \n", amplitude*sin(rad(sin_val)),sin_val); 

//	ausgabe=(sin_val*4095)/10; // Das kapier ich nicht so ganz

//	outport (0x300,ausgabe); 

//	inportb (0x300);	// ist das nicht ewtas überflüssig wenn ich doch nur schreiben will?

	} 

Sollten keine negativen Werte erreicht werden sondern nur 0-10, dann mußt Du halt die Hälfte rechnen:

printf ("Wert %5.3f bei %2.1f Grad \n", amplitude/2+(amplitude/2*sin(rad(sin_val))),sin_val);

@Klotzkopp:

Port 0x300 sind experimentelle Prototyp-Karten.

@dem anderen:

Was hast Du denn eingebaut?

Geschrieben

@excalibur

Lass Dich nicht verwirren. Dein Listing arbeitet ja richtig, nur dass Du Werte ausgibst, die Du linear von 0.1-9.9 rauf und runter zaehlst. Aendere einfach die Werte auf 0 und PI und gib das Ergebnis der Sinusfunktion dieser Werte, multimpliziert mit einem Faktor verschoben um einen Gleichanteil. Dann siehst Du schon, wo der Hase lang laeuft.

Geschrieben

Erst mal Dank an alle die übers Wochenende sich den Kopf über die blöde Kurve zerschlagen haben. Ich habe es nicht getan sondern ertsmal relaxt.

So. dann zu den Fragen:

@Klotzkopp

meine Port hat den Wertbereich 0 - 4095,

@Crush

Ich will einfach nur eine Sinuswelle von 0-10 V augeben, die ich dann auf dem Oszi anzeigen kann.

Den Port lese ich nach dem Schreiben wieder mit Inport damit die Karte den Wert ausgibt. Ja ich weiß ist ein wenig doof gemacht. Aber so verlangts der Hersteller.

"ausgabe=(sin_val*4095)/10" ist eine einfache Verhältnissrechnung. Mein Ausgabewert verhält sich zu 10 V wie sin_val zu 4095. Damit rechnet er meinen Ausgabewert in Volt um.

@gajUli

Aendere einfach die Werte auf 0 und PI und gib das Ergebnis der Sinusfunktion dieser Werte, multimpliziert mit einem Faktor verschoben um einen Gleichanteil.

Ich bin verwirrt und versteh kein Wort. Bin halt nur AZUBI im erstem Jahr.

Geschrieben

1.

Wenn Du Dein Ergebnis sowieso auf auf 0 - 4095 skalieren musst, dann ist die Angabe 10 V sinnlos. Entscheidend ist: Die Sinusfunktion liefert Werte zwischen -1 und 1, d.h. Du musst 1 addieren und mit 2047.5 multiplizieren, um auf Deinen gewünschten Wertebereich zu kommen.

2.

Das Argument der Sinusfunktion ist ein Winkel, es macht wenig Sinn, da die Spannung einzusetzen. Wenn Du eine vollständige Periode sehen willst (ein Berg, ein Tal), brauchst Du Werte von 0 bis 360°. Die meisten Programmiersprachen erwarten das Argument allerdings in Bogenmaß, dabei sind 360° gleich 2 PI.

Das folgende Beispiel liefert 360 Werte. Wenn Dir das zu grob oder zu fein ist, musst Du den Wert in der For-Schleife hinter dem += ändern.

#define PI 3.14159265358979323

int main()
{
double wert;
for( double grad= 0.0; grad <= 360.0; grad += 1.0 ) {
wert = ( sin( grad / 180.0 * PI ) + 1.0 ) * 2047.5;
printf( "%d\n", (int) wert );
}
return 0;
}[/CODE]

Geschrieben

sin(x) pendelt zwischen -1 und 1, wenn Du x von 0 bis PI laufen laesst.

10V entspricht 4095, wenn ich recht verstanden habe, und negative Spannungswerte kann die Karte nicht erzeugen.

Also muessen wir erstmal die Sinuskurve in den positiven Bereich verschieben:

sin(x) + 1

Jetzt pendelt sie zwischen 0 und 2.

Du moechtest aber, dass sie zwischen 0 und 4095 pendelt, also dass der sog. Spitze-Spitze-Wert 10 Volt betraegt.

Also muessen wir das ganze Signal mit der Haelfte von 4095 multiplizieren.

(sin(x) +1 ) * 2047

Alles klar?

Geschrieben

Jungs, meine schlaflosen Nächte sind vorüber.

Ich habs. (Endlich).

und damit ihr auch mal schauen könnt wie geht. Poste ich hier mal den Quellcode. Viel Spaß beim Anschauen, und nochmals Danke für die Hilfe.

#define sin_start 0

#define sin_end 360

#define schrittweite 20

#define amplitute 10

#define m_pi 3.14159265358979323

#define rad2dag® R*(m_pi*180.00)

#define rad® R*(3.14159265358979323/180.00)

#define grad® R*(180.00/3.14159265358979323)

#define m_rad 3.14159265358979323/180.00

#define m_grad 180.00/3.14159265358979323

char abbruch;

double ausgabe;

int main ()

{

outport (0x300,0);

inportb (0x300);

clrscr ();

double sin_val;

do

{

if ( kbhit() )

{

abbruch=getch();

if (abbruch==27)

goto beenden;

}

for ( sin_val=sin_start; sin_val<=sin_end; sin_val+=(sin_end-sin_start)/schrittweite)

{

printf ("Wert &5.6f bei %2.1f Grad \n", amplitute/2+(amplitute/2*sin(rad(sin_val))),sin_val);

ausgabe=(sin_val*4095)/10;

outport (0x300,ausgabe+2048);

inport (0x300);

}

}

while (!kbhit());

beenden:

return 0;

}

:marine :marine :marine :marine :marine :marine :marine :marine

Geschrieben
Original geschrieben von gugelhupf

Hmmm...also er erhöht doch sin_val in seiner Schleife, oder nicht ?

Ja, aber immer um den gleichen Wert, also linear. Hab ich Tomaten auf den Augen, oder ist sin_val 0, 20, 40, 60, 80, ..., 340, 360? Der wirkliche Funktionswert wird nur fürs prinft errechnet, aber nicht auf den Port gegeben.
Geschrieben
Original geschrieben von gugelhupf

Ich muss auch blind sein, aber er gibt doch seine "ausgabe" an den port weiter....

Ja, aber ausgabe ist proportional zu sin_val, der Schleifenvariablen.

Naja, wenns bei ihm klappt, dann ist doch alles in Butter :D :D
Wohl war. :D
Geschrieben

Irgendwie ist der Thread ja krank. Ich wuerde auch nicht drauf wetten, dass der Excalibur sich nicht vielleicht doch nochmal meldet; dann aber bitte mit umfassender Beschreibung des Ausgabegeraetes. ;)

Geschrieben

Eigentlich müßte das Ganze so aussehen:

for ( sin_val=sin_start; sin_val<=sin_end; sin_val+=(sin_end-sin_start)/schrittweite)

{

// Das ist nur der Ausschlag

printf ("Wert &5.6f bei %2.1f Grad \n", amplitute/2+(amplitute/2*sin(rad(sin_val))),sin_val);

// hier sollte dann alles auf das Oszi-Raster rumgerechnet werden

ausgabe=(sin(rad(sin_val)))*2048)+2048;

outport (0x300,ausgabe);

inport (0x300);

}

Du hast outport() und inport() nicht näher erläutert, aber ich vermute schwer, daß der Integer haben will und keine Fließkommazahlen. Vielleicht solltest Du rein sicherheitshalber noch ein (int) davor casten.

Bist Du Dir sicher, daß die Auflösung 12 Bit ist? Haben die unbenutzen Bits nicht noch irgendwelche anderen Steuerfunktionen?

Die 10 Volt von denen Du sprichst würde ich allerdings nicht einrechnen, weil dann einfach nur eine kleinere Amplitude ausgegeben wird und Du unnötig den Meßbereich am Oszi hochschrauben mußt. Möchtest Du den Ausschlag auf voller Display-Größe sehen darfst Du keine unnötigen "Verzerrungen" einrechnen. Du gibst hier doch nur Digitaldaten weiter und keine echten Spannungen. Deshalb ist diese Volt-Einheit hier etwas fehl am Platz.

Wenn das, was Du zuletzt gepostet hast funktioniert, dann liegt der Fehler am Parameter von outport(). Ich würde mir nochmal ganz genau anschauen, wie der Oszi die Daten vom Port ausliest und auf den Bildschirm bringt. Nach diesem Beispiel würde die Abweichung einer Sinuskurve gemessen und nicht der Sinus selbst, was allerdings optisch auch wie eine Sinuskurve wirken würde. Es könnte also auch sein, daß die Einstellung am Oszillator nicht die Richtige ist.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...