Go Down

Topic: I2C - Arduino als Slave (Read 4760 times) previous topic - next topic

sarah_gru

#30
Aug 07, 2018, 02:27 pm Last Edit: Aug 07, 2018, 02:38 pm by sarah_gru
Ich habe einen Mega2560 (egal, ein Arduino eben) als Master an einen Uhrenbaustein DS3231 als Slave angeschlossen und lese die Uhrzeit und Datum als sieben Bytes. Sieht dann so aus:



Die 100kHz ist der Takt bei SCL, den der Master generiert. Das muß bei Dir der Stellantrieb liefern.
USB und I2C geht gleichzeitig (die Uhrzeit zeige ich mit dem seriellen Monitor über USB an), aber irgendein Programm muß auf dem Arduino schon laufen. Wüßte nicht, wie es sonst funktionieren sollte.

Okey perfekt danke :)
Ich sitze jetzt über dem Programm, dass eben etwas auf den Arduino geschrieben wird.
Ich muss dann ja angeben, worauf ich den Wert schreiben will (also auf welchem Pin). Schreib ich das dann auf meine Digitalen I/O oder direkt auf die SDA Leitung? Weil die hat ja eigentlich nur was mit I2C zu tun und nicht damit, die Daten auf den Arduino zu bringen :smiley-slim:
Ich könnte die Daten auch über den Baustein Serial Write Bytes schreiben, jedoch müsste ich hier ein Interface angeben - was ist damit gemeint oder funktioniert das grundsätzlich nicht?



Es wird langsam Zeit, daß Du Links auf die benötigte(n) LabView-für-Arduino Bibliothek(en) lieferst. Die müssen dann mit der I2C Bibliothek in einen Sketch gepackt werden, damit LabView über USB und der Stellantrieb über I2C mit dem Arduino kommunizieren können.
Das hier ist das Zusatzpaket für Arduino bei LabVIEW :)
http://sine.ni.com/nips/cds/view/p/lang/de/nid/213629
Ich habe diesen Download dann entpackt und in meinem LabVIEW-Ordner abgespeichert. Ich kann die Bausteine jetzt eben in LabVIEW selbst gleich aufrufen. Meinst du das mit in einen Sketch packen? :)

DrDiettrich

Nein, dazu muß irgendwie noch Arduino Sourcecode gehören.

agmue

Vorbemerkung: Ich kenne LabView nicht.

Ich muss dann ja angeben, worauf ich den Wert schreiben will (also auf welchem Pin).
Ich kenne Animationsprogramme, wo der PC eine Animation für LEDs berechnet. Die Helligkeitswerte der LEDs werden dann per USB in Variablen auf dem Arduino übertragen. Der Arduino nimmt dann diese Werte und schiebt sie zu den LEDs raus.

Meine analoge Vorstellung: LabView überträgt Werte, die eigentlich der Sensor erfaßt, mittels USB zum Arduino. Der speichert sie, bis der I2C-Master danach fragt und übermittelt sie dann zum Master. Ziel wären dann Arduino-Variablen, die Register.

Alternativ könnte der Arduino auch erst dann die Meßwerte bei LabView anfragen, wenn der Master sie anfordert. Dürfte aber hinsichtlich zeitlichem Ablauf kritisch sein.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

sarah_gru

#33
Aug 08, 2018, 07:57 am Last Edit: Aug 08, 2018, 08:12 am by sarah_gru
Vorbemerkung: Ich kenne LabView nicht.
Ich kenne Animationsprogramme, wo der PC eine Animation für LEDs berechnet. Die Helligkeitswerte der LEDs werden dann per USB in Variablen auf dem Arduino übertragen. Der Arduino nimmt dann diese Werte und schiebt sie zu den LEDs raus.
Genau - hier werden dann dementsprechend die einzelnen Pins auf 1 oder 0 gesetzt, an denen die LEDs angeschlossen sind. Ich bräuchte aber irgendwie ein Register oder so etwas auf dem Arduino, wo ich Werte speichern kann und dann an die Datenleitung vom I2C Bus weiterleiten kann, sobald eine Anfrage kommt.
Man muss, wenn man eben etwas in den Arduino schreiben will auswählen, ob ich einen digitalen oder analogen Ausgang beschreiben will und dann welcher Pin genau. Ich habe ja aber weder etwas am digitalen, noch am analogen Ausgang angeschlossen.

Meine analoge Vorstellung: LabView überträgt Werte, die eigentlich der Sensor erfaßt, mittels USB zum Arduino. Der speichert sie, bis der I2C-Master danach fragt und übermittelt sie dann zum Master. Ziel wären dann Arduino-Variablen, die Register.
So wäre der Plan - jetzt ist eben nur die Frage, wo ich die Werte abspeichern kann, dass sie nach Anfrage vom Master direkt auf der Datenleitung gesendet werden.
Im Post 8 wurde das hier vorgeschlagen:
Werte, die ein Reset überdauern sollen, kannst Du unter Beachtung der maximal möglichen Schreibzyklen im EEPROM des UNO gespeichert werden. Sonst bietet sich auch FRAM an.

Wie kann ich jedoch auf dem EEPROM zugreifen? Ist dieser auch so konstruiert wie Pins, sodass ich ihm einfach Daten schicken kann?


Nein, dazu muß irgendwie noch Arduino Sourcecode gehören.
Ich frag nochmal meinen Kollegen, der schon einmal einen Arduino in LabVIEW eingebunden hat. Danke für den Hinweis :)

agmue

Genau - hier werden dann dementsprechend die einzelnen Pins auf 1 oder 0 gesetzt, an denen die LEDs angeschlossen sind.
Sorry, ich meinte nicht normale LEDs, sondern APA102 oder WS2812, die wie Schieberegister angesteuert werden. Die Farbwerte werden in einem Feld gesammelt und dann zusammen zu den ICs geschoben, die die LEDs mittels PWM ansteuern. Ist nicht wichtig, aber es werden auch Daten in Registern gesammelt.

So wäre der Plan - jetzt ist eben nur die Frage, wo ich die Werte abspeichern kann, dass sie nach Anfrage vom Master direkt auf der Datenleitung gesendet werden.
Normalerweise in einem Datenfeld.

Ist das Datenblatt des Sensors geheim? Ohne ist es Stochern im Nebel, also frustrierend. Dies ist ein öffentliches Forum, das auf öffentlich zugänglichen Informationen basierend Hilfe anbietet, die auch für andere Personen hilfreich sein könnte. Idealerweise sollte es ein Geben und Nehmen sein. Ich versuche zu helfen, um etwas zu lernen. Nur mal so als zarter Hinweis :)
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

DrDiettrich

Die genauen Angaben zum Sensor können doch geheim bleiben, sie ändern am Lösungsverfahren überhaupt nichts.

Benötigt wird ein Array, entsprechend den Registern im Sensor. Die Größe des Arrays entspricht der Anzahl der Register. Der Typ des Arrays hängt vom Typ der Register ab, möglicherweise 8 oder 16 Bit u/int.

Das alles ist erst mal nicht unser Problem, solange keine ganz spezifischen Fragen kommen - und das dürfte noch eine ganze Weile dauern. Aktuell ist doch die wichtigste Frage, was LabView sendet, und wie die dazu gehörende Bibliothek aussieht, die auf dem Arduino die Werte in Empfang nimmt. Die muß dann irgendwie I2C-fähig gemacht werden, wenn da nicht schon was vorgesehen ist. Doku Lesen soll da ganz hilfreich sein ;-)

ArduFE

#36
Aug 08, 2018, 08:54 am Last Edit: Aug 08, 2018, 08:59 am by ArduFE
Also wenn ich die Beschreibung auf der in #30 verlinkten NI Seite lese
Quote
The PWS Toolkit is a LabVIEW add-on to be used in conjunction with the Arduino Compatible Compiler for LabVIEW, allowing the programming and downloading of LabVIEW code to the Programmable Wireless Stamp (PWS) device. The PWS is a low cost micro-controller based wireless board tailored to general test and measurement, wireless data acquisition and IoT applications.
bleiben bei mir einige Fragen offen.

Ist dieser Compiler nur für dieses PWS Board ?
Falls er auch für andere Arduinos ist, wurde da richtig eingestellt, dass er für einen Uno übersetzen muss ?

[Edit] Ah, ok, in #7 steht noch was dazu. Der Link diente wohl nur zur Verwirrung.

sarah_gru

Ist das Datenblatt des Sensors geheim? Ohne ist es Stochern im Nebel, also frustrierend. Dies ist ein öffentliches Forum, das auf öffentlich zugänglichen Informationen basierend Hilfe anbietet, die auch für andere Personen hilfreich sein könnte. Idealerweise sollte es ein Geben und Nehmen sein. Ich versuche zu helfen, um etwas zu lernen. Nur mal so als zarter Hinweis :)
Ich habe leider selbst kein Datenblatt vom Sensor, da es eine Kundenhardware ist und ich somit keinen Zugriff darauf habe. Ich habe nur die 3 Blätter, die ich im Anhang mal mit eingefügt habe - mehr nicht sry.

Benötigt wird ein Array, entsprechend den Registern im Sensor. Die Größe des Arrays entspricht der Anzahl der Register. Der Typ des Arrays hängt vom Typ der Register ab, möglicherweise 8 oder 16 Bit u/int.

Das alles ist erst mal nicht unser Problem, solange keine ganz spezifischen Fragen kommen - und das dürfte noch eine ganze Weile dauern. Aktuell ist doch die wichtigste Frage, was LabView sendet, und wie die dazu gehörende Bibliothek aussieht, die auf dem Arduino die Werte in Empfang nimmt. Die muß dann irgendwie I2C-fähig gemacht werden, wenn da nicht schon was vorgesehen ist. Doku Lesen soll da ganz hilfreich sein ;-)
Das Array habe ich schon erstellt. Ich finde jedoch kein einzigsten Vermerk, wie ich mittels LabVIEW in den EEPROM Daten schreiben kann. Auf der Arduino Seite gibt es ja nur den Code EEPROMWrite für das eigene Programm. Dort ist es ja so, dass die Daten von dem Analogen 0 in den EEPROM schreibt.
Ich kann mit LabVIEW zwar Daten an den Analogen Eingang senden, aber dann nicht in den EEPROM überführen. -.-

agmue

#38
Aug 08, 2018, 10:52 am Last Edit: Aug 08, 2018, 10:57 am by agmue
Ich habe leider selbst kein Datenblatt vom Sensor, ...
Meine Meinung: Murks!

Ich habe nur die 3 Blätter, ...
Ich sehe nur ein Blatt :smiley-confuse:

Ich finde jedoch kein einzigsten Vermerk, wie ich mittels LabVIEW in den EEPROM Daten schreiben kann.
EEPROM ist zum Erhalt von Daten über Reset hinaus, das brauchst Du nicht. Versuche es mal mit RAM oder Arbeitsspeicher, da wo Variablen abgelegt und verändert werden.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

DrDiettrich

Ich habe leider selbst kein Datenblatt vom Sensor, da es eine Kundenhardware ist und ich somit keinen Zugriff darauf habe. Ich habe nur die 3 Blätter, die ich im Anhang mal mit eingefügt habe - mehr nicht sry.
Da war mal 1 Blatt angehängt, mehr konnte ich nicht finden.

sarah_gru

Da war mal 1 Blatt angehängt, mehr konnte ich nicht finden.
Ah Entschuldigung ich wollte das Gesamte noch mit an den letzten Post anhängen :smiley-sweat:
Jetzt aber :)

EEPROM ist zum Erhalt von Daten über Reset hinaus, das brauchst Du nicht. Versuche es mal mit RAM oder Arbeitsspeicher, da wo Variablen abgelegt und verändert werden.
Okey danke dann werde ich da mal weitersuchen  :)

agmue

#41
Aug 08, 2018, 04:02 pm Last Edit: Aug 10, 2018, 04:57 pm by agmue
Jetzt aber :)
Geht doch :)

Basierend auf den Programmen, die Dir Serenifly im Thema I2C Datenübertragung gezeigt hat, eine Erweiterung mit den Registern aus dem Datenblatt:

Slave:
Code: [Select]
#include <Wire.h>

const byte SLAVE_ADR = 8;
byte index;

union RegisterData
{
  uint16_t r;
  byte b[sizeof(uint16_t)];
};

RegisterData reg[16];


void setup()
{
  Wire.begin(SLAVE_ADR);
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent);

  reg[0].r = 0 ; //  01
  reg[1].r = 0 ; //  02
  reg[2].r = 0 ; //  03
  reg[3].r = 0 ; //  04
  reg[4].r = 12000 ; //  05 get temperature
  reg[5].r = 0 ; //  06
  reg[6].r = 0 ; //  07
  reg[7].r = 0 ; //  08
  reg[8].r = 0 ; //  09
  reg[9].r = 0 ; //  10
  reg[10].r = 0 ; //  11
  reg[11].r = 0 ; //  12
  reg[12].r = 0 ; //  13
  reg[13].r = 100 ; //  14 Correction
  reg[14].r = 0 ; //  15
  reg[15].r = 0 ; //  16
}

void loop()
{
}

void receiveEvent(int numBytes)
{
  index = Wire.read();
}

void requestEvent()
{
  Wire.write(reg[index].b, sizeof(RegisterData));
}


Master:
Code: [Select]
#include <Wire.h>

const byte SLAVE_ADR = 8;

union RegisterData
{
  uint16_t r;
  byte b[sizeof(uint16_t)];
};

RegisterData reg[16];


void setup()
{
  Serial.begin(9600);
  Wire.begin();
}

void loop()
{
  for (byte i = 0; i < sizeof(reg) / sizeof(reg[0]); i++)
  {
    getTemp(i);
    Serial.println(reg[i].r);
  }  
  Serial.println();

  delay(2000);
}

void getTemp(byte index)
{
  Wire.beginTransmission(SLAVE_ADR);
  Wire.write(index);
  Wire.endTransmission();

  Wire.requestFrom(SLAVE_ADR, sizeof(RegisterData));
  while (Wire.available())
  {
    for (byte i = 0; i < sizeof(RegisterData); i++)
      reg[index].b[i] = Wire.read();
  }
}


Ob union notwendig ist, bliebe zu hinterfragen, aber ich wollte nah am Vorbild bleiben.

Der Slave muß jetzt "nur" noch um das Holen und Beschreiben von sinnvollen Daten von LabView und sowas wie "trigger for a new measurement" ergänzt werden.

Was Dein Stellantrieb als Master dann davon hält, ist noch mal eine ganz andere Frage.

Möglicherweise wäre ein zweiter Arduino als Master für Dich hilfreich, weil Du da sehen kannst, was ankommt. Wenn zwei Arduinos als Master-Slave-Gespann zusammen funktionieren, kannst Du mit dem Stellantrieb vergleichen. Nur so eine Idee.

EDIT 20180810: Andere Variante der Programme siehe #60.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

DrDiettrich

An diesen Code muß noch Hand angelegt werden, bis er funktioniert und auch zum Sensor paßt.

agmue

Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

DrDiettrich

Deshalb sage ich ja, daß er noch überarbeitet werden muß. Einfach nur zufällig funktionieren ist kein Argument, solchen kaputten Code weiterzuverbreiten :-(

Go Up