Bits / Bytes von der SPI auslesen

Guten Morgen,

da ich relativ neu in der Arduino Welt bin, habe ich nicht die größte Erfahrung mit dieser Plattform.

Ich möchte die Bitfolge eines Master via SPI auslesen.

Habe zunächst versucht diese manuell entsprechend auszuwerten, jedoch ohne Erfolg.

Habe das Problem, dass wohl die digitalen Pins des Arduinos evtl. zu langsam arbeiten (?).

int digitalIn;
int i;
unsigned long signalHigh_cs, signalLow_cs;


void setup() {
  Serial.begin(115200);
  pinMode(40, INPUT); // MOSI vom Master
  pinMode(52, INPUT); // Chip Select
}



void loop() {

  // Zeiten der High und Low Phasen des Chip Select
  signalHigh_cs = pulseInLong(52, HIGH); //Zeit in µs
  signalLow_cs = pulseInLong(52, LOW); //Zeit in µs


i = 0;
while (digitalRead(52) != 1 && i <15) {     // i: Anzahl der Bits die in einer Zeile stehen sollen
  
    digitalIn = digitalRead(40);
    Serial.print(digitalIn);
    delay(1000);
    i++;

  }
  Serial.println();

}

Ganz schön wäre natürlich, wenn man die SPI Schnittstelle des Arduino verwenden könnte. Habe aber die Beispiele nicht ganz verstanden und es auch nicht hinbekommen.

Ich wäre für jede Hilfe dankbar! :smiley:

P.S: Benutze einen Arduino Due

Hallo,

im Schleifenkopf wird nur geprüft ob die Bedingung noch gültig ist. Auch shiftest du kein Bit in deine Zielvariable. Benutze bitte für deine Pins sprechende Variablen mit const byte. Ansonsten editierst du dich später tot, vergisst irgendwann eine Änderung und wunderst dich das nichts mehr funktinioniert.

Ich möchte ja dann die High und Low des zweiten Digitalen Eingangs lesen, wenn der Chip Select auf low ist. Und das wollte ich mit der Schleife bezwecken.

Hallo,

du musst MISO lesen was wiederum nur mit einem Taktsignal funktioniert.
CS muss im setup schon auf High stehen und danach als Ausgang definiert werden. Fehlt irgendwie.

Danach CS auf Low, IC auslesen und am Ende CS wieder auf High.

Vielleicht solltest du vorher die Grundlagen und Funktionsweise von SPI lesen.

Hallo,

das wäre ein rudimentäres Grundgerüst was ggf. noch Anpassungen bedarf. Hängt vom SPI IC ab. SPI Mode ist auch noch nicht berücksichtigt. Wie gesagt, man sollte erst die Funktionsweise verstehen und wissen was der IC liefert. Ggf. noch ein Register ansprechen. Dann kommste mit den fertigen SPI Funktionen am Ende besser weg.

const byte pinMISO = 50; // Nummern ggf. anpassen
const byte pinCLK = 49;
const byte pinCS = 48;


void setup() {
  Serial.begin(115200);

  digitalWrite(pinCS, HIGH);
  pinMode(pinMISO, INPUT_PULLUP);
  pinMode(pinCLK, OUTPUT);
  pinMode(pinCS, OUTPUT);
}


void loop() {


}


long readDevice()
{
  long data = 0;     

  digitalWrite(pinCS, LOW);
  
  for (int i=15; i>=0; i--) {    // 16 Bit, MSB first
    digitalWrite(pinCLK, HIGH); 
    data = data | (digitalRead(pinMISO)<<i);  
    digitalWrite(pinCLK, LOW); 
  }

  digitalWrite(pinCS, HIGH);
  return data;
}

Was hindert dich daran mit SPI.transfer() ein ganzes Bytes einzulesen? Oder zwei Bytes mit transfer16()
https://www.arduino.cc/en/Reference/SPITransfer

Das kann man danach immer noch in einzelne Bits auseinanderbrechen

@Doc_Arduino

Hatte gehofft, dass es durch einfaches einlesen der digitalen Pinne möglich wäre.
Vielen Dank für deinen Vorschlag. Werde versuchen es entsprechend umzusetzen!

@Serenifly

Die Unwissenheit und die m.M. schlechte Referenz. Persönlich verstehe ich nicht, was die Funktion für Eingabewerte erwartet bzw. auch auf welchem Pin usw. (Denke wohl MOSI) :smiley:

transfer() ist eine Funktion zum Senden und Empfangen. Da es zwei Datenleitungen gibt geht das gleichzeitig. Wenn man nur Empfangen will übergibt man einfach 0 als Dummy-Parameter

MOSI = master out, slave in
MISO = master in, slave out

@Serenifly

Sorry, aber stehe voll auf dem Schlauch.

Ja, ich weiß wie eine SPI funktioniert.

Aber ich kriege das nicht umgesetzt. Habe die SPI vom Master auf zweimal 0x00 gesetzt, jedoch empfange ich mehr 1 als 0.

Müsste ja irgendwie den Chip Select synchronisieren.

Hallo,

ist denn die Funktionsweise von SPI verstanden? Das rumgeeier mit dem CS sagt mir nicht.
Um welchen IC geht es denn überhaupt?
Die Bsp. der IDE unter "SPI" kannste dir auch anschauen.

Serenifly:
Was hindert dich daran mit SPI.transfer() ein ganzes Bytes einzulesen?

Wenn ich das richtig verstanden habe, will er die Daten eines anderen SPI Masters lesen:

Tuki_38:
Ich möchte die Bitfolge eines Master via SPI auslesen

D.h. der Due muss als SPI slave agieren. Die HW gibt das schon her, aber nicht die Arduino SPI-Lib. Die kann nur ‘master’ spielen. Das SPI.transfer() hilft ihm also nicht.

Man müsste mal suchen, ob es für den Due eine Lib gibt, die SPI im slave-Mode erlaubt. Das alles in SW zu machen ist ja eigentlich blöd, da es die passende HW ja gibt.

@Tuki_38:Was ist das eigentlich für ein Master, den Du auslesen willst? Mir scheint, Du hast SPI nicht verstanden, denn CS und CLK sind am Master Output - am Slave sind das Inputs. Oder handelt es sich doch um einen SPI Slave? Das geht irgendwie alles noch etwas durcheinander.

MicroBahner:
Wenn ich das richtig verstanden habe, will er die Daten eines anderen SPI Masters lesen: D.h. der Due muss als SPI slave agieren. Die HW gibt das schon her, aber nicht die Arduino SPI-Lib.

Ah, ja. Da war mal was. Das ergibt dann Sinn :slight_smile:

@MicroBahner
Der "Test"-Master ist im Moment ein Arduino Mega. Dieser dient jedoch nur als Testgerät. Sobald hierfür die Daten ausgelesen werden können, kann man dies auf andere Master anpassend übertragen. :slight_smile:

Der Due soll als Slave agieren und die Daten "nur" auslesen.

"Warning: Unlike most Arduino boards, the Arduino Due board runs at 3.3V. The maximum voltage that the I/O pins can tolerate is 3.3V. Applying voltages higher than 3.3V to any I/O pin could damage the board."

Wie hast Du das berücksichtigt?

@agmue
Mit einem Spannungsteiler :slight_smile:

Tuki_38:
Der "Test"-Master ist im Moment ein Arduino Mega.

Ist das Programm geheim? Sonst könnte sich der Helfende dies auf seinen Mega laden und schauen, ob es tut, was es soll.

Hast Du schon mal mit einem Logic Analyser geschaut?

@agmue

Nein, dieser ist nicht geheim. Zum Nachvollziehen bzw zum Überprüfen habe ich einen Oszi benutzt.
Der Master tut schon das was er tun soll :smiley:

Den Mega werde ich aber nicht überschreiben können, da er in Benutzung ist. Ich hätte noch einen Arduino Nano zur Verfügung, den ich als Master benutzen könnte. (falls es darauf hinaus laufen sollte :D)

Wenn Du den Slave per Software realisieren willst, musst Du die Bits einzeln empfangen und in die Zielvariable 'reinschieben. Dabei musst Du natürlich das Clocksignal des Masters auswerten.
Evtl. könnte auch shiftIn eine Lösung sein. Letzendlich ist SPI ja nichts anders als eine 'Schieberegister' Schnittstelle.
Mit welcher Frequenz sendet dein Master?

@MicroBahner

Die Funktion shiftIn hört sich gar nicht mal so verkehrt an.

-CS mit 1kHz
-CLK mit 1MHz

Derzeit übertrage ich Text von einem Mega2560 zu einem UNO, wobei ich mir Unterstützung von Nick Gammon geholt habe.

Ob das auch für einen Due funktionieren würde, kann ich mangels Hardware leider nicht probieren. Also Mega als Master und Nano als Slave wäre eine Option zum Testen, wenn es mit dem Due nicht will.