Hi an all die Profis, Ich habe Probleme mit meinen Code und komme einfach nicht weiter. Ich nutze ein Mega als Master und ein Nano als Slave. Der Master sendet Text zum Slave, dieser kommt auch an und der Slave soll ein Text zurücksenden doch beim Master kommt nur genau das an was der Master sendet.Das der Slave was sendet muss ok sein, da der Master beim nicht senden kein Text zusammensetzten kann. Sendedaten und Empfangsdaten haben aber keinen Bezug. Weswegen der Master dann aber das zusammensetzt was er sendet ist für mich nicht nachvollziehbar. Hier der Code: //Master #include <SPI.h> volatile boolean senden; volatile char Paket_vom_Slave; volatile char Paket_zum_Slave; char buf [100]; volatile byte pos; String Paket = ""; void setup (void) { Serial.begin(9600); // pinMode(53, OUTPUT); pinMode(SS, OUTPUT); // digitalWrite(SS, HIGH); //SS Pin auf HIGH setzten SPI.begin (); //Verbindung starten SPI.setClockDivider(SPI_CLOCK_DIV8); //Geschwindigkeit verlangsamen } void loop (void) { //Text_erstellen(); digitalWrite(SS, LOW); //starten der Kommunikation mit Slave for (const char * p = "TxT v Master\n" ; Paket_zum_Slave = *p; p++) { //Text_erstellen(); Paket_vom_Slave = SPI.transfer(Paket_zum_Slave); //senden von Text Text_erstellen(); delayMicroseconds (500); Serial.print("sent: "); Serial.print(Paket_zum_Slave); Serial.print("\t empfangen: "); //Serial.println(Paket_vom_Slave); Serial.println(Paket); delay(200); } digitalWrite(SS, HIGH); //beenden der Kommunikation delay (1000); //kurze pause } void Text_erstellen() { if (pos < sizeof buf) { char c = Paket_vom_Slave; //kopieren der Daten von SPI Buffer buf [pos++] = c; //hinzufuegen des naechsten Zeichens if (c == '\n') senden = true; } if (senden) { buf[pos] = 0; Paket = (buf); Paket.trim(); Serial.println (("empfangen :--->") + (Paket)); Serial.println (("empfangen :--->") + (Paket)); Serial.println (("empfangen :--->") + (Paket)); pos = 0; senden = false; } } //Slave #include <SPI.h> volatile boolean senden; volatile boolean versandbereit; //volatile byte Paket_Master,Sendung_Slave; volatile char Paket_Master; volatile char Sendung_Slave; String Paket = ""; String Sendung = ""; int i = -1; char buf [20]; char buf1 [20]; volatile byte pos; volatile byte pos1; void setup(void) { Serial.begin(9600); // pinMode(12, OUTPUT); pinMode(MISO, OUTPUT); SPCR |= _BV(SPE); // turn on SPI in slave mode //SPCR |= bit (SPE); senden = false; SPCR |= _BV(SPIE); // turn on interrupts SPI.attachInterrupt(); } void loop(void) { if ((versandbereit) == false); { Paket_Text(); } if (senden) { i = i + 1; buf[pos] = 0; Paket = (buf); buf1[pos] = 0; Sendung = (buf1); if (i == 12) { SPDR = "\n"; } else { SPDR = (buf1[i]); } Paket.trim(); Sendung.trim(); Serial.println (("empfangen :--->") + (Paket)); Serial.println (buf1[i]); Serial.println (i); Serial.println (("gesendet :--->") + (Sendung)); pos = 0; senden = false; } if (i == 12) i = -1; } ISR(SPI_STC_vect) { byte c = SPDR; //kopieren der Daten von SPI Buffer if (pos < sizeof buf) { buf [pos++] = c; //hinzufuegen des naechsten Zeichens if (c == '\n') senden = true; } } void Paket_Text() { if (pos1 < sizeof buf1) for (const char * p = "Paket--Slave\n" ; char c = *p; p++) { buf1 [pos1++] = c; Serial.println (buf1); if (c == '\n') versandbereit = true; } }
Bin zwar kein Arduino-Profi, arbeite meistens direkt auf Register level mit Microcontrollern aber versuche mal hier zu helfen. Der erste Tipp den ich habe ist, dass du das nächste Datenbit beim Slave schon im Interrupt in das SPDR schreibts. Denn sonst kann es passieren, dass der Slave in der main loop den SPDR setz code nicht zwischen 2 SPI transfers erreicht. Aber das kann ja nicht das eigentliche Problem sein. Schau nochmal ob du beim Slave MISO als output gesetzt hast. Dass der Master das gleiche empfängt kann nämlich auch an der verkabelung liegen. Wenn zwei Leitungen nebeneinander laufen (was bei dir der Fall sein wird) dann gibt es dazwischen Übersprechen, besonders wenn eine auf beiden Seiten Eingänge (hochohmig) hängen hat, und die andere halbwegs hohe Frequenzen (sieht ja nach 2MHz aus) hat. Sonst auch noch mal die Steckverbindung selbst überprüfen.
Hallo, ich habe da so mein Problem mit der Schreibweise von sizeof(<type>) in deinem Code. Ich kenne die Anwendung nur als Funktionsaufruf: https://www.geeksforgeeks.org/sizeof-operator-c/
So geht das nicht. Beim Senden muß der Slave nach jedem Byte warten, bis der Master es abgeholt hat (Interrupt Flag). Und der Master muß nach jedem Byte eine Wartezeit abwarten, damit der Slave das nächste Byte in SPDR schreiben kann. Die AVRs haben nämlich keinen Sendebuffer.
Die Verkabelung und Slave MISO als output ist alles ok ein Beispielprogramm was eine Zahl hin und her sendet läuft ohne Probleme.
Kannst du mir ein Tipp gegen wie ich das in meinen Code wo und wie einsetzen kann ich glaube auch das rs das ist. Leider bin ich hier sehr unerfahren hab versucht mich schlau zu lesen komme aber nicht weiter.
Ich komme langsam voran :-) Aber hab momentan ein Problem mit der Datenübergabe. Ich übergebe beim Start: char Paket_zum_Master [50] = "Starten vom Slave."; und ändere in der SPI interrupt routine den Inhalt in "neuer Text" Gesendet wird aber "Starten vom Slave." Wie muss ich das ändern.
1 | // Slave
|
2 | char Paket_zum_Master [50] = "Starten vom Slave."; |
3 | volatile int pos; |
4 | volatile bool active; |
5 | String Send_Paket; |
6 | |
7 | |
8 | ISR (SPI_STC_vect) // SPI interrupt routine |
9 | {
|
10 | Send_Paket = "neuer Text"; |
11 | char Sendung = ((Send_Paket + "\n").c_str()); |
12 | Paket_zum_Master [50] = Sendung; |
13 | byte c = SPDR; |
14 | if (c == 1) // starting new sequence? |
15 | {
|
active = true; pos = 0; SPDR = Paket_zum_Master [pos++]; // sendet erste byte return; } if (!active) { SPDR = 0; return; } SPDR = Paket_zum_Master [pos]; if (Paket_zum_Master [pos] == 0 || ++pos >= sizeof (Paket_zum_Master)) active = false; } // end of interrupt service routine (ISR) SPI_STC_vect
Dieter T. schrieb: > Wie muss ich das ändern. Wie musst du was ändern um was zu erreichen? Das schaut so schrecklich und chaotisch aus dass man wirklich keine Lust hat darauf einzusteigen. Bring erst mal Ordnung und Übersicht in dein Leben und deine Programmier-Planung sowie die Code-Darstellung.
Ich denke, du solltest dringend zuerst auf einem PC die Sprache C lernen, dann C++, dann die Besonderheiten von Arduino. Das hier macht nie und nimmer das, was du erwartest:
1 | char Paket_zum_Master [50] = "...; |
2 | String Send_Paket;
|
3 | |
4 | Send_Paket = "neuer Text"; |
5 | char Sendung = ((Send_Paket + "\n").c_str()); |
6 | Paket_zum_Master [50] = Sendung;
|
he: Auh Weia "Bring erst mal Ordnung und Übersicht in dein Leben " ist ja wohl eine sehr persönliche Aussage, die muss ich mir von sone Wurst bestimmt nicht sagen lassen. Bin 60 Jahre alt und denke, dass ich mein Leben sehr gut im Griff habe. Zudem hab ich vor 30 Jahren schon einiges programmiert, das war da leider noch nicht so objekt gebunden, wie es heute ist. Ich bin vor 1 Monat wieder angefangen mich mit Programmieren zu beschäftigen und momentan erschlagen mir förmlich die Mengen an Funktionen. Aber ganz abgesehen davon: Es gibt im Netz kein vernünftiges Beispiel einer SPI Übertragung, wo der Master ein String überträgt und gleichzeitig ein String empfängt. Es bietet sich hier ja an, gemeinsam was vernümftiges zusammenzustricken und sei es nur dafür, das ein anderer es nutzen kann. Und Stefanus F. mein Code ist außer die Variabel Namen ein Code von Nick Gammon und er funktioniert auch. Ich glaube so unübersichtlich programmiert Nick Gammon auch nicht. Was ich momentan ändern will, ist das der String der oben deklariert ist variabel änderbar ist.
Du willst nicht einsehen, dass dein grob grob fehlerhaft ist. Dann kann man Dir nicht helfen. Punkt.
Stefanus F. schrieb: > Du willst nicht einsehen, dass dein grob grob fehlerhaft ist. > Dann kann man Dir nicht helfen. Punkt. Yes. Und danke sehr.
Bin ich irgendwo von der Welt Stefanus, ich weiss das irgendwo ein Fehler ist deswegen bin ich ja hier. In der Regel erwartet man ja Unterstützung und nicht eine Aussage wie oben das man erst mal sein Leben in Ordnung bringen soll. Und auch keine Aussage das da ein Fehler drin ist. Sondern wo der Fehler sein könnte und wie man ihn beseitigt. Ich glaub Stefanus auf deine Hilfe kann ich auch gut verzichten.
Dieter T. schrieb: > Es gibt im Netz kein vernünftiges Beispiel einer SPI Übertragung, wo der > Master ein String überträgt und gleichzeitig ein String empfängt. Ohhh, es gibt keine fertige Wichsvorlage... Das ist ja richtig schlimm... Da muss man doch tatsächlich wirklich selber programmieren... Das Leben kann ja so hart sein... De facto ist es allerdings so: es gibt Unmassen solcher Beispiele. Man muss nur wenigstens soviel von der Sache verstehen, dass man sie auch finden kann. D.h.: man muss ubedingt das Grundkonzept der SPI-Kommunikation verstanden haben... > Bin 60 Jahre alt So what? Gerade mal drei Jahre älter als ich. Nö: das kann ich definitiv nicht als Ausrede gelten lassen... Ich bin nichtmal sicher, ob das überhaupt wahr ist. Die KI sagt: definitiv NEIN, geschätztes Alter 2x. Ich schwanke noch, aus meiner Sicht: könnte zumindest so sein. In etlichen Fällen musste ich aber lernen, dass die KI beim Schätzen des Alters deutlich bessere Trefferraten erzielt als ich selber...
c-hater schrieb: > man muss ubedingt das Grundkonzept der > SPI-Kommunikation verstanden haben... Dieter, du brauchst die Grundlagen, wie man Zeichenketten in C, C++ und Arduino verwendet. Mit dem Thema SPI lenkst du oder wirst du vom Kern des Problems abgelenkt. Spiele erstmal mit einem ganz "normalen" Arduino Uno Board und der Serial Klasse herum. Dabei wirst du einiges lernen, was du dann auf die SPI Klasse übertragen kannst. Ich habe weiter oben ein paar fragwürdige Zeilen von deinem Quelltext zitiert. Bringe die mal auf dem Arduino Uno mit der Serial Klasse ans Laufen. Dann sehen wir weiter.
Dieter T. schrieb: > Gesendet wird aber "Starten vom Slave." > Wie muss ich das ändern. Aufhören in der ISR irgendetwas zu ändern. In der ISR wird nur gesendet, bzw. empfangen, die Position wird geprüft und entsprechende Flags gesetzt. Alles andere führt meistens zu Fehlern.
Also ihr beiden Profis, anstatt sich mal mit der Sache zu beschäftigen und mal sich mit ein Problem überhaupt mal auseinander zu setzen, sucht ihr glaub ich nur nach irgendwelchen Ausreden, um euer beklopptes Verhalten zu rechtfertigen. Nochmal ich suche hier eigentlich nur nach einen Tipp, aber anscheinend seit ihr selber zu dumm, den Code zu lese. Ich habe diese beiden Zeilen ausgetauscht und auch wenn ihr beiden es nicht glauben wollt, es läuft so wie es soll. Send_Paket = "neuer Text"; strcpy(Paket_zum_Master, Send_Paket.c_str()); Serial.print ("Text vom Slave :----> "); Ich werde den Code noch ein wenig ausarbeiten und hier als Beispiel einsetzen, für diejenigen die nach einen guten Beispiel suchen. Auf weitere Fachmeinungen von euch beiden kann ich gut verzichten. MfG Dieter
Dieter_T schrieb: > Der Master sendet Text zum Slave, dieser kommt auch an und der Slave > soll ein Text zurücksenden doch beim Master kommt nur genau das an was > der Master sendet. Aus deiner Formulierung entspringt ein grundlegendes Verständnisproblem bzgl. SPI. Über das SPI wird auf Ansage des Masters (Clock vom Master) zwei Bytes zwischen Master und Slave ausgetauscht. Der Slave sendet nie selbständig, sondern der Master holt sich etwas vom Slave.
Dieter T. schrieb: > Ich werde den Code noch ein wenig ausarbeiten und hier als Beispiel > einsetzen, für diejenigen die nach einen guten Beispiel suchen. Ich bin sicher, die weltweite Gemeinde der C-Programmierer wird mit Begeisterung ihre nun alten und wertlosen Bibliotheken und Programme wegwerfen und von da an nur deinen ausgezeichneten Code benutzen...
Ich glaube auch, daß hier ein grundlegende Verständnis-Problem vorliegt. Ganz gut wird das in dieser Grafik erklärt. Mit jedem Zyklus "tauschen" Master und Slave den Inhalt ihrer Datenregister. Entnommen aus dem Ddatenblatt des ATMega328p
:
Bearbeitet durch User
Dieter T. schrieb: > Also ihr beiden Profis, > anstatt sich mal mit der Sache zu beschäftigen und mal sich mit ein > Problem überhaupt mal auseinander zu setzen, sucht ihr glaub ich nur > nach irgendwelchen Ausreden, um euer beklopptes Verhalten zu > rechtfertigen. Meinst du das wirklich ernst? Ich helfe Dir jetzt nicht mehr weiter. Lerne mal, Dich zu benehmen! Demut und Dankbarkeit wären die ersten Themen für Dich. Als nächste käme Selbsterkenntnis, denn das ist der Erste Weg zur Besserung.
Ja stimmt natürlich der Master sendet natürlich ein Byte, und empfängt im Gegenzug ein Byte. Allgemein gesagt Daten ausgetauscht.
Meinst du das wirklich ernst? Stefanus für dich nehm es zurück, aber das läuft soo, nie!! stimmt ja auch nicht. Beim durchlesen hätte ich von einen Profi erwartet, das er auf die Fehlerstelle hinweist und nicht "das wird nie laufen." Mittlerweile läuft es super. "Spiele erstmal mit einem ganz "normalen" Arduino Uno Board" Also das Netz und die Gruppen bieten sich zusätzlich zum Lernen, an, auch Fragen zu stellen und so seine Kenntnisse zu erweitern. Wer sagt denn, dass ich nicht zusätzlich mich auch mit C-Programmierung: Zeichenkettenfunktionen uvm. beschäftige. Aber auf eine Frage die Antwort "Lern erst mal....." passt ja auch nicht. Hilfreicher wäre einfach nur ein Hinweis in der Sache ein Tipp ...
Dieter T. schrieb: > Hilfreicher wäre einfach nur ein Hinweis in der Sache ein Tipp ... Da war so viel auf einmal nicht in Ordnung, dass ein "Hinweis" oder "Tipp" gar nicht möglich war. Zuerst muss man eine gemeinsame Sprache haben, bevor man miteinander reden kann.
Dieter T. schrieb: > Ich übergebe beim Start: char Paket_zum_Master [50] = "Starten vom > Slave."; > und ändere in der SPI interrupt routine den Inhalt in "neuer Text" Nein, tust Du nicht. Du initialisierst mit "Starten vom Slave.", was ein großer Unterschied ist. Dann mit "Paket_zum_Master [50] = Sendung;" schreibst Du ein Zeichen hinter die Variable, d.h. in einen ungültigen Bereich. Ich kenne mich mit C++ nicht aus, aber in C kopiert man Strings mit strcpy(). Und die Länge ermittelt man mit strlen(). Schau mal ins Manual zur <string.h>. sizeof() gibt Dir nur Anzahl Bytes einer Variablen, in diesem Fall konstant 50. Dieter T. schrieb: > ISR (SPI_STC_vect) // SPI interrupt routine > { > Send_Paket = "neuer Text"; > char Sendung = ((Send_Paket + "\n").c_str()); Ich hab absolut keine Ahnung, was das bezwecken soll.
Send_Paket = "neuer Text"; strcpy(Paket_zum_Master, Send_Paket.c_str()); Macht mehr Sinn, Hiermit läuft es auch die Nachricht "neuer Text" wird vom Master empfangen. Ich habe beim Slave jetzt die Möglichkeit je nach Ereignis einen passenden Text vom Master abholen zu lassen.
Peter D. schrieb: > Ich hab absolut keine Ahnung, was das bezwecken soll. Wann wirst auch du begreifen dass du einen Troll fütterst? Oder ist das reine Absicht? Sorry, so blind kann keiner sein. Aber vielleicht gehörst du zu der Seite die den Troll initiiert hat.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.