Mehrere Slaves an SPI, Anfängerproblem

Hallo zusammen,

ich habe mich hier neu angemeldet und bin auch noch recht frisch in der Arduinowelt. Eigentlich habe ich mir einen UNO aus Langeweile bestellt. Krankheitsbedingt. Vorher habe ich diverse Programme in python programmiert, jetzt geht es mit der Arduino IDE und c++ weiter. Soviel zu mir, jetzt zum ersten Problem.

Ich möchte etwas über SPI lernen, dazu folgender Versuchsaufbau.

(Verwendet habe ich in diesem Fall einen ESP8266, mit dem UNO ist das Ergebnis allerdings übrigens identisch..)
Ich habe ein TFT-Display mit dem ST7735 und einen PT100-Sensor mit einem MAX31865 an SPI angeschlossen. Dazu teilen sich beide Slaves MOSI, MISO, CLK und haben separate SS.
Für das Display verwende ich die TFT_eSPI-Libary von Bodmer, für den PT100 die Libary von Adafruit. Beide Slaves funktionieren mit den jeweiligen Beispielsketches. Um beide gleichzeitig zu testen habe ich die Bespielsketches etwas reduziert und zusammenkopiert. Dabei fällt auf, dass immer nur das Gerät, welches als letztes initialisiert wird funktioniert.
Die beiden Zeilen die ich in der Reihenfolge vertausche habe ich mit Kommentaren versehen.

Sketch:

#include <Adafruit_MAX31865.h>
#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>

TFT_eSPI tft = TFT_eSPI();       // Invoke custom library
Adafruit_MAX31865 thermo = Adafruit_MAX31865(15, 13, 12, 14);
#define RREF      430.0
#define RNOMINAL  100.0


void setup(void) {
  Serial.begin(115200);
  thermo.begin(MAX31865_2WIRE);  // ...entweder diese Zeile zuerst
  tft.init();                  // ...oder diese...
  tft.setRotation(1);
}

void loop() {
  tft.fillScreen(TFT_BLACK);

  // Draw some random filled elipses
  for (int i = 0; i < 20; i++)
  {
    int rx = random(10);
    int ry = random(10);
    int x = rx + random(160 - rx - rx);
    int y = ry + random(128 - ry - ry);
    tft.fillEllipse(x, y, rx, ry, random(0xF0FF));
  }

  tft.fillScreen(TFT_BLACK);

  // Draw some random outline elipses
  for (int i = 0; i < 40; i++)
  {
    int rx = random(40);
    int ry = random(40);
    int x = rx + random(160 - rx - rx);
    int y = ry + random(128 - ry - ry);
    tft.drawEllipse(x, y, rx, ry, random(0xF00F));
    uint16_t rtd = thermo.readRTD();

    // Serial.print("RTD value: "); Serial.println(rtd);
    float ratio = rtd;
    ratio /= 32768;
    // Serial.print("Ratio = "); Serial.println(ratio,8);
    // Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
    Serial.println(thermo.temperature(RNOMINAL, RREF));
  }
}

Meine Vermutung ist, dass beide Libaries die SPI.h nutzen und diese somit zweimal hintereinander mit unterschiedlichen Werten initialisiert wird. Leider habe ich aber keine Idee wo ich noch suchen soll. Habt ihr einen Tipp?

Viele Grüße Tom

Hallo,

vielen Dank für die Tipps! Auch wenn ich die Idee dahinter verstehe, muss ich nach einem Nachmittag einsehen, dass das wohl meine Skills übersteigt :confused:

Gruß Tom

Ich würde #include <spi.h> an den Anfang setzen, dann merken die Bibliotheken vielleicht daß die Basis schon mal definiert ist.

Eventuell testhalber LEDs an die SS Leitungen hängen, damit man sehen kann ob da ein Slave ständig selektiert bleibt.

@TO: punkt 1 würde ich erst mal statt dem software bitbang den Hardware SPI nutzen, vieleicht tust du den Libraries unrecht.

/**************************************************************************/
/*!
    @brief Create the interface object using software (bitbang) SPI
    @param spi_cs the SPI CS pin to use
    @param spi_mosi the SPI MOSI pin to use
    @param spi_miso the SPI MISO pin to use
    @param spi_clk the SPI clock pin to use
*/
/**************************************************************************/
//
Adafruit_MAX31865::Adafruit_MAX31865(int8_t spi_cs, int8_t spi_mosi,
                                     int8_t spi_miso, int8_t spi_clk) {
  spi_dev = Adafruit_SPIDevice(spi_cs, spi_clk, spi_miso, spi_mosi, 1000000,
                               SPI_BITORDER_MSBFIRST, SPI_MODE1);
}

/**************************************************************************/
/*!
    @brief Create the interface object using hardware SPI
    @param spi_cs the SPI CS pin to use along with the default SPI device
*/
/**************************************************************************/
Adafruit_MAX31865::Adafruit_MAX31865(int8_t spi_cs) {
  spi_dev =
      Adafruit_SPIDevice(spi_cs, 1000000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
}

soll heißen,

Adafruit_MAX31865(int8_t spi_cs)
wäre mein erster Versuch.

Außerdem deine Pins passen gar nicht so zum Beispiel:
// Use software SPI: CS, DI, DO, CLK
//Adafruit_MAX31865 thermo = Adafruit_MAX31865(10, 11, 12, 13);
// use hardware SPI, just pass in the CS pin
Adafruit_MAX31865 thermo = Adafruit_MAX31865(10);

Hallo,

in der Zwischenzeit habe ich versucht die SPI.h einzubinden, leider brachte das keinen Erfolg. Auch die Änderung auf Hardware-SPI funktionierte zwar separat, allerdings nicht im Verbund mit beiden Slaves.

Jetzt möchte ich zaghafte Änderungen an den libs vornehmen, bin aber dabei auf ein Rechnerproblem gestoßen und muss das wohl zuerst klären oder lösen.

Vor den Änderungen habe ich die lib Adafruit_MAX31865.cpp kopiert und im gleichen Ordner wieder eingefügt. Der Name lautet dann Adafruit_MAX31865 (Kopie).cpp. Das führt dann zu einem Kompilerfehler:

/home/t/Programmierung/Programme Arduino IDE/libraries/Adafruit_MAX31865_library/Adafruit_MAX31865.cpp:176: multiple definition of `Adafruit_MAX31865::temperature(float, float)'; /tmp/arduino_build_886077/libraries/Adafruit_MAX31865_library/Adafruit_MAX31865 (Kopie).cpp.o:/home/t/Programmierung/Programme Arduino IDE/libraries/Adafruit_MAX31865_library/Adafruit_MAX31865 (Kopie).cpp:176: first defined here
collect2: error: ld returned 1 exit status
Bibliothek Adafruit_MAX31865_library in Version 1.2.3 im Ordner: /home/t/Programmierung/Programme Arduino IDE/libraries/Adafruit_MAX31865_library wird verwendet
Bibliothek Adafruit_BusIO in Version 1.5.0 im Ordner: /home/t/Programmierung/Programme Arduino IDE/libraries/Adafruit_BusIO wird verwendet
Bibliothek SPI in Version 1.0 im Ordner: /home/t/.arduino15/packages/esp8266/hardware/esp8266/2.7.4/libraries/SPI wird verwendet
Bibliothek Wire in Version 1.0 im Ordner: /home/t/.arduino15/packages/esp8266/hardware/esp8266/2.7.4/libraries/Wire wird verwendet
exit status 1
Fehler beim Kompilieren für das Board WeMos D1 R1.

Sehe ich das richtig, dass die Datei und ihre Kopie eingelesen werden und es somit zu einer doppelten Definition (wovon auch immer) kommt? Ist das normal?

Die Namen bleiben innerhalb der Kopie erhalten. Werden beide Bibliotheken zusammen compiliert, kann das durchaus zu Problemen führen.

Du scheinst da mehr als nur 1 Kopie von diversen Bibliotheken zu haben? Wozu überhaupt?

Ah, ich verstehe.

Wenn man nicht so genau weiß was man tut, finde ich es eigentlich immer sinnvoll den Urzustand zu sichern.

Dann ist es vermutlich besser den ganzen Ordner zu kopieren?!

Danke und Gruß tom

zeig mal deine zwei funktionierenden Einzelsketche - beide mit Hardware-SPI.
Sowie einen gesamthaften Schaltplan wie es aktuell verkabelt ist
Sowie Bilder worauf wir jede einzelne Leitung entsprechend dem Schaltplan zuordnen können.

außerdem fehlt noch immer

such mal die Links wo die libs auf Github oder ähnlichem liegen. Vieleicht kann dir dann wer helfen...

noiasca:
zeig mal deine zwei funktionierenden Einzelsketche - beide mit Hardware-SPI.
Sowie einen gesamthaften Schaltplan wie es aktuell verkabelt ist
Sowie Bilder worauf wir jede einzelne Leitung entsprechend dem Schaltplan zuordnen können.

außerdem fehlt noch immer

Hallo,

vielen Dank für das Angebot. Das soll auch nicht undankbar erscheinen, aber ich möchte es erst mal noch alleine probieren. Wenn ich das Gefühl habe, dass ich es nicht schaffe, bin ich mit Schaltplan und den links zurück. Ich finde so lernt man irgendwie am meisten...

Danke und Gruß

Sein Name ist sKepsis :wink: