Serielle Kommunikation zwischen Arduino´s

Hallo Community,

ich suche aktuell eine Variante wo ich über einen seriellen Bus mehrere Arduino´s seriell kommunizieren lassen kann. Am Ende soll es für ein H0-Modulbauprojekt sein eines größeren Bahnhof´s. Das Stellsystem soll dabei autark laufen, also ohne PC, sonst könnte ich mein bisheriges Prinzip nutzen.

elektrisch sieht der RS485 Bus am versprechendsten aus, aber mir fehlt irgendwo ein konkretes Beispiel wo mehr als 2 Arduino´kommunizieren.

Schalten und eingänge lesen kriege ich schon hin, sowohl direkt an dem Arduino angesteckt als auch via I2C (da habe ich eine Adafruit Lib)

Meine konkrete Vorstellung wäre das wenn der Master (könnte ein Arduino Mega2560 sein), input von zwei bestimmten tasten (Start-Ziel taste einer Fahrstraße), dann an die entsprechenden Arduino´s die entsprechenden Schaltbefehle sendet.

ein Beispiel wie ich es mir gedacht hatte am Master:

if (buttonPin1 && buttinPin2 == HIGH) { RS485.send(adr31,"fs3-67"); delay (100); }

am entsprechenden Slave

int adr=31;

if (receiveadr=31 && "fs3-67") { digitalWrite (6, OUTPUT); digitalWrite (7, OUTPUT); }

als konkretes Beispiel wie ich es mir denke. Ich habe bisher jedoch nicht das richtige gefunden.

grüße sachsenlok

Du könntest dich z.B. am ModBus orientieren.

Hallo

@noiasca

jein, gibt es schon, möchte ich aber hier nicht nutzen, sonst würde ich auf vorhandene Hardware zurückgreifen und da brauch ich immer einen Laptop/PC und das möchte ich nicht hierbei.

ich suche eher was in die Richtung wie die Adadruit MCP23017 Lib, wo ich halt alles vorher definiere und dann in void loop() nur entsprechend sage, schalte das und das

grüße

Hallo

also DCC Zentrale auf Arduíno Basis gibts schon (hab ich auf platte liegen).

bei Modultreffen ist fahren ein System und wenn ein bahnhof was geschaltet werden muss, muss das autark erfolgen ohne sich die Daten aus dem Fahrkreis zu holen.

wie groß es am Ende wird, das ist noch eine Frage. von einer Einfahrt zu einer Einfahrt ist die längste strecke knapp 27m Wenn ich aber auf bestehendes zurückgreifen wöllte würde ich das machen.

mir gehts hier nich aus kostengründen was eigenes zu entwickeln. Eher aus spaß am entwickeln und basteln. Meine End-Hardware ist für den Uno konzipiert und so etwas Gehirnjogging zu betreiben. Die Hardware verlangt endabgeschaltete motorische Antriebe.

Ich kann auch mein anderes konzept mit Arduino hier verfolgen, ist dann zwar “etwas” mehr Verkabelungsaufwand bei Fahrtreffen aber ginge genauso.

grüße

Und warum nimmst du nicht I2C, so wie von dir schon angedacht ? Auch der MCP23017 ist per I2C steuerbar. Und Master-Slave ist kein so großes Hindernis in I2C. Das zeigt auch diese Doku.

Und Master-Slave ist kein so großes Hindernis in I2C.

Mehrere AVR als Master können schon ein Problem sein! Zwei, ist noch ok, da kann nichts passieren.. Aber je mehr dazu kommen, desto größer wird die Wahrscheinlichkeit einer Kollision/Deadlock, und das wird eben von Wire nicht abgefangen.

I2C,

Hier scheint es um lange Meter zu gehen. Und da ist I2C mit zusätzlichen Hürden verbunden.

Hallo

Den hardware I2C beim uno verwende ich schon für die MCP23017. Bei denen ist die Adresse Hardwareseitig eingestellt( über die Pins A0-A2).

Das tut ist schon mal sehr gut.

Bräuchte ich dann doch ein Software I2C für den “ Hauptbus“''. Die Hardware war auch anders konzipiert worden ( für zwei Arduino in einem Verbund).

Man könnte jetzt auch auf Arduino Due, der zwei I2C hat, aber die Wire.h soll wohl noch nicht ganz so gut sein.

Wie sähe das mit einem Software I2C aus? Da reicht mir eine Vorlage mit Beschreibung, den Rest baue ich darauf auf.

sachsenlok: Den hardware I2C beim uno verwende ich schon für die MCP23017. Bei denen ist die Adresse Hardwareseitig eingestellt( über die Pins A0-A2).

Das tut ist schon mal sehr gut.

Bräuchte ich dann doch ein Software I2C für den “ Hauptbus“''. Die Hardware war auch anders konzipiert worden ( für zwei Arduino in einem Verbund). ....

Wenn jeder Slave seine eigene Adresse hat, kannst du die über einen I2C-Bus betreiben. Da brauchst du keine Software I2C.

combie: Mehrere AVR als Master können schon ein Problem sein! Zwei, ist noch ok, da kann nichts passieren.. Aber je mehr dazu kommen, desto größer wird die Wahrscheinlichkeit einer Kollision/Deadlock, und das wird eben von Wire nicht abgefangen.

Stimmt natürlich, allerdings war von Multi-Master hier bisher noch nicht die Rede.

Hier scheint es um lange Meter zu gehen. Und da ist I2C mit zusätzlichen Hürden verbunden.

Aber auch die sind durch zusätzlicher Hardware lösbar.

Bräuchte ich dann doch ein Software I2C für den " Hauptbus"''. Die Hardware war auch anders konzipiert worden ( für zwei Arduino in einem Verbund).

Es gibt ja auch noch Multiplexer....

Damit bekommt man durchaus 7*16 MCP23017 an einen Hardware I2C dran. Mit nur einem Multiplexer!

sachsenlok:
Bräuchte ich dann doch ein Software I2C für den “ Hauptbus“’’.

Nein. Bei ICs wie MCP23017 gibt es eine Basisadresse, die mittels Eingängen (A0-A2) oder auf andere Art variiert werden kann. Wenn Du einen zweiten Arduino als Slave anschließt, kannst Du den selben I2C-Bus verwenden und ihm eine (nahezu) beliebige Adresse geben, beispielsweise “21”:

Wire.begin(21);

Jeder Slave bekommt eine eindeutige Adresse im Bus.

Ein Beispiel von mir.

Einführung in den I2C-Bus

I2C - Two-Wire Peripheral Interface - for Arduino

Die I2C-Extender Testplatine mit P82B715 / breakout board für die große Entfernung.

Hallo

@agmue

da ich die Adafruit_MPC23017 lib bevorzuge wie sähe es dann aus

ich hab es mir so gedacht:

master->

void loop()
{
if (buttonState1&&buttonState3== HIGH)
{
Wire.begin(21);
wire.write (werte,5);
Wire.end();
}
}

slave->

void setup() {
 Serial.begin(9600);
 Wire.begin(21);
 Wire.onReceive(receiveEvent);
}
void loo()
{
if (receivewert == 5)
{
 mcp1.digitalWrite (9, LOW);
 mcp1.digitalWrite (7, HIGH);
}
}

grüße

Setze deinen Sketch bitte in Code-Tags, damit ist er für alle besser lesbar
Verwende die Schaltfläche </> oben links im Editorfenster.

Edit:
Ok, so ist er besser lesbar…aber leider unvollständig.
Warum postest du die Sketche nicht komplett ?

Also die Entscheidung gegen BUS ist schon gefallen? Ich denke die Ansage die combie gemacht hat mit Modbus hat schon immense Vorteile. d.h. mehrere Station die miteinander schon unterhalten. Modbus ist ein Industrie Standard es lassen sich sehr schnell auch HMI aufbauen bzw. einbinden. Erweiterungen bestehender Anlagen sind extrem schnell umzusetzen. Mit einem NodeMCU ist ratz fazt ein WLAN drin mit dem du auch via HANDY entweder auf dem ESP eine Website zum steuern nutzt oder eine Modbus APP mit den entsprechenden vorgaben. Willst du eine zuverlässige HMI kannst du auch mal eben eine von Kinco dranhängen mit Modbus und das ist drag drop ohne komplizierte Zeichnerrei via Arduino oder das komplizierte Handling via seriell mit dem Nextion entfällt auch. nur ein TIP Gruß DerDani

Wire.begin(21);

Das gehört zum Slave nach setup, steht da ja auch.

Wire.beginTransmission(21);

Das adressiert den Slave mit Adresse 21.

mcp1.digitalWrite (9, LOW);

Das gehört zum Master.

Beim Slave fehlt die Interrupt Service Routine (ISR) receiveEvent gänzlich.

Hallo

wenn ich das hoffentlich richtig verstanden habe

master (mal auf einen Arduino Mega bezogen)

#include <Wire.h>
#include <Adafruit_MCP23017.h>

const int buttonPin1 = 26
const int buttonPin3 = 27

int buttonState1 = 0;
int buttonState3 = 0;
void setup(){
serial.begin (9600);
wire.begin ();
pinMode(buttonPin1, INPUT);
pinMode(buttonPin3, INPUT);
}

void loop()
{
buttonState1=digitalRead(buttonPin1);
buttonState3=digitalRead(buttonPin3);

if (buttonState1 && buttonState3==HIGH)
{
wire.beginTransmission(21);
mcp1.digitalWrite (8,LOW);
mcp1.digitalWrite (9, HIGH);
wire.endTransmission
}
}

slave

#include <Wire.h>
#include <Adafruit_MCP23017.h>

Adafruit_MCP23017 mcp1

volatile bool flag = false;
volatile byte werte[2];

void setuo (){
Serial.begin(9600);
Wire.begin(21);
Wire.onReceive(receiveEvent);
mcp1.begin (0); //mcp1 adr 0x20
mcp1.pinMode (15, INPUT); //Kontaktmelder über optkoppler als Haltmelder
mcp1.pinMode (8, Output);
mcp1.pinMode (9, Output);
}

void loop()
{
if (flag){
flag=false;

if (mcp1.digitalRead(15==HIGH)
}
mcp1.digitalWrite (9 LOW);
mcp1.digitalWrite (8, HIGH);
}
}

void receiveEvent (int howMany)
{
data.Werte[j]=Wire.read();
flag = true;

}

die Zustände des 23017 muss ich ja beim slave definieren? die Adafruit Lib muss ich ja auch beim Master definieren, sonst weiß die IDE ja nix mit anzufangen.

@volvodani

ich glaub mit Modbus ist derzeit fast zuviel des guten.

grüße

sachsenlok: die Zustände des 23017 muss ich ja beim slave definieren?

Nein.

Elektrisch hängen Master, Slave und MCP23017 am selben Bus. Logisch hängen Slave und MCP23017 nur am Master. Der Master kommuniziert mit dem Slave (oder den Slaves) und der Master kommuniziert mit dem MCP23017 (oder den MCP23017gern). Würde der Slave mit dem MCP23017 kommunizieren wollen, würde er als Master agieren (der MCP23017 kann nur als Slave), was zu einem Multimaster-Bus führen würde. Theoretisch kann das Protokoll des I2C-Busses das, praktisch begeben wir uns in stürmisches Gewässer.

So lange die Slaves mit den eigenen Ein- und Ausgängen klarkommen, wird das, was Du vorhast, funktionieren. Auch kannst Du weitere I2C-Hardware anschließen, solange diese ausschließlich von dem einen Master angesprochen wird. Auch ein LC-Display am I2C-Bus wäre beispielsweise möglich, wobei die Kapazität jedes Busses endlich ist.

Modbus und CAN-Bus kenne ich nicht, daher schreibe ich nichts dazu, aber durchaus möglich, daß die besser geeignet wären.

Hallo

bezüglich des 23017 habe ich eine andere Lösung. Es gibt ja auch ein äquivalentes Gegenstück für SPI, den MCP23S17. Das Layout ändert sich nur marginal, statt der beiden I2C Leitungen gehen halt die 4 Leitungen für SPI drann.

Programmtechnisch wird er fast genauso adressiert und angesprochen wie der MCP23017. Das Pinning für die I/O ist identisch mit dem 23017. im arduino Playground ist auch alles gut dokumentiert und leicht verständlich. Ich binde halt nur eine andere lib ein.

Damit sind Port Expander und Bus wieder getrennt voneinander.

grüße

sachsenlok: Damit sind Port Expander und Bus wieder getrennt voneinander.

Und warum machst du das ? Das sehe ich als aufwändiger an, als es am I2C zu lassen.

HotSystems: Das sehe ich als aufwändiger an, als es am I2C zu lassen.

ich sehe es für mich als einfacher an, die Port Expander am jeweiligen Slave zu haben und von dort aus anzusprechen als vom I2C Master aus. da hab ich für mich eher eine Übersicht und kann meine Dokumentation vereinfachen.

grüße