Go Down

Topic: ATINY85 als I2C Slaves - unzuverlässige Kommunikation  (Read 1 time) previous topic - next topic

benjARRRGHmin

Hallo,

ich kämpfe nun seit einigen Tagen mit folgenden Problem:

Für eine Messanwendung sollen mehrere gleiche Sensoren (1x Temperatur - 1x Kapazität) per I2C angesprochen werden.
Leider besitzen diese Sensoren eine fixe I2C Adresse.

Um eine individuelle Abfrage der Messwerte zu bewerkstelligen, sitz vor jedem dieser Sensoren ein ATTiny85.
Dieser fungiert als I2C Slave und schaltet den jeweilg zugehörigen Sensor ein oder aus.
Somit lassen sich alle Sensoren individuell abfragen. Soviel zu Theorie...

Leider funktioniert dies nur sehr unzuverlässig. Teilweise sind die ATTinys nicht erreichbar, teilweise schalten sie die zugehörigen Sensoren nicht ein oder aus. Dann wird mal nur die Temperatur gemessen, die Kapazität liefert irgendeinen Wert.

Hier meine Code Schnipsel:
ATTINY85 Slave
Code: [Select]

#include <TinyWireS.h>

#define output 1
#define I2C_SLAVE_ADDR 10

void setup() {
  TinyWireS.begin(I2C_SLAVE_ADDR);
  pinMode(output, OUTPUT);
}

void loop(){
  byte msg = 0;
  if (TinyWireS.available()){           
    msg = TinyWireS.receive();     
     
      switch (msg) {
        case 'a':
          digitalWrite(output, HIGH);
        break;
        case 'b':
          digitalWrite(output, LOW);
        break;
      }
  }
}


Master (in diesem Fall Arduino Pro Mini 5V/16Mhz)
Code: [Select]

...

bool switchSensor(int address_sensor, bool OnOff) {
    Wire.beginTransmission(address_sensor);
    if (OnOff == true){
      Wire.write('a');
    } else if (OnOff == false){
      Wire.write('b');
    }
    Wire.endTransmission();
    delay(300);
}

//-----------------------------------------------------------------------------------------------

float getDataMCP9808(int address_mcp9808) {
  uint16_t val;
  Wire.beginTransmission(address_mcp9808);
  Wire.write((uint8_t)0x05);
  Wire.endTransmission();
 
  Wire.requestFrom((uint8_t)address_mcp9808, (uint8_t)2);
  val = Wire.read();
  val <<= 8;
  val |= Wire.read(); 
 
  float temp = val & 0x0FFF;
  temp /=  16.0;
  if (val & 0x1000) temp -= 256;
  return temp;
}

//-----------------------------------------------------------------------------------------------

float getDataFDC1004(int address_fdc1004) {
    //Set CONF_MEAS1 0x08
    //CHA = CIN1 / CHB = dis / CAPDAC = 0
    //MSB first!
    //0001 1100 0000 0000 = 0x1c00
    Wire.beginTransmission(address_fdc1004);
    //Reg 0x08
    Wire.write(0x08);
    //MSB
    Wire.write(0x1c);
    //LSB
    Wire.write(0x00);
    Wire.endTransmission();
    delay(1);

    //SET FDC_Conf 0x0c
    //Reset = 0 / Rate = 100s/s / Repeat = 0 / Meas 1 enable
    //MSB first!
    //0000 0100 1000 0000 = 0x0480
    Wire.beginTransmission(address_fdc1004);
    //Reg 0x0c
    Wire.write(0x0c);
    //MSB
    Wire.write(0x04);
    //LSB
    Wire.write(0x80);
    Wire.endTransmission();
    delay(50);
  /*
    //? Check if measurement is done?
    Wire.beginTransmission(address_fdc1004);
    Wire.write(0x0c);
    Wire.endTransmission();
    Wire.requestFrom(address_fdc1004, 2);
    byte checkLSB=Wire.read();
    byte checkMSB=Wire.read();
    delay(1);

        Serial.print("FDC1004 Reg 0x0c: ");
        Serial.print(checkLSB);
        Serial.print(", ");
        Serial.println(checkMSB);
  */

    Wire.beginTransmission(address_fdc1004);
    Wire.write(0x00);
    Wire.endTransmission();
    Wire.requestFrom(address_fdc1004, 2);
    byte c1LSB=Wire.read();
    byte c1MSB=Wire.read();
    delay(1);

    Wire.beginTransmission(address_fdc1004);
    Wire.write(0x01);
    Wire.endTransmission();
    Wire.requestFrom(address_fdc1004, 2);
    byte c2LSB=Wire.read();
    byte c2MSB=Wire.read();
    delay(1);

    uint32_t meas = ((((c1LSB << 8) | c1MSB) << 8) | c2LSB);
    Serial.println(meas, BIN);
    float cap = meas / pow(2.0, 19.0);

    return cap;
}

...

void loop()
{

  //-----------------------------------------------------------------------------------------------
 
  #ifdef ECHO_TO_SERIAL
    Serial.println("Measuring...");
  #endif

  //-----------------------------------------------------------------------------------------------
  //Reading Sensor

  //Switch on I2C LIne
  pinMode(I2CPOWA, OUTPUT);
  digitalWrite(I2CPOWA, HIGH);
  delay(500);

  //-----------------------------------------------------------------------------------------------
  //Read Sensor 1
  //Switch ON Sensor
  switchSensor(Cap_Sensor_1, true);

    //Reading Temp.- Sensor
    float sens1_tempMCP9808=getDataMCP9808(MCP9808_Sensor);
      #ifdef ECHO_TO_SERIAL
        Serial.print("Sens1 t [C]: " );
        Serial.println(sens1_tempMCP9808);
      #endif

    //Reading Cap Sensor
    float sens1_capFDC1004=getDataFDC1004(FDC1004_Sensor);
      #ifdef ECHO_TO_SERIAL
        Serial.print("Sens1 C [pF]: " );
        Serial.println(sens1_capFDC1004, 4);
      #endif

  //Switch OFF Sensor
  switchSensor(Cap_Sensor_1, false);

 
  digitalWrite(I2CPOWA, LOW);
  delay(3000);
}


Habe auch schon unterschiedliche TinyWireS Libarys getestet. Momentan ist's die von "rambo".
Ich vermute ein Zeitproblem...

Hoffe ihr könnt mir helfen - danke schonmal!

Grüße B

combie

Tipp:
TCA9548A


Quote
Ich vermute ein Zeitproblem...
Und vermute, dass dir die abgeschalteten Dinger den Bus runter ziehen.
Ein Oszi würde dir das bestätigen.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

benjARRRGHmin

Danke für den Tipp, kannleider aus Platzgründen nicht verwendet werden.
Die Messeinheiten (Also Attiny und die zwei Sensoren) befinden sich in einem Strang hintereinander - mehr als 4 Leitungen für das I2C sind nicht möglich.

combie

Ja, dann.... (solltest du dein Konzept evtl nochmal überdenken)
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

HotSystems

Danke für den Tipp, kannleider aus Platzgründen nicht verwendet werden.
Die Messeinheiten (Also Attiny und die zwei Sensoren) befinden sich in einem Strang hintereinander - mehr als 4 Leitungen für das I2C sind nicht möglich.
Dann frage ich doch mal....wie lang ist dein Strang (Kabel) zu den einzelnen Attiny ?
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

benjARRRGHmin

Der Strang ist insgesamt 320mm lang. GLaube demnach nicht, dass es an der Länge liegen kann.
Die Zuleitung ist ein geschirmtes 4-poliges Kabel.
Der ATTiny lauft mit den internen 8Mhz, wie laut der TinyWireS Lib vorgeschalgen wird.

HotSystems

Der Strang ist insgesamt 320mm lang. GLaube demnach nicht, dass es an der Länge liegen kann.
Die Zuleitung ist ein geschirmtes 4-poliges Kabel.
Der ATTiny lauft mit den internen 8Mhz, wie laut der TinyWireS Lib vorgeschalgen wird.
Ok....die Länge alleine ist wohl nicht das Problem.
Hast du am I2C Pullups dran ?
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

benjARRRGHmin

Jop. 10K jeweils.
Wurde auch mit einen RPi getestet: Eine zeitlang lassen sich die Werte auslesen, dann beginnts zu stocken und dann kommt es zu Lese-/Schreibefehlern am Bus.

HotSystems

Jop. 10K jeweils.
Wurde auch mit einen RPi getestet: Eine zeitlang lassen sich die Werte auslesen, dann beginnts zu stocken und dann kommt es zu Lese-/Schreibefehlern am Bus.
Ich sehe in deinem Slave-Sketch nicht, wie du die Sensoren ansprichst.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

agmue

Wie viele ATtinys sind an einem Bus angeschlossen?
Wahnsinn und Verstand trennt nur eine dünne Wand. (Daniel Düsentrieb)

benjARRRGHmin

Die Sensoren werden in diesem SInne nicht angesprochen.
Lediglich durch den Attiny über Pin 1 Ein-bzw. Ausgeschaltet.

Zum Testen ist's nur einer, hab das aber auch schon mit 3 probiert.

HotSystems

#11
Jul 20, 2018, 02:04 pm Last Edit: Jul 20, 2018, 02:05 pm by HotSystems
Ups.....das hatte ich überlesen.
Du schaltest die Spannung der Sensoren und lässt die auf dem I2C-Bus drauf ?
Das muss in die Hose gehen.....das hat auch combie schon geschrieben.


Du kannst nicht einfach Die Spannung wegnehmen und meinen, das ist ok so.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

Tommy56

Wie schaltest Du die Sensoren ab und welche Sensoren (Link) sind das?

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

HotSystems

#13
Jul 20, 2018, 02:09 pm Last Edit: Jul 20, 2018, 02:15 pm by HotSystems
Dann lies dir mal Post#3 durch und halte dich daran.

Edit:
Du könntest den ATtiny über I2C auffordern, den Sensor auszulesen und die Daten an den Master übertragen.
Aber Achtung. Das ist Multimaster.
Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

benjARRRGHmin

#14
Jul 20, 2018, 02:15 pm Last Edit: Jul 23, 2018, 09:58 am by benjARRRGHmin
Mir ist schon klar, das die Ein- und Ausschalterei nicht ganz optimal ist.
Leider bin ich platztechnisch ziemlich begrenzt und muss das in einem Strang verlaufen lassen.

Zu den Sensoren:

MCP9808
FDC1004

Edit:
@HotSystems: sowas in der Art hab ich mir auch schon gedacht.

Go Up