Forum: Mikrocontroller und Digitale Elektronik STM32L431RC - Probleme mit Stromsensorenauswertung


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Fred G. (kross_g_braten)


Angehängte Dateien:

Lesenswert?

Hallo Forum,

ich hoffe ihr könnt mir bei meinem Problem helfen.

Problem: Ich möchte den Strom von diversen Stromkreisen erfassen ohne 
diese auftrennen zu müssen. Der zu messende Stromkreis hat 230V 50Hz. 
Der eigentliche gemessene Wert ist dabei nicht wichtig. Wichtig sind für 
mich folgende Zustände:

1. Es fließt kein Strom
2. Es fließt Strom
3. Der Sensor fehlt
4. interne Fehler, Wert kann nicht zugewiesen werden

Damit ich auch ohne Debugger etc. den gemessenen Wert erkennen kann, 
habe ich mir überlegt dort eine RGB Led einzufügen.

Fall 1 = gelb |
Fall 2 = grün |
Fall 3 = rot |
Fall 4 = blau |

Insgesamt sollen vier Sensoren anzuschließen sein.

Wieviel Strom bzw. wie viel Ampere da vorhanden sind, ist irrelevant.

Dazu wählte ich folgende Stromwandler, damit ich die betreffende Leitung 
nicht auftrennen muss:

https://www.poweruc.pl/collections/split-core-current-transformers2/products/split-core-current-transformer-sct013-rated-input-5a-100a

Ich habe, um eine möglichst hohe Empfindlichkeit zu erreichen, einen 
Sensor genommen mit dem Übertragungswert K = 5A/1V = 0,2 OHM


Da findet ihr auch das Datenblatt.

Lt. Datenblatt und Rücksprache mit dem Hersteller reagieren die Sensoren 
erst ab 5mA, was okay für mich ist.


Ich baute also eine Schaltung auf, am Ende mit einem Transistor 
versehen, um ein klares "AN/AUS"-Signal am Ende zu haben und einen OPV, 
damit selbst kleinste Spannungen extrem verstärkt werden. Schaltplan ist 
im Anhang.

Bei der Schaltung hatte ich noch eine Zener eingefügt, damit die 
Spannung begrenzt wird, der STM32L431RC kann bei den Analog Eingängen 
nur 3,3V ab.


Soweit, so gut.

Damit ich die Fälle nun unterscheiden kann, habe ich folgendes 
festgestellt:

1.Fall (kein Strom): Der Sensor zieht den OPV-Eingang auf GND, der 
Transistor wird nicht angesteuert, am Ausgang habe ich ein Potential von 
0V.

2.Fall (Strom fließt): Da ich Wechselstrom messe, pendelt der Wert stets 
von 0V bis 3,3V, wegen der Zener-Diode. Durch Anpassen der Sample_time 
etc. kann man feststellen, wenn es einen Wechsel gibt, dass dieser Fall 
eingetreten ist.

3.Fall (Sensor fehlt): Der Eingang IN+ vom OPV ist einfach offen, der 
Transistor ist komplett ausgesteuert und es liegt das komplette 
Potential am Ausgang an.

4. Fall (interner Fehler): Falls etwas anderes passieren sollte.

Ich habe diese Schaltung mit den Sensoren mal aufgebaut und am Nucleo 
Board getestet, funktioniert sehr gut.

Im Code habe ich folgende 4 Variablen benutzt, um eben diese Fälle 
unterscheiden zu können:
1
uint32_t sensor_value = 0;
2
uint32_t actual_val_min = 0;
3
uint32_t actual_val_max = 0;
4
uint16_t actual_inkr   = 0;

Ich taste damit den gemessenen Wert ab und weise den kleinsten 
gemessenen Wert und den größten gemessenen Wert jeweils zu. Die 
Inkr-Variable ist dann die Differenz.

Der komplette Code ist im Anhang.

Wenn ich die Fälle nochmal betrachte im Vergleich mit den Werten, die 
gemessen werden, ergibt sich folgendes:

Fall 1: Alle Werte auf 0
Fall 2: min = 0, max = 3300, inkr = 3300
Fall 3: min und max = 3300, inkr < 50

Zur Auswertung habe ich Schwellwerte hinzugefügt, um ein breiteren range 
zu haben:
1
uint16_t ADC_VAL [4] = {0};
2
uint16_t threshold_max = 2500;
3
uint16_t threshold_inkr = 2000;
4
uint16_t threshold_min = 850;

Hier die Funktion:
1
#include "main.h"
2
#include "stdio.h"
3
uint32_t sensor_value = 0;
4
uint32_t actual_val_min = 0;        //aktueller kleinster Wert der Messung
5
  uint32_t actual_val_max = 0;        //aktueller größter Wert der Messung
6
  uint16_t actual_inkr   = 0;
7
8
9
uint8_t current_sensor_status(ADC_HandleTypeDef *hadc,uint32_t timeout,uint16_t threshold_min,uint16_t threshold_max,uint16_t threshold_inkr)
10
{
11
  //
12
            //Sensor-Wert
13
          //aktuelle Inkremente der Messung, max - min
14
sensor_value = 0;
15
actual_val_min = 0;        //aktueller kleinster Wert der Messung
16
actual_val_max = 0;        //aktueller größter Wert der Messung
17
actual_inkr   = 0;
18
  uint8_t status_on = 0x01;          //Status AN
19
  uint8_t  status_off = 0x00;          //Status AUS
20
  uint8_t status_sensor_missing = 0x02;    //Status Sensor fehlt
21
  uint8_t  status_internal_error = 0xFE;    //Status interner Fehler
22
  uint8_t status_function_cancelled = 0xFF;  //Status Funktion abgebrochen
23
  uint8_t i = 0;                //Zählervariable
24
    
25
    //Analogwert einlesen#######################################################
26
      if(HAL_ADC_PollForConversion(hadc, timeout) == HAL_OK){            //ADC-Wert Abfrage HAL-Funktion
27
      sensor_value = HAL_ADC_GetValue(hadc);                  //Zuweisung des Wertes zu der Variablen "sensor_value"
28
        actual_val_min = sensor_value;                      //Zuweisung von "actual_val_min" zum Wert des "sensor_value"
29
      }
30
    else{
31
      return status_function_cancelled;                    //falls polling != HAL_OK, dann Funktion mit "status_function_cancelled" sofort beenden
32
    }
33
      do{
34
      if(HAL_ADC_PollForConversion(hadc, timeout) == HAL_OK){          //ADC-Wert Abfrage HAL-Funktion
35
            sensor_value = HAL_ADC_GetValue(hadc);                //Zuweisung des Wertes zu der Variablen "sensor_value"
36
        }
37
      else{
38
        return status_function_cancelled;                  //falls polling != HAL_OK, dann Funktion mit "status_function_cancelled" sofort beenden
39
      }
40
        if(sensor_value < actual_val_min)actual_val_min = sensor_value;      //Wenn "sensor_value" kleiner ist als der Minimalwert, dann den Minimalwert und "sensor_value" gleichsetzen
41
        if(sensor_value > actual_val_max)actual_val_max = sensor_value;      //Wenn "sensor_value" groesser ist als der Maximalwert, dann den Maximalwert und "sensor_value" gleichsetzen
42
        HAL_Delay(1);                              //Delay 1 ms zur Verbesserung der performance
43
        i++;                                  //Zähler inkrementieren
44
      }while(i < 20);                                //Einlesen und Grenzwerte zuweisen, bis Zähler erreicht ist (Durch Wiederholung Antastung an den Realwert)
45
    //Analogwert einlesen ENDE##################################################
46
      actual_inkr = actual_val_max - actual_val_min;                //Inkremente zwischen Minimal- und Maximalwert bestimmen
47
    //Auswertung des Messergebnisses     #######################################
48
      if((actual_inkr   >= threshold_inkr)      &&                //Falls die Inkremente groesser gleich dem Maximalschwellwert sind       UND
49
         (actual_val_max   >= threshold_max)     &&                //    der aktuelle Maximalwert groesser gleich dem Maximalschwellwert ist UND
50
         (actual_val_min   <= threshold_min)){                    //    der aktuelle Minimalwert kleiner gleich dem Minimalschwellwert ist 
51
      return status_on;                            //dann fleißt Strom durch den Sensor, Status AN
52
      }
53
      else if((actual_inkr < threshold_inkr)    &&                //Falls die Inkremente kleiner gleich dem Minimalschwellwert sind       UND
54
        (actual_val_max <= threshold_min)   &&                //    der aktuelle Maximalwert kleiner gleich dem Minimalschwellwert ist  UND
55
        (actual_val_min <= threshold_min)){                  //    der aktuelle Minimalwert kleiner gleich dem Minimalschwellwert ist 
56
      return status_off;                            //dann fleißt kein Strom durch den Sensor, Status AUS
57
      }
58
      else if((actual_inkr < threshold_inkr)    &&                //Falls die Inkremente kleiner gleich dem Minimalschwellwert sind       UND
59
        (actual_val_max >= threshold_max)   &&                //    der aktuelle Maximalwert groesser gleich dem Maximalschwellwert ist UND
60
        (actual_val_min >= threshold_max)){                  //    der aktuelle Minimalwert groesser gleich dem Maximalschwellwert ist 
61
      return status_sensor_missing;                      //dann fehlt der Sensor, Status SENSOR FEHLT
62
      }
63
      else
64
    {
65
      return status_internal_error;                      //Sonst ist der Status interner Fehler, d.h. Werte lassen sich nicht zuordnen
66
    }
67
    //Auswertung des Messergebnisses ENDE#######################################
68
}
Da der Controller nur einen einzigen ADC hat, aber Multichannelbetrieb 
möglich ist, muss ich nach jeder Messung den Kanal wechseln:
1
void ADC_Select_CH1(void){
2
  ADC_ChannelConfTypeDef sConfig = {0};
3
  sConfig.Channel = ADC_CHANNEL_1;
4
  sConfig.Rank = ADC_REGULAR_RANK_1;
5
  sConfig.SamplingTime = ADC_SAMPLETIME_92CYCLES_5;
6
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
7
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
8
  sConfig.Offset = 0;
9
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
10
  {
11
  Error_Handler();
12
  }
13
}

In der main habe ich dann diese Funktion aufgerufen:
1
ADC_Select_CH1();
2
        HAL_ADC_Start(&hadc1);
3
        ADC_VAL[0] = current_sensor_status(&hadc1,1000,threshold_min,threshold_max,threshold_inkr);
4
        status1 = ADC_VAL[0];
5
        HAL_ADC_Stop(&hadc1);
6
        switch(status1){                                    //status im switch
7
            case 0x00:  HAL_GPIO_WritePin(P6_green_GPIO_Port, P6_green_Pin, GPIO_PIN_SET);  //LED grün aus
8
                        HAL_GPIO_WritePin(P6_red_GPIO_Port, P6_red_Pin, GPIO_PIN_SET);    //LED rot aus
9
                    HAL_GPIO_WritePin(P6_blue_GPIO_Port, P6_blue_Pin, GPIO_PIN_RESET);
10
                        break;
11
            case 0x01:  HAL_GPIO_WritePin(P6_green_GPIO_Port, P6_green_Pin, GPIO_PIN_SET);  //LED grün an
12
                          HAL_GPIO_WritePin(P6_red_GPIO_Port, P6_red_Pin, GPIO_PIN_RESET);    //LED rot aus
13
                    HAL_GPIO_WritePin(P6_blue_GPIO_Port, P6_blue_Pin, GPIO_PIN_RESET);
14
                          break;
15
            case 0x02:  HAL_GPIO_WritePin(P6_green_GPIO_Port, P6_green_Pin, GPIO_PIN_RESET);  //LED grün aus
16
                      HAL_GPIO_WritePin(P6_red_GPIO_Port, P6_red_Pin, GPIO_PIN_SET);    //LED rot an
17
                      HAL_GPIO_WritePin(P6_blue_GPIO_Port, P6_blue_Pin, GPIO_PIN_RESET);
18
                      break;
19
            case 0xFE:  HAL_GPIO_WritePin(P6_green_GPIO_Port, P6_green_Pin, GPIO_PIN_RESET);  //LED grün aus
20
                      HAL_GPIO_WritePin(P6_red_GPIO_Port, P6_red_Pin, GPIO_PIN_RESET);    //LED rot an
21
                      HAL_GPIO_WritePin(P6_blue_GPIO_Port, P6_blue_Pin, GPIO_PIN_SET);
22
                      break;
23
            case 0xFF:  HAL_GPIO_WritePin(P6_green_GPIO_Port, P6_green_Pin, GPIO_PIN_RESET);  //LED grün aus
24
                      HAL_GPIO_WritePin(P6_red_GPIO_Port, P6_red_Pin, GPIO_PIN_RESET);    //LED rot an
25
                      HAL_GPIO_WritePin(P6_blue_GPIO_Port, P6_blue_Pin, GPIO_PIN_SET);
26
                      break;
27
            }




Wie erwähnt funktioniert der ganze Kram bei dem Nucleo Board sehr gut, 
auch die Bedenken, die ich anfangs hatte bzgl. zwei Sensoren in einem 
OPV-Case war unbegründet.

Aufgrund dieser Ereignisse habe ich nun eine eigene PCB dafür kreiert. 
Bei dieser habe ich aber das Problem, dass sich zeitweise die Werte 
entweder gegenseitig beeinflussen, oder aber andere parasitäre 
Spannungen abzeichnen. Deshalb wird dann zeitweise der jeweilige 
Transistor angesteuert und es kommt zu Fehlmessungen bzw. zum Fall 4, 
der eigentlich nie passieren darf.

Ich überlege nochmals die Schaltung zu ändern, bzw. die Messungen durch 
einen separaten µC machen zu lassen und nur den Status weiterzugeben.
Vielleicht habt ihr eine Idee was man da machen kann. Die Schaltung wie 
erwähnt funktioniert beim Nucleo echt gut, nur eben bei der PCB nicht. 
Layoutfehler sind natürlich nicht ausgeschlossen, habe da auch versucht 
durch Widerstandsnetzwerke da an Platz zu sparen. Kann das eine Ursache 
sein?
Ist vielleicht die Verstärkung zu heftig gewählt, dass selbst solche 
parasitären Spannungen verstärkt werden?

Stehe nun echt auf dem Schlauch.

von Peter D. (peda)


Lesenswert?

Die Schaltung ist Käse.
Der LM358 hat 3mV Offset. Bei 680k/33 werden die auf 62V verstärkt.

Schaltungen sind besser lesbar, wenn die Eingänge links und die Ausgänge 
rechts sind.

: Bearbeitet durch User
von STK500-Besitzer (Gast)


Lesenswert?

Peter D. schrieb:
> Schaltungen sind besser lesbar, wenn die Eingänge links und die Ausgänge
> rechts sind.

und man sich nicht erst die Pinbelegung des Bausteins raussuchen muss.
Dazu hat man irgendwann mal Schaltungssymbole veröffentlicht.

von STK500-Besitzer (Gast)


Lesenswert?

STK500-Besitzer schrieb:
> und man sich nicht erst die Pinbelegung des Bausteins raussuchen muss.

OK, man sollte das Bild vielleicht auch aufzoomen. Dann kann man auch 
die Pinbeschriftung lesen.

von Stefan F. (Gast)


Lesenswert?

Vermutlich funktionieren die Transistoren nicht so, wie du es willst.

Du hast die Kollektor-Schaltung gewählt, da braucht man keine 
Vorwiderstände vor der Basis. Im Gegenteil, diese Widerstände 
verfälschen deren Ausgangsspannung unnötig. Die Ausgangsspannung am 
Emitter ist ungefähr 0,7 Volt geringer als die Eingangsspannung an der 
Basis.

Warum hast du überhaupt Transistoren zwischen OP_Amp und Mikrocontroller 
gepackt?

von Fred G. (kross_g_braten)


Lesenswert?

Peter D. schrieb:
> Die Schaltung ist Käse.
> Der LM358 hat 3mV Offset. Bei 680k/33 werden die auf 62V verstärkt.
>
> Schaltungen sind besser lesbar, wenn die Eingänge links und die Ausgänge
> rechts sind.

Habe ich mir schon gedacht. Komisch ist ja nur, dass es bei dem Nucleo 
Board funktioniert.

Kennt Ihr dort einen passenderen OPV?

von STK500-Besitzer (Gast)


Lesenswert?

Fred G. schrieb:
> Habe ich mir schon gedacht. Komisch ist ja nur, dass es bei dem Nucleo
> Board funktioniert.

Kein NUCLEO-Board hat einen LM358 drauf.

von Stefan F. (Gast)


Lesenswert?

Fred G. schrieb:
> Kennt Ihr dort einen passenderen OPV?

Nicht für diese hohe DC Verstärkung.

Audio-Verstärker hätten in Reihe zu deinen 33 Ohm Widerständen jeweils 
einen Kondensator, so dass nur AC verstärkt wird. Vielleicht kämst du 
damit besser klar.

von Fred G. (kross_g_braten)


Lesenswert?

Stefan ⛄ F. schrieb:
> Vermutlich funktionieren die Transistoren nicht so, wie du es willst.
>
> Du hast die Kollektor-Schaltung gewählt, da braucht man keine
> Vorwiderstände vor der Basis. Im Gegenteil, diese Widerstände
> verfälschen deren Ausgangsspannung unnötig. Die Ausgangsspannung am
> Emitter ist ungefähr 0,7 Volt geringer als die Eingangsspannung an der
> Basis.
>
Ohne Vorwiderstand kann ich mal probieren, ist auf jedenfall ne gute 
Idee, Danke :)

> Warum hast du überhaupt Transistoren zwischen OP_Amp und Mikrocontroller
> gepackt?

Anfangs hatte ich OUT1/2 direkt mit dem Analogeingang gemessen. Da gab 
es aber immer wieder andere Werte, vermutlich eben wegen dem OPV, wie 
Peter D. schrieb. Das wusste ich nur nicht.

Deswegen habe ich, da ich auch nicht den exakten Wert des Stromes 
brauche, einen Transistor dazwischen gebaut, um nur ein AN/AUS/Sensor 
fehlt zu haben

von Fred G. (kross_g_braten)


Lesenswert?

STK500-Besitzer schrieb:
> Fred G. schrieb:
>> Habe ich mir schon gedacht. Komisch ist ja nur, dass es bei dem Nucleo
>> Board funktioniert.
>
> Kein NUCLEO-Board hat einen LM358 drauf.

Das stimmt. Habe auf einen Breadboard die Schaltung aufgebaut und dann 
an den Pin PA0 angeschlossen.
Wie gesagt, macht genau das was ich möchte

von Fred G. (kross_g_braten)


Lesenswert?

Stefan ⛄ F. schrieb:
> Fred G. schrieb:
>> Kennt Ihr dort einen passenderen OPV?
>
> Nicht für diese hohe DC Verstärkung.
>
> Audio-Verstärker hätten in Reihe zu deinen 33 Ohm Widerständen jeweils
> einen Kondensator, so dass nur AC verstärkt wird. Vielleicht kämst du
> damit besser klar.

habe so eine OPV Version gerade nicht hier.

Ist dieser denn gänzlich unpassend? Der OPV soll ja "nur" den Transistor 
ansteuern, der dann das Signal durchgibt, der widerrum ausgelesen wird 
vom ADC.
Wenn es einen Offset gibt, sodass dieser immer schaltet bzw. 
unzuverlässig arbeitet, kann ich dies dann irgendwie beeinflussen?

Ist eine Lösung mit OPV überhaupt sinnvoll?

Wäre über eure Hilfe sehr dankbar :)

von Stefan F. (Gast)


Lesenswert?

Fred G. schrieb:
> habe so eine OPV Version gerade nicht hier.

???

Du sollst Kondensatoren hinzufügen, nicht den Operationsverstärker 
austauschen. Den Verstärker kannst du später als weitere Verbesserung 
immer noch austauschen, wenn es dann immer noch nicht gut genug läuft.

> Wenn es einen Offset gibt, sodass dieser immer schaltet bzw.
> unzuverlässig arbeitet, kann ich dies dann irgendwie beeinflussen?

Indem du wie gesagt nur den AC Anteil verstärkst, und DC nicht. Dafür 
ist der Kondensator ja da. Versuche mal 220 µF in Reihe zu den 33 Ohm, 
mit dem Minus Pol an GND.

> Ist eine Lösung mit OPV überhaupt sinnvoll?

Eigentlich kommt mir hier jede Form der Verstärkung unnötig vor. Ich 
würde die Stromwandler (durch einen 10kΩ Schutzwiderstand) direkt an den 
analogen Eingang des µC anschließen. 1 Volt kann der doch super messen, 
und Überspannung würden die internen ESD Schutzdioden des 
Mikrocontrollers ableiten.

Auf diese Weise kannst du allerdings nur die positiven Halbwellen des 
Wechselstromes messen. Die negativen werden abgeschnitten. Ist egal, 
oder?

Für den Fall
> 3. Der Sensor fehlt
Du könntest den analogen Eingang parallel zum Stromwandler mit einem 
100kΩ Widerstand auf 3,3V ziehen. Da der Stromwandler einen viel 
geringeren Innenwiderstand hat, wird er die Spannung herunter ziehen, 
wenn er angeschlossen ist.
1
                 +---[100k]---o +3,3V
2
                 |
3
             o---+---[10k]---o ADC Eingang
4
Stromwandler
5
             o---| GND

von Fred G. (kross_g_braten)


Lesenswert?

Stefan ⛄ F. schrieb:
> Fred G. schrieb:

> Du sollst Kondensatoren hinzufügen, nicht den Operationsverstärker
> austauschen. Den Verstärker kannst du später als weitere Verbesserung
> immer noch austauschen, wenn es dann immer noch nicht gut genug läuft.
>
>> Wenn es einen Offset gibt, sodass dieser immer schaltet bzw.
>> unzuverlässig arbeitet, kann ich dies dann irgendwie beeinflussen?
>
> Indem du wie gesagt nur den AC Anteil verstärkst, und DC nicht. Dafür
> ist der Kondensator ja da. Versuche mal 220 µF in Reihe zu den 33 Ohm,
> mit dem Minus Pol an GND.
>

Das werde ich nochmal probieren, danke für den Tipp :)

>
> Eigentlich kommt mir hier jede Form der Verstärkung unnötig vor. Ich
> würde die Stromwandler (durch einen 10kΩ Schutzwiderstand) direkt an den
> analogen Eingang des µC anschließen. 1 Volt kann der doch super messen,
> und Überspannung würden die internen ESD Schutzdioden des
> Mikrocontrollers ableiten.
>
> Auf diese Weise kannst du allerdings nur die positiven Halbwellen des
> Wechselstromes messen. Die negativen werden abgeschnitten. Ist egal,
> oder?
>
Die negativen Halbwellen sind nicht wichtig, genau. Wichtig ist nur, 
dass ich zuverlässig erkenne, ob es AN/AUS/Sensor fehlt ist.

Habe das mal eben mit dem NUCLEO ausprobiert. Das Potential vom ADC 
Eingang zieht sich auf 0V, wenn kein Strom durch den Stromsensor geht. 
Das ist gut. Auch für Fall 3, wenn der Sensor fehlt, wird das Potential 
nach oben gezogen auf 3,3V, auch super.

Allerdings erkennt er nun nicht mehr, ob überhaupt Strom durch den 
Sensor geht. Da schwankt der Wert extrem.
Habe nochmal an der Sampletime rumgestellt, komme aber nicht zu einem 
klaren, eindeutigem Ergebnis.

Wenn der Sensor erst ab 5mA reagiert, und sein Übertragungsbeiwert 0,2 
Ohm ist, ergibt das ja theoretisch eine Ausgangsspannung von 5mA * 0,2 
Ohm = 1mV.
Wenn ich nun die 12Bit Auflösung betrachte, und das mal gegenrechne, wie 
viel Spannung einem Inkrement entspricht, komme ich auf 3,3V/4096 Inkr = 
0,806 mV / Inkrement.
Da leuchtet quasi bei 5mA höchstens 2 Inkremente auf, das könnte zu 
wenig sein.

Ich denke ganz ohne Verstärkung gehts nicht.


Habt ihr da noch eine Idee? Finde die Schaltung von Stefan ⛄ F. genial 
simpel. Kann man dies noch kombinieren mit einer Verstärkerschaltung?

von Stefan F. (Gast)


Lesenswert?

Fred G. schrieb:
> Da leuchtet quasi bei 5mA höchstens 2 Inkremente auf, das könnte zu
> Ich denke ganz ohne Verstärkung geht's nicht.

Hmm ja, das habe ich wohl zu knapp geschätzt.

Manche ADC haben einen per software konfigurierbaren Vorverstärker, das 
wäre jetzt praktisch gewesen.

Allerdings bin ich zuversichtlich, dass das Sache mit viel geringerer 
Verstärkung (z.B. 20x) prima arbeiten wird. Wenn du deine OP-Amp 
Schaltung entsprechend änderst, hast du den Vorteil, dass sie weniger 
rauscht. Die Transistoren und Zenerdioden würde ich weg lassen. 10kΩ 
Widerstände zwischen Ausgang des OP-Amp und Eingang des ADC werden als 
Schutz gegen Überspannung reichen.

Sage mal, vertragen deine OP-Amps eigentlich die maximal vorkommende 
negative Spannung, die deine Stromwandler liefern? Denke daran, dass 
Einschalt-Spitzen viel höher als 16A sein können.

von Stefan F. (Gast)


Lesenswert?

Du hattest zwischendurch um eine Empfehlung für einen "besseren" Op-Amp 
gebeten. Schau dir mal den TS912 an. Dessen Ein- und Ausgänge kommen 
näher an die Versorgungsspannung heran.

von Bauform B. (bauformb)


Angehängte Dateien:

Lesenswert?

Den TS912 sollte man mit den gleichen 3.3V wie den STM32 betreiben. 
Dadurch ist der ADC-Eingang ohne zusätzliche Bauteile gut geschützt. 
Allerdings brauchen die Eingänge des TS912 genauso viel Schutz wie der 
ADC-Eingang, vor allem deswegen:

Stefan ⛄ F. schrieb:
> Sage mal, vertragen deine OP-Amps eigentlich die maximal vorkommende
> negative Spannung, die deine Stromwandler liefern? Denke daran, dass
> Einschalt-Spitzen viel höher als 16A sein können.

Die positiven Spitzen werden natürlich auch zu hoch, von 
230V-Kurzschlüssen garnicht zu reden.

Fred G. schrieb:
> Deswegen habe ich, da ich auch nicht den exakten Wert des Stromes
> brauche, einen Transistor dazwischen gebaut, um nur ein AN/AUS/Sensor
> fehlt zu haben

Das ist natürlich viel einfacher als Messen, aber wegen der "Sensor 
fehlt" Erkennung geht ein AC-gekoppelter Verstärker nicht so einfach. 
Aber:

Fred G. schrieb:
> Ich taste damit den gemessenen Wert ab und weise den kleinsten
> gemessenen Wert und den größten gemessenen Wert jeweils zu. Die
> Inkr-Variable ist dann die Differenz.

damit wird die AC-Kopplung per Software gemacht und Offset-Fehler 
spielen keine Rolle. Die Verstärkung darf natürlich nicht unnötig hoch 
sein; muss sie aber auch nicht, weil:

Fred G. schrieb:
> Lt. Datenblatt und Rücksprache mit dem Hersteller reagieren die Sensoren
> erst ab 5mA, was okay für mich ist.

Wenn dabei diese Differenz größer als 42 wird, ist die Verstärkung 
gerade richtig. Ich hab mal versucht, das alles in einer Schaltung 
zusammen zu fassen. Die Verstärkung kann mit R2 angepasst werden, die 
anderen Widerstände sind liebevoll aufeinander abgestimmt ;)

R5 müsste streng genommen an den Stromwandler angepasst werden, 
theoretisch sollte die Summe aus R5 und Stromwandler-Innenwiderstand 5k 
sein. Aber 500 Ohm hin oder her verschieben nur den Offset. Und der 
liegt sowieso irgendwo und fällt in der Software raus.

Man könnte für R5 einen 5W-Drahtwiderstand nehmen, dann würde der 
Eingang auch 230V für ein paar Sekunden vertragen ;)

: Bearbeitet durch User
von Fred G. (kross_g_braten)


Lesenswert?

Stefan ⛄ F. schrieb:
> Fred G. schrieb:
>> Da leuchtet quasi bei 5mA höchstens 2 Inkremente auf, das könnte zu
>> Ich denke ganz ohne Verstärkung geht's nicht.
>
> Hmm ja, das habe ich wohl zu knapp geschätzt.
>
> Manche ADC haben einen per software konfigurierbaren Vorverstärker, das
> wäre jetzt praktisch gewesen.

Das wäre die Lösung. Falls das geht, könntet ihr mir erläutern wie? :)

> Allerdings bin ich zuversichtlich, dass das Sache mit viel geringerer
> Verstärkung (z.B. 20x) prima arbeiten wird. Wenn du deine OP-Amp
> Schaltung entsprechend änderst, hast du den Vorteil, dass sie weniger
> rauscht. Die Transistoren und Zenerdioden würde ich weg lassen. 10kΩ
> Widerstände zwischen Ausgang des OP-Amp und Eingang des ADC werden als
> Schutz gegen Überspannung reichen.

Das habe ich soeben ausprobiert.

Bei "kein Strom" habe ich die 0 Inkremente, max und min ebenfalls, 
super.

Bei "Strom" ist, wenn ich bspw. ein Relais als Verbraucher nehme, 
welches ca. 7mA zieht, ein max wert von 35-45 Inkremente, min = 0.

Bei "sensor fehlt" zieht er dies hoch auf volle 4096 - 1 Inkrement.
Wird der ADC Input somit nicht überlastet, wenn dieser dann auf ca. 4,8V 
steht? Er scheint nicht kaputt zu sein, sondern pendelt halt stets aus. 
Somit ist das auch super.

Ich habe dann die Verstärkung von ca. 20 auf 40 erhöht, was dann aber 
wieder zur Folge hat, dass auch bei "kein Strom" die restlichen mV einen 
Ausschlag geben. Wieder wegen der Verstärkung :( Evtl. hat sich das 
Problem mit einem Rail-to-Rail erledigt. Muss ich mal checken

> Sage mal, vertragen deine OP-Amps eigentlich die maximal vorkommende
> negative Spannung, die deine Stromwandler liefern? Denke daran, dass
> Einschalt-Spitzen viel höher als 16A sein können.

von Stefan F. (Gast)


Lesenswert?

Fred G. schrieb:
>> Manche ADC haben einen per software konfigurierbaren Vorverstärker, das
>> wäre jetzt praktisch gewesen.
>
> Das wäre die Lösung. Falls das geht, könntet ihr mir erläutern wie?

Kommt auf den konkreten Mikrocontroller an. Da schaust dann besser mal 
in dessen Reference manual. Es wird wohl ein Register geben, wo man mit 
ein paar Bits unterschiedliche Verstärkungsfaktoren wählen kann.

Fred G. schrieb:
> Wird der ADC Input somit nicht überlastet, wenn dieser dann auf ca. 4,8V
> steht?

Bei den mir bekannten STM32 Modellen vertragen die analogen Eingänge 
offiziell maximal ein kleines bisschen mehr als 3,3V. Ich würde das 
sicherheitshalber mit einem Widerstand und Zenerdiode auf 3,6V 
begrenzen.

Probiere 
Beitrag "Re: STM32L431RC - Probleme mit Stromsensorenauswertung" aus. 
Der Kollege hat sich offenbar eine Menge richtige Gedanken gemacht.

von Fred G. (kross_g_braten)


Lesenswert?

Vilen Dank für eure Beiträge. Ich glaube ich habe da nun eine Lösung 
gefunden, die ich gerne teilen möchte.

Muss nun aber dringend weg, werde euch morgen mal meine Lösung 
präsentieren und sehr gerne eure Meinung dazu hören.

Bis morgen!

von Fred G. (kross_g_braten)



Lesenswert?

So, ich hatte mir nochmals Gedanken über die Thematik gemacht, und eure 
Beiträge gaben mir viele Denkanstöße, und dann bin ich auf diese Lösung 
gekommen:

Die Schaltung von Stefan ⛄ F. hatte ich ja ausprobiert, und aufgrund der 
Auflösung etc. kamen bei ca. 7mA nur 2 Inkremente heraus. Das Ergebnis 
widerrum von den anderen Fällen zu unterscheiden schien mir unmöglich. 
Also hatte ich die Schaltung um einen OPV erweitert. Zusätzlich hatte 
ich noch eine Z-Diode reingebastelt, um die Spannung am OUT1 zu 
begrenzen, damit der ADC-Input nicht stirbt. Ebenfalls hatte ich die 
Verstärkung angepasst.

Aber auch hier hatte ich ein Rauschen. Mist.

Dennoch hatte ich nochmals mir den Signalverlauf verdeutlicht. Dazu die 
Graphen im Anhang:

Ideal-Kennlinie: So sollte das Signal von OUT1 des OPV aussehen, damit 
ich dieses am besten auswerten kann.

Da das im reallife nun nicht so ist, stellte das Problem dar.
Die zu erwartenden Werte zeige ich im Bild "Kennlinie mit Werten" auf.

Da fiel mir auf, dass mein Code der Auswertung des Messergebnisses 
eventuell zu kompliziert ist, und passte diesen an.
1
if(actual_inkr > threshold_inkr){
2
        return status_on;
3
      }
4
      else if ((actual_val_max <= threshold_min) && (actual_val_min <= threshold_min))
5
        {
6
            return status_off;
7
        }
8
      else if ((actual_val_max >= threshold_max) && (actual_val_min >= threshold_max))
9
          {
10
              return status_sensor_missing;
11
          }
12
      else{
13
      return status_internal_error;

Denn: Wenn der Inkrement-Wert, also die Differenz zwischen dem 
höchst-gemessenen Wert und dem niedrigst-gemessenen Wert, klein bzw. 0 
ist, dann kann kein Signal anliegen.

Hatte dann den Code mal durchlaufen lassen und dann bemerkt, dass 
aufgrund des LM358 immer das Rauschen als Nebeneffekt auftritt. Dieses 
Rauschen ist aber immer im gleichen Verhältnis, was mir bis dahin nicht 
klar war.

Im Bild "Kennlinie RL" habe ich mir das nochmal dargestellt.

Wenn nun die Schwellwerte so gewählt werden, dass dieser Sachverhalt 
quasi geskipped wird, ist die Auswertung stets eindeutig.

Ich änderte nun die Schwellwerte auf folgende Werte:
1
uint16_t threshold_max = 3000;
2
uint16_t threshold_inkr = 100;
3
uint16_t threshold_min = 500;

und verdeutliche dies mit dem Bild "Kennlinie mit threshold_werten".

Wenn nun der Stromwandler keinen Strom misst, sind wir im status_off 
Bereich. Es rauscht, ist aber egal, da die Differenz zwischen max und 
min zu gering ist und die jeweiligen Werte kleiner sind als der 
Schwellwert von max.

Wenn der Stromwandler ein Signal nun umwandelt, also ein Stromkreis 
geschlossen ist und "Strom fließt", sind wir im status_on Bereich. Das 
Signal springt quasi hin und her. Zur Auswertung ideal, da die Differenz 
von min und max (Inkr) nun auf jeden Fall den Schwellwert von Inkr 
übersteigt. Die genauen Werte von min und max spielen dann keine Rolle 
mehr, das Ding ist an!

So, und wenn nun der Sensor fehlt, sind wir im status_sensor_missing 
Bereich. Das funktioniert sehr gut durch den 100k Widerstand, wie lt. 
Stefan ⛄ F. empfohlen.
Der Inkr-Schwellwert wird erneut nicht gebrochen, dafür aber der 
max-Schwellwert.


Habe das nun an einem NUCLEO-Board getestet und lief sehr gut, ohne auch 
nur einen Fehler. Als nächstes teste ich das noch mit 4 Sensoren, und 
dann nochmals an der PCB, die ich nun mit dem Lötkolben bearbeiten muss. 
Bin da aber ziemlich motiviert, dass das klappt.

Was sagt ihr dazu?

Die aktuelle Schaltung ist ebenfalls im Anhang.

Vorab möchte ich mich bei Stefan ⛄ F., Bauform B.,STK500-Besitzer und 
peda bedanken, weil ihr mir geholfen habt mit euren Ideen und ich 
glaube, dass eure Hilfe mich auf den Weg einer Lösung des Problems 
gebracht hat.

Die weiteren Tests der Schaltung/des Codes werde ich dann wieder hier 
preisgeben.

von Stefan F. (Gast)


Lesenswert?

Fred G. schrieb:
> Was sagt ihr dazu?

Mache in Reihe zum 2,2kΩ Widerstand eine R/C Kombination:
1
---[2,2k]---+--[220k]---+----| GND
2
            |           |
3
            +----||-----+
4
                22µF

Dadurch reduzierst du den Verstärkungsfaktor für sehr niedrige 
Frequenzen und Gleichspannung. Gleichspannung, insbesondere den 
Eingangs-Offset des Op-Amps, willst du nicht 100x verstärken. Durch die 
Änderung bekommst du einen niedrigeren Ausgangspegel wenn kein Strom 
fließt, der erheblich weniger von Materialstreuungen und Temperatur 
abhängt.

Da du in der Schaltung recht hochohmige Widerstände hast, die manchmal 
unerwünscht auf Radiowellen reagieren, würde auch besonders hohe 
Frequenzen abblocken. Füge dazu parallel zu dem 220kΩ Widerstand einen 
1nF Kondensator ein.

Ich vermisse am + Eingang des OP-Amp einen Schutz gegen Überspannung (in 
beide Richtungen, positiv und negativ). Da würde ich wenigstens einen 
10kΩ Widerstand vor schalten, besser auch noch eine Zenerdiode. Bedenke, 
dass der Stromwandler beim Einschalten von Lasten und noch mehr bei 
Kurzschlüssen ganz erhebliche Überspannung liefert.

Viele Geräte haben einen Netzfilter, durch den ständig einige mA Strom 
fließt. Ich denke, es ist daher besser, viel weniger zu verstärken. Bei 
wenig Strom sollte aus deinem OP-Amp auch wenig Spannung heraus kommen, 
gerade so viel dass es noch eindeutig zu detektieren ist.

Deine Logik zur Auswertung in der Software scheint mir stimmig.

Teste nicht nur mit minimalem Strom (5mA ?) sondern auch mit maximalem. 
Und beide Fälle auch mit extremen Temperaturen (kalt und heiß).

von Fred G. (kross_g_braten)


Angehängte Dateien:

Lesenswert?

Schaltung siehe Anhang.


Wenn ich das nun richtig dem Text entnommen habe, müsste der Schaltplan 
nun so aussehen.

Habe das mal mit LT-Spice simuliert.
Da gibts Probleme, wenn ich auf eine Amplitude stelle von 0.01.

Mir kommt der R7 und der C1 schon sehr hoch vor. Sollte ich die nicht 
etwas anpassen?

von Stefan F. (Gast)


Lesenswert?

Fred G. schrieb:
> Wenn ich das nun richtig dem Text entnommen habe, müsste der Schaltplan
> nun so aussehen.

Ja.

> Mir kommt der R7 und der C1 schon sehr hoch vor.

Das habe so beabsichtigt. Bei 50 Hz hat der Kondensator 144 Ohm.

Gleichstrom fließt nur durch den Widerstand, so dass der OP-Amp 
Gleichspannungen um Faktor 2 Verstärkt. Wechselstrom fließt 
hauptsächlich durch den Kondensator (am Widerstand vorbei), so dass 
dafür die von dir vorgesehene Verstärkung von 101 gilt.

> Da gibts Probleme, wenn ich auf eine Amplitude stelle von 0.01.

Keine Ahnung welches Problem du hast und welche Amplitude du meinst.

von Fred G. (kross_g_braten)


Lesenswert?

Stefan ⛄ F. schrieb:

> Das habe so beabsichtigt. Bei 50 Hz hat der Kondensator 144 Ohm.
>
> Gleichstrom fließt nur durch den Widerstand, so dass der OP-Amp
> Gleichspannungen um Faktor 2 Verstärkt. Wechselstrom fließt
> hauptsächlich durch den Kondensator (am Widerstand vorbei), so dass
> dafür die von dir vorgesehene Verstärkung von 101 gilt.

Achja klar, danke. Auf sone Kombi wäre ich nicht gekommen :)

>> Da gibts Probleme, wenn ich auf eine Amplitude stelle von 0.01.
>
> Keine Ahnung welches Problem du hast und welche Amplitude du meinst.

Hat sich mittlerweile erledigt, hatte falsche settings.

Habe die Schaltung getestet, und funktioniert sehr gut. Ich werde nun 
mal 4 Stück zeitgleich testen, mit NUCLEO, Kanalwechsel, bei 
Temperaturänderungen etc.etc.

Melde mich nach Beendigung der Tests nochmal.

Und erneut vielen Dank für eure Zeit :)

von Fred G. (kross_g_braten)


Lesenswert?

Hallo Leute,

hier nochmal die Rückmeldung.

Nach erfolgreichen Tests, Versuchsaufbau mit Temperaturschwankungen, 
Versuchsläufe mit mehreren Sensoren und mehreren OPVs, nach 
PCB-Anfertigung sowie meinem Urlaub habe ich folgendes erreicht:

Alles läuft genau so wie es soll. Ich musste die Schwellwerte nochmals 
anpassen, aber sonst ist alles OK!

Vielen Dank euch nochmals fürs Mitdenken, diskutieren und weiterhelfen. 
Wart mir ne echte Hilfe.
Danke für eure aufgebrachte Zeit

Bis zum nächsten Problem :)

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.