Ich brauche dringend Hilfe bezüglich dem auslesen von AMSYS SM9236/SM9235!

Hallo Zusammen,

innerhalb meiner Ausbildung baue ich einen Windkanal und muss in diesem Messungen durchführen. An zwei verschiedenen Positionen möchte ich die Strömungsgeschwindigkeit mithilfe von Differenzdrucksensoren bestimmen. Die Druckunterschiede sind recht gering. Deshalb habe ich die von AMSYS den SM9236-BCE-S-600-000 und den SM9235-BCE-S-300-000 Sensor
Desweiteren messe ich noch den Umgebungsdruck mit einem BMP280. Alle drei Sensoren hängen an einem Multiplexer Adafruit TCA9548A), der an einem Arduino Uno hängt.
Das auslesen des BMP280 über I2C hat ohne Probleme geklappt. Leider schaffe ich es nicht die beiden anderen Sensoren auszulesen.
Ich würde mich riesig freuen, wenn mir jemand mit dem Code dafür helfen könnte. :slight_smile:
Bisher sieht das so aus …

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bme;

#define TCAADDR 0x70
void tcaselect(uint8_t i) {
  if (i > 7) return;
 
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();  
}

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

  Serial.println(F("##############################"));            
  Serial.println(F("Starting Initialization"));
  Serial.println(F("##############################"));       
 

  //*************INITIALIZING FIRST SENSOR*******************************   
  tcaselect(4);
  if (!bme.begin()) {  
    Serial.println("Could not find a valid BMP280 sensor!");
    while (1);
  }
  
  //**********************************************************************

  //*************INITIALIZING SECOND SENSOR*******************************  
  tcaselect(1);  
  ???
  
  //*********************************************************************      

 //*************INITIALIZING THIRD SENSOR********************************    
 tcaselect(2);  
  ???
  
  
  //**********************************************************************
  
 
  //**********************************************************************  
  Serial.println();
  Serial.println(F("##############################"));            //30-times #
  Serial.println(F("Initialization Finished"));
  Serial.println(F("##############################"));            //30-times # 
  Serial.println();
  Serial.println();
}
  //*********************************************************************
  //*************NOW LET'S START MEASURING*******************************
void loop() 
{ 
   tcaselect(4);
   Serial.print("Temperature = ");
   Serial.print(bme.readTemperature());
   Serial.println(" *C");
   Serial.print("Pressure = ");
   Serial.print(bme.readPressure());
   Serial.println(" Pa");
   Serial.print("Approx altitude = ");
   Serial.print(bme.readAltitude(1013.25)); 
   Serial.println(" m");
   Serial.println();   
 
  tcaselect(1);
   
  ???
  tcaselect(2);
  ???
   
   
   
   Serial.println();
   Serial.println();

   delay(2000);   
 
}/code]

Hat jemand eine Idee, wie ich die auslesen kann?

Poste bitte Hyperlinks (zum anklicken) deiner unbekannten Sensoren.
Hast du da mal nach Libraries gesucht ?

Zudem verstehe ich nicht warum du die SPI-Pins des BMP280 definierst, den aber mit I2C ausliest.

Und was für einen Multiplexer verwendest Du ?

Das sind die Sensoren:
Sensoren
Ich konnte bisher leider keine passende Bibliothek dafür finden.

Als Multiplexer verwende ich den TCA9548A von Adafruit.

Ups, das ist noch ein Relikt aus den ersten Versuchen. Habe ich entfernt :slight_smile:

a) Schließe nur einen Sensor an - und schreibe welchen
b) Poste einen - DEINEN - Schaltplan für diesen Einen Sensor inkl. aller Stromanschlüsse
c) Poste ein Echtbild - bzw so viele Bilder woraus wir erkennen können, was wie angeschlossen ist
d) Lad einen i2c Scanner hoch, und berichte, ober der Sensor gefunden wird.

a) Ich habe jetzt nur den SM9236 angeschlossen.

b) Schaltplan habe ich im Anhang.

c) Ich habe mir Mühe gegeben, aber es sieht auf den Bildern etwas unordentlich aus. Der Kondensator ist nicht zu sehen, aber angeschlossen.

d)Der I2C Scanner zeigt folgendes an:
19:17:13.742 → Scanning…
19:17:13.776 → I2C device found at address 0x01 !
19:17:13.810 → I2C device found at address 0x6C !
19:17:13.847 → I2C device found at address 0x6D !
19:17:13.882 → done
19:17:13.882 →

Der Sensor wird also erkannt.
Vielen Dank für die schnellen Rückmeldungen :slight_smile:

na dann nimmst jetzt mal die Adresse ohne CRC und versuchst mal das eine Register auszulesen, ob da was Plausibles retourkommt.

P.S. Am Schaltplan fehlt der Uno und die Stromversorgungen

Ich stehe gerade etwas auf dem Schlauch. Meinst du das so?

#include <Wire.h>

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

void loop(){

  Wire.beginTransmission(0x01);
  
  Wire.write(0x00);
  
  Wire.endTransmission();
  
  Wire.requestFrom(0x01, 7);
  
  while(Wire.available() == 0);
  
  int a = Wire.read();
  int b = Wire.read();
  int c = Wire.read();
  int d = Wire.read();
  int e = Wire.read();
  int f = Wire.read();
  int g = Wire.read();
  
  Serial.print(a);
  Serial.print(", ");
  Serial.print(b);
  Serial.print(", ");
  Serial.print(c);
  Serial.print(", ");
  Serial.print(d);
  Serial.print(", ");
  Serial.print(e);
  Serial.print(", ");
  Serial.print(f);
  Serial.print(", ");
  Serial.print(g);
  Serial.println(", ");
  delay(9000)

Damit bekomme ich für das Register 0x00:

20:20:01.695 → 2208, 0, 151, 2, 214, 16, 2,

Sorry. Mit I2C bin ich no nicht so vertraut :frowning:

PS.: Danke :slight_smile:

13.5.2

For all examples below the 7-bit device slave address used is 0x6C for unprotected commands,

und dann würde ich jeweils zwei byte von 0x2E und 0x30 lesen, und testweise die anderen auch mal...

Vielen Dank schon mal. 0x6C habe ich komplett überlesen.

Folgende Werte habe ich ausgelesen...

0x2E:
22:10:14.909 -> 43, 230, 31, 153, 24, 192, 0,
22:10:23.916 -> 76, 230, 31, 153, 24, 192, 0,
22:10:32.928 -> 98, 230, 31, 153, 24, 192, 0,

Für 0x30:
22:10:41.368 -> 31, 153, 24, 192, 0, 12, 30,
22:10:42.960 -> 33, 153, 24, 192, 0, 12, 30,
22:10:51.983 -> 31, 153, 24, 192, 0, 12, 30,

0xF2
22:14:50.307 -> 173, 223, 129, 154, 0, 109, 100,
22:14:59.321 -> 173, 223, 129, 154, 0, 109, 100,
22:15:08.324 -> 173, 223, 129, 154, 0, 109, 100,

0x7D
22:16:02.463 -> 77, 129, 252, 48, 0, 0, 0,
22:16:11.451 -> 77, 129, 252, 48, 0, 0, 0,
22:16:20.471 -> 77, 129, 252, 48, 0, 0, 0,

0xEA
22:16:38.149 -> 111, 126, 34, 13, 0, 133, 109,
22:16:47.140 -> 111, 126, 34, 13, 0, 133, 109,
22:16:56.171 -> 111, 126, 34, 13, 0, 133, 109,

0x82
22:18:39.696 -> 0, 0, 107, 0, 233, 255, 15,
22:18:48.712 -> 0, 0, 107, 0, 233, 255, 15,
22:18:57.729 -> 0, 0, 107, 0, 233, 255, 15,

0x32
22:19:22.211 -> 8, 192, 0, 12, 30, 192, 32,
22:19:31.230 -> 8, 192, 0, 12, 30, 192, 32,
22:19:40.260 -> 8, 192, 0, 12, 30, 192, 32,

0x1E
22:19:56.092 -> 84, 17, 215, 36, 0, 0, 0,
22:20:05.082 -> 84, 17, 215, 4, 0, 0, 0,
22:20:14.094 -> 84, 17, 215, 4, 0, 0, 0,

0x00
22:20:30.315 -> 208, 0, 151, 2, 214, 16, 2,
22:20:39.342 -> 208, 0, 151, 2, 214, 16, 2,
22:20:48.361 -> 208, 0, 151, 2, 214, 16, 2,

Von der Idee her, würde ich versuchen, daraus die Temperatur zu ermitteln um die Werte zu verifizieren. Ich habe aber keine Ahnung, wie ich die Konvertieren kann.

jetzt vergleichst du Datenblatt vs Applikation Note und versucht die Bytes entsprechend zu interpretieren. Vorlesen kann ich es nicht. Warum in der App-Note maskiert wird und im Datenblatt nichts davon steht, musst du dir mit dem Hersteller ausmachen.

Ich habe es mal probiert, bin aber nicht sicher ob ich auf dem richtigen Weg bin.
Folgenden Code habe ich probiert …

#include <Wire.h>
int _data;
int i2c_byte1;
int i2c_byte2;
int i2c_byte3;
int i2c_byte4;
int temperature;
int pressure;
int status1;

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

void loop(){

  Wire.beginTransmission(0x6C);

  Wire.write(0x2E);

  Wire.endTransmission();

  Wire.requestFrom(0x6C, 4);

  while(Wire.available() == 0);

  i2c_byte1 = Wire.read();
  i2c_byte2 = Wire.read();
  i2c_byte3 = Wire.read();
  i2c_byte4 = Wire.read();

  i2c_byte4 >>= 5; 
  temperature= (i2c_byte3*8) + i2c_byte4;

  pressure = 0x3fff & ((i2c_byte1 * 256) + i2c_byte2);

  status1 = i2c_byte1 >> 6;

  Serial.print(temperature);
  Serial.print(", ");
  Serial.print(pressure);
  Serial.print(", ");
  Serial.print(status1);
  Serial.print(", ");
  Serial.print(i2c_byte1);
  Serial.print(", ");
  Serial.print(i2c_byte2);
  Serial.print(", ");
  Serial.print(i2c_byte3);
  Serial.print(", ");
  Serial.print(i2c_byte4);
  Serial.print(", ");
  delay(9000);
}

Als Ausgabe bekomme ich da:
11:49:03.999 → 284, 9193, 1, 99, 233, 35, 4,

Könnte mir jemand mit dem Code helfen? Die Werte machen so ja keinen Sinn…

tja, wie gesagt, warum die AN nicht zum Datasheet passt ...
Aber rein so aus dem Bauch raus,

28,4 Grad und 919,3 hPA klingt doch nicht so unplausibel oder?

Ich habe schon beim Hersteller angefragt... mal sehen was sich ergibt.

Die Temperaturwerte finde ich auch recht plausibel. Der Druck müsste aber ein Differenzdruck sein und dementsprechend null. Er schwankt auch etwas zu stark ...

13:17:08.602 -> 260, 3305, 3, 
13:17:09.607 -> 244, 3305, 3, 
13:17:10.592 -> 276, 3817, 3, 
13:17:11.610 -> 252, 5097, 3, 
13:17:12.592 -> 252, 5097, 3, 
13:17:13.607 -> 244, 5609, 3, 
13:17:14.608 -> 268, 5097, 3, 
13:17:15.586 -> 252, 5609, 3, 
13:17:16.587 -> 244, 5097, 3, 
13:17:17.597 -> 252, 5097, 3, 
13:17:18.597 -> 268, 6121, 3, 
13:17:19.619 -> 252, 5609, 3, 
13:17:20.627 -> 268, 6121, 3, 
13:17:21.632 -> 252, 7401, 3, 
13:17:22.616 -> 252, 6889, 3, 
13:17:23.622 -> 252, 6889, 3, 
13:17:24.632 -> 252, 7401, 3, 
13:17:25.618 -> 252, 7913, 3, 
13:17:26.633 -> 268, 7913, 3, 
13:17:27.620 -> 252, 8937, 3, 
13:17:28.617 -> 252, 7913, 3, 
13:17:29.622 -> 268, 7401, 3, 
13:17:30.624 -> 252, 7401, 3, 
13:17:31.641 -> 252, 7913, 3,

Ich habe vom Hersteller die entsprechende AN bekommen. Kann mir jemand dabei helfen, was ich im folgenden Code ändern muss, damit das dieser entspricht? Das wäre großartig :slight_smile:

#include <Wire.h>

int i2c_byte1;
int i2c_byte2;
int i2c_byte3;
int i2c_byte4;
int temperature;
int pressure;
int status1;

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

void loop(){

  Wire.beginTransmission(0x6C);

  Wire.write(0x2E);

  Wire.endTransmission();

  Wire.requestFrom(0x6C, 4);

  while(Wire.available() == 0);
  {
    i2c_byte1 = Wire.read();
    i2c_byte2 = Wire.read();
    i2c_byte3 = Wire.read();
    i2c_byte4 = Wire.read();
  }

  i2c_byte4 >>= 5; 
  temperature= (i2c_byte3*8) + i2c_byte4;

  pressure = 0x3fff & ((i2c_byte1 * 256) + i2c_byte2);

  status1 = i2c_byte1 >> 6;

  Serial.print(temperature);
  Serial.print(", ");
  Serial.print(pressure);
  Serial.print(", ");
  Serial.print(status1);
  Serial.println(", ");
 
  
  delay(1000);
}

40an7000 - I2C application note protocol B (SMxx91, SMxx31).pdf (1 MB)

turbofan:
Kann mir jemand dabei helfen, was ich im folgenden Code ändern muss, damit das dieser entspricht? Das wäre großartig :slight_smile:

Da steht was in der Appnote unter 6.

SCNR

lies mal 6 byte von 0x2E

zweimal hintereinander mit etwa einer Sekunde delay.
Ergebnis hier reinstellen.

Da kommt immer folgendes bei raus ...
17:00:51.640 -> 0, 0, 0, 0, 40, 89,
17:00:52.640 -> 0, 0, 0, 0, 40, 89,
17:00:53.669 -> 0, 0, 0, 0, 40, 89,
17:00:54.650 -> 0, 0, 0, 0, 40, 89,
17:00:55.669 -> 0, 0, 0, 0, 40, 89,
17:00:56.651 -> 0, 0, 0, 0, 40, 89,
17:00:57.671 -> 0, 0, 0, 0, 40, 89,
17:00:58.674 -> 0, 0, 0, 0, 40, 89,
17:00:59.668 -> 0, 0, 0, 0, 40, 89,
17:01:00.670 -> 0, 0, 0, 0, 40, 89,
17:01:01.662 -> 0, 0, 0, 0, 40, 89,
17:01:02.676 -> 0, 0, 0, 0, 40, 89,
17:01:03.670 -> 0, 0, 0, 0, 40, 89,
17:01:04.686 -> 0, 0, 0, 0, 40, 89,
17:01:05.671 -> 0, 0, 0, 0, 40, 89,
Vielen Dank schon mal für die Unterstützung.

turbofan:
Da kommt immer folgendes bei raus ...

Hast Du mal bei den benachbarten Sensoren geschaut?
Offensichtlich gibt es eine Headerdatei, die da Verwendung findet.

Ich würd mich definitiv nochmal um das Arduino-Example aus Deiner AN bemühen.

Edit:
Vielleicht auch mal hier reinsehen:https://forum.arduino.cc/index.php?topic=676687.msg4717764#msg4717764

turbofan:
Da kommt immer folgendes bei raus …
17:00:51.640 → 0, 0, 0, 0, 40, 89,

dann saug oder blas mal in eines deiner röhrl ob sich da was ändert.

Mit obigen Werten, kommt man wenig überraschend:

uint8_t value[6];
uint16_t dsp_t, dsp_s;
uint16_t status;

void setup() {
  Serial.begin(115200);

  // simulated read
  value[0]=0;  // DSP_T (Lo-Byte)
  value[1]=0;  // DSP_T (Hi-Byte)
  value[2]=0;  // DSP_S (Lo-Byte)
  value[3]=0;  // DSP_S (Hi-Byte)
  value[4]=40;  // Status (b7 - b0)
  value[5]=89;  // Status (b15 - b8)

  // calculate
  calculate();

  // output
  print_in();
  print_calc();
}

void loop() {
}

void calculate()
{
  dsp_t = value[1] << 8 | value[0];
  dsp_s = value[3] << 8 | value[2];
  status = value[5] << 8 | value[4];
}

void print_in()
{
  for (byte i; i < sizeof(value); i++)
  {
    Serial.print(i);
    Serial.print("=");
    Serial.print(value[i]);
    Serial.print("\t");
  }
  Serial.println();
}

void print_calc()
{
  Serial.print("DSP_T="); Serial.print(dsp_t);
  Serial.print("\tDSP_S="); Serial.print(dsp_s);
  Serial.print("\tStatus="); Serial.println(status, BIN);
}

auf

18:22:55.302 -> 0=0	1=0	2=0	3=0	4=40	5=89	
18:22:55.302 -> DSP_T=0	DSP_S=0	Status=101100100101000

Ich habe leider noch keine Rückmeldung bezüglich eines Beispielloses und die vorhanden Bibliotheken habe ich probiert. Kommt nichts sinnvolles bei raus. :frowning:

Wenn ich in das Röhrchen blase kommt folgendes dabei raus:

11:47:43.600 -> 233, 229, 185, 179, 24, 192, 
11:47:44.611 -> 235, 229, 115, 180, 24, 192, 
11:47:45.617 -> 233, 229, 20, 153, 24, 192,

...

DSP_T=58857 DSP_S=46009 Status=1100000000011000
0=233 1=229 2=185 3=179 4=24 5=192 
DSP_T=58857 DSP_S=46009 Status=1100000000011000

Immer noch nicht ganz sinnvoll oder interpretiere ich das falsch?