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!! Zitieren
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 ? Zitieren
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! " Zitieren
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. Zitieren
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()); Zitieren
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. Zitieren
gugelhupf Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 Du verwendest einen linearen sin_val Wert: sin(sin_val) bei der ausgabe ! Zitieren
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). Zitieren
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 Zitieren
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.) Zitieren
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* Zitieren
Klotzkopp Geschrieben 19. Juli 2002 Geschrieben 19. Juli 2002 Was für einen Wertebereich hat denn Dein Port überhaupt? -409 bis +409 klingt eigenartig. Zitieren
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? Zitieren
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. Zitieren
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. Zitieren
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] Zitieren
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? Zitieren
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 Zitieren
Klotzkopp Geschrieben 22. Juli 2002 Geschrieben 22. Juli 2002 Und das funktioniert? Du gibst doch immer noch lineare Werte aus :confused: Zitieren
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 ? Zitieren
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. Zitieren
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 Zitieren
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. Zitieren
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. Zitieren
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. Zitieren
Empfohlene Beiträge
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.