Forum: Mikrocontroller und Digitale Elektronik PCF 8591 Frage - Übernahme von Daten


von Achim S. (achims)


Lesenswert?

Hallo Gemeinde
Zum einlesen von analogen Spannungen an einem PCF8591 benutze ich den 
folgenden Code: (AT 1284p, C, 16M mit Anzeige auf dem Bus)
1
while(1)
2
  {  
3
    i2c_start(PCF8591w);
4
    i2c_write(0x44);  // 0x44
5
    i2c_stop();
6
    
7
    i2c_start(PCF8591r);
8
      for (i=0;i<5;i++)
9
        {
10
        results[i]=(i2c_readAck());
11
          adc1=results[1];
12
          adc2=results[2];
13
          adc3=results[3];
14
          adc4=results[4];
15
          }    
16
    
17
    itoa( adc1, Buffer, 10 );    // Zeile 1
18
    lcd_printlc(1,1,Buffer);
19
    
20
    itoa( adc2, Buffer, 10 );    // Zeile 2
21
    lcd_printlc(2,1,Buffer);
22
    
23
    itoa( adc3, Buffer, 10 );    // Zeile 3
24
    lcd_printlc(3,1,Buffer);
25
    
26
    itoa( adc4, Buffer, 10 );    // Zeile 4 
27
    lcd_printlc(4,1,Buffer);
28
    
29
    _delay_ms(1300);        // Pause 200 ms
30
    
31
    i2c_stop();
32
    
33
    _delay_ms(200);        // Pause 200 ms
34
      
35
    return 0;                                    //
36
  }
37
}
Leider verstehe ich ein paar Sachen nicht. Im Datenblatt bin ich auch 
nicht fündig geworden.
1.
1
for (i=0;i<5;i++)
2
    {
3
      results[i]=(i2c_readAck());
4
      adc1=results[1];
5
      adc2=results[2];
6
      adc3=results[3];
7
      adc4=results[4];
8
        }
Mit i zähle ich von 0 bis <5, das 5 mal. in results verwende ich aber 
nur 1 bis 4. Gebe ich 0 mit an ergibt es sehr komische Werte oder eine 
verzögerte Anzeige oder es muss reset gedrückt werden. Warum?

2.
Nach dem einschalten werden die Werte der Einstellung von A0 bis A3 
eingelesen und angezeigt. Aber nur dann. Da alles in einer while 
Schleife ist, müsste es doch ständig neu (Wert änderung) angezeigt 
werden. Leider macht es das nur ein mal Warum?
achim

: Verschoben durch User
von Falk B. (falk)


Lesenswert?

@Achim Seeger (achims)

>Zum einlesen von analogen Spannungen an einem PCF8591 benutze ich den
>folgenden Code: (AT 1284p, C, 16M mit Anzeige auf dem Bus)

Na, mal wieder am kämpfen mit dem I2C Bus? ;-)

>while(1)
>  {
>    i2c_start(PCF8591w);
>    i2c_write(0x44);  // 0x44
>    i2c_stop();


>    i2c_start(PCF8591r);
>      for (i=0;i<5;i++)
>        {
>        results[i]=(i2c_readAck());

Soweit richtig. Aber was soll das hier?

>          adc1=results[1];
>          adc2=results[2];
>          adc3=results[3];
>          adc4=results[4];
>          }

Warum kopierst du IN der Schleife die Daten immer wieder um? Das ist 
sinnlos. Erst recht, wenn man die Daten sowohl im Array results[] als 
auch in 4 Einzelvariablen stehen hat. Das Array reicht und ist besser!


>    _delay_ms(1300);        // Pause 200 ms

Was fällt dir hier auf?

>    i2c_stop();

Das muss weiter oben stehen, nach der Ausleseschleife.

>    _delay_ms(200);        // Pause 200 ms

>    return 0;                                    //

Das hat in der while(1) Schleife nichts zu suchen.

>Leider verstehe ich ein paar Sachen nicht. Im Datenblatt bin ich auch
>nicht fündig geworden.

>for (i=0;i<5;i++)
>    {
>      results[i]=(i2c_readAck());
>      adc1=results[1];
>      adc2=results[2];
>      adc3=results[3];
>      adc4=results[4];
>        }

>Mit i zähle ich von 0 bis <5, das 5 mal. in results verwende ich aber
>nur 1 bis 4. Gebe ich 0 mit an ergibt es sehr komische Werte oder eine
>verzögerte Anzeige oder es muss reset gedrückt werden. Warum?

Das ist so oder so MURKS! Ist das von dir oder aus dem Internet kopiert?
So wäre es sinnvoll!
1
while(1) {  
2
  i2c_start(PCF8591w);
3
  i2c_write(0x44);
4
  i2c_stop();
5
    
6
  i2c_start(PCF8591r);
7
  for (i=0; i<4; i++) {
8
    results[i]=(i2c_readAck());
9
  }
10
  i2c_readNAck();
11
  i2c_stop();
12
    
13
  itoa( results[0], Buffer, 10 );    // Zeile 1
14
  lcd_printlc(1,1,Buffer);
15
    
16
  itoa( results[1], Buffer, 10 );    // Zeile 2
17
  lcd_printlc(2,1,Buffer);
18
    
19
  itoa( results[2], Buffer, 10 );    // Zeile 3
20
  lcd_printlc(3,1,Buffer);
21
    
22
  itoa( results[3], Buffer, 10 );    // Zeile 4 
23
  lcd_printlc(4,1,Buffer);
24
    
25
  _delay_ms(1300);
26
}

>Nach dem einschalten werden die Werte der Einstellung von A0 bis A3
>eingelesen und angezeigt. Aber nur dann. Da alles in einer while
>Schleife ist, müsste es doch ständig neu (Wert änderung) angezeigt
>werden. Leider macht es das nur ein mal Warum?

Weil du ein return IN der Schleife hast, was dort nie reingehört.

von Achim S. (achims)


Lesenswert?

Hallo Falk
stimmt wie immer was du sagst, kämpfe wieder mit dem Bus. Hatte den PCF 
8591 lange vor mir her geschoben. Gehe in jetzt an, kann mmich nicht 
ewig da vor drücken. Eigentlich ist es leichter als gedacht.
Teile stammen aus dem Netz, das andere aus dem Datenblatt.
Werde es so machen wie du es schreibst. Kämpfe auch noch mit dem 
Festkomma dazu.
Leider sind die Beispiel im Netz sehr wenig. Da hilft nur fragen.
danke
achim

von Falk B. (falk)


Lesenswert?

@ Achim Seeger (achims)

>Werde es so machen wie du es schreibst. Kämpfe auch noch mit dem
>Festkomma dazu.

Warum? Du kennst doch den Artikel Festkommaarithmetik. Dort sthet 
nahezu alles drin.

>Leider sind die Beispiel im Netz sehr wenig.

Man hat nicht immer Beispiele. Und man braucht sie auch nicht immer. 
Manchmal muss man sich das allein erarbeiten.

von Falk B. (falk)


Lesenswert?

Ergänzung. Das hier gehört eigentlich VOR die Endlosschleife!

  i2c_start(PCF8591w);
  i2c_write(0x44);
  i2c_stop();

von Falk B. (falk)


Lesenswert?

OK, hier mal aufgeräumt und mit Erkenntnissen nach dem Lesen des 
Datenblatts ;-)
1
i2c_start(PCF8591w);
2
i2c_write(0x44);   // Analog out enable, auto increment, channel 0
3
i2c_stop();
4
5
while(1) {  
6
    
7
  i2c_start(PCF8591r);
8
  i2c_readAck(); // first data is old
9
10
  for (i=0; i<4; i++) {
11
    results[i]=i2c_readAck();
12
  }
13
  i2c_readNAck();
14
  i2c_stop();
15
    
16
  itoa( results[0], Buffer, 10 );    // Zeile 1
17
  lcd_printlc(1,1,Buffer);
18
    
19
  itoa( results[1], Buffer, 10 );    // Zeile 2
20
  lcd_printlc(2,1,Buffer);
21
    
22
  itoa( results[2], Buffer, 10 );    // Zeile 3
23
  lcd_printlc(3,1,Buffer);
24
    
25
  itoa( results[3], Buffer, 10 );    // Zeile 4 
26
  lcd_printlc(4,1,Buffer);
27
    
28
  _delay_ms(1300);
29
}

von Achim S. (achims)


Lesenswert?

Bin genau in diesem Artikel drin und lese.
Mit einem Beispiel lebt es sich leichter. Damit hat man einen Hinweis 
wie es geht.
achim

von Achim S. (achims)


Lesenswert?

Hallo Falk
hat noch einen anderen Effekt
Wird eine Spannung verändert z.B. A0 oder A3, ändern sich alle  Werte 
oder es läuft eine 1 in der ersten Stelle von oben nach unten
achim

von spess53 (Gast)


Lesenswert?

Hi

Mal eine Zwischenfrage:  Was machst du mit dem Control Byte?

MfG Spess

von Achim S. (achims)


Lesenswert?

Noch gar nichts, soweit bin ich noch nicht. Bin gerade dabei die Länge 
der Ausgabe zu begrenzen und umzurechnen.

Ausgabe min-max = 0 bis 255
Uref 5V
Faktor *195
Beispiel
Ausgabe 128-> *195 Anzeige U 253506
Jetzt fehlt nur noch die Begrenzung auf 3 Stellen und das Komma
Bin Festkommaarithmetik drin und versuche zu verstehen
Habe das Control Byte gesehen und im Datenblatt gelesen und werde es auf 
jeden fall nutzen. Schon eine Idee wie es geht?
achim

von Falk B. (falk)


Lesenswert?

@ Achim Seeger (achims)

>Noch gar nichts, soweit bin ich noch nicht.

Ach so? Und was ist das hier?

    i2c_start(PCF8591w);
    i2c_write(0x44);  // 0x44
    i2c_stop();

Kann es sein, daß du mal wieder gar nicht so recht weißt, was du da 
eigentlich tust?

> Bin gerade dabei die Länge
>der Ausgabe zu begrenzen und umzurechnen.

Vollkommen falsch. Zuerst muss mal das Auslesen des ADC sauber laufen. 
Da zeigt man einfach den ADC Wert an und fertig. Die Umrechnung in V 
kommt viel später.

>Habe das Control Byte gesehen und im Datenblatt gelesen und werde es auf
>jeden fall nutzen. Schon eine Idee wie es geht?

Du bist ein echter Künstler . . .

Sagt der Taxifahrer: "Das Lenkrad werde ich auch nutzen, weiß einer wie 
das geht?"

von Achim S. (achims)


Lesenswert?

Du meinst das 0x44?
Laut Datenblatt habe ich die Einstellung gemacht. Man kann auch mehr 
auswählen, Eingänge oder so, gelesen ja, angewendet ja, mehr nicht. 
Hatte zu Anfand z.B. so was drin 0b01000100 (0x44).
Der ADC wird jetzt sauber ausgelesen. Lasse den ADC wert neben der 
Angabe P1 bis P4 anzeigen, Bereich von 0 bis 255. Leider geht es 
manchmal nicht auf 0 und springt manchmal, Wahrscheinlich Poti,
Benutze zur Ausgabe ein I2C display mit 4x16
Warum meckerst du immer über mich. Kämpfe mich durch. Einen Porsche habe 
ich gerade nicht, auch keinen VW, die haben selber Probleme mit der 
Software. Bin von früher her einen Trabi gewöhnt. Auch damit kommt man 
von A nach B, zwar langsamer, aber man kann ankommen damit.

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.