Go Down

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

agmue

#60
Aug 10, 2018, 04:50 pm Last Edit: Aug 10, 2018, 09:21 pm by agmue
Große Worte - besser wäre, gleich damit  rauszurücken, was Dich stört - nur so als dezenter Hinweis - nicht Jeder hier kann in Dein Hirn rein schauen.
Danke :)

Und dafür sollte man eher ein if verwenden.
Mit while, if und ganz ohne funktioniert es.

Nun habe ich mal bei Nick Gammon geschaut. Wenn ich das für mich übernehme, kommt dies dabei heraus:

Slave mit Veränderung der Temperatur:
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()
{
  Serial.begin(9600);
  Serial.setTimeout(10);
  Serial.println(F("Temperatur eingeben"));
  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()
{
  if (Serial.available())
  {
    reg[4].r = Serial.parseInt() * 100 + 10000;
  }
}

void receiveEvent(int numBytes)
{
  for (byte j = 0; j < numBytes; j++)
  {
    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();

  if (Wire.requestFrom(SLAVE_ADR, sizeof(RegisterData)))
  {
    for (byte i = 0; i < sizeof(RegisterData); i++)
      reg[index].b[i] = Wire.read();
  }
  while (Wire.available () > 0)
    Wire.read ();  // Fehler: zu viele Daten, daher Daten wegwerfen
}
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Serenifly

Wenn man parseInt() verwendet, dann sollte man auch setTimeOut() auf was vernünftiges anpassen. Sonst wartet man bei jeder Eingabe eine ganze Sekunde

agmue

Danke für den Hinweis, habe ich ergänzt. Wobei ich mich frage, welcher Wert da sinnvoll ist. Bei 115200 Baud funktioniert bei einer zweistelligen Zahl der Wert 1 (=1 ms), bei 9600 Baud ist 10 besser.

Für dieses Thema dürfte parseInt() allerdings nur für den schnellen Test mit dem seriellen Monitor und nicht für die Kommunikation mit dem PC von Interesse sein.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Go Up