Guten Abend, Ich komme bei meinem Projekt nicht recht weiter und bin auf eure Hilfe angewiesen... Ich möchte 100 byte Variablen mit Werten zwischen 0 und 16 vom Master zu 3-4 Slave Arduino megas übergeben um Motoren zu steuern. Die Werte der Variablen werden durch ein touch Display eingestellt. Eine Übertragung eines Arrays mit festgelegten Zahlen per I2C habe ich hinbekommen, aber wenn ich zb die variable x ins Array schreibe und byte x den Wert von beispielsweise 12 zuweise, wird aus der 12 im seriellen Monitor des slaves eine 0. Wo ist da mein Denkfehler und wie kann ich das Problem beheben? Vielen Dank! Nico
:
Bearbeitet durch User
Das Problem ist in Zeile 42 deines Sketches! Gruss Chregu
Nico schrieb: > Wo ist da mein Denkfehler und wie kann ich das Problem beheben? Byte-Wert ≠ ASCII-Darstellung?
Du mußt erstmal festlegen, willst Du die Werte binär oder als Textarray übertragen und auswerten. Und welchen Bereich sollen sie umfassen.
Nico schrieb: > wie kann ich das Problem beheben? Da die Glaskugel gerade zur Politur eingeschickt wurde, kann ich dir nur so pauschal antworten, wie du gefragt hast. Als Erstes solltest du einen Monitor (Logikanalysator) auf der Verbindung Master <-> Slave lauschen lassen. Dann siehst du, ob der Sender Müll schreibt oder der Empfänger Verständnisprobleme hat. Nach der Messung diskutieren wir dann weiter. Es würde nicht schaden, wenn du etwas über die Art der Verbindung Master <-> Slave sagen würdest und auch die Sende- und Empfangsroutinen könntest du (als Anhang) zeigen. Dann geht es vielleicht auch ohne Glaskugel weiter.
Nico schrieb: > Wo ist da mein Denkfehler Keine Ahnung! Nico schrieb: > wie kann ich das Problem beheben? 1. Problem analysieren 2. Lösung erarbeiten 3. Lösung durchsetzen
Bei I²C finde ich die Verwendung eines Logic Analyzers sehr hilfreich. Die 10 Euro sind gut investiert.
Hallo zusammen, Danke für eure Beiträge! Ich beschäftige mich erst seit einiger Zeit mit Programmierung, hat bisher auch ganz gut funktioniert, aber zu diesem Problem habe ich noch nicht wirklich viel im Netz gefunden. Also ich würde gerne durch das Touch Display bis zu 100 Variablen einen ganzzahligen Wert von 0....16 zuweisen, und diese dann nach jeder neuen Wertänderung an die Slaves weiterleiten per I2C. Die Code Beispiele unten funktionieren, nur nicht für die Variable x. Beispielcode für den Master:
1 | #include <Wire.h> |
2 | |
3 | byte Wert[29]; // Anzahl der Elemente im Array welches übertragen wird |
4 | |
5 | byte x; |
6 | |
7 | void setup() { |
8 | Serial.begin(9600); |
9 | Wire.begin(); //I2C initialisieren |
10 | }
|
11 | |
12 | void loop() { |
13 | |
14 | x=16; //Variable x wird Wert 16 zugewiesen |
15 | |
16 | Wert[0]=1; |
17 | Wert[1]=2; |
18 | Wert[2]=3; |
19 | Wert[3]=4; |
20 | Wert[4]=5; |
21 | Wert[5]=0; |
22 | Wert[6]=1; |
23 | Wert[7]=0; |
24 | Wert[8]=1; |
25 | Wert[9]=0; |
26 | Wert[10]=1; |
27 | Wert[11]=0; |
28 | Wert[12]=1; |
29 | Wert[13]=0; |
30 | Wert[14]=1; |
31 | Wert[15]=0; |
32 | Wert[16]=1; |
33 | Wert[17]=0; |
34 | Wert[18]=1; |
35 | Wert[19]=0; |
36 | Wert[20]=1; |
37 | Wert[21]=16; |
38 | Wert[22]=1; |
39 | Wert[23]=0; |
40 | Wert[24]=1; |
41 | Wert[25]=0; |
42 | Wert[26]=8; |
43 | Wert[27]=x; //hier ist die Variable x, im Slave wird daraus im Seriellen //Monitor eine 0 |
44 | Wert[28]=0; |
45 | |
46 | |
47 | Wire.beginTransmission(6);// Senden an Slave #6 |
48 | |
49 | Wire.write((byte*)Wert, sizeof(Wert)); |
50 | |
51 | Wire.endTransmission(); |
52 | |
53 | |
54 | delay(50); |
55 | }
|
Beispielcode Slave:
1 | #include <Wire.h> |
2 | |
3 | volatile byte Wert[28]; |
4 | |
5 | volatile bool newData = false; |
6 | |
7 | |
8 | void setup() { |
9 | |
10 | |
11 | Serial.begin(9600); |
12 | Wire.begin(6); |
13 | |
14 | Wire.onReceive(receiveEvent); |
15 | delay(5000); |
16 | }
|
17 | |
18 | |
19 | void loop() { |
20 | |
21 | |
22 | if (newData) |
23 | {
|
24 | for (int i = 0; i < 29; i++) |
25 | {
|
26 | Serial.println(Wert[i]); |
27 | }
|
28 | |
29 | newData = false; |
30 | }
|
31 | delay(5000); |
32 | }
|
33 | void receiveEvent(int howMany) |
34 | {
|
35 | |
36 | |
37 | if (howMany == 29) |
38 | {
|
39 | Wire.readBytes((byte*)Wert, 29), |
40 | |
41 | newData = true; |
42 | }
|
43 | }
|
:
Bearbeitet durch User
Keine Ahnung, ob es daran liegt, aber du solltest in receiveEvent besser:
1 | if (!newData && howMany == 29) |
verwenden. Der Hintergrund ist, dass receiveEvent in einem ISR-Kontext gerufen wird, und also während du in der for(int i=0;i<29;i++)-Schleife iterierst dazwischen grätschen und neue Einträge in Wert machen kann. LG, Sebastian
Ich habe keine Erklärung für das Phänomen. Allerdings behalte mal im Hinterkopf, dass die I²C Bilbiothek von Arduino maximal 64 Bytes puffert. Die Hälfte davon hast du schon verwendet (was OK ist).
Nico schrieb: > byte Wert[29]; // Anzahl der Elemente im Array welches übertragen wird > > volatile byte Wert[28]; Sollte nicht der Buffer beim Empfänger mindestens gleich groß sein wie der des Senders?
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Sollte nicht der Buffer beim Empfänger in etwa gleich groß sein wie der > des Senders? Adlerauge sei wachsam. Das wird es wohl sein!
Der Master wartet 50 ms zwischen den Transmits von 29 Byte. Der Slave braucht bei 9600 geschätzt 1 ms um ein Zeichen auszugeben. Würde das Delay im Master deutlich raufsetzen, das Delay(5000) im Slave weglassen und die Baudrate höher setzen. Steve van de Grens schrieb: > dass die I²C Bilbiothek von Arduino maximal 64 Bytes > puffert kommt drauf an, bei IDE 1.8 sinds nur 32, siehe C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\Wire\src\Wire.h #define BUFFER_LENGTH 32
:
Bearbeitet durch User
Steve van de Grens schrieb: > Lothar M. schrieb: >> Sollte nicht der Buffer beim Empfänger in etwa gleich groß sein wie der >> des Senders? > > Adlerauge sei wachsam. Das wird es wohl sein! lag tatsächlich daran! Danke, jetzt funktioniert es... Die anderen Tips werde ich auch beherzigen VG Nico
:
Bearbeitet durch User
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.