Forum: Mikrocontroller und Digitale Elektronik Mehrere Variablen von Master zu Slave Arduino senden


von Nico (nick_alex)


Lesenswert?

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
von Christian M. (christian_m280)


Lesenswert?

Das Problem ist in Zeile 42 deines Sketches!

Gruss Chregu

von Sebastian R. (sebastian_r569)


Lesenswert?

Nico schrieb:
> Wo ist da mein Denkfehler und wie kann ich das Problem beheben?

Byte-Wert ≠ ASCII-Darstellung?

von Peter D. (peda)


Lesenswert?

Du mußt erstmal festlegen, willst Du die Werte binär oder als Textarray 
übertragen und auswerten. Und welchen Bereich sollen sie umfassen.

von Georg G. (df2au)


Lesenswert?

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.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

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

von Monk (roehrmond)


Lesenswert?

Bei I²C finde ich die Verwendung eines Logic Analyzers sehr hilfreich. 
Die 10 Euro sind gut investiert.

von Nico (nick_alex)


Lesenswert?

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
von Sebastian W. (wangnick)


Lesenswert?

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

von Monk (roehrmond)


Lesenswert?

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).

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Monk (roehrmond)


Lesenswert?

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!

von Helmut H. (helmuth)


Lesenswert?

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
von Nico (nick_alex)


Lesenswert?

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
Noch kein Account? Hier anmelden.