Forum: Compiler & IDEs ADC-Wert als Spannung Strom ausgeben


von Rainer (Gast)


Lesenswert?

ich versuche eine Spannung zumessen und einen Strom mithilfe des ADC im 
ATmega8.
Die schaltung um strom zu messen ist Diese hier:
http://www.mikrocontroller.net/articles/Operationsverst%C3%A4rker-Grundschaltungen

Verstärkergrundschaltungen
[Bearbeiten] Grundbeschaltung mit Berechnung Bild b

Mein zumessender strom beträgt 3Ampere

Die ADC-Routiene hab ich vom Tutorial hier,
nun ist meine Frage wie reche ich die Spannung vom OPV in einen 
Stromwert um und gebe sie dann auf die uart aus
1
/* ADC initialisieren */
2
void ADC_Init(void) {
3
 
4
  uint16_t result;
5
  uint16_t  ampere; 
6
  uint16_t  volt ;   
7
8
9
  ADMUX = (0<<REFS1) | (1<<REFS0);
10
  
11
  // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
12
  // schon auf 0, also single conversion
13
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
14
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren
15
 
16
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
17
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
18
 
19
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
20
  while (ADCSRA & (1<<ADSC) ) {         // auf Abschluss der Konvertierung warten
21
  }
22
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
23
     Wandlung nicht übernommen. */
24
  result = ADCW;
25
}
26
 
27
/* ADC Einzelmessung */
28
uint16_t ADC_Read( uint8_t channel )
29
{
30
  // Kanal waehlen, ohne andere Bits zu beeinflußen
31
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
32
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
33
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
34
  }
35
  return ADCW;                    // ADC auslesen und zurückgeben
36
}
37
 
38
/* ADC Mehrfachmessung mit Mittelwertbbildung */
39
/* beachte: Wertebereich der Summenvariablen */
40
uint16_t ADC_Read_Avg( uint8_t channel, uint8_t nsamples )
41
{
42
  uint32_t sum = 0;
43
 
44
  for (uint8_t i = 0; i < nsamples; ++i ) {
45
    sum += ADC_Read( channel );
46
  }
47
 
48
  return (uint16_t)( sum / nsamples );
49
}
50
 
51
...
52
 
53
/* Beispielaufrufe: */
54
 
55
int main()
56
{
57
  char Buff_V[10];
58
  char Buff_A[10];
59
  uint16_t adcval;
60
  ADC_Init();
61
 
62
  while( 1 ) {
63
 
64
   adcval = ADC_Read_Avg(0, 4);  // Kanal 0, Mittelwert aus 4 Messungen
65
  
66
   ampere = adcval * 5.0 / 1024.0;
67
   // A/D-Wert in Spannung umrechnen   (AREF=5V, 10 Bit A/D-Wandler: 
68
69
70
   adcval = ADC_Read_Avg(0, 4);  // Kanal 0, Mittelwert aus 4 Messungen
71
   volt = adcval  / 1024.0;
72
   // A/D-Wert in AMPERE umrechnen (AREF=5V, 10  Bit A/D-Wandler: 
73
74
75
  sprintf( Buff_V, "%5d", volt );
76
77
  sprintf( Buff_A, "%5d", volt );
78
  uart_puts( Buff_V );
79
  uart_puts( Buff_A );
80
81
82
  }
83
}

von Karl H. (kbuchegg)


Lesenswert?

Um den Strom zu messen, der durch ein Bauteil fliesst, musst du die 
Spannung vor dem Bauteil und die Spannung hinter dem Bauteil messen. Die 
Spannungsdifferenz, zusammen mit dem Ohmschen Gesetz und dem bekannten 
Innenwiderstand des Bauteils ergibt dann den Strom, der durch das 
Bauteil fliesst.

(die 2.te Spannung kann natürlich auch 0 sein, wenn das Bauteil direkt 
an Masse hängt. Dann brauchst du nur   U = R * I )

von Rainer (Gast)


Lesenswert?

1
unsigned int  spannung;
2
unsigned int  ampere;
3
4
char Buff_V[10];  //Spannung
5
char Buff_A[10]; //Ampere
6
7
//SPANNUNG AUSGEBEN
8
9
adcval = ADC_Read_Avg(0, 4); // Kanal 0, Mittelwert aus 4 Messungen 
10
spannung = ((long)adcval * 1000) / 1024; // A/D-Wert in Spannung umrechnen (AREF=5V, 10 Bit A/D-Wandler: 
11
12
 sprintf( Buff_V, "Spannung %2d.%3d", spannung/ 1000, spannung % 1000 ); 
13
uart_puts(Buff_V);
14
15
16
//STROM AUSGEBEN
17
18
//Der OPV in meinem Fall ein LM358 gibt ja eine spannung proportional zum 
19
//Strom aus.
20
//Mein Maximaler strom den ich Messen kann liegt bei 3Ampere
21
//bei 3Ampere hab ich am ausgang vom Lm358  5Volt
22
//mein messwiederstand beträgt 0,1Ohm 5Watt
23
//Meine Frage ist jetzt ob die rechnung so richtigt ist um mir den Strom
24
//richtig anzuzeigen.
25
26
adcval = ADC_Read_Avg(0, 4); // Kanal 0, Mittelwert aus 4 Messungen 
27
Strom = ((long)adcval * 3000) / 1024; // A/D-Wert in Strom umrechnen (AREF=5V, 10 Bit A/D-Wandler: 
28
29
sprintf( Buff_A, "Strom %2d.%3d", strom/ 1000, strom % 1000 ); 
30
uart_puts(Buff_A);
Vielleicht kann mir jemand behilflich sein um den Strom auszugeben.
Mfg

von Karl H. (kbuchegg)


Lesenswert?

Rainer schrieb:

> Vielleicht kann mir jemand behilflich sein um den Strom auszugeben.

Was ist denn dein konkretes Problem? Wo haperts denn?
Grundsätzlich sieht das ja nicht so dumm aus. Bis auf das, dass deine 
Variable ganz oben 'ampere' heißt, du aber unten das Rechenergebnis 
einer Variablen 'Strom' (mit großem S) zuweisen möchtest, die Ausgabe 
dann aber von einer Variablen 'strom' (mit kleinem s) machst. Einige 
dich auf einen Variablennamen und benutze den dann auch.

PS:
Ändere deinen Formatspezifizierer zu  %2d.%03d
dann kriegst du im 'Nachkommaanteil' auch führende 0-en

von Karl H. (kbuchegg)


Lesenswert?

1
spannung = ((long)adcval * 1000) / 1024; // A/D-Wert in Spannung umrechnen (AREF=5V, 10 Bit A/D-Wandler:

Wenn du da aber eine richtige Spannung in Volt haben willst, dann 
solltest du aber mit 5000 multiplizieren. Denn "Vollausschlag" vom ADC 
bedeutet ja 5V oder eben 5000mV

Und noch ein PS:
Das wird jetzt geschätzt bei dir nicht den großen Unterschied machen, 
aber du solltest trotzdem beides, die Spannung und den Strom, von ein 
und derselben Messung ausrechnen. dh. Messung machen. Daraus die 
Spannung ausrechnen und aus derselben Messung den zu dieser Spannung 
gehörenden Strom ausrechnen. Den theoretisch könnte sich der 
entsprechende Wert ja zwischen 2 Messungen ja auch signifikant 
verändern. Bei dir ist aber der angezeigte 'Strom' ja nur eine andere 
Anzeigeform deiner 'Spannung'. Die beiden gehören zusammen.

von Rainer (Gast)


Lesenswert?

Erstmal vielen Dank für ihre antwort,
Das mit den Variablen Name da ist mir hier ein kleiner Fehler beim 
erstellen  unterlaufen.
Ich werde dann nur eine messung machen.

Mein problem ist derzeit wie ich den Stromwert richtig angezeigt bekomme
ob meine rechnung für den strom überhaubt richtig ist,
Das ist ein problem
Mfg

von Karl H. (kbuchegg)


Lesenswert?

Rainer schrieb:

> Mein problem ist derzeit wie ich den Stromwert richtig angezeigt bekomme

Was heißt 'richtig angezeigt'?
Kommt denn über die UART eine Ausgabe aufs Terminal?

> ob meine rechnung für den strom überhaubt richtig ist,
> Das ist ein problem

Echt?

  10 Äpfel kosten  23 Euro
  wieviel kosten 8 Äpfel?


  1024        entsprechen  5000mV  entsprechen   3000 mA
  adcval      entspricht    y mV    entsprechen    x  mA
  ----------------------------------

        3000 * adcval
   x = ---------------
            1024

(direkter Dreisatz: Merkregel: Zahl über x, mal Stumpf, durch Spitz)

würde mal sagen: Das ist korrekt.

Ausserdem muss dir das ja auch deine Ausgabe bestätigen.
Lass einen (bekannten) STrom fliessen und miss ihn.
Mit dem Voltmeter misst du am ADC Pin nach, welche Spannung das 
Voltmeter feststellt. Dann schaust du auf deine Anzeige:
  Dort muss dieselbe SPannung auftauchen wie am Voltmeter
  Und wenn dort diese Spannung auftaucht und es tatsächlich so ist,
  dass 5V den 3 Ampere entsprechen, dann muss die in Ampere
  umgerechnete Spannungsangabe dann auch dem bekannten Strom
  entsprechen, der tatsächlich fliesst.

bischen mehr Selbstvertrauen! Das ist doch soweit alles in Ordnung im 
Programm (bis auf den Patzer in den Volt). Jetzt musst du nur noch 
lernen, wie man sich selber Testszenarien ausdenkt. Leg 5V an den ADC 
und auf deiner ANzeige muss 5.000V stehen (fast) bzw. 3.000A (auch 
wieder: fast). Dann machst du 2.5V an den ADC Eingang (Poti als 
SPannungsteiler) und auf der Anzeige muss wieder 2.5V stehen bzw. 1.5A

von Karl H. (kbuchegg)


Lesenswert?

Ähm.
In deinem ersten Beispiel fällt mir was auf.

Du versuchst zwar über die UART auszugeben. Du initialisierst die UART 
aber nirgends.
Das geht natürlich nicht. Du musst schon auch eine funktionierende UART 
haben!

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.