I2c probleem tussen Arduino Due en Uno

Arduino specifieke Software
Berichten: 133
Geregistreerd: 10 Jan 2016, 16:39

I2c probleem tussen Arduino Due en Uno

Berichtdoor Nightmystic » 25 Jun 2018, 19:10

Communicatie tussen een Due en een Uno via SPI lukte niet (gaat waarschijnlijk niet vanwege het verschil in chips), maar I2c wil ook niet werken.
Serial gebruik ik liever niet voor de overdracht, in dit voorbeeld heb ik Serial enkel gebruikt om het verzenden te starten.
De sketch voor zender en ontvanger werken prima tussen twee uno's of twee mega's of een uno en een mega.
Ik heb een mogelijke oplossing gevonden, maar ik weet niet hoe ik het toe kan passen en hoop dat iemand me daarbij kan helpen.
Het probleem zit er volgens de forum.arduino.cc leden in dat de DUE de Wire.endTransmission niet accepteert.

De link naar het Arduino.cc forum topic: http://forum.arduino.cc/index.php?topic=385377.msg2947227#msg2947227

Dit stukje code:
cpp code
Wire.beginTransmission(8); 
Wire.write("1");
Wire.endTransmission();

Zou omgezet moeten worden in dit format, maar ik krijg het niet voor elkaar:
cpp code
Wire.requestFrom(FPGA_ADDRESS, 1, FPGA_REG, 1, true);


Mijn volledige code van de zender:
cpp code
#include <Wire.h>

String input = "";
boolean newData = false;

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

void loop()
{
if (Serial.available() > 0)
{
input = (char) Serial.read();
newData = true;
}

if (input == "1")
{
Wire.beginTransmission(8);
Wire.write("1");
Wire.endTransmission();
if (newData == true)
{
Serial.print("Verzonden Character: ");
Serial.println("1");
newData = false;
}
}
else if (input == "2")
{
Wire.beginTransmission(8);
Wire.write("2");
Wire.endTransmission();
if (newData == true)
{
Serial.print("Verzonden Character: ");
Serial.println("2");
newData = false;
}
}
}

De volledige code van de ontvanger:
cpp code
#include <Wire.h>

int rood = 13;
int groen = 12;
int blauw = 11;

String data = "";

void setup ()
{
Wire.begin (8);
Serial.begin(115200);
Wire.onReceive(receiveEvent);

pinMode(rood, OUTPUT);
pinMode(groen, OUTPUT);
pinMode(blauw, OUTPUT);
}

void loop()
{
if (data == "1")
{
digitalWrite(rood, HIGH);
digitalWrite(groen, LOW);
}
else if (data == "2")
{
digitalWrite(groen, HIGH);
digitalWrite(rood, LOW);
}
}

void receiveEvent(int howMany)
{
data = "";
while( Wire.available())
{
data += (char)Wire.read();
}
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor Koepel » 27 Jun 2018, 20:09

Je vraag begrijp ik niet.
Die link naar het forum or arduino.cc is nogal verwarrend, let daar maar niet op. Let vooral niet op die ongedocumenteerde functie.
Ik kan voor je opschrijven wat mij opvalt, misschien kun je er iets mee.

Je schrijft over SPI, maar het gaat over I2C.
De Master is waarschijnlijk de Due en de Slave een Arduino Uno.
Je wilt een Wire.requestFrom() doen, maar ik weet niet hoe of wat.
De Arduino Due is een 3.3V board en de Arduino Uno is een 5V board, je hebt een I2C level shifter nodig.
De Arduino Due heeft een ontwerp fout, er zitten volgens het schema pullup weerstanden van 1k5 op de SDA en SCL pinnen. In de praktijk zitten er vaak zelfs 1k weerstanden, dat is nog slechter. Gebruik liever SDA1 en SCL1 en zet er zelf pullup weerstanden van 10k op.
De Wire library voor de Arduino Due heeft misschien een bug. Het is beter om na een Wire.endTransmission() een delay(1) te doen voordat een Wire.requestFrom() wordt aangeroepen.
De Wire library voor de Arduino Due heeft misschien nog een bug als de Due als Slave staat. Kijk in receiveEvent() altijd of er überhaupt data is. Is het aantal ontvangen bytes nul, doe dat niets.
Je gebruikt een String object in een interrupt functie (de receiveEvent wordt aangeroepen vanuit een interrupt). Dat geeft problemen. Over het algemeen wordt nooit leesbare tekst over I2C verstuurd, maar binaire data.

De Due wordt steeds minder gebruikt. De nieuwe boarden zijn allemaal SAMD21 met de M0+ processor.

Berichten: 133
Geregistreerd: 10 Jan 2016, 16:39

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor Nightmystic » 29 Jun 2018, 19:55

Bedankt voor je reactie. :D

De vraag gaat nu over I2c idd. SPI lukte niet en volgens bepaalde informatie zal SPI nooit gaan werken vanwege het verschil in chips tussen een DUE en een UNO, vandaar dat ik over gegaan ben op I2c.

Ik heb de level shifter aangesloten, 10k pull up weerstanden aangesloten, SDA1 en SCL1 gebruikt en aangesproken met de code wire1 in plaats van wire.
In plaats van een character verstuur ik nu een integer.
Helaas wil het nog niet werken.

De globale vraag zou zijn, hoe maak ik I2c communicatie mogelijk tussen een DUE en een UNO.

Op het Arduino.cc forum (waarvan je zegt dat ik er beter niet naar kan kijken) wordt beweerd dat de communicatie niet werkt omdat de DUE blokkeert door onderstaande code:

Code: Alles selecteren
Wire.beginTransmission(8);
Wire.write("1");
Wire.endTransmission();


endtransmission zou niet worden geaccepteerd door de DUE.

De oplossing die ze aandragen is om een wire.requestfrom te gebruiken in plaats van begintransmission, write en endtransmission.

Zoals:
Code: Alles selecteren
Wire.requestFrom(FPGA_ADDRESS, 1, FPGA_REG, 1, true);


Aangezien ik niet snap hoe ik FPGA_REG in moet vullen zodat het kan gaan werken met mijn code, krijg ik de DUE niet aan het communiceren met de UNO.

Komt mijn vraag/bedoeling nu beter over?

Berichten: 133
Geregistreerd: 10 Jan 2016, 16:39

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor Nightmystic » 29 Jun 2018, 19:57

Zender code (due):
cpp code
#include <Wire.h>

String input = "";
boolean newData = false;

int x=1;
int y=2;

void setup()
{
Wire1.begin(8);
Serial.begin(115200);
}

void loop()
{
if (Serial.available() > 0)
{
input = (char) Serial.read();
newData = true;
}

if (input == "1")
{
Wire1.beginTransmission(8);
Wire1.write(x);
Wire1.endTransmission();
delay(1);
if (newData == true)
{
Serial.print("Verzonden Character: ");
Serial.println("1");
newData = false;
}
}
else if (input == "2")
{
Wire1.beginTransmission(8);
Wire1.write(y);
Wire1.endTransmission();
delay(1);
if (newData == true)
{
Serial.print("Verzonden Character: ");
Serial.println("2");
newData = false;
}
}
}


Ontvanger code (uno):
cpp code
#include <Wire.h>

int rood = 13;
int groen = 12;
int blauw = 11;

//String data = "";
int data;

void setup ()
{
Wire.begin (8);
Serial.begin(115200);
Wire.onReceive(receiveEvent);

pinMode(rood, OUTPUT);
pinMode(groen, OUTPUT);
pinMode(blauw, OUTPUT);
}

void loop()
{
if (data == 1)
{
digitalWrite(rood, HIGH);
digitalWrite(groen, LOW);
}
else if (data == 2)
{
digitalWrite(groen, HIGH);
digitalWrite(rood, LOW);
}
}

void receiveEvent(int howMany)
{
//data = "";
data;
while( Wire.available())
{
//data += (char)Wire.read();
data = Wire.read();
}
}

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor Koepel » 29 Jun 2018, 21:53

Kijk gerust op http://forum.arduino.cc/, maar dat verhaal dat er iets met de Wire.endTransmission op Due niet zou werken en vervangen zou moeten worden door Wire.requestFrom, dat is complete nonsense :evil:

Je Due en Uno zijn allebei een Slave op I2C address 8, dat mag niet.
In de Uno receiveEvent() staat er zomaar de regel: "data;"

Het lijkt me beter om even helemaal van vooraf aan te beginnen.
Laat de Slave zoals het is, of kies deze code:
Code: Alles selecteren
#include <Wire.h>

void setup()
{
  Wire.begin( 8);
}

void loop()
{
}


Draai op de Due de I2C Scanner: https://playground.arduino.cc/Main/I2cScanner.
Als het goed is wordt de Slave herkend.
Wanneer dat niet werkt, dan werkt je I2C bus niet eens.

Werkt dat wel, doe dan een heel klein stapje meer. Dus zo klein en algemeen en ongecompliceerd mogelijk.

Due (een deel van de sketch)
Code: Alles selecteren
byte count = 10;

void setup()
{
  Wire1.begin();     
  Serial.begin(115200);
}
 
void loop()
{
  Wire1.beginTransmission( 8);
  Wire1.write( count);
  Wire1.endTransmission();

  count++;

  delay( 1000);
}


Uno (een deel van de sketch)
Code: Alles selecteren
volatile byte data;

...

void loop()
{
  if (data != 0)   // ugly, the data is ignored when it is zero.
  {
    Serial.println( data);
    data = 0;
  }
}
 
void receiveEvent( int howMany)
{
  if( howMany == 1)
  {
    data = Wire.read();
  }
}


Wil jij steeds je hele sketch laten zien ? Dat is gemakkelijker voor mij. Ik laat uit gemakzucht hierboven alleen de stukjes zien die er toe doen.

Berichten: 133
Geregistreerd: 10 Jan 2016, 16:39

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor Nightmystic » 30 Jun 2018, 12:20

Is goed, ga ik doen. Dankjewel.

Berichten: 4064
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor shooter » 02 Jul 2018, 19:53

of gebruik easytransfer.
paul deelen
shooter@home.nl

Berichten: 133
Geregistreerd: 10 Jan 2016, 16:39

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor Nightmystic » 05 Jul 2018, 20:01

Shooter, wat is easytransfer?

Berichten: 133
Geregistreerd: 10 Jan 2016, 16:39

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor Nightmystic » 05 Jul 2018, 20:04

Ik heb de code gebruikt van de volgende link : https://www.arduino.cc/en/Tutorial/MasterWriter
Level shifter zit ertussen, pull ups van 10k op de lijnen en hij verstuurd en ontvangt! :D
Thanks Koepel!!!

Dit is de output in de Serial monitor:
-1
x 105
97
-1
x120
115
x 105
101
-1
x120
115
120
-1
-1
-1
120
-1
107
120
xx 105

De tekst komt niet goed door zoals je ziet. Er zou "X is" moeten staan.

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: I2c probleem tussen Arduino Due en Uno

Berichtdoor Koepel » 05 Jul 2018, 21:05

Er bestaat een EasyTransfer I2C library.
https://github.com/madsci1016/Arduino-EasyTransfer.
Voor zover ik me kan herinneren kan die alleen gegevens versturen van de Master naar de Slave.

Er bestaat ook I2C_Anything.
http://www.gammon.com.au/forum/?id=10896&reply=8#reply8.
Dat kun je gebruiken om elk soort variabele over te sturen, ongeacht hoeveel bytes dat is.
Mijn voorkeur heeft I2C_Anything.

Iets vergelijkbaars als I2C_Anything zou ik zelf willen maken. Maar algemene code voor de Slave schrijven is lastig. Het staat al wel bij mijn wensen-lijstje: https://github.com/Koepel/CommonSensorClass/blob/master/CommonSensorClass.h.

@Nightmystic, wanneer je schrijft dat er "X is" zou moeten staan, dan kan ik daar helemaal niets mee :cry:
Laat twee volledige en werkende sketchen zien. Wie weet, misschien is het nodig om hier en daar nog wat bij te schaven.
Zit je nog steeds dingen te versturen vanuit een interrupt routine :o

Volgende

Terug naar Arduino software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 13 gasten