Mega 2560 / Pin 52 (SCK) im Setup auf GND ziehen.

Hallo,

ich benötige für einige ms im Setup einen SCK (Pin52) Low-Pegel.
Danach soll der Pegel wieder normal sein und per I2C genutzt werden.
Letztere funktioniert bereits.

Frage; kann ich den Pin 52 als ganz normalen Pin auf Low setzen, danach einige ms abwarten und dann als SCK nutzen?
Wenn ja; muß der Pin dann irgendwie umdefiniert werden oder soll ich auf high setzen oder macht das die i2cmaster-library oder???

Hallo,

meinst du mit SCK den Clock vom SPI Modus? Nutzt du den SPI Modus?
Oder meinst du nur damit die Pin Bezeichung?
Nutzt du Software I2C auf dem Pin 52?
Du hast doch an Pin 20,21 Hardware I2C.
Am besten du zeigst mal den Sketch.

Hi, der Sketch hat fast 30 Din A 4 Seiten.

Ich nutze den I2C Bus mit <i2cmaster.h> für die MXL90614 Infrarot-Temperatursensoren. Die brauchen beim Start auf dem SCK einen Low-Pegel, ansonsten kommt ein PWM Signal statt Daten.

SPI (20-21) kommuniziert mit drei weiteren Arduinos und Serial - Serial2 sind bereits belegt.

Ich würde den Sensor einmal umprogrammieren, damit er gleich im SMBus-Modus startet, statt im PWM Modus (factory default). Sonst könnten ggf. andere I2C Slaves durcheinanderkommen, wenn SCK anders angesteuert wird als erwartet.

Hallo,

solange ich nicht durchblicke kann ich nicht gezielt helfen.
Auch mit deiner Antwort komme ich nicht klar.

Serial.0 ... Pin 0/1
Serial.1 ... Pin 18/19
Serial.2 ... Pin 16/17
Serial.3 ... Pin 14/15
I2C ... Pin 20/21

Wo liegt das Problem?

Du kannst natürlich im setup kurzzeitig den Pegel wechseln. Ob das zulässig ist hat Dr. schon angezweifelt. Du musst wissen was du machst.

@ DrDittrich
Ja, das mit dem Umprogrammieren des Sensors war schon mal ein Post von mir. Hat aber zu nichts geführt.
Ist anscheinend nur machbar, wenn der SCL beim Start für einige ms auf Low ist.
Ist der SCL beim Einschalten auf High wird automatisch auf PWM umgeschaltet und der Bus/Arduino friert ein :frowning:
Und genau das muss ich verhindern!

Ich habe das Problem so gelöst, daß ich am Stecker den SCL Pin um 2 mm gekürzt habe.
Steckt man den ein startet der MXL nicht mit PWM.
Aber wehe man vergisst den Stecker und startet am nächsten Morgen neu, dann geht nix mehr.
Erst alles abschalten, Stecker mit dem MXL raus, neu starten und MXL wieder einstecken.

Nach dem Data Sheet 7.6.3 sollte die dauerhafte Umprogrammierung funktionieren. Dann sollte nicht einmal ein Request (SCL low) geschickt werden. Ich würde das jedenfalls nochmal versuchen.

Hmmm, in meinem Datasheet gibt's nur ein 7.1 und 7.2
Außerdem brauche ich das in C oder gleich als ino.
Selber kriege ich das nicht hin ;-(

Mein Datenblatt von Sparkfun ist von 2006. Vielleicht solltest Du Dir das mal besorgen, wenn in Deinem wesentliche Teile fehlen?

Wichtig erscheint mir, daß die Daten ins EEPROM geschrieben werden, nicht in das Register. Dafür sind Opcodes 001x xxxx vorgesehen, also 0010 0010 (0x22) für das PWMCTRL Byte. Dort sollte man dann zwei Nullbytes reinschreiben. Und dann noch das PEC Byte mit der Checksum (hier: 0x01).

Ich habe schon etliche MXL verwendet, hatte dieses Problem aber noch nie.
Kann ich das mit dem Programm machen mit dem man die Adresse ändert?

//#include <i2cmaster.h>
// Pins:  Mega: SDA:D20 SCL:D21
// andere SDL und SDA abziehen!!!

//byte MLXAddr = 0x5A<<1 ;           //  MLX90614  Default address
byte MLXAddr = 0x0A<<1 ;           // weitere address
//byte MLXAddr = 0xB4<<1 ;           // New Address: Change this value to wathever you want the new adress of the MLX to be.
//  #######   Wunschadresse


void setup(){
  Serial.begin(57600);
  Serial.println("Setup...");
 
  i2c_init();                                // Initialise the i2c bus
  //PORTC = (1 << PORTC4) | (1 << PORTC5);   // Enable pullups resistors (uncomment for std arduinos)
  //PORTD = (1 << PORTD1) | (1 << PORTD0);     // Enable pullups resistors (uncomment for arduino MEGA)
 
delay(1000);                    // Wait to allow serial connection
  ReadAddr(0);                    // Read current address bytes
  ChangeAddr(MLXAddr>>1, 0x00);   // Change address to new value
  
  ReadAddr(0);                    // Read address bytes
  Serial.println("MLX von 3,3 - 5 V trennen! You have 5 seconds.");
  delay(5000);                    // Cycle power to MLX during this pause

  Serial.println("wieder Anschliessen!");
  delay(2000);                     // Additionnal delay buffer
  Serial.println("Testing temperature reading on universal address.");
  
  ReadTemp(0);                    // Read temperature using default address
  Serial.println("Testing temperature reading on new address.");
  ReadTemp(MLXAddr);              // Read temperature using new address
  Serial.println("Done");
  
}

void loop(){
  delay(1000);                    // wait a second
  ReadTemp(MLXAddr);              // Read temperature using new address
}


word ChangeAddr(byte NewAddr1, byte NewAddr2) {

  Serial.println("> Change address");

  i2c_start_wait(0 + I2C_WRITE);    //send start condition and write bit
  i2c_write(0x2E);                  //send command for device to return address
  i2c_write(0x00);                  // send low byte zero to erase
  i2c_write(0x00);                  //send high byte zero to erase
  if (i2c_write(0x6F) == 0) {
    i2c_stop();                     //Release bus, end transaction
    Serial.println("  Data erased.");
  }
  else {
    i2c_stop();                     //Release bus, end transaction
    Serial.println("  Failed to erase data");
    return -1;
  }

  Serial.print("  Writing data: ");
  Serial.print(NewAddr1, HEX);
  Serial.print(", ");
  Serial.println(NewAddr2, HEX);

  for (int a = 0; a != 256; a++) {
    i2c_start_wait(0 + I2C_WRITE);  //send start condition and write bit
    i2c_write(0x2E);                //send command for device to return address
    i2c_write(NewAddr1);            // send low byte zero to erase
    i2c_write(NewAddr2);            //send high byte zero to erase
    if (i2c_write(a) == 0) {
      i2c_stop();                   //Release bus, end transaction
      delay(100);                   // then wait 10ms
      Serial.print("Found correct CRC: 0x");
      Serial.println(a, HEX);
      return a;
    }
  }
  i2c_stop();                       //Release bus, end transaction
  Serial.println("Correct CRC not found");
  return -1;
}

void ReadAddr(byte Address) {

  Serial.println("> Read address");

  Serial.print("  MLX address: ");
  Serial.print(Address, HEX);
  Serial.print(", Data: ");

  i2c_start_wait(Address + I2C_WRITE);  //send start condition and write bit
  i2c_write(0x2E);                  //send command for device to return address
  i2c_rep_start(Address + I2C_READ);
 
  Serial.print(i2c_readAck(), HEX); //Read 1 byte and then send ack
  Serial.print(", ");
  Serial.print(i2c_readAck(), HEX); //Read 1 byte and then send ack
  Serial.print(", ");
  Serial.println(i2c_readNak(), HEX);
  i2c_stop();
}

float ReadTemp(byte Address) {
  int data_low = 0;
  int data_high = 0;
  int pec = 0;

  Serial.println("> Read temperature");

  Serial.print("  MLX address: ");
  Serial.print(Address, HEX);
  Serial.print(", ");

  i2c_start_wait(Address + I2C_WRITE);
  i2c_write(0x07);                  // Address of temp bytes
 
  // read
  i2c_rep_start(Address + I2C_READ);
  data_low = i2c_readAck();         //Read 1 byte and then send ack
  data_high = i2c_readAck();        //Read 1 byte and then send ack
  pec = i2c_readNak();
  i2c_stop();
 
  //This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps
  float Temperature = 0x0000;       // zero out the data
 
  // This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.
  Temperature = (float)(((data_high & 0x007F) << 8) + data_low);
  Temperature = (Temperature * 0.02) - 273.16;
 
  Serial.print(Temperature);
  Serial.println(" C");
  return Temperature;
}

Der Code für die Checksum ist ja furchtbar :frowning:

Im Prinzip kann man den Code auch für andere EEPROM Adressen verwenden, wenn man das Kommando-Byte auch noch als Parameter übergibt. Ob allerdings die I2C Adresse 0 dafür zulässig ist, kann ich nicht sagen, dafür sollte eigentlich die richtige (eingestellte) Adresse verwendet werden, statt eines Broadcast (Adresse 0). Dir ist klar, daß obiges Programm (wegen Broadcast) nur funktioniert, wenn genau 1 I2C Slave angeschlossen ist?

Hmmm, das scheint zu einer Doktorarbeit zu werden. So viel Zeit habe ich momentan nicht.
Dann muss ich zurück zu meiner ursprünglichen Frage. Kann ich den SCK Pin beim Start im Setup irgendwie auf GND runterziehen? Wenn ja, wie? Ich kann nur Pin 52 dafür nutzen, oder einen anderen Digitalpin? Auch nicht die Pins 14-21

Hallo,

dann scheinst du ja wirklich den Code nur zusammen kopiert zu haben. Sonst könntest du die erlernten Basics mit pinmode und digitalwrite anwenden.

Rubbernose:
Dann muss ich zurück zu meiner ursprünglichen Frage.

Rubbernose:
Ich nutze den I2C Bus mit <i2cmaster.h> für die MXL90614 Infrarot-Temperatursensoren. Die brauchen beim Start auf dem SCK einen Low-Pegel, ansonsten kommt ein PWM Signal statt Daten.

SPI (20-21) kommuniziert mit drei weiteren Arduinos und Serial - Serial2 sind bereits belegt.

Nach meinem Kenntnisstand ist das falsch, denn SCK und I2C passen nicht zusammen. Mein Schaltbild vom Mega2560 zeigt

20 - SDA von I2C
21 - SCL von I2C
50 - MISO von SPI
51 - MOSI von SPI
52 - SCK von SPI
53 - SS von SPI

Das hatte Doc_Arduino bereits festgestellt. Was meinst Du tatsächlich?

Im Code stehen die Pins 20 und 21 für SDA und SCL. Das SPI ist wohl ein Flüchtigkeitsfehler.

Da der Sensor tatsächich I2C benutzt, erübrigt sich dieser Teil der Diskussion.

DrDiettrich:
Im Code ...

Ich sehe keinen Code. Der Code in #9 hat mit der ursprünglichen und jetzt wieder aktuellen Fragestellung nichts zu tun, oder?

DrDiettrich:
Das SPI ist wohl ein Flüchtigkeitsfehler.

In der Überschrift steht "Mega 2560 / Pin 52 (SCK)" und das ist SPI. Das ist ja genau die Frage: Redet der TO über Pin 52 - SCK - SPI oder Pin 21 - SCL - I2C? Denn Pin 52 - SCK zusammen mit einem I2C-Sensor ergibt für mich keinen Sinn.

Wenn Du ihn aber verstehst und helfen kannst, will ich mich gerne raus halten, viel Erfolg :slight_smile:

Eben, Pin 52 und 50 werden für I2C genutzt und den Pin 52 muss ich runter ziehen. Geht das oder mach ich was kaputt wenn ich den im Setup als digital out definiere und auf null setzen? Anschließend muss ich den allerdings wieder als SCK nutzen können.

Rubbernose:
Eben, Pin 52 und 50 werden für I2C genutzt und den Pin 52 muss ich runter ziehen. Geht das oder mach ich was kaputt wenn ich den im Setup als digital out definiere und auf null setzen? Anschließend muss ich den allerdings wieder als SCK nutzen können.

Warum probierst du es nicht einfach.

Am Labortisch kannst du es testen und messen und machst nichts kaputt.
Wenn du es vor der Nutzung des I2C machst, sollte def. nichts passieren.

Rubbernose:
Eben, Pin 52 und 50 werden für I2C genutzt und den Pin 52 muss ich runter ziehen.

Dann liegst Du tatsächlich völlig daneben, und kannst so nchts zum Laufen kriegen - diese Pins sind für SPI, nicht für I2C.

Rubbernose:
Ich habe schon etliche MXL verwendet, hatte dieses Problem aber noch nie.

Wie hattest Du die denn angeschlossen?

Hallo,

letzte Chance.
Verwechselst du absichtlich I2C mit SPI um uns zu verwirren? :o
In deinem Code von #9 ist nirgends erkennbar das du die SPI Schnittstelle an Pin 50-53 verwendest.
Nur I2C an Pin 20 und 21.
Also was zur Hölle willst mit Pin 50-53 machen? Was hängt dort dran?
Wenn du SPI nicht verwendest, dann kannste mit den Pins machen was du möchtest.
Nur passt das alles nicht zur Frage.

Sammel und sortiere deine Gedanken. Mach zur Not einen Schaltplan.