mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Funktionswert in anderer Funktion integrieren


Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich wollte gerne eine kleine Berechnung mit nen Mikrocontroller 
durchführen. Ich nehme über den ADC-Wandler drei Spannugsmesswerte auf 
(3-Spannugsmessermethode), aus denen sich zwei Variablen errechnen.
Das Problem dabei ist, dass ich zur Berechnung Letzterer das Ergebnis 
einer anderen Brechnung aus den 3 Eingangsspannungsmesswerten brauche. 
Die Frage also: Wie kann ich das Ergebnis einer Funktion in eine andere 
Funktion integrieren ?

Der Code dazu:

float phi(float Ue, float Un, float Ux)
{
return acos(((Ue*Ue)-(Un*Un)-(Ux*Ux))/(2*Un*Ux));
}

float Rx(float Ux, float Un)
{
return (10*Ux/Un)*cos(phi);
}

float Xx(float Ux, float Un)
{
return (10*Ux/Un)*sin(phi);
}

das Ergebnis phi aus der ersten Berechnung, soll nun in der 
cos/sin-Berechnung auftauchen.
Ist da ein Pointer auf die Funktion von Nöten ?

Ich hoffe ihr könnt mir weiterhelfen

Helge

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Helge schrieb:
> das Ergebnis phi aus der ersten Berechnung, soll nun in der
> cos/sin-Berechnung auftauchen.

Dann könnte man sich das Ergebnis der ersten Berechnung in einer
Variablen merken, und diese an die beiden anderen Funktionen übergeben.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Helge schrieb:

> das Ergebnis phi aus der ersten Berechnung, soll nun in der
> cos/sin-Berechnung auftauchen.
float phi(float Ue, float Un, float Ux)
{
  return acos(((Ue*Ue)-(Un*Un)-(Ux*Ux))/(2*Un*Ux));
}
 
float Rx(float Ux, float Un, float phi)
{
  return (10*Ux/Un)*cos(phi);
}
 
float Xx(float Ux, float Un, float phi)
{
  return (10*Ux/Un)*sin(phi);
}

void foo( .... )
{
  float tmp = phi( ..... )
  Rx( ...., tmp );
  Xx( ...., tmp );
}

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort.
O.k. ich verknüpfe also die drei Funktionen phi, Rx und Xx zu einer 
Funktion namens foo.
Ist es dann so richtig mit den Variabeln wenn ich annehme, dass Ux = 5 
und Un = 3 seitens der Eingangssignale sind ?

...

void foo(float Ue, float Un, float Ux)
{
  float tmp = phi(1,3,5)
  Rx(5,3, tmp );
  Xx(5,3, tmp );
}

Helge

Autor: foo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Helge schrieb:
> O.k. ich verknüpfe also die drei Funktionen phi, Rx und Xx zu einer
> Funktion namens foo

Aber das klappt nur wenn du die foo nennst!

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, so ähnlich.

Allerdings sah es bisher danach aus, daß du die Rückgabewerte von
Rx() und Xx() noch irgendwie verwenden willst, das fehlt in
dem Beispiel jetzt aber.

Außerdem wird wahrscheinlich der Aufrufer von foo() diese
Werte brauchen, also müssten die wieder dorthin gebracht werden.
Einfacher ist es wahrscheinlich, auf foo() zu verzichten und
deinen obigen Inhalt von foo() gleich beim Aufrufer anstatt
des Aufrufs von foo() einzusetzen.

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
achso, also wäre auch das möglich ?

float Messergebnis (float Ue, float Un, float Ux)
{
  tmp = acos(((Ue*Ue)-(Un*Un)-(Ux*Ux))/(2*Un*Ux));

  Rx = (10*Ux/Un)*cos(tmp);
  Xx = (10*Ux/Un)*sin(tmp);

  return Rx,Xx ;
}

Autor: fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Helge schrieb:
> return Rx,Xx

Kannst du zwei Variablen zurückgeben?

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
O.K. das geht wohl schlecht.
Tut mir Leid, bin noch blutiger Anfänger.

dann so vielleicht ?


float Messergebnis_Rx (float Ue, float Un, float Ux)
{
  tmp = acos(((Ue*Ue)-(Un*Un)-(Ux*Ux))/(2*Un*Ux));

  Rx = (10*Ux/Un)*cos(tmp);

  return Rx;
}

float Messergebnis_Xx (float Ue, float Un, float Ux)
{
  tmp = acos(((Ue*Ue)-(Un*Un)-(Ux*Ux))/(2*Un*Ux));

  Xx = (10*Ux/Un)*sin(tmp);

  return Xx;
}

Autor: fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder du returnst z.b. ein struct.

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das beste wär, du besorgst dir erst mal ein gutes C-Buch, oder Tutorial 
und kommst mit der Sprache unter Windows oder Liunux (oder was immer du 
nutzt) klar, bevor mit dem µC und der Peripherie eine weitere 
Fehlerquelle hinzukommt.

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
O.K., aber so geht's auch, oder ?

Ich habe jetzt gleich noch ein weiteres Problem:

Wie ich Anfangs geschrieben habe, nehme ich die 3 Messwerte mit den ADC 
auf, den ich multiplexe (anders geht's ja nicht, der Controller ist 
übrigens der AT90USB1287).
So schaut bei mir die main Funktion aus:

while (1)
{
unsigned char i; //Zählvariable
unsigned int adcval;

  PORTD=0x00;

  for (i=0; i<=2; i++)
  {
  adcval = read_adc(i);

  }}

nun ist es ja so, dass die Variable adcval den Messwert von einen der 
drei Eingangskanäle trägt, je nachdem auf welchen Zählstand die Variable 
i steht. Für i=1 ist adcval also Ue, für i=2 ist adcval Un und für i=3 
ist adcval Ux.
Wie stelle ich nun die Berechnung den Funktionen Messergebnis_Rx/Xx an ?
Ich müsste die Ue/Un/Ux ja irgendwie zwischenspeichern, weil sie sich ja 
ständig untereinander verändern.

Vielleicht kann mir da jemand einen Tip geben ?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, wieder: erst mal C lernen.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Stichwort hierzu wäre übrigens switch

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, ihr habt ja recht. Aber an der Praxis lernt man die Sachen ja doch 
am schnellsten.

Autor: fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das stimmt. aber wenn man sachen nachschlagen kann is auch gut

Autor: fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lass dich nicht einschüchtern : ) Generell haben die hier ja recht, 
trotzdem ist es so, dass hier Fragen auch schnell im Keim erstickt 
werden, weil sie anderen zu lächerlich sind.

Nichts desto trotz wirst du hier immer gute Ratschläge bekommen! Ein 
wenig Eigenbeteiligung vorausgesetzt.

Autor: fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na und in keinem Buch der Welt bekommst du so gute und vor allem aufs 
Problem zugeschnittene Hilfe wie hier ;-)

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
switch lautet also das Stichwort.
Es bleiben die Variablen Ue,Un,Ux also solange gespeichert, bis sie in 
der nächsten Runde der Schleife wieder ggf. überschreiben werden. Liege 
ich da richtig ?


while (1)
{
unsigned char i; //Zählvariable


  for (i=1; i<=3; i++)
  {
    switch (i) {

   case 1:
   Ue = read_adc(i);

   case 2:
   Un = read_adc(i);

   case 3:
   Ux = read_adc(i);

  Messergebnis_Rx (float Ue, float Un, float Ux)
  Messergebnis_Xx (float Ue, float Un, float Ux)

}}}

Autor: fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Helge schrieb:
> Es bleiben die Variablen Ue,Un,Ux also solange gespeichert

Das kommt darauf an, wo du sie deklariert hast.

Helge schrieb:
> }}}

Sowas solltest du nicht machen (ist nur ein Schönheitsfehler)...

Keiner kennt deinen ganzen Code, jedoch wenn du Ereignisse machen 
solltest, die von Interrupts ausgehen, so solltest du entsprechende 
Variablen als volatile deklarieren.

Autor: fragensteller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Darüber hinaus schadet es nicht, bei der switch-Anweisung ein default zu 
deklarieren, damit, falls mal was schief läuft, nicht garnichts mehr 
passiert (auch "nur" ein Schönheitsfehler) - ist eher generell.

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
O.K.
Schönheitsfehler müssen nicht sein und die Variablen Ue,Un,Ux habe ich 
ja noch gar nicht deklariert. Ich darf sie nicht vor der main-Funktion 
deklarieren, also setzte ich die Deklaration nach der while(1) Schleife 
und vor der for-Schleife.
Jetzt müsste es so sein, dass nachdem die Schleife dreimal durchgelaufen 
ist, die drei Variablen Ue, Un und Ux mit den jeweiligen Messwert 
vollgeschrieben sind und die Funktionen Messergebnis_Rx/Xx das Ergebnis 
zurückgeben können, oder ?


while (1)
{
unsigned char i; //Zählvariable
PORTD=0x00;
float Ue;
float Un;
float Ux;

  for (i=1; i<=3; i++)
  {
    switch (i) {

   case 1:
   Ue = read_adc(i);

   case 2:
   Un = read_adc(i);

   case 3:
   Ux = read_adc(i);

   default:
   Ue,Un,Ux = 0;

  Messergebnis_Rx (float Ue, float Un, float Ux)
  Messergebnis_Xx (float Ue, float Un, float Ux)
}
}
}

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und bevor ich hier einen Augenkrampf bekomme:
Versuche bitte
1. Deine Quelltexte vernünftig zu formatieren (Einrückungen in Blöcken,
  öffnende und schließende { ... } übereinander etc.)
2. Quelltext hier in einem C-Tag einzufügen, also etwa so:
[c]
int main( ... )
{
   if( ... )
   {
       ...
   }
}
[/c]
Das ergibt dann sowas:
int main( ... )
{
   if( ... )
   {
       ...
   }
}

Das ist wesentlich übersichtlicher und angenehmer zu lesen.

Wenn du dir beim Formatieren 10 Sekunden sparst, und du hier
von 5 Leuten Antworten bekommst, dann haben schon 50 Leute
gelesen und jeweils 10 Sekunden länger gebraucht zum Lesen.
Macht bei dir 10 gesparte und bei allen anderen 500 vergeudet.
Das ist nicht nett, wenn man sich helfen lassen will.

Und Grundlagen selber lernen ist nach wie vor netter als
sich hier jeden Satz vorkauen zu lassen, der in jedem Grundlagenbuch
steht.
Da ist das Mißverhältnis an Aufwand noch deutlich größer.

Für "ich hatte noch nie ein Buch in der Hand und will morgen
C können" gibt es andere Foren, bitte.
Auch wenn ich gleich wieder als arrogant tituliert werde, aber
man muß nicht dieses Forum mit Fragen zuspammen in der Art
"was ist eine Variable".

(Es ist nicht mein Forum, und eine solche Grundsatzfrage
entscheiden die Betreiber.
Deshalb bitte von denen mal bei Gelegenheit einen Kommentar,
ob ich da falsch liege.
Aber in den letzten Wochen ist m.E. mehrheitlich nur noch
sowas hier unterwegs. Wenn das hier so weitergeht bin ich
wahrscheinlich nicht der einzige, der sich ausklinkt.)

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tut mir Leid, wenn es hier so rüber kommt, als ob ich zu faul wäre ein 
C-Buch zu lesen. Genau das habe ich im Moment vor mir liegen und wenn 
ich hier meine Frage ins Forum stelle, dann mache ich das, weil eben 
wirklich nicht mehr weiter komme.
Gut möglich, dass Experten in diesem Gebiet sich über Formulierung und 
Fragen von Anfängern und Autodidtakten den Kopf schütteln, aber oft ist 
es eben die einzige Möglichkeiten bei manchen Problemen weiterzukommen.

Autor: Wolfgang Bengfort (et-tutorials) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Helge schrieb:
> Tut mir Leid, wenn es hier so rüber kommt, als ob ich zu faul wäre ein
> C-Buch zu lesen. Genau das habe ich im Moment vor mir liegen und wenn
> ich hier meine Frage ins Forum stelle, dann mache ich das, weil eben
> wirklich nicht mehr weiter komme.
> Gut möglich, dass Experten in diesem Gebiet sich über Formulierung und
> Fragen von Anfängern und Autodidtakten den Kopf schütteln, aber oft ist
> es eben die einzige Möglichkeiten bei manchen Problemen weiterzukommen.

Hallo Helge,
vielleicht hilft Dir auch mein C-Kurs
http://et-tutorials.de/mikrocontroller/

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Danke für den link,
ich hoffe das mir das ein bisschen weiterhilft

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
// ggf. µC spezifische Includedateien einbinden
#include <stdio.h>
#include <math.h>

int main(void)
{
  float Ue, Un, Ux;
  float Rx, Xx, phi, len;

  // ggf. DDRD initialisieren
  // ggf. ADC initialisieren
  // ggf. printf auf LCD oder UART lenken

  while(1)
  {
    // Messung
    PORTD=0x00;
    Ue = read_adc(1);
    Un = read_adc(2);
    Ux = read_adc(3);

    // Berechnung
    phi = acos(((Ue*Ue)-(Un*Un)-(Ux*Ux))/(2*Un*Ux));
    len = (10*Ux/Un);
    Rx = len * cos(phi);
    Xx = len * sin(phi);

    // Ausgabe
    printf("phi=%f len=%f Rx=%f Xx=%f \r\n", phi, len, Rx, Xx);
}

Autor: Helge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke !

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.