Forum: Mikrocontroller und Digitale Elektronik Funktionswert in anderer Funktion integrieren


von Helge (Gast)


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

von Klaus W. (mfgkw)


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.

von Karl H. (kbuchegg)


Lesenswert?

Helge schrieb:

> das Ergebnis phi aus der ersten Berechnung, soll nun in der
> cos/sin-Berechnung auftauchen.
1
float phi(float Ue, float Un, float Ux)
2
{
3
  return acos(((Ue*Ue)-(Un*Un)-(Ux*Ux))/(2*Un*Ux));
4
}
5
 
6
float Rx(float Ux, float Un, float phi)
7
{
8
  return (10*Ux/Un)*cos(phi);
9
}
10
 
11
float Xx(float Ux, float Un, float phi)
12
{
13
  return (10*Ux/Un)*sin(phi);
14
}
15
16
void foo( .... )
17
{
18
  float tmp = phi( ..... )
19
  Rx( ...., tmp );
20
  Xx( ...., tmp );
21
}

von Helge (Gast)


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

von foo (Gast)


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!

von Klaus W. (mfgkw)


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.

von Helge (Gast)


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 ;
}

von fragensteller (Gast)


Lesenswert?

Helge schrieb:
> return Rx,Xx

Kannst du zwei Variablen zurückgeben?

von Helge (Gast)


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;
}

von fragensteller (Gast)


Lesenswert?

Oder du returnst z.b. ein struct.

von Vlad T. (vlad_tepesch)


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.

von Helge (Gast)


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 ?

von Klaus W. (mfgkw)


Lesenswert?

ja, wieder: erst mal C lernen.

von Klaus W. (mfgkw)


Lesenswert?

Das Stichwort hierzu wäre übrigens switch

von Helge (Gast)


Lesenswert?

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

von fragensteller (Gast)


Lesenswert?

das stimmt. aber wenn man sachen nachschlagen kann is auch gut

von fragensteller (Gast)


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.

von fragensteller (Gast)


Lesenswert?

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

von Helge (Gast)


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)

}}}

von fragensteller (Gast)


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.

von fragensteller (Gast)


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.

von Helge (Gast)


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)
}
}
}

von Klaus W. (mfgkw)


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:
1
[c]
2
int main( ... )
3
{
4
   if( ... )
5
   {
6
       ...
7
   }
8
}
9
[/c]
Das ergibt dann sowas:
1
int main( ... )
2
{
3
   if( ... )
4
   {
5
       ...
6
   }
7
}

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.)

von Helge (Gast)


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.

von Wolfgang B. (et-tutorials) Benutzerseite


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/

von Helge (Gast)


Lesenswert?

Vielen Danke für den link,
ich hoffe das mir das ein bisschen weiterhilft

von Stefan B. (stefan) Benutzerseite


Lesenswert?

1
// ggf. µC spezifische Includedateien einbinden
2
#include <stdio.h>
3
#include <math.h>
4
5
int main(void)
6
{
7
  float Ue, Un, Ux;
8
  float Rx, Xx, phi, len;
9
10
  // ggf. DDRD initialisieren
11
  // ggf. ADC initialisieren
12
  // ggf. printf auf LCD oder UART lenken
13
14
  while(1)
15
  {
16
    // Messung
17
    PORTD=0x00;
18
    Ue = read_adc(1);
19
    Un = read_adc(2);
20
    Ux = read_adc(3);
21
22
    // Berechnung
23
    phi = acos(((Ue*Ue)-(Un*Un)-(Ux*Ux))/(2*Un*Ux));
24
    len = (10*Ux/Un);
25
    Rx = len * cos(phi);
26
    Xx = len * sin(phi);
27
28
    // Ausgabe
29
    printf("phi=%f len=%f Rx=%f Xx=%f \r\n", phi, len, Rx, Xx);
30
}

von Helge (Gast)


Lesenswert?

Danke !

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.