Forum: Mikrocontroller und Digitale Elektronik uC Input Problem - GPIO


von Stefan (Gast)


Lesenswert?

Hallo,

ich habe da ein Problem und würde mich freuen, wenn Ihr mir Tipps zur 
Fehlersuche geben könnt.

Ich nutze einen ADUC702x Eval Board. Mein Ziel ist es, den Tastgrad 
eines PWM Signals, welches an einem GPIO Pin (P2.0) anliegt, zu 
bestimmen.

Dazu habe ich einen Code geschrieben, welcher per Timer Interrupt, den 
aktuellen Zustand am Pin abfragt/abtastet (High oder Low) und dann am 
Periodenende immer den Tastgrad rausspuckt.

Die Periode des Eingangssignals (PWM) ist etwa 75ms lang und der 
Interrupt wird alle 750us aufgerufen, also es wird etwa 100 mal pro 
Periode abgetastet, bis die Periode dann zu Ende ist und der Zähler für 
High und Low auf Null initialisiert.

Das Problem ist nun folgend:

Wenn ich das PWM Signal, welches eine Schaltung erzeugt, an den Pin 
schicke, tastet der uC nur High Signale. Ab und an kommt ein Low Signal 
durch (1 bis 2), das war es auch.
Dasselbe Ergebnis erziele ich auch, wenn ich das Signal "nicht" an den 
Pin schicke und das Programm einfach so durchlaufen lasse (ohne Signale 
am Pin). Also bekommt es gar kein Signal, obwohl ich es mit dem Oszi 
messen kann. Es hat einen Tastgrad von 0,5

Wenn ich jedoch ein PWM Signal, welches von dem Oszi generiert wird (der 
Oszi kann auch selbst Signale erzeugen und an einem Kanal rausschicken) 
an den Pin des uC schicke, erkennt dieser den Tastgrad einwandfrei.

Das PWM Signal, welches ich mit dem Oszi erzeuge, stelle ich so ein, 
dass es dieselbe Amplitude und dieselbe Frequenz hat, wie das PWM Signal 
aus meiner Schaltung.

Was könnte der Grund dafür sein, dass es das eine PWM Signal richtig 
analysiert, dass andere jedoch nicht, obwohl es fast identische Signale 
sind?

Danke

von Timmo H. (masterfx)


Lesenswert?

Das Problem ist, dass du keinen code postest

von Wolfgang (Gast)


Lesenswert?

Timmo H. schrieb:
> ... dass du keinen code postest

... und auch keinen Schaltplan, aus dem hervorgeht, wie die Quelle aus 
sieht, die dein PWM-Signal ausgibt (Push-Pull, Open-Kollektor, 
"NPN","PNP") und wie du es mit ggf. mit Pull-Up oder -Down hälst.

von Stefan (Gast)


Lesenswert?

Ok, mein Fehler.

Ich werde morgen alle nötigen Infos Hinzufügen. Habe alles auf einem 
anderen Rechner/Ort.

Danke für den Hinweis ;D. Ne Antwort ist besser als keine.

Bis morgen.

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Also.

Den Quellcode habe ich unten hinzugefügt.

Was tut es:
Es tastet im Timer Interrupt ein PWM Signal ab (Periode von 75ms), bis 
es einen Periodenbeginn feststellt.
Der Periodenbeginn wird festgestellt, indem auf eine Zustandsänderung 
gewartet wird (Von High auf Low oder von Low auf High).
Wenn dies der Fall ist inkrementiert es den entsprechenden Zähler (high 
oder low).
Wenn sich der Zustand ändert, inkrementiert es entsprechend den anderen 
Zähler.
Dies geht solange, bis sich der Zustand erneut ändert, sprich bis eine 
Periode komplett abgestatet wurde.
Aus den Daten des High- und Lowzählers wird dann der Tastgrad errechnet.
Die Zähler werden zurück gesetzt und der Tastgrad der neuen Periode wird 
ermittelt.
1
if(start == inactive && periode == periode_aus){
2
  if((GP2DAT & 0x01) == HIGH){
3
    zustand = HIGH;
4
  }
5
  
6
  else if((GP2DAT & 0x01) == LOW){
7
    zustand = LOW;
8
  }
9
    start = active;    
10
}
11
12
else if(start == active && periode == periode_aus){
13
  if(zustand == HIGH){
14
    if((GP2DAT & 0x01) == LOW){
15
      periode = periode_beginn;
16
      low_zaehler = 1 + low_zaehler;
17
      zustand = LOW;
18
    }    
19
  }
20
  
21
  else if(zustand == LOW){  
22
    if((GP2DAT & 0x01) == HIGH){
23
      periode = periode_beginn;
24
      high_zaehler = 1 + high_zaehler;
25
      zustand = HIGH;
26
    }
27
  }
28
}
29
30
else if(start == active && periode == periode_beginn){
31
  if((GP2DAT & 0x01) == zustand){
32
    if(zustand == HIGH){
33
      high_zaehler = 1+ high_zaehler;
34
    }  
35
    else if(zustand == LOW){
36
      low_zaehler = 1 + low_zaehler;
37
    }
38
  }
39
  
40
  else if((GP2DAT & 0x01) != zustand){
41
    if(zustand == HIGH){
42
      low_zaehler = 1 + low_zaehler;
43
      periode = periode_mitte;
44
      zustand = LOW;
45
    }  
46
    else if(zustand == LOW){
47
      high_zaehler = 1 + high_zaehler;
48
      periode = periode_mitte;
49
      zustand = HIGH;
50
    }    
51
  }
52
}
53
54
else if(start == active && periode == periode_mitte){
55
  if((GP2DAT & 0x01) == zustand){
56
    if(zustand == HIGH){
57
      high_zaehler = 1+ high_zaehler;
58
    }
59
    else if(zustand == LOW){
60
      low_zaehler = 1 + low_zaehler;
61
    }
62
  }
63
  
64
  else if((GP2DAT & 0x01) != zustand){
65
    tastgrad = (float)(high_zaehler)/(float)(low_zaehler+high_zaehler);
66
    low_zaehler = 0;
67
    high_zaehler = 0;
68
  }
69
}
Hier ist ein Teil des "init"-Abschnitts mit den relevanten Daten:
1
void init_aduc(void){ //Initialisierung der Taktgeschwindigkeit
2
POWKEY1 = 0x01;
3
POWCON  = 0x0; 
4
POWKEY2 = 0xF4;
5
} //ende init_aduc
6
7
void init_port(void){  //Initialisierung der Ports
8
9
GP2CON = 0x00000000;    //GPI0
10
GP2DAT = 0x00000000;     //Port 2 komplett Eingänge
11
      
12
} //ende init_port

Das PWM Signal, welches an den Portpin P2.0 geht und abgetastet wird, 
kommt aus einem ACPL-021L-500E.
Die Beschaltung des Optokopplers habe ich als Bild hinzugefügt.

Danke

: Bearbeitet durch User
von Ralf (Gast)


Lesenswert?

Hi Stefan,

du hast nicht den Quellcode zur Verfügung gestellt, sondern Auschnitte 
davon reinkopiert - hilft nicht, weil man nicht das komplette Bild hat 
(wenn der Fehler in der Software liegen sollte, dann riskierst du 
Verzögerung bei der Hilfestellung, wenn der Fehler in dem Teil liegt, 
den du nicht gepostet hast). Pack den kompletten Code in ein ZIP und 
häng es hier an.

Das gleiche gilt für die komplette elektrische Schaltung. Mir ist noch 
nicht ganz klar, ob du das mit dem Oszi erzeugte PWM-Signal auch über 
den Optokoppler schickst - dass es direkt am Pin gehen mag, glaub ich 
dir, speziell dann wenn das Oszi eine Push-Pull-Stufe hat. Die hat dein 
Optokoppler zwar wohl auch, die Frage ist, ob der Optokoppler das 
Eingangssignal richtig verarbeitet (GND, etc. wird ja alles korrekt mit 
dem Controller verbunden sein, nehme ich mal an).

Wenn das oben gezeigte Codefitzelchen ein Ausschnitt aus dem Interrupt 
ist, dann sollte m.E. mindestens das Float-Geraffel rausfliegen, weil 
das Zeit braucht. Abgesehen davon ist float i.d.R. unnötig, das Ziel 
kann man auch mit Integer erreichen und dann ist es schneller.

Ralf

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:

> Der Periodenbeginn wird festgestellt, indem auf eine Zustandsänderung
> gewartet wird (Von High auf Low oder von Low auf High).
> Wenn dies der Fall ist inkrementiert es den entsprechenden Zähler (high
> oder low).
> Wenn sich der Zustand ändert, inkrementiert es entsprechend den anderen
> Zähler.
> Dies geht solange, bis sich der Zustand erneut ändert, sprich bis eine
> Periode komplett abgestatet wurde.

Hä?
Du machst das aber reichlich kompliziert.

Wenn der Timer sowieso regelmässig kommt, dann nimm doch einfach den 
Input Pegel her. Ist er High dann inkrementierst du den einen Zähler, 
ist er low dann inkrementierst du den anderen Zähler.

Stellst du beim Vergleich mit dem Input Zustand vom VORHERGEHENDEN 
Interrupt Aufruf fest, dass es eine steigende Flanke gab, dann 
errechnest du den Tastgrad aus dem Verhältnis der Zähler und setzt sie 
wieder auf 0.
Dein jetziges Schema zu diesem Thema ist untauglich, weil du davon 
abhhängig bist, dass der Flankenwechsel genau innerhalb der Interrupt 
Routine passiert, was höchst wahrscheinlich so gut wie nie der Fall sein 
wird.
(Edit: und ich gestehe auch, dass ich das alles nicht bis ins letzte 
durchanalysiert habe, weil du das deutlich zu kompliziert angegangen 
bist)
1
...
2
3
volatile uint8_t duty;
4
5
interrupt Service Routine
6
{
7
  static uint8_t prevInput;
8
  static uint16_t highCnt = 0;
9
  static uint16_t lowCnt = 0;
10
  uint8_t nowInput;
11
12
  nowInput = GP2DAT & 0x01;
13
14
  if( nowInput != prevInput && nowInput ) {    // steigende Flanke?
15
    duty = highCnt * 100 / ( highCnt + lowCnt );
16
    highCnt = 0;
17
    lowCnt = 0;
18
  }
19
20
  if( nowInput )
21
    highCnt++;
22
  else
23
    lowCnt++;
24
25
  prevInput = nowInput;
26
}

fertig. Du hast dich da selbst ausgetrickst.


Und noch ein Rat.
Gewöhn dir solche Sachen (gemeint ist der explizite Vergleich mit HIGH)
1
  if((GP2DAT & 0x01) == HIGH){
schleunigst ab. Du schiesst dir damit auf lange Sicht nur ins Knie.
Bei dir funktioniert das jetzt, weil du zufälligerweise mittels 0x01 das 
Bit 0 ausmaskierst. Aber bei jedem anderen Bit funktioniert das nicht 
mehr. Denn beispielsweise GP2DAT & 0x02 ergibt dann eben nicht mehr 1, 
sondern 2, wenn das Bit auf 1 ist
Aus gutem Grund gilt in C die Regel, dass ein Zahlenwert von 0 als 
logisch FALSE gewertet wird und jeder andere von 0 verschiedene als 
logisch TRUE. D.h. du musst gar nicht wissen, welches der Zahlenwert von 
beispielsweise GP2DAT & 0x08 bei einem 1 Bit an der betreffenden Stelle 
tatsächlich ergibt. Denn wenn das entsprechende Bit 4 auf 0 ist, dann 
kommt da 0 heraus und wenn das Bit auf 1 ist dann kommt etwas ungleich 0 
heraus. Und das reicht dann schon.

Solche explizit geforderten Vergleiche wie du sie machst, sind 
Zeitbomben!
1
  if( GP2DAT & 0x01 ) {

entweder der angegebene Ausdruck ergibt etwas ungleich 0 (dann war das 
Bit auf 1), dann wird das if genommen, oder der Ausdruck ergibt 0 (dann 
war das Bit auf 0) und der else kommt zum Zug. Keinen Menschen muss 
dabei interessieren, welcher Zahlenwert sich durch die Und-Verknüfung 
tatsächlich ergibt. Insbesondere muss der nicht dem Wert von HIGH 
(welcher auch immer das ist) entsprechen. Denn bei einem Byte passt der 
Wert von HIGH dann nur in einem von 8 möglichen Fällen. (1 Byte besteht 
aus 8 Bits. Es gibt also 8 von 0 verschiedene Werte, bei denen genau 1 
Bit gesetzt ist)

Und aus ebenso gutem Grund, verlangt ein if keinen Vergleich! Ein if 
will einen Ausdruck sehen!. Der wird ausgewertet und wenn dieses 
Ergebnis ungleich 0 ist, dann wird der then-Zweig ausgeführt, 
andernfalls der else Zweig. Jaaaa, in C sind Vergleiche auch nichts 
anderes als Operationen, die ein Ergebnis liefern. 1 (also etwas 
ungleich 0) wenn der Vergleich zutrifft und 0 wenn er nicht zutrifft. 
Das interessiert aber das if nur insofern, als es ein Ergebnis sehen 
will. Ob das Ergebnis mittels Vergleich zustande kam oder ob da etwas 
ausgerechnet wird, das ist dem if sch...egal.

Aus Sicht des if gibt es keinen Unterschied zwischen
1
   if( 2 + 3 )
und
1
   if( 4 < 3 )
in den Klammern steht lediglich ein arithmetischer Ausdruck, der 
ausgewertet wird und dessen Ergebnis entsprechend '0 oder nicht 0' 
bewertet wird. Der '<' ist in keinster Weise für das if spezieller als 
das '+'.

An dieser Stelle gilt aber: weniger ist mehr!


> Das PWM Signal, welches an den Portpin P2.0 geht und abgetastet wird,
> kommt aus einem ACPL-021L-500E.
> Die Beschaltung des Optokopplers habe ich als Bild hinzugefügt.

Du hast aber schon eine Masseverbindung?

: Bearbeitet durch User
von uwe (Gast)


Lesenswert?

Normalerweise haben µCs einen Input Capture an ihren Timer/countern 
eingebaut, der sollte dir alles leichter machen.

von uwe (Gast)


Lesenswert?

Hat er nicht, aber ist ein PLA drin, damit kannste dir das selber bauen.
Ab Seite 60 ist sogar beschrieben wie man die einzelnen 
Konfigurationsbits des PLAs beschreiben muß damit die gewünschte 
funktion rauskommt.
http://www.keil.com/dd/docs/datashts/adi/aduc702x_ds.pdf

von Stefan (Gast)


Lesenswert?

Ralf schrieb:

> du hast nicht den Quellcode zur Verfügung gestellt, sondern Auschnitte
> davon reinkopiert - hilft nicht, weil man nicht das komplette Bild hat
> (wenn der Fehler in der Software liegen sollte, dann riskierst du
> Verzögerung bei der Hilfestellung, wenn der Fehler in dem Teil liegt,
> den du nicht gepostet hast). Pack den kompletten Code in ein ZIP und
> häng es hier an.
>

Den gesamten Quellcode kann ich morgen gerne zur Verfügung stellen

> Das gleiche gilt für die komplette elektrische Schaltung. Mir ist noch
> nicht ganz klar, ob du das mit dem Oszi erzeugte PWM-Signal auch über
> den Optokoppler schickst - dass es direkt am Pin gehen mag, glaub ich
> dir, speziell dann wenn das Oszi eine Push-Pull-Stufe hat. Die hat dein
> Optokoppler zwar wohl auch, die Frage ist, ob der Optokoppler das
> Eingangssignal richtig verarbeitet (GND, etc. wird ja alles korrekt mit
> dem Controller verbunden sein, nehme ich mal an).
>

Ich kann/darf die Eagle Datei der Schaltung nicht hochladen. Ist von dem 
Projekt und wir haben keine Urheberrechte. Deswegen hat hier einer schon 
Ärger gehabt.
Deshalb habe ich die Optokopplerbeschaltung auch selbst ge"paintet".

Das vom Oszi erzeugte PWM Signal schicke ich "direkt" an den Input Pin 
des uC. Das Signal stelle ich von der Frequenz und Amplitude her genauso 
ein (133,3 Hz - 7,5ms - ca. 3,3V), wie das Signal, welches die Schaltung 
über den Optokoppler an den uC Pin schickt.
Lediglich den Tastgrad variiere ich, um testen zu können, ob das Progamm 
den Tastgrad richtig erkennt.


Es kommen 2 Kabel vom Output Channel des Oszis. Eins geht an den 
Massestecker des Oszis, das andere geht direkt an den Input des uC.
Dies funktioniert auch wie bereits erwähnt ohne Probleme.

---

Vor dem Optokoppler ist eine Schaltung, die aus einer Spannung ein PWM 
Signal erzeugt.
Der Tastgrad des PWM Signals gibt die Höhe dieser Spannung an. (bis 
maximal 15V)

Das ganze besteht aus einem Dreiecksgenerator (Smitt Trigger - 
Integrator) und einem dahinter liegenden Komparator.
Das vom Komparator erzeugte PWM Signal hat eine Amplitude von 15V.
Diese liegt dann über den Vorwiderstand der Anode und der Diode des 
Optokopplers an (1,5V).

Der bereits angegebene Optokoppler gibt das ganze galvanisch getrennt an 
den Input des uC.

Die rechte Seite des Optokopplers ist wie folgt beschaltet:

- Die 3,3V VCC werden auf dem darauf liegenden Polygon mittels eines 
Regler IC´s erzeugt. Auf dem Polygon werden nur Hilfsspannungen erzeugt.

- Out liegt, mittels Steckverbinder, an P2.0 des uC Boards an. (PWM 
Signal mit 3,3V Amplitude).

- GND liegt am Minuspol des Konstanters an, welches das Polygon für die 
Hilfsspannungen versorgt.

Das uC Eval Board hat eine eigene Versorgung über ein Netzteil.

Ich Frage mich nun, was du damit meinst: "GND, etc. wird ja alles 
korrekt mit dem Controller verbunden sein, nehme ich mal an."

Habe ich diesbezüglich einen Fehler gemacht, wenn man meine Beschreibung 
liest?

> Wenn das oben gezeigte Codefitzelchen ein Ausschnitt aus dem Interrupt
> ist, dann sollte m.E. mindestens das Float-Geraffel rausfliegen, weil
> das Zeit braucht. Abgesehen davon ist float i.d.R. unnötig, das Ziel
> kann man auch mit Integer erreichen und dann ist es schneller.
>

Ja, es ist der Ausschnitt aus dem Interrupt. Diesbezüglich werde ich 
mich erkundigen und versuchen es umzusetzen. Ich hatte bereits gelesen, 
dass man im Interrupt "nicht soviel" Zeit verschwenden soll.

Danke

von Stefan (Gast)


Lesenswert?

Karl H. schrieb:
> Stefan schrieb:
>
> Hä?
> Du machst das aber reichlich kompliziert.
>
> Wenn der Timer sowieso regelmässig kommt, dann nimm doch einfach den
> Input Pegel her. Ist er High dann inkrementierst du den einen Zähler,
> ist er low dann inkrementierst du den anderen Zähler.
>
> Stellst du beim Vergleich mit dem Input Zustand vom VORHERGEHENDEN
> Interrupt Aufruf fest, dass es eine steigende Flanke gab, dann
> errechnest du den Tastgrad aus dem Verhältnis der Zähler und setzt sie
> wieder auf 0.
> Dein jetziges Schema zu diesem Thema ist untauglich, weil du davon
> abhhängig bist, dass der Flankenwechsel genau innerhalb der Interrupt
> Routine passiert, was höchst wahrscheinlich so gut wie nie der Fall sein
> wird.

Danke für den Tipp und den Code. Man sieht sicherlich, dass ich nicht so 
oft programmiere ;D. Dein Code hat mich aber überzeugt, dass dies viel 
einfacher geht.

> Und noch ein Rat.
> Gewöhn dir solche Sachen (gemeint ist der explizite Vergleich mit HIGH)
> if((GP2DAT & 0x01) == HIGH){
> schleunigst ab. Du schiesst dir damit auf lange Sicht nur ins Knie.
> Bei dir funktioniert das jetzt, weil du zufälligerweise mittels 0x01 das
> Bit 0 ausmaskierst. Aber bei jedem anderen Bit funktioniert das nicht
> mehr. Denn beispielsweise GP2DAT & 0x02 ergibt dann eben nicht mehr 1,
> sondern 2, wenn das Bit auf 1 ist
> Aus gutem Grund gilt in C die Regel, dass ein Zahlenwert von 0 als
> logisch FALSE gewertet wird und jeder andere von 0 verschiedene als
> logisch TRUE. D.h. du musst gar nicht wissen, welches der Zahlenwert von
> beispielsweise GP2DAT & 0x08 bei einem 1 Bit an der betreffenden Stelle
> tatsächlich ergibt. Denn wenn das entsprechende Bit 4 auf 0 ist, dann
> kommt da 0 heraus und wenn das Bit auf 1 ist dann kommt etwas ungleich 0
> heraus. Und das reicht dann schon.
>
> Solche explizit geforderten Vergleiche wie du sie machst, sind
> Zeitbomben!  if( GP2DAT & 0x01 ) {
>
> entweder der angegebene Ausdruck ergibt etwas ungleich 0 (dann war das
> Bit auf 1), dann wird das if genommen, oder der Ausdruck ergibt 0 (dann
> war das Bit auf 0) und der else kommt zum Zug. Keinen Menschen muss
> dabei interessieren, welcher Zahlenwert sich durch die Und-Verknüfung
> tatsächlich ergibt. Insbesondere muss der nicht dem Wert von HIGH
> (welcher auch immer das ist) entsprechen. Denn bei einem Byte passt der
> Wert von HIGH dann nur in einem von 8 möglichen Fällen. (1 Byte besteht
> aus 8 Bits. Es gibt also 8 von 0 verschiedene Werte, bei denen genau 1
> Bit gesetzt ist)
>
> Und aus ebenso gutem Grund, verlangt ein if keinen Vergleich! Ein if
> will einen Ausdruck sehen!. Der wird ausgewertet und wenn dieses
> Ergebnis ungleich 0 ist, dann wird der then-Zweig ausgeführt,
> andernfalls der else Zweig. Jaaaa, in C sind Vergleiche auch nichts
> anderes als Operationen, die ein Ergebnis liefern. 1 (also etwas
> ungleich 0) wenn der Vergleich zutrifft und 0 wenn er nicht zutrifft.
> Das interessiert aber das if nur insofern, als es ein Ergebnis sehen
> will. Ob das Ergebnis mittels Vergleich zustande kam oder ob da etwas
> ausgerechnet wird, das ist dem if sch...egal.

Ich werde das in dem aktuellen Quellcode und in meinen folgenden 
Projekten einpflegen. Ich habe das leider so gelernt. Nun muss ich es 
mir abgewöhnen

>> Das PWM Signal, welches an den Portpin P2.0 geht und abgetastet wird,
>> kommt aus einem ACPL-021L-500E.
>> Die Beschaltung des Optokopplers habe ich als Bild hinzugefügt.
>
> Du hast aber schon eine Masseverbindung?

Also die Masseverbindung des Optokopplers liegt an dem Minuspol des 
Konstanters, welcher den Optokoppler versorgt.

Das uC Board hat eine eigene Versorgung über ein 9V Netzteil.

Danke

von Stefan (Gast)


Lesenswert?

uwe schrieb:
> Hat er nicht, aber ist ein PLA drin, damit kannste dir das selber
> bauen.
> Ab Seite 60 ist sogar beschrieben wie man die einzelnen
> Konfigurationsbits des PLAs beschreiben muß damit die gewünschte
> funktion rauskommt.
> http://www.keil.com/dd/docs/datashts/adi/aduc702x_ds.pdf

Weiß zwar nicht was das sein soll. Werde es mir aber bei Zeit mal 
ansehen.

Danke dir.

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:

> Also die Masseverbindung des Optokopplers liegt an dem Minuspol des
> Konstanters, welcher den Optokoppler versorgt.
>
> Das uC Board hat eine eigene Versorgung über ein 9V Netzteil.

Die Masse vom Optokoppler Ausgang muss an die Masse von der 
µC-Versorung.

Sonst hängt der Eingang ohne Referenz in der Luft. Kein Wunder wenn du 
dann keine Pulse kriegst.

von Stefan (Gast)


Lesenswert?

Karl H. schrieb:
> Stefan schrieb:
>
>> Also die Masseverbindung des Optokopplers liegt an dem Minuspol des
>> Konstanters, welcher den Optokoppler versorgt.
>>
>> Das uC Board hat eine eigene Versorgung über ein 9V Netzteil.
>
> Die Masse vom Optokoppler Ausgang muss an die Masse von der
> µC-Versorung.
>
> Sonst hängt der Eingang ohne Referenz in der Luft. Kein Wunder wenn du
> dann keine Pulse kriegst.

Also könnte das die Ursache gewesen sein? Das werde ich morgen sofort 
testen. Müsste eine Verbindung vom GND Pin des Optokopplers an den GND 
Pin des uC ziehen. Die Verbindung an den Minuspol des Konstanters müsste 
ich demnach ablöten.

-

Ich habe da nochwas, was ich vergessen habe zu erwähnen. Am Pin 2.0, 
welche ich über die entsprechenden Register als Input konfiguriert habe, 
hat bei Messungen 2V gegen Masse, ohne das dort was angeschlossen ist.

Hat dies damit zutun, dass an dem Pin PullUp aktiviert ist?

Und was hat es mit dem hier bereits erwähnten Push-Pull auf sich?

Danke

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:

> Also könnte das die Ursache gewesen sein? Das werde ich morgen sofort
> testen. Müsste eine Verbindung vom GND Pin des Optokopplers an den GND
> Pin des uC ziehen. Die Verbindung an den Minuspol des Konstanters müsste
> ich demnach ablöten.

Ja. Die Signalquelle kommt ausschliesslich an die von die mit Annode und 
Kathode bezeichneten Pins.

> Ich habe da nochwas, was ich vergessen habe zu erwähnen. Am Pin 2.0,
> welche ich über die entsprechenden Register als Input konfiguriert habe,
> hat bei Messungen 2V gegen Masse, ohne das dort was angeschlossen ist.
>
> Hat dies damit zutun, dass an dem Pin PullUp aktiviert ist?

Kann sein. Aber wenn ein Pullup aktiviert ist und sonst nichts drann 
hängt, solltest du am Eingang eigentlich einen Wert von ziemlich genau 
der Versorungsspannung messen können.

> Und was hat es mit dem hier bereits erwähnten Push-Pull auf sich?

Push Pull ist ein Ausgangstreiber. Der kann einen Pin aktiv auf 1 (also 
Versorgungsspannung) als auch auf 0 (also GND) ziehen. Im Prinzip sind 
das 2 Schalter, einer nach Vcc und einer nach GND, von denen immer einer 
geschlossen ist.

von Stefan (Gast)


Lesenswert?

Karl H. schrieb:
> Stefan schrieb:
>
>> Also könnte das die Ursache gewesen sein? Das werde ich morgen sofort
>> testen. Müsste eine Verbindung vom GND Pin des Optokopplers an den GND
>> Pin des uC ziehen. Die Verbindung an den Minuspol des Konstanters müsste
>> ich demnach ablöten.
>
> Ja. Die Signalquelle kommt ausschliesslich an die von die mit Annode und
> Kathode bezeichneten Pins.
>
>> Ich habe da nochwas, was ich vergessen habe zu erwähnen. Am Pin 2.0,
>> welche ich über die entsprechenden Register als Input konfiguriert habe,
>> hat bei Messungen 2V gegen Masse, ohne das dort was angeschlossen ist.
>>
>> Hat dies damit zutun, dass an dem Pin PullUp aktiviert ist?
>
> Kann sein. Aber wenn ein Pullup aktiviert ist und sonst nichts drann
> hängt, solltest du am Eingang eigentlich einen Wert von ziemlich genau
> der Versorungsspannung messen können.
>
>> Und was hat es mit dem hier bereits erwähnten Push-Pull auf sich?
>
> Push Pull ist ein Ausgangstreiber. Der kann einen Pin aktiv auf 1 (also
> Versorgungsspannung) als auch auf 0 (also GND) ziehen. Im Prinzip sind
> das 2 Schalter, einer nach Vcc und einer nach GND, von denen immer einer
> geschlossen ist.

Ich danke dir sehr.
Werde morgen meine Korrekturen machen und hoffen, dass es hinhaut und 
ich mit dem Code weiter machen kann.

Der Tastgrad ist im Grunde gesehen nur meine Regelgröße (Istwert) für 
die Spannungsregelung. Die Regelgröße für die Stromregelung bekomme ich 
von einem Lem Wandler.

Vielleicht stoße ich da nochmal auf Hindernisse ;D.

Danke

von Stefan (Gast)


Lesenswert?

Karl H. schrieb:
> Stefan schrieb:
>
> Die Masse vom Optokoppler Ausgang muss an die Masse von der
> µC-Versorung.
>
> Sonst hängt der Eingang ohne Referenz in der Luft. Kein Wunder wenn du
> dann keine Pulse kriegst.

Wie sieht es denn mit Signalen aus, die ich vom uC Board an eine andere 
Schaltung schicken möchte? (z.B. vom uC erzeugte PWM Signale an einen 
Schalter.

Muss ich mir da auch Gedanken bezülich der Masse machen?

von Karl H. (kbuchegg)


Lesenswert?

Stefan schrieb:
> Karl H. schrieb:
>> Stefan schrieb:
>>
>> Die Masse vom Optokoppler Ausgang muss an die Masse von der
>> µC-Versorung.
>>
>> Sonst hängt der Eingang ohne Referenz in der Luft. Kein Wunder wenn du
>> dann keine Pulse kriegst.
>
> Wie sieht es denn mit Signalen aus, die ich vom uC Board an eine andere
> Schaltung schicken möchte? (z.B. vom uC erzeugte PWM Signale an einen
> Schalter.
>
> Muss ich mir da auch Gedanken bezülich der Masse machen?

Du musst IMMER einen Massebezug herstellen!

Es gibt keine absoluten Spannungen. Spannungen sind 
Potentialdifferenzen! ALso der Potentialunterschied zwischen 2 
Anschlüssen oder Leitungen oder.

Nur: verschiedene Schaltungen haben erst mal nichts miteinander zu tun.
Nimmst du 2 Batterien her
1
       Batterie A                   Batterie B
2
3
          +--+                       +--+
4
     +----+  +----+             +----+  +----+
5
     |            |             |            |
6
     |            |             |            |
7
     |            |             |            |
8
     |   1.5V     |             |   2.0V     |
9
     |            |             |            |
10
     |            |             |            |
11
     |            |             |            |
12
     |            |             |            |
13
     +------------+             +------------+

dann hat der Pluspol der Batterie B keine irgendwie definierte 
Spannunglage zu irgendeinem der Pole A. Du kannst die beiden so 
verschalten
1
       Batterie A                   Batterie B
2
3
                           +----------+
4
                           |          |
5
  X       +--+             |         +--+
6
     +----+  +----+        |    +----+  +----+
7
     |            |        |    |            |
8
     |            |        |    |            |
9
     |            |        |    |            |
10
     |   1.5V     |        |    |   2.0V     |
11
     |            |        |    |            |
12
     |            |        |    |            |
13
     |            |        |    |            |
14
     |            |        |    |            |
15
     +------------+        |    +------------+
16
           |               |
17
           +---------------+                Y

dann hat der Pluspol von B dasselbe Potential wie der - Pol von A und du 
misst von X nach Y eine Spannung von 3.5V

Du kannst sie auch so verschalten
1
       Batterie A                   Batterie B
2
3
   X      +--+                       +--+      W
4
     +----+  +----+             +----+  +----+
5
     |            |             |            |
6
     |            |             |            |
7
     |            |             |            |
8
     |   1.5V     |             |   2.0V     |
9
     |            |             |            |
10
     |            |             |            |
11
     |            |             |            |
12
     |            |             |            |
13
     +------------+             +------------+ 
14
            |                          |       Y
15
            +--------------------------+

dann haben die - Pole von A und B dasselbe Potential. Von X nach Y misst 
du dann 1.5V, von W nach Y 2.0V und von W nach X 0.5V

du kannst sie auch so verschalten
1
       Batterie A                   Batterie B
2
3
            +-------------------------+
4
            |                         |
5
   X      +--+                       +--+      W
6
     +----+  +----+             +----+  +----+
7
     |            |             |            |
8
     |            |             |            |
9
     |            |             |            |
10
     |   1.5V     |             |   2.0V     |
11
     |            |             |            |
12
     |            |             |            |
13
     |            |             |            |
14
     |            |             |            |
15
     +------------+             +------------+
16
   V                                            Y

Dann haben X und W dasselbe Potential. Von X nach Y misst du 2.0V, von W 
nach V misst du 1.5V, von Y nach V 0.5V


Aber solange du die beiden Batterien nicht miteinander verbindest,
1
       Batterie A                   Batterie B
2
3
          +--+                       +--+
4
     +----+  +----+             +----+  +----+
5
     |            |             |            |
6
     |            |             |            |
7
     |            |             |            |
8
     |   1.5V     |             |   2.0V     |
9
     |            |             |            |
10
     |            |             |            |
11
     |            |             |            |
12
     |            |             |            |
13
     +------------+             +------------+
ist die Frage nach irgendeiner Spannung von B in Bezug auf A eine Frage, 
die du nicht stellen kannst. Denn es gibt keinen gemeinsamen Bezug, auf 
den sich irgendeine Spannungslage bezieht. Die Spannung einer Batterie 
ist die Potentialdifferenz zwischen ihren beiden Polen. Die kannst du zb 
0 und 1.5 nennen, die kannst du aber auch 1000 und 1001.5 nennen. Egal 
wie, wichtig ist die Differenz! Und diese Differenzen kannst du nur dann 
miteinander in Beziehung setzen, wenn es eine gemeinsame Referenz gibt.

Ist die Spitze eines 2 Meter hohen Holzstabes weiter oben als die Spitze 
eines 3 Meter hohen Holzstabes? Kann man nicht sagen. Steht der 2 Meter 
hohe auf dem Balkon im 2.ten Stocj und der 3 Meter hohe im Keller, dann 
wahrscheinlich nicht. Die Ausgangsfrage ist unbeantwortbar. Erst durch 
die Zusaninformation, mit der ich die jeweils unteren Enden über ein 
Gebäude miteinander in Beziehung gebracht habe, wird sie zu einer 
sinnvollen Frage.


Bleibt noch anzumerken, dass es natürlich auch Verbindunge gibt, die 
keine Masseverbindung benötigen. Das ist zb ein Optokoppler oder ein 
Trafo. Aber: in beiden Fällen sind es ja nicht Spannungen, die da die 
Verbindung überbrücken. In dem einen Fall ist es Licht und im anderen 
Fall ist es ein Magnetfeld.
Aber wenn du zwischen verschiedenen Schaltungen eine elektrische 
Verbindung machen willst, so dass eine gewisse Spannungslage der einen 
Schaltung eine Bedeutung in der anderen Schaltung hat, dann musst du 
einen gemeinsamen Bezug herstellen. Üblicherweise nennt man den 'Masse', 
auch wenn das nicht so sein müsste.

: Bearbeitet durch User
von Stefan (Gast)


Lesenswert?

Ich möchte mich erstmal für den Tipp von gestern Abend bedanken.
Die 3,3V Versorgung des Optokopplers beziehe ich nun von dem uC. Ebenso 
habe ich GND an den des uC's angeschlossen.

Nun funktioniert die Erkennung des Tastgrades. Den Quellcode habe ich 
auch, entsprechend deines Tipps, etwas geändert.
Integer statt Float werde ich auch, wo es möglich ist, noch ändern.

Wie bereits erwähnt ist der Tastgrad, den ich bestimme, eine von 2 
Regelgrößen (Istwert Spannung).

Als Stellgröße nutze ich die Totzeit von PWM Signalen, welche der uC 
erzeugt. Diese gehen dann über Steckverbindungen an eine andere Platine, 
um dort Mosfets zu schalten.

Also habe ich 2 Schaltungen (uC Board & "Leistungsboard") die über 2 
verschiedene Quellen versorgt werden. Diese haben keinen gemeinsamen 
Massebezug.

Ich danke dir hier auch für die sehr informative Erklärung zu den 
Potentialdifferenzen und der Verschaltung bzw. Bedeutung der 
Masseverbindung.

Demnach müsste ich ja eine Verbindung zwischen Minuspol des Konstanters, 
welche den Leistungsboard bedient, und dem eines Masseanschlusses ( vom 
Oszi oder des Konstanters) machen.
Und zusätzlich eine weitere Verbindung zwischen dem Minuspol (oder GND 
Pin) des uC Boards und dem selben Masseanschluss.

In diesem Fall hätten die Versorgungen der beiden Schaltungen ein 
gemeinsames Bezugspotential.

Somit wäre ja auch die Verbindung zwischen dem Optokoppler (VCC & GND) 
und dem uC nicht mehr Notwendig, da beide Versorgungen sich auf die 
selbe Masse beziehen.

Ist meine Interpretation aus den letzten Absätzen korrekt?

Danke

von T.com (Gast)


Lesenswert?

Stefan schrieb:
> Demnach müsste ich ja eine Verbindung zwischen Minuspol des Konstanters,
> welche den Leistungsboard bedient, und dem eines Masseanschlusses ( vom
> Oszi oder des Konstanters) machen.
> Und zusätzlich eine weitere Verbindung zwischen dem Minuspol (oder GND
> Pin) des uC Boards und dem selben Masseanschluss.
>
> In diesem Fall hätten die Versorgungen der beiden Schaltungen ein
> gemeinsames Bezugspotential.
>
> Somit wäre ja auch die Verbindung zwischen dem Optokoppler (VCC & GND)
> und dem uC nicht mehr Notwendig, da beide Versorgungen sich auf die
> selbe Masse beziehen.
>
> Ist meine Interpretation aus den letzten Absätzen korrekt?


Ja dein annahmen sind richtig. beide quellen an den gleichen massebezug 
legen und du hast keine kopfschmerzen mehr.

von Stefan (Gast)


Lesenswert?

T.com schrieb:
> Stefan schrieb:
>> Demnach müsste ich ja eine Verbindung zwischen Minuspol des Konstanters,
>> welche den Leistungsboard bedient, und dem eines Masseanschlusses ( vom
>> Oszi oder des Konstanters) machen.
>> Und zusätzlich eine weitere Verbindung zwischen dem Minuspol (oder GND
>> Pin) des uC Boards und dem selben Masseanschluss.
>>
>> In diesem Fall hätten die Versorgungen der beiden Schaltungen ein
>> gemeinsames Bezugspotential.
>>
>> Somit wäre ja auch die Verbindung zwischen dem Optokoppler (VCC & GND)
>> und dem uC nicht mehr Notwendig, da beide Versorgungen sich auf die
>> selbe Masse beziehen.
>>
>> Ist meine Interpretation aus den letzten Absätzen korrekt?
>
> Ja dein annahmen sind richtig. beide quellen an den gleichen massebezug
> legen und du hast keine kopfschmerzen mehr.

Kann ich somit die zwischen uC Board und dem Optokopller hergestellte 
Verbindung (VCC und GND) lösen? Sind ja nun beide Versorgungen an der 
selben Bezugsmasse.

Ich Frage nur, weil die Verbindug per Steckverbinder total nervig ist.

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.