Sensor Amsys5812

Wow, diese Werte sind in der Tat plausibel. War ja auch tolles Wetter gestern:-) vielen dank für das einfache vorrechnen.
Folgendes hab ich jedoch nicht verstanden:

Da können keine Hexadezimalzahlen sein weil 0x220 ist größer als ein Byte, also müssen es Dezimalzahlen sein.
Dann ist Druck: 72256+40 = 18472
und Temperatur: 56
256+220 = 14556

Woher hast du dir genommen das du das erste byte mit 256 multiplizieren musst?

Im Datenblatt steht ja:

Für einen Drucksensor vom Typ AMS 5812-0015-D (0…1.5PSI differentiell) wird ein digitaler Druckwert von
Digoutp(p) = 550AHex counts = 21770Dec counts
und ein digitaler Temperaturwert von
DigoutT(T) = 3A9AHex counts = 15002Dec counts

Darum ging ich davon aus das die Daten darstellung hexadezimal stattfindet.
Oder hätte mir dann der Serialmonitor für das erste Byte 0x72, fürs 2.byte 0x40 und analog folgend, ausgeben müssen?

weyoun:
Woher hast du dir genommen das du das erste byte mit 256 multiplizieren musst?
Im Datenblatt steht ja:

Für einen Drucksensor vom Typ AMS 5812-0015-D (0…1.5PSI differentiell) wird ein digitaler Druckwert von
Digoutp(p) = 550AHex counts = 21770Dec counts
und ein digitaler Temperaturwert von
DigoutT(T) = 3A9AHex counts = 15002Dec counts

Darum ging ich davon aus das die Daten darstellung hexadezimal stattfindet.
Oder hätte mir dann der Serialmonitor für das erste Byte 0x72, fürs 2.byte 0x40 und analog folgend, ausgeben müssen?

Die Zahl 220 ist definitiv (uner der Bedingung sie ist eine 1Byte-Zahl) keine Hex-Zahl weil 8 Bit con 0 bis 0xff oder 0 bis 255dezimal geht.
Der Sensor schickt Dir immer 4 8-Bit Binärzahlen. Jetzt ist es an Dir diese darzustellen.
Wenn Du die 2 Byte, die Du vom Sensor bekommst als 2-stellige Hex-Zahl ausgeben läßt, kannst Du sie einfach zu einer 4 stelligen hintereinanderschreiben. Wenn Du sie als Dezimalzahl ausgibst mußt Du die Wertigkeit der höherwertigen Zahl berüchsichtigen, die nicht 100 dezimal ist sonder 256 dezimal ist.

Beim Umrechnen von den 2 1-Byte Werten zu einer unsigned Int-Variablen mußt Du den höherwertigen Teil mit 256 multiplizieren und dann den niederwertigen Teil addiren.

Die niederwertige Zahl geht von 0 bis 255. Wenn du zu 255 eins dazuzähls, wird die niederwertige Zahl 0 und Du hast einen Übertrag von 1 der im nächst Höherwertigen Zahl gespeichert wird; also 1 und 0.
Dies, weil Du nicht mit mit einem System zu tun hast, das dezimal zählt, sondern binär und geschichtlich gesehen 8 Bit zu einer größeren Einheit (Byte) zusammengfaßt wurden.
Weiß nicht ob Dir mit meiner Erklärung schon alles klar ist.

Weiterer Versuch:

binär: 0101 0011 0111 1110 // 2 8-Bitzahlen nach 4 bit gruppiert rechts niederwertiges Bit.
hex: 5 3 7 E //also 53 7E das sind in dezimal 21374 (Umwandlung Taschenrechner Windows)
binär: 83 126 // zusammengerechnet: 83*256+126 = 21374.

weyoun:
Darum ging ich davon aus, das die Daten Darstellung hexadezimal stattfindet.
Oder hätte mir dann der Serialmonitor für das erste Byte 0x72, fürs 2.byte 0x40 und analog folgend, ausgeben müssen?

Die Serial.print() Funktion gibt standartmäßig die Zahl als einen Dezimalwert aus. Du kannst das mit einem zusätzlichen Parameter auch ändern.
Serial.print(val, format) siehe Serial.print() - Arduino Reference
Die Serial.print() Funktion gibt aber zur Hex-Zahl kein "0x" hinzu.
Im Beispiel im Datenblatt haben sie HEX-Werte genommen, weil das einfacher zu rechnen ist. (4 bit gruppieren und zu einer Zahl von 0 bis F umrechnen und dann alles zusammenhängen. Hexzahlen von 1 Byte haben immer nur 2 Stellen.

Grüße Uwe

Wow, danke für die ausführliche Auskunft. :slight_smile:

Ich werde mich mal nächste Woche ausführlicher damit beschäftigen.

Leider hatte ich in meinem Studium nicht allzuviel am Hut mit Mikrocontrollern. Kennst du ein gutes Buch zur Einführung empfehlen,so dass auch laien dieser Thematik sich selbst so etwas erarbeiten können. Das scheint ja etwas sehr fundamentales zu sein und ich hab keine Lust, mit so etwas anscheinend sehr trivialem Leute in nem Forum zu nerven.

Danke im vorraus, weyoun

Sooo leider muss ich dieses Thema mal wieder aus der Versenkung ausgraben:-(

ich habe weiterhin Probleme mit meinem Drucksensor und der I2C Schnittstelle.

Das Problem muß irgendwie im Quellcode liegen. Die Kommunikation mit dem Sensor funktioniert nicht Richtig.
Mir ist aufgefallen das die Werte für den Druck beim Durchlaufen des Programmes sich nicht ändern. Ich beobachte den Wert über den Serialmonitor und es passiert nicht. Er zeigt ständig Die selbe Temperatur an, wenn ich den Sensor mit Kältespray besprühe ändert sich der Wert erst wenn ich das USB-Kabel einmal abziehe.
Das Programm läuft jedoch durch, ich habe nach jeder Zeile ein Serialprint mit einer Zahl eingefügt.
Hier der Code:

#define address2 0x78
#include <Wire.h>

void setup(){
Serial.begin(9600);}

void loop(){
Serial.println(0);
Wire.begin();
Serial.println(1);
Wire.beginTransmission(address2); // drucksensor initialisieren
Serial.println(2);
Wire.send(0);// Zeiger auf 0 setzen
Serial.println(3);
Wire.requestFrom(address2, 4);// bescheid sagen wiviele Bytes kommen. nämlich 4
Serial.println(4);
int Druck1;// variablen für die einzelnen Bytes
int Druck2;
int Druck;
int Temperatur1;
int Temperatur2;
int Temperatur;
int ausgabewert_Druck;
int ausgabewert_Temperatur;

Druck1 = Wire.receive(); //1.Byte
Serial.println(5);
// Serial.println(Druck1);

Druck2 = Wire.receive();//2.Byte
//Serial.println(Druck2);
Serial.println(6);
Temperatur1 = Wire.receive();//3.byte
Serial.println(7);
// Serial.println(Temperatur1);
Temperatur2 = Wire.receive();//4.Byte
Serial.println(8);
//Serial.println(Temperatur2);

Serial.println(9);
//Wire.endTransmission();// ende der übertragung
Druck = (((256Druck1+Druck2)-3277)/58)+758;
Serial.println(10);
Temperatur=(((256
Temperatur1+Temperatur2)-3277)/238.31)-25;
Serial.println(11);

Serial.println(Temperatur);
Serial.println(Druck);
Serial.println(13);
Wire.endTransmission();// ende der übertragung
delay(2000);
}

Welchen Fehler mache ich?
Ich starte die Kommunikation, ich beende sie, egal wo ich das endTransmission hinsetze es ändert nichts:-( hat wer nen guten Tip?

So ich habe gerad mal was ausprobiert,

#define address2 0x78
#include <Wire.h>
[b]int add=0;[/b]

void setup(){
Serial.begin(9600);}

void loop(){
 Wire.begin();
 Wire.beginTransmission(address2); // drucksensor initialisieren
[b]Wire.send(add);// Zeiger auf 0 setzen[/b]
Wire.requestFrom(address2, 4);// bescheid sagen wiviele Bytes kommen. nämlich 4
  int Druck1;// variablen für die einzelnen Bytes
  int Druck2;
  int Druck;
  int Temperatur1;
  int Temperatur2;
  int Temperatur;
  int ausgabewert_Druck;
  int ausgabewert_Temperatur;
  Druck1 = Wire.receive(); //1.Byte
  // Serial.println(Druck1);
      Druck2 = Wire.receive();//2.Byte
    //Serial.println(Druck2);
   Temperatur1 = Wire.receive();//3.byte
 // Serial.println(Temperatur1);
    Temperatur2 = Wire.receive();//4.Byte
    //Serial.println(Temperatur2);
   //Wire.endTransmission();// ende der übertragung
  Druck = (((256*Druck1+Druck2)-3277)/58)+758;
  Temperatur=(((256*Temperatur1+Temperatur2)-3277)/238.31)-25;
  Serial.println(Temperatur);
  Serial.println(Druck);
  Wire.endTransmission();// ende der übertragung
  [b] add++;
  if(add==3){
     add=0;
   }[/b]
  delay(200);
}

den fettgedruckten teil habe ich gerade eingefügt und seitdem zeigt mir der Sensor Schwankende Temperaturen und auch Druckwerte an.
Ich habe für add verschiedene Werte ausprobiert aber sobald ich höre zahlen eingebe kommt quatsch raus anch 4 messung ist der Wert grütze.
Ich frage jetzt mal, was habe ich da gemacht?
es muss irgendwas mit Speicherregister zu tun haben. Ich weiss nur nich was und wie ich die richtige Frage formulieren soll.
Kann mir mal wer auf die Sprünge helfen?

Liebe Leute,

auch ich beschäftige mich mit diesem Problem und bin sehr glücklich, auf diesen Beitrag gestoßen zu sein. Mein Sensor ist ein AMS5812-0003-D-B, also ein Differenzdrucksensor. Das Problem mit dem "Festhängen" der Werte hatte ich ebenfalls. In der Anleitung lese ich etwas von "If no acknowledge bit is generated by the receiving master, the pressure sensor is set to inactive." Dies deckt sich ja mit unserer Beobachtung: erst nach Ab- und Wiederanstecken wurde ein neuer Wert gelesen, doch auch dieser festgehalten.

Mithilfe deines Codes und dem Anpassen der Messbereichsgrenzen messe ich plausible Werte, die ich mithilfe eines Schrägrohrmanometers überprüft habe.

#define address 0x78
#include <Wire.h>

// Variablendeklaration
int add=0;
int Druck1;
int Druck2;
int Temperatur1;
int Temperatur2;
float Druck;
float Temperatur;
  
void setup(){
  Serial.begin(9600);
  }

void loop(){

  Wire.begin();
  Wire.beginTransmission(address); // Kommunikation starten
  Wire.write(add);// ???
  Wire.requestFrom(address, 4); // 4 Bytes anfordern

  Druck1 = Wire.read(); // MSB
  Druck2 = Wire.read(); // LSB
  Temperatur1 = Wire.read(); // MSB
  Temperatur2 = Wire.read(); //LSB

  // Berechnung unter Berücksichtigung von Most/Least Significant Byte
  Druck = (((256*Druck1+Druck2)-3277)/(26214/41.36))-20.68;
  Temperatur=(((256*Temperatur1+Temperatur2)-3277)/(26214/110))-25;
  
  // Ausgabe
  Serial.println("Druck in mbar: ");  
  Serial.println(Druck);
  Serial.println("Temperatur in °C: ");  
  Serial.println(Temperatur);
  Serial.println("-------------------");
  
  // Kommunikation beenden
  Wire.endTransmission();
  add++;
  if(add==3){
     add=0;
  }
  delay(200);
  }

Auch mich interessiert nun, warum ab dem Befehl

Wire.write(4)

Unsinn heraus kommt. Was genau tut denn die write-Funktion?

Für jegliche Hilfestellung bin ich dankbar.

Viele Grüße

pfeili

Der I2C Code ist falsch:

  Wire.begin();
  Wire.beginTransmission(address); // Kommunikation starten
  Wire.write(add);// ???
  Wire.requestFrom(address, 4); // 4 Bytes anfordern

1.) Wire.begin() macht man einmal in setup()
2.) beginTransmission() schreibt nur in den Ausgangs-Puffer. Das muss mit endTransmission() abgeschlossen werden. endTransmission() schließt das Schreiben ab, nicht das Lesen

Bei wire.write() wird das Register übergeben ab dem du Daten auslesen willst. Also z.B. 0 wenn du von 0-3 Lesen willst

requestFrom() liest genaugenommen auch die Daten schon aus und fordert diese nicht nur an. Mit read() werden sie dann aus dem Eingangspuffer entfernt. requestFrom() hat auch einen Rückgabe-Wert: die Anzahl der Bytes die wirklich empfangen wurden

Korrekt:

  Wire.beginTransmission(address); //Schreiben zu Slave mit Adresse "address"
  Wire.write(register);       //Anfangs-Register setzen
  Wire.endTransmission();  //Daten auf den Bus schreiben
  Wire.requestFrom(address, 4); // 4 Bytes anfordern

  Druck1 = Wire.read(); // MSB
  Druck2 = Wire.read(); // LSB
  Temperatur1 = Wire.read(); // MSB
  Temperatur2 = Wire.read(); //LSB

Und das endTransmission() ganz am Ende entfernen

Vielen Dank für deine rasche und umfassende Antwort. Ich habe den Code (hoffentlich nach deinen Vorstellungen) umgesetzt:

#define address 0x78
#include <Wire.h>

// Variablendeklaration
int startregister = 0;
int Druck1;
int Druck2;
int Temperatur1;
int Temperatur2;
float Druck;
float Temperatur;
  
void setup(){
  Serial.begin(9600);
  Wire.begin();
  }

void loop(){
  Wire.beginTransmission(address); //Schreiben zu Slave mit Adresse "address"
  Wire.write(startregister);       //Anfangs-Register setzen
  Wire.endTransmission();  //Daten auf den Bus schreiben
  Wire.requestFrom(address, 4); // 4 Bytes anfordern

  Druck1 = Wire.read(); // MSB
  Druck2 = Wire.read(); // LSB
  Temperatur1 = Wire.read(); // MSB
  Temperatur2 = Wire.read(); //LSB
  
  // Berechnung unter Berücksichtigung von Most/Least Significant Byte
  Druck = (((256*Druck1+Druck2)-3277)/(26214/41.36))-20.68;
  Temperatur=(((256*Temperatur1+Temperatur2)-3277)/(26214/110))-25;
  
  // Ausgabe
  //Serial.println("Druck in mbar: ");  
  Serial.print(Druck);
  //Serial.println("Temperatur in °C: ");  
  //Serial.print(" ");
  //Serial.println(Temperatur);

  // nächstes Register auswählen
  startregister++;
  if(startregister==3){
     startregister=0;
  }
  delay(1000);
  }

Wire.begin() habe ich ins Setup genommen und das letzte Wire.endTransmission() herausgelöscht. Ich habe außerdem die Variable "register" in "startregister" umbenannt, da "register" scheinbar vorbelegt ist. Leider wird mir nach dem Upload im Serial Monitor nur

-26.26
-26.26
-26.26
.
.
.

angezeigt. Der Wert ändert sich auch bei Druckänderung nicht. Habe ich doch etwas falsch gemacht? Und: wieviele Register gibt es überhaupt?

Viele Grüße

pfeili

Laut Datenblatt Seite 9...:

...wird da aber eigentlich gar nichts zum Sensor geschickt. Man soll wohl immer 4 Bytes auslesen. Nach der Adresse ist gleich das 1. Byte auf dem Bus.

Probiere also mal den beginTransmission(), write(), endTransmission() Teil ganz wegzulassen

Das ist aber nur die Theorie laut Datenblatt. Praktische Erfahrung habe ich mit dem Teil nicht.

Du kannst mal das als Test probieren:

int received = Wire.requestFrom(address, 4);
Serial.print("rec: "); Serial.println(received);

Dann siehst du wie viele Bytes empfangen wurden

Ich danke dir ganz herzlich. Du hast recht. Bereits mit folgendem Code funktioniert das Auslesen der digitalen Werte:

#define address 0x78
#include <Wire.h>

// Variablendeklaration
int Rueckgabe;
int Druck1;
int Druck2;
int Temperatur1;
int Temperatur2;
float Druck;
float Temperatur;
  
void setup(){
  Serial.begin(9600);
  Wire.begin();
  }

void loop(){
  
  Rueckgabe = Wire.requestFrom(address, 4); // 4 Bytes anfordern
  Druck1 = Wire.read(); // MSB
  Druck2 = Wire.read(); // LSB
  Temperatur1 = Wire.read(); // MSB
  Temperatur2 = Wire.read(); //LSB
  
  // Berechnung unter Berücksichtigung von Most/Least Significant Byte
  Druck = (((256*Druck1+Druck2)-3277)/(26214/41.36))-20.68;
  Temperatur=(((256*Temperatur1+Temperatur2)-3277)/(26214/110))-25;

  // Ausgabe Rueckgabewert
  Serial.print(" ");  
  Serial.print(Rueckgabe);
  // Ausgabe Druck in mbar
  Serial.print(" ");
  Serial.println(Druck);
  //Ausgabe Temperatur in °C  
  Serial.print(" ");
  Serial.println(Temperatur);
  
  delay(200);
  }

Ich dachte nur, dass ich manuell immer dieses Acknowledge-Bit bzw. abschließend die "Stop-Condition" vom Arduino aus senden muss. Aber scheinbar ist dies schon in requestFrom() durch Angabe der entsprechenden Byte-Zahl enthalten.

Nochmals vielen Dank. Du hast mir sehr geholfen.

Beste Grüße

pfeili

pfeili:
Ich dachte nur, dass ich manuell immer dieses Acknowledge-Bit bzw. abschließend die "Stop-Condition" vom Arduino aus senden muss. Aber scheinbar ist dies schon in requestFrom() durch Angabe der entsprechenden Byte-Zahl enthalten

Ja. Das macht die Wire Klasse intern

Das ist etwas im Hintergrund versteckt, aber zumindest das mit dem Stop-Bit kann man aus der Doku ableiten:

Ich bin da auch schon durcheinander gekommen was da jetzt genau von der Library gemacht wird. Laut Datenblatt muss da z.B. ein R/W Bit im Adress-Byte gesetzt werden je nachdem ob man liest oder schreibt. Da könnte man jetzt auf die Idee kommen das per Hand tun zu müssen. Ist aber nicht der Fall. Das wird automatisch auf der untersten Ebene in twi.c erledigt.

Hallo Serenifly,

nochmals danke für deine Hilfe. Nun habe ich nur noch eine Frage hierzu:

Wie kann ich mehrere Sensoren auslesen? Da diese alle auf 0x78 adressiert sind kommt es doch sicher zu Problemen? Zwar kann man vom Hersteller umadressieren lassen, aber das kostet sicher Geld. Ist es auch noch anders möglich oder kann ich mit

int received = Wire.requestFrom(address, 8);

einfach gleich die viert nächsten Bytes mitlesen?

Viele Grüße

pfeili

Da diese alle auf 0x78 adressiert sind kommt es doch sicher zu Problemen?

Sehr gut erkannt!

Viellicht wäre sowas was für dich: I2C Multiplexer

Super. Den Multiplexer schaue ich mir mal an. Danke.

Nun habe ich doch noch ein Problem. Mithilfe des folgenden Codes lese ich einen anderen Drucksensor aus:

#define address 0x78
#include <Wire.h>

// Variablendeklaration
int Rueckgabe;
int Druck1;
int Druck2;
int Temperatur1;
int Temperatur2;
float Druck = 0.00;
float Temperatur;
  
void setup(){
  Serial.begin(9600);
  Wire.begin();
  }

void loop(){
  
  Rueckgabe = Wire.requestFrom(address, 2); // 2 Bytes anfordern
  Druck1 = Wire.read(); // MSB
  Druck2 = Wire.read(); // LSB
  
  // Berechnung unter Berücksichtigung von Most/Least Significant Byte
  Druck = (((256*Druck1+Druck2)-3277)/(26214/10)) + 0;
  
  // Ausgabe Rueckgabewert
  Serial.print(Druck1);
  Serial.print(" ");
  Serial.print(Druck2);
  Serial.print(" ");
  // Ausgabe Druck in mbar
  Serial.println(Druck);
  
  delay(200);
  }

Die rückgegebenen Werte sind absolut stimmig, aber die Variable Druck ändert sich nicht in den Nachkommastellen (s. Anhang). Ich habe sie doch aber als float deklariert.

Was mache ich hier falsch?

Viele Grüße

pfeili

keineNachkommastellen.png

Druck = (((256*Druck1+Druck2)-3277)/(26214/10)) + 0;

Muss wahrscheinlich / 10.0 heißen

/ 10 macht eine Integer Division und liefert 2621, nicht 2621,4. Nachfolgend wird dann auch eine Integer-Division durch 2621 gemacht

So geht es vielleicht:

Druck = (((256L*Druck1+Druck2)-3277)/(26214/10.0));

Beachte auch das 256L. Das ist sicherheitshalber besser, da 256 * Druck1 einen Überlauf in einem int verursacht wenn Druck1 größer als 127 wird. Das tritt real vielleicht nie ein wenn der Druck nicht so hoch wird, aber es ist eine potentielle Fehlerquelle. Mit dem L wird das in long gerechnet

Ihr seid einfach klasse. Herzlichen Dank dafür.

Beste Grüße

pfeili

Liebe Leute,

ich hoffe, der Beitrag ist noch nicht zu alt.

Ich probiere mittlerweile das digitale Auslesen von gleich 5 AMSYS 5812 Drucksensoren über I2C. Durch den Erwerb eines entsprechenden USB-Boards konnte ich jedem der Sensoren eine sekundäre Adresse geben (hier: 1...5 hex). Mit folgendem Code funktioniert das Auslesen der ersten beiden Sensoren auch einwandfrei:

#define address1 0x01
#define address2 0x02
#define address3 0x03
#define address4 0x04
#define address5 0x05
#include <Wire.h>

// Variablendeklaration
int add=0;
int Druck11;
int Druck12;
int Temperatur11;
int Temperatur12;
float Druck1;
float Temperatur1;
int Druck21;
int Druck22;
int Temperatur21;
int Temperatur22;
float Druck2;
float Temperatur2;
int Druck31;
int Druck32;
int Temperatur31;
int Temperatur32;
float Druck3;
float Temperatur3;  
int Druck41;
int Druck42;
int Temperatur41;
int Temperatur42;
float Druck4;
float Temperatur4;  
int Druck51;
int Druck52;
int Temperatur51;
int Temperatur52;
float Druck5;
float Temperatur5;

void setup(){
  Serial.begin(9600);
  }

void loop(){

  Wire.begin();
  Wire.beginTransmission(address1); // Kommunikation starten
  Wire.write(add);// ???
  Wire.requestFrom(address1, 4); // 4 Bytes anfordern
  // Auslesen
  Druck11 = Wire.read(); // MSB
  Druck12 = Wire.read(); // LSB
  Temperatur11 = Wire.read(); // MSB
  Temperatur12 = Wire.read(); //LSB
  // Zusammensetzen unter Berücksichtigung von Most/Least Significant Byte
  Druck1 = (((256*Druck11+Druck12)-3277)/(26214/1034.0))-517.0;
  Temperatur1 =(((256*Temperatur11+Temperatur12)-3277)/(26214/110))-25;
  
  // Ausgabe
  Serial.print("Druck in Pa: ");  
  Serial.print(Druck1);
  Serial.print(" | ");
  //Serial.println("Temperatur in °C: ");  
  //Serial.print(" ");
  //Serial.println(Temperatur);
  
    // Kommunikation beenden
  Wire.endTransmission();
  add++;
  if(add==3){
     add=0;
  }
  //delay(200);
  
  Wire.begin();
  Wire.beginTransmission(address2); // Kommunikation starten
  Wire.write(add);// ???
  Wire.requestFrom(address2, 4); // 4 Bytes anfordern
  // Auslesen
  Druck21 = Wire.read(); // MSB
  Druck22 = Wire.read(); // LSB
  Temperatur21 = Wire.read(); // MSB
  Temperatur22 = Wire.read(); //LSB
  // Zusammensetzen unter Berücksichtigung von Most/Least Significant Byte
  Druck2 = (((256L*Druck21+Druck22)-3277)/(26214/1034.0))-517.0;
  Temperatur2 =(((256L*Temperatur21+Temperatur22)-3277)/(26214/110))-25;
  
  // Ausgabe
  //Serial.print("Druck2 in mbar: ");  
  Serial.println(Druck2);
  // Serial.print("| ");
  //Serial.println("Temperatur in °C: ");  
  //Serial.print(" ");
  //Serial.println(Temperatur);
  
    // Kommunikation beenden
  Wire.endTransmission();
  add++;
  if(add==3){
     add=0;
  }
  delay(200);

}

Ich habe erstmal nur Wert auf den Druck der ersten beiden Sensoren gelegt. Die Werte sind stimmig und ändern sich auch bei veränderter Druckbeaufschlagung.

Nun wollte ich eigentlich das Ganze schöner lösen und in eine Unterfunktion packen:

#define address1 0x01
#define address2 0x02
#define address3 0x03
#define address4 0x04
#define address5 0x05
#include <Wire.h>

// Variablendeklaration
int add=0;
int p1;
int p2;
int t1;
int t2;
float Druck;
float Temperatur;
float Druck1;
float Temperatur1;
float Druck2;
float Temperatur2;
float Druck3;
float Temperatur3;  
float Druck4;
float Temperatur4;  
float Druck5;
float Temperatur5;

void setup(){
  Serial.begin(9600);
  }

void loop(){
  Druck1 = read_sensor(address1);
  Druck2 = read_sensor(address2);
  Druck3 = read_sensor(address3);
  Druck4 = read_sensor(address4);
  Druck5 = read_sensor(address5);

  Serial.print("Sensor 1: ");
  Serial.print(Druck1);
  Serial.print("Pa | ");
  Serial.print("Sensor 2: ");
  Serial.print(Druck2);
  Serial.print("Pa | ");
  Serial.print("Sensor 3: ");
  Serial.print(Druck3);
  Serial.print("Pa | ");
  Serial.print("Sensor 4: ");
  Serial.print(Druck4);
  Serial.print("Pa | ");
  Serial.print("Sensor 5: ");
  Serial.print(Druck5);
  Serial.println("Pa | ");
  delay(500);  
  
}

float read_sensor(int address){
  
  Wire.begin();
  //start the communication with IC with the address xx
  Wire.beginTransmission(address); 
  //send a bit and ask for register 0...3
  Wire.write(add);
  //request 1 byte from address xx
  Wire.requestFrom(address, 4);
  //wait for response
  //while(Wire.available() == 0);
  // Auslesen
  p1 = Wire.read(); // MSB
  p2 = Wire.read(); // LSB
  t1 = Wire.read(); // MSB
  t2 = Wire.read(); //LSB
  // Zusammensetzen unter Berücksichtigung von Most/Least Significant Byte
  Druck = (((256L*p1+p2)-3277)/(26214/1034.0))-517;
  Temperatur =(((256L*t1+t2)-3277)/(26214/110.0))-25;   
  return Druck;
  //end transmission
  Wire.endTransmission();
  add++;
  if(add==3){
     add=0;
  }
  delay(100);
}

Leider ändert sich nur der erste, nicht aber der zweite Druckwert. Habt ihr eine Idee, woran das liegt?

Vielen Dank und beste Grüße

pfeili

Wire.begin() macht man nur einmal in setup(). Das ist analog zu Serial.begin()

Dann auch wieder der übliche Fehler:
nach requestFrom() kommt kein endTransmission() ! endTransmission() sendet Daten. Das da zu machen bewirkt zwar wahrscheinlich keine Fehlfunktion, da sowie nichts im Ausgangspuffer ist, aber es gehört da trotzdem nicht hin.

Das endTransmission() muss direkt nach dem write() kommen. write() schreibt Daten in den Ausgangspuffer. endTransmission() sendet den Puffer.

Deine Funktion kehrt nach return zurück. Alles danach ist "unreachable code"

Hallo Serenifly,

vielen Dank für deine rasche Antwort. Ich habe das Wire.begin() und return Druck umgebaut. Allerdings muss das Wire.endTransmission() wirklich an diese Stelle. Wenn ich es bereits hinter Wire.write() setze, funktioniert es nicht.

#define address1 0x01
#define address2 0x02
#define address3 0x03
#define address4 0x04
#define address5 0x05
#include <Wire.h>

// Variablendeklaration
int add=0;
int p1;
int p2;
int t1;
int t2;
float Druck;
float Temperatur;
float Druck1;
float Temperatur1;
float Druck2;
float Temperatur2;
float Druck3;
float Temperatur3;  
float Druck4;
float Temperatur4;  
float Druck5;
float Temperatur5;

void setup(){
  Serial.begin(9600);
  Wire.begin();  
}

void loop(){
  Druck1 = read_sensor(address1);
  Druck2 = read_sensor(address2);
  Druck3 = read_sensor(address3);
  Druck4 = read_sensor(address4);
  Druck5 = read_sensor(address5);

  Serial.print("Sensor 1: ");
  Serial.print(Druck1);
  Serial.print("Pa | ");
  Serial.print("Sensor 2: ");
  Serial.print(Druck2);
  Serial.print("Pa | ");
  Serial.print("Sensor 3: ");
  Serial.print(Druck3);
  Serial.print("Pa | ");
  Serial.print("Sensor 4: ");
  Serial.print(Druck4);
  Serial.print("Pa | ");
  Serial.print("Sensor 5: ");
  Serial.print(Druck5);
  Serial.println("Pa");
  delay(500);  
  
}

float read_sensor(int address){
  
  //start the communication with IC with the address xx
  Wire.beginTransmission(address); 
  //send a bit and ask for register 0...3
  Wire.write(add);
  //request 4 bytes from address xx
  Wire.requestFrom(address, 4);
  // Auslesen
  p1 = Wire.read(); // MSB
  p2 = Wire.read(); // LSB
  t1 = Wire.read(); // MSB
  t2 = Wire.read(); //LSB
  // Zusammensetzen unter Berücksichtigung von Most/Least Significant Byte
  Druck = (((256L*p1+p2)-3277)/(26214/1034.0))-517;
  Temperatur =(((256L*t1+t2)-3277)/(26214/110.0))-25;   
  //end transmission
  Wire.endTransmission();
  add++;
  if(add==3){
     add=0;
  }
  return Druck;
  delay(100);
}

Herzlichen Dank und einen wunderbaren Tag.

pfeili

Das funktioniert aber so von der Logik her nicht richtig. Was du mit write() in den Ausgangspuffer schreibst wird erst bei endTransmission() gesendet und damit erst beim nächsten Aufruf der Funktion verwendet.

Du hast immer noch ein delay(100) nach return. Das wird nie aufgerufen.

"Druck" muss (und sollte) übrigens keine globale Variable sein. Das kannst du lokal in der Funktion deklarieren. Wenn du zwei Rückgabe-Werte braucht (Druck und Temperatur), kann man das mit Referenzparameter erledigen.