excalibur Geschrieben 18. Juli 2002 Geschrieben 18. Juli 2002 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!!
gugelhupf Geschrieben 18. Juli 2002 Geschrieben 18. Juli 2002 #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 ?
excalibur Geschrieben 19. Juli 2002 Autor Geschrieben 19. Juli 2002 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! "
Klotzkopp Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 Poste doch mal den relevanten Teil Deines Codes, dann können wir eher sagen, woran es liegt.
excalibur Geschrieben 19. Juli 2002 Autor Geschrieben 19. Juli 2002 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());
Klotzkopp Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 Du gibst (als Text) zwar sin(sin_val) aus, aber ausgabe errechnest Du aus sin_val selbst, und das ist linear. ausgabe=(sin(sin_val)*4095)/10; sollte helfen.
gugelhupf Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 Du verwendest einen linearen sin_val Wert: sin(sin_val) bei der ausgabe !
Crush Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 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).
excalibur Geschrieben 19. Juli 2002 Autor Geschrieben 19. Juli 2002 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
gajUli Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 *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.)
excalibur Geschrieben 19. Juli 2002 Autor Geschrieben 19. Juli 2002 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*
Klotzkopp Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 Was fĂŒr einen Wertebereich hat denn Dein Port ĂŒberhaupt? -409 bis +409 klingt eigenartig.
Crush Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 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?
gajUli Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 @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.
excalibur Geschrieben 22. Juli 2002 Autor Geschrieben 22. Juli 2002 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.
Klotzkopp Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 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]
gajUli Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 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?
excalibur Geschrieben 22. Juli 2002 Autor Geschrieben 22. Juli 2002 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
Klotzkopp Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 Und das funktioniert? Du gibst doch immer noch lineare Werte aus :confused:
gugelhupf Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 Original geschrieben von Klotzkopp Und das funktioniert? Du gibst doch immer noch lineare Werte aus :confused: Hmmm...also er erhöht doch sin_val in seiner Schleife, oder nicht ?
Klotzkopp Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 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.
gugelhupf Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 Ich muss auch blind sein, aber er gibt doch seine "ausgabe" an den port weiter.... Naja, wenns bei ihm klappt, dann ist doch alles in Butter :D
Klotzkopp Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 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 Wohl war.
gajUli Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 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.
Crush Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 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.
Empfohlene BeitrÀge
Erstelle ein Benutzerkonto oder melde Dich an, um zu kommentieren
Du musst ein Benutzerkonto haben, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto fĂŒr unsere Community erstellen. Es ist einfach!
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde Dich hier an.
Jetzt anmelden