i2c probleem met arduino due.

Ik heb een due en een issue met mijn RTC eeprom combi shieldje.
als ik hem connnect via mijn uno werken ze perfect maar doe ik dit via mijn due niet meer
ik krijg in het begin perfect antwoord en dan 1 of 2 leesfouten de eerste 20 seconden.
dan de volgende 20 seconden 4 of 5 waarna hij helemaal niet meer reageert.
als dan even de usb kabel los trek doet hij het weer.

Ik weet dat de klok 4,6v nodig heeft en dat ik hem voed met maar 3,3 dus ik ben gaan zoeken naar een converter

dus ik vond er een aantal waarvan ik er diverse heb besteld.
ook zag ik de transistor versie van http://playground.arduino.cc/Main/I2CBi-directionalLevelShifter
aangezien ik wel transistoren genoeg heb liggen die direct gemaakt.
maar ook dan werkt het niet
Als ik mijn logic analyser data bekijk zie ik iets wat op data lijkt maar de logic analyser kan er geen decimalen van maken. wat hij normaal wel doet.
Hij doet het op de uno op de mega en op de due perfect (als ik de klok op 3,3v aansluit.)
nu heb ik de datalijnen dus via de transistor schakeling aangesloten de klok gevoed met 5v.
en krijg ik uberhaupt nooit meer een tijd terug.

iemand een idee want ik ben een beetje lost.

Johan

jl-p:
dus ik ben gaan zoeken naar een converter
dus ik vond er een aantal waarvan ik er diverse heb besteld.
ook zag ik de transistor versie van http://playground.arduino.cc/Main/I2CBi-directionalLevelShifter
aangezien ik wel transistoren genoeg heb liggen die direct gemaakt.
maar ook dan werkt het niet

Als ik mijn logic analyser data bekijk zie ik iets wat op data lijkt maar de logic analyser kan er geen decimalen van maken. wat hij normaal wel doet.
Hij doet het op de uno op de mega en op de due perfect (als ik de klok op 3,3v aansluit.)
nu heb ik de datalijnen dus via de transistor schakeling aangesloten de klok gevoed met 5v.
en krijg ik uberhaupt nooit meer een tijd terug.

Heb hier een gelijkaardig probleem gehad, ik gebruikte een level shifter op ebay gekocht, die met 2 stuks mosfet BSS138 was uitgerust: zoals deze:level-converter. De Due kon van geen kant de data lezen via deze level converter, ik snapte het niet meer. :angry:
Gelukkig had ik ook nog een andere level-shifter voorhanden, eentje met 4 stuks BSS138 zoals deze van ebay: level-converter en waarachtig werkte het daar wel mee.

Ik ben er niet achter gekomen waarom de ene wel en de andere niet werkte, maar blijkbaar is dat ontwerp met een BSS138 niet zo betrouwbaar of gebruiken sommige fabrikanten fets die niet aan de specificaties voldoen.

Je kunt ook gewoon de RTC module met 5 volt voeden en in de clock en data lijnen weerstandjes opnemen.
Een weerstandje van 1 k tussen de I2C pinnen van de RTC en de I2C pinnen van de Due en een 2k weerstandje tussen massa en de DUE I2C pinnen. Dat verlaagt de spanning tot (2/(2+1) ) * 5V = 3,3V. Mogelijk is dat betrouwbaarder dan een levelshifter met fets of transistors.

voor een gewone input op de DUE zal het met 2 weerstandjes prima kunnen werken maar de I2C bus is geen gewone ingang en heeft pull_up weerstanden nodig. Dus dat lukt vast niet

Een methode om de RTC-I2C bus met de DUE of een andere 3.3V processor te verbinden is om de pull-up weerstanjes op de RTC module te verwijderen. Dit is in het geval dat je een DS3231 RTC module hebt waarschijnlijk een smd weerstandnetwerkje van 4 weerstandjes van 4k7. In het geval je een DS1307 RTC module hebt zijn het soms 2 losse smd weerstandjes of soms ook een smd weerstandnetwerkje. Gewoon even met een ohmmeter zoeken (soms 3k3 soms 4k7 afhankelijk van het model).
Alle uitgangen SCL, SDA, 32kHz en INT/SQW op de DS3231 (DS op DS1307 module) zijn allemaal open drain uitgangen. d.w.z. dat ze een externe pull-up weerstand naar Vcc nodig hebben om een output-signaal te kunnen maken. Je kunt dus zonder probleem de module op 5V laten werken en de I2C bus met alleen pull-up weerstandjes, 4k7 of kleiner, aan de DUE zijde op 3.3V aangesloten. Of het goed werkt met alleen pull-ups aan de DUE zijde hangt af van de maximale lengte van de I2C bus en van het aantal aangesloten apparaten op de bus. In het geval van alleen een RTC module met een korte I2C bus zal het wel geen probleem zijn.

Maar het moet, volgens de specificaties van de DS1307 en DS3231 zonder meer mogelijk zijn deze RTC chips betrouwbaar op 3.3 volt te laten werken. Probleem kan wel de backup batterij worden. Soms is dit een CR2032 lithium batterij van 3V. Dan is er volgens mij geen probleem. Soms is dit een oplaadbare LIR2032 lithium-ion cel die een open spanning van 4,17 volt kan hebben, dit lijkt me niet goed als de RTC module op 3.3 volt werkt. In dat geval gewoon de LIR2032 vervangen door een CR2032 cel en dan is dat ook geen probleem meer.

Ik heb het zelf nog niet uit geprobeerd, geen garantie op juistheid. Ik ga het binnenkort uitproberen en zal het resultaat hier vermelden.

@ jl-p

Naar mijn mening is de wire library de oorzaak van de meeste problemen.

Heb hier wat geexperimenteerd met DUE, I2C en RTC's type DS1307 en type DS3231.
Volgens datasheet heeft de DS1307 inderdaad een voedingsspanning nodig van 4,5 tot 5,5 volt.(typical 5 volt). Dus deze RTC zal ofwel een levelconverter benodigen of je moet de 2 pullup weerstandjes op de RTC moduul weghalen. Hoewel de DS1307 moduul soms gewoon op 3.3V werkt is dit totaal onbetrouwbaar.
DS3231 doet het met een voedingsspanning tussen 2.3 en 5.5 volt (typical 3.3volt).
Deze zou in principe zonder problemen met een DUE moeten kunnen samenwerken.
Echter steeds weer problemen van een hangende SDA, die laag blijft, terwijl de SCL hoog blijft, waardoor programma hangt. Vaak werkt het maar als ik de DUE dan een paar keer reset hangt de SDA lijn. Opnieuw resetten helpt dan niet meer, dan moet ik de SDA lijn naar de RTC even losmaken, soms daarbij ook de voeding van de DUE RTC, voor de I2C weer werkt.
Ook geprobeerd met een level-converter op de DS1307 of DS3231. Beide zelfde resultaat, hangende SDA lijn.
Volgens deze topic Due I2C not working heeft de DUE problemen met I2C en de wire library.

DUE is een (beetje) teleurstellend (tot nu toe). De I2C is niet betrouwbaar en veel libraries werken pas na aanpassingen. Heb zo ook de LiquidCrystal_I2C library op enkele punten moeten aanpassen voor deze voor de DUE wilde compileren.

Hier modificatie RTC DS1307 staat een modificatie voor de Tiny RTC I2C module als deze op een CR2032 batterij werkt. Deze batterij mag namelijk niet opgeladen worden. Dit kan gevaarlijk zijn.!! Het komt neer op verwijderen van D1, R4 en R6. R6 moet een 0-ohm weerstand worden.

Ook de nieuwe library al geprobeerd?
Laatste post van jouw link:

This is a confirmed bug in the arduino Wire library:  https://github.com/arduino/Arduino/pull/1994

Specifically:

Download:

https://raw.githubusercontent.com/bluesign2k/Arduino/d8d6d62853a5308c21b95dad4bdd64e358e857cc/hardware/arduino/sam/libraries/Wire/Wire.cpp

And overwrite in your arduino installation: hardware/arduino/sam/libraries/Wire/Wire.cpp

For me, this just fixed i2c on the Due.

Other people said that it gave a compile error - I don't know why.

Toch wel vreemd dat dat punt nog niet is opgelost..... Tegelijkertijd zie je steeds meer alternatieven komen voor de 32 bitters. Heb met hulp van Jantje een board.txt en platform.txt om de Nucleo-Stm32l-l152re boards te kunnen gebruiken in de Eclipse omgeving ism. MBED. En die bordjes (met 80kb ram en 512kb flash) kosten ook nog maar iets van 13-14 euro bij conrad.
En wil je echt groot stap dan over op bijvoorbeeld een Cubieboard (dual core A7 met Linux) of vergelijkbaars

Ja ook geprobeerd om de wire.cpp in /hardware/arduino/sam/libraries/wire/wire.cpp te vervangen door deze fix.

De sketch wil daarna niet meer compileren. Dus ben die bugfix maar vergeten.

Ik heb mijn test met bevindingen incl. omschrijving hoe en welke hardware/software ik heb gebruikt in het DUE forum geplaatst. Inclusief de simpele sketch.
[code> http://forum.arduino.cc/index.php?topic=288573.0 </code]
http://forum.arduino.cc/index.php?topic=288573.0

Misschien is er ergens op deze planeet wel een helder licht die ziet dat ik het fout heb gedaan en kan die me dan vertellen hoe het wel moet :disappointed_relieved:

Probleem opgelost.

Het was geen probleem met de wire library voor de DUE maar werd veroorzaakt door een reset op het moment dat het programma 7 bytes van de RTC opvraagt.

Met een logic analyser was te zien wanneer wel en niet het probleem optrad. Dit was dus altijd tijdens de leescyclus van de RTC.

test programma zo gewijzigd dat de tijd nog maar eens per minuut (of per seconde) wordt opgevraagd. De kans op hangende I2C bus is zodoende dramatisch gereduceerd.

gebruikte code:

#include <Wire.h>
const int DS1307 = 0x68;
byte second = 0;
byte minute = 0;
byte hour = 0;
byte weekday = 0;
byte monthday = 0;
byte month = 0;
byte year = 0;
byte lastMinute = 0;
byte heart = 7;
byte lastHeartBeat = 0;
byte heartBeat =0;
byte secCount=60;
   
void setup() {
  pinMode(heart,INPUT_PULLUP);  // heartbeat input
  Wire.begin();
  Wire.beginTransmission(DS1307); //setting up heartbeat
  Wire.write(byte(0x07));  // control register DS1307
  Wire.write(byte(0x90));  // SQR 1 Hz 1001 0000 
  Wire.endTransmission();
  Serial.begin(9600);
  Serial.println("year,month,monthday,weekday,hr,min,sec");
}

void loop() {
 heartBeat = digitalRead(heart);
 if (heartBeat == 1 && lastHeartBeat == 0){  // eerste keer pollen dan
       secCount++;
     if (secCount>=60){readTime();secCount=0;}                                 // tijd uitlezen
       lastHeartBeat = 1;                          // tijd is gelezen 
     }
 else if (heartBeat == 0) {
     lastHeartBeat = 0;     // klaar om de volgende puls te lezen
  }
}

byte bcdToDec(byte val) {
  return ((val/16*10) + (val%16));
}

void readTime() {
  Wire.beginTransmission(DS1307);
  Wire.write(byte(0));
  Wire.endTransmission();
  Wire.requestFrom(DS1307, 7);
  second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read());
  weekday = bcdToDec(Wire.read());
  monthday = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
  printTime();
}

void printTime() {
  Serial.print(year);
  Serial.print("     ");
  Serial.print(month); 
  Serial.print("      ");
  Serial.print(monthday); 
  Serial.print("    ");
  Serial.print(weekday);  
  Serial.print("     ");
  Serial.print(hour);
  Serial.print("   ");
  Serial.print(minute); 
  Serial.print("   ");
  Serial.print(second);
  Serial.println(" ");
}

Twee nieuwe level converters er tussen en probleem lijkt opgelost.
Aangezien ik er 10 had besteld
meteen even allemaal geprobeerd en 9 werken perfect 1 van de nieuwe doet het ook niet lekker.
wel op een normale pin en bv mijn ultrasoon sensoren. maar i2C heeft i geen zin in

Ik heb een DS1307 gestript van alle weerstanden en ook de diode. De backup batterij direct doorverbonden met de DS1307chip, dus niet via 470k. Zonder bijladen (dat kan/mag ook helemaal niet met een lithium batterij) moet het op backup minstens een jaar kunnen blijven tikken. 5 volt voeding voor de DS1307 maar geen 5V-pullup weerstanden meer op de RTC, de pullups van de DUE (1k5) zijn genoeg en dan werkt het goed.
Zo’n levelconverter vind ik een heel gedoe met een hoop draadjes en dat probeer ik daarom te vermijden.

Mocht je trouwens soms gehinderd worden door een hangende I2C bus op de DUE (ook na een reset) wat wordt veroorzaakt door een slave die de SDA laag houdt. Dat kun je wat extra regeltjes voor in de setup op nemen.

  pinMode(21,OUTPUT);
  for (byte t=0;t<8;t++){
    digitalWrite(21,HIGH);
    delayMicroseconds(3);
    digitalWrite(21,LOW);
    delayMicroseconds(3);
  }
  pinMode(21,INPUT);
  Wire.begin();

De DS1307 slave houd de SDA , niet zo heel vaak voorkomend, laag en deze regeltjes zorgen er voor dat de slave zijn data kwijt kan.

en hoe doe ik dit voor SDA1 en SCL2 dan

jl-p:
en hoe doe ik dit voor SDA1 en SCL2 dan

Het enige wat je doet is 8 clockcycli genereren om te voorkomen dat de I2C bus soms hangt omdat een slave niet gereset wordt. Als je dit voor I2C1 wilt doen moet pin 71 i.p.v. 21 gebruiken

pinMode(71,OUTPUT);
for (byte t=0;t<8;t++){
digitalWrite(71,HIGH);
delayMicroseconds(3);
digitalWrite(71,LOW);
delayMicroseconds(3);
}
pinMode(71,INPUT);
Wire1.begin();

In de pinmapping-SAM3X tabel staat SCL1 foutief aangegeven als SCL2
70 - PA17 - SDA1 - 3 - 6
71 - PA18 - SCL2 - 15 - 9

De juiste naam is SCL1, zoals ook op het board zelf is aangegeven.
In je programma moet je de pinnummers 70/71 gebruiken en voor alle wire aanroepen Wire1 gebruiken .
Ook moet je niet vergeten om SCL1 en SDA1 pull-up weerstanden te geven omdat i.t.t. SCL/SDA deze geen onboard pullups hebben.

Thx,

Ja klopt maar enerzijds zie ik het als de tweede I2C bus
en ja het is SCL1

Maar thx. ik wist niet dat ik die ook gewoon kon doornummeren.

Johan

De DUE nummering/benaming voor I2C en I2C1 is inderdaad een beetje vreemd maar toch wel logisch want op b.v. de MEGA2560 zijn de 4 Seriele poorten met dezelfde logica benaamd.
.
De normale/standaard seriele poort heet RXD/TXD (pin 0/1) initialiseren met Serial.begin(rate).
en opvolgend Serial 1/2/3 , RX1/TX1 (pin 18/19) , RX2/TX2 (pin 17/16) en RX3/TX3 (pin 15/14), te initialiseren met Serial1.begin(rate) , Serial2.begin(rate) en Serial3.begin(rate).