Go Down

Topic: Arduino Due I2C funktioniert nicht (Read 6046 times) previous topic - next topic

pylon

Dein Testscript ist für einen 8-bit AVR Arduino geschrieben und funktioniert so auf dem Due nicht. Leider hat Arduino beim Wechsel auf den Due die Bedeutung des Rückgabewerts der Wire.endTransmission()-Methode geändert. Bei den "alten" Arduinos heisst ein Rückgabewert 0 Erfolg, alles andere bedeutet Fehler. Beim Due ist der Rückgabewert die Anzahl gesendeter Bytes.
Auch ist in der TWI-Bibliothek keine Möglichkeit vorgesehen, das ACK/NAK zu überprüfen. Somit ist ein I2C-Scanner, wie Du ihn verwendest, mit dieser Plattform und dieser Library nicht möglich.

Du kannst die Implementation abändern:

Code: [Select]
uint8_t TwoWire::endTransmission(uint8_t sendStop) {
// transmit buffer (blocking)
TWI_StartWrite(twi, txAddress, 0, 0, txBuffer[0]);
if (! TWI_WaitByteSent(twi, XMIT_TIMEOUT)) return 0;
int sent = 1;
while (sent < txBufferLength) {
TWI_WriteByte(twi, txBuffer[sent++]);
if (! TWI_WaitByteSent(twi, XMIT_TIMEOUT)) return 0;
}
TWI_Stop( twi);
if (! TWI_WaitTransferComplete(twi, XMIT_TIMEOUT)) return 0;

// empty buffer
txBufferLength = 0;

status = MASTER_IDLE;
return sent;
}


Dann kriegst Du einen Null zurück, wenn ein NAK empfangen wurde. Deinen Scanner musst Du sowieso überarbeiten, so macht er keinen Sinn, denn er testet eigentlich verschiedene Geschwindigkeiten durch, aber durch Deine Auskommentieren macht er das gar nicht mehr.


Hiermit sollte es auf dem Due funktionieren (ungetestet, nur Quick-Hack):
Code: [Select]
//
//    FILE: MultiSpeedI2CScanner.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.03
// PURPOSE: I2C scanner @different speeds
//    DATE: 2013-11-05
//     URL:
//
// Released to the public domain
//

#include <Wire.h>
#include <Arduino.h>


// DELAY BETWEEN TESTS
#define RESTORE_LATENCY  5    // for delay between tests of found devices.
bool delayFlag = false;

// MINIMIZE OUTPUT
bool printAll = true;
bool header = true;

// STATE MACHINE
enum states {
  STOP, ONCE, CONT, HELP };
states state = STOP;

uint32_t startScan;
uint32_t stopScan;

void setup()
{
  Serial.begin(115200);
  Wire.begin();
  displayHelp();
}


void loop()
{
  switch (getCommand())
  {
  case 's':
    state = ONCE;
    break;
  case 'c':
    state = CONT;
    break;
  case 'd':
    delayFlag = !delayFlag;
    Serial.print(F("<delay="));
    Serial.println(delayFlag?F("5>"):F("0>"));
    break;
  case 'e':
    // eeprom test TODO
    break;
  case 'h':
    header = !header;
    Serial.print(F("<header="));
    Serial.println(header?F("yes>"):F("no>"));
    break;
  case '?':
    state = HELP;
    break;
  case 'p':
    printAll = !printAll;
    Serial.print(F("<print="));
    Serial.println(printAll?F("all>"):F("found>"));
    break;
  case 'q':
    state = HELP;
    break;
  default:
    break;
  }

  switch(state)
  {
  case ONCE:
    I2Cscan();
    state = HELP;
    break;
  case CONT:
    I2Cscan();
    delay(1000);
    break;   
  case HELP:
    displayHelp();
    state = STOP;
    break;
  case STOP:
    break;
  default: // ignore all non commands
    break;
  }
}

char getCommand()
{
  char c = '\0';
  if (Serial.available())
  {
    c = Serial.read();
  }
  return c;
}

void displayHelp()
{
  Serial.println(F("\nArduino I2C Scanner - 0.1.03\n"));
  Serial.println(F("\ts = single scan"));
  Serial.println(F("\tc = continuous scan - 1 second delay"));
  Serial.println(F("\tq = quit continuous scan"));
  Serial.println(F("\td = toggle latency delay between successful tests."));
  Serial.println(F("\tp = toggle printAll - printFound."));
  Serial.println(F("\th = toggle header - noHeader."));
  Serial.println(F("\t? = help - this page"));
  Serial.println();
}


void I2Cscan()
{
  startScan = millis();
  uint8_t count = 0;

  // TEST
  for (uint8_t address = 0; address < 128; address++)
  {
    bool printLine = printAll;
    bool found;

      Wire.beginTransmission (address);
      found = (Wire.endTransmission () != 0);
      //delay(1);
      fnd |= found[s];
      // give device 5 millis
      if (fnd && delayFlag) delay(RESTORE_LATENCY);
    }

    if (found) count++;
    printLine |= found;

    if (printLine)
    {
      Serial.print(millis());
      Serial.print(F("\t"));
      Serial.print(address, DEC);
      Serial.print(F("\t0x"));
      Serial.print(address, HEX);
      Serial.print(F("\t"));
      Serial.println();
    }
  }

  stopScan = millis();
  if (header)
  {
    Serial.println();
    Serial.print(count);
    Serial.print(F(" devices found in "));
    Serial.print(stopScan - startScan);
    Serial.println(F(" milliseconds."));
  }
}

Thee

Hallo Pylon,

vielen Dank für die Unterstützung und die Geduld. Nun muss ich ne ganze Menge Software umschreiben. Die Teilnehmer sind auf die Art, die Du beschrieben hast erreichbar.
Viele Grüsse

Detlef


Go Up