Zwei serielle Schnittstellen mit Nano: welche Libraries?

Ich habe ein kleines Projekt, das von einer optischen D0(SML)-Schnittstelle (Stromzähler) auf eine Halbduplexschnittstelle (RS485, MODBUS) umsetzen soll. Dazu will ich einen Nano benutzen, der ja keine Hardware-Serial außer der zum Programmieren benutzten besitzt.

Das D0-Signal ist Read-only und kommt mit 9600 8N1 an, in Paketen von ca. 400 Byte Größe und etwas Pause zwischen den Paketen.

Die RS485-Schnittstelle läuft mit 19200 8N1; wann dort Datenpakete kommen, ist unbestimmt. Die sind wenige Byte groß, sie werden mit Paketen von ebenfalls wenigen bis zu ca. 520 Byte beantwortet (was innerhalb von 1s passieren sollte, um Timeouts auf dem MODBUS zu vermeiden).

Stellt sich mir die Frage nach der/den empfehlenswerten Serial-Libraries.

SoftwareSerial: mehrere gleichzeitig möglich, allerdings immer nur eine davon in Aktion. Hohe Latenz. Außerdem ist die auch halfduplex, also geht entweder Senden oder Lesen. In meinem Falle aber okay, weil ich ja auf beiden Schnittstellen immer nur einen Modus habe.

AltSoftSerial: duplexfähig, geringe Latenz. Es ist aber nur eine davon möglich, sie müsste also mit einer SoftwareSerial kombiniert werden.

Jetzt sagt die Doku zu AltSoftSerial, dass man wegen der Latenz die SoftwareSerial für die schnellere Schnittstelle nehmen sollte. Die Logik dahinter entzieht sich mir etwas.

Ich habe auch eine Anzahl ATtiny85 herumliegen. Möglich, wenn auch aufwendig, wäre auch je ein ATtiny mit einer SoftwareSerial an beiden Schnittstellen, die dann über I²C mit dem Nano verbunden sind, der die eigentliche Logik enthält. 500 Byte Puffer könnten im ATtiny möglich sein, was das Ganze zusätzlich zeitlich entkrampfen würde. Allerdings dürften sich SoftwareSerial und I²C um die Interrupts streiten und im schlechtesten Fall gegenseitig blockieren.

Oder ich muss doch etwas anderes als den Nano nehmen... Vom Formfaktor ist der ideal, weil schön klein. Ein Mega2560 ist dagegen ja ein ziemliches Brett, hat aber genügend UARTs. Ein ESP32 ist Kanonen auf Spatzen, ein ESP8266 hat wieder keine UARTs usw. Argh...

Habt Ihr Empfehlungen oder eine ganz andere Idee?

Hallo,

wieviele serielle Schnittstellen brauchst du denn wirklich?

Doc_Arduino:
Hallo,

wieviele serielle Schnittstellen brauchst du denn wirklich?

Zwei - siehe oben. Eine zum Empfang der D0-Pakete, die andere zum Empfangen und Senden von RS485-Daten.

(deleted)

Peter-CAD-HST:
Moin Miq1

nimm am besten 2 Nanos und programmiere mit #include <SoftwareSerial.h> die seriellen Schnittstellen, die du brauchst.
Und dann teste einfach ob die beiden Nanos sich bei 19k6 verstehen. Dafür brauchst du keine Pegelwandler nach RS422 oder was auch immer.

Gruss Peter
und gesund bleiben…

Mhm, RS485 ist Pflicht, da das Ding an einen existierenden MODBUS gehängt werden soll. Aber 2 Nanos ist vielleicht gar nicht blöd: da kann ich auf beiden AltSoftSerial mit der geringen Latenz benutzen (einen am D0- und den anderen am RS485-Anschluss) und lasse die beiden mit I²C untereinander reden. Mal sehen, wohin das führt.

(deleted)

Wenn es klein bleiben soll, könnte auch ein pro Micro eine Alternative sein. Der hat für die Programmierung eine native USB Schnittstelle, und damit ist die serielle HW-Schnittstelle frei verfügbar. Dann brauchst Du nur noch eine SoftSerial, was dann ja kein Problem sein sollte.

MicroBahner:
Wenn es klein bleiben soll, könnte auch ein pro Micro eine Alternative sein. Der hat für die Programmierung eine native USB Schnittstelle, und damit ist die serielle HW-Schnittstelle frei verfügbar. Dann brauchst Du nur noch eine SoftSerial, was dann ja kein Problem sein sollte.

Den kannte ich noch gar nicht, danke für den Tipp.

Ich freunde mich immer mehr mit der 2-Nano-Lösung an, denn die habe ich eh im Vorrat :wink:

Ich würde den Mega 2560 PRO Mini mit kleinen Abmessungen verwenden.

Alternativ auch Teensy 3.2 mit drei UARTs, klein aber teuer.

Wenn die "Kanone" ESP32 günstig ist, kann Dir die ungenutzte Elektronik doch egal sein.

agmue:
Alternativ auch Teensy 3.2 mit drei UARTs, klein aber teuer.

Dann auch eine 'bluePill' - STM32F103. Klein, hat auch 3 Uarts, ist aber billig :wink:

Leider ein wenig ein 'Exot' bei den Arduinos, aber mit sehr gutem Preis/Leistungsverhältnis.

agmue:
Ich würde den Mega 2560 PRO Mini mit kleinen Abmessungen verwenden.

...

Wenn die "Kanone" ESP32 günstig ist, kann Dir die ungenutzte Elektronik doch egal sein.

Der Mega PRO mini ist aber ein Gerät! Doppelreihige Anschlussleisten! Klar, sonst kriegt man die ganzen Pins nicht an den Boden :slight_smile:
Bei dem Preis liegt dann aber wirklich der ESP32 näher, zumal ich mich mit dem inzwischen ganz gut auskenne.

MicroBahner:
Dann auch eine 'bluePill' - STM32F103. Klein, hat auch 3 Uarts, ist aber billig :wink:

Leider ein wenig ein 'Exot' bei den Arduinos, aber mit sehr gutem Preis/Leistungsverhältnis.

Auch nicht schlecht. Da habe ich noch nie was mit gemacht, aber soll ja weitgehend Arduino-kompatibel sein? und 3 UARTS sind ja mehr als genug :slight_smile:

Jetzt hast Du die Qual der Wahl, nur SoftwareSerial fällt raus.

Hallo,

wieviel du benötigst wurde dann leider im Text etwas schwammig, weil moniert wurde das bei mancher Lib nur eine Serielle möglich sei und das als Einschränkung zu betrachten war. Nur deshalb die konkrete Nachfrage. Gut, also 2.

2 Nanos macht es nur komplizierter, es müssen Daten untereinander ausgetauscht werden.

Ich hätte auch noch eine Option. Arduino Nano Every mit Board-Package von MCUdude (Github). Hat man 2 zusätzliche Serielle, abgesehen von der Serial-USB belegten.

Doc_Arduino:
Ich hätte auch noch eine Option. Arduino Nano Every mit Board-Package von MCUdude (Github). Hat man 2 zusätzliche Serielle, abgesehen von der Serial-USB belegten.

Scheint mir dann die problemloseste Variante im Nano-Format zu sein. Ich hatte den Every nicht vorgeschlagen, weil ich diesen Core nicht kannte, und der Standard-Core nur eine serielle ( neben USB ) unterstützt. Aber wenn dieser Core die Hardware de 4809 besser ausreizt, ist das eine perfekte Lösung ( Wenn man die Leistung eines 32Bit-Arm Kerns nicht braucht ).

Miq1:
Auch nicht schlecht. Da habe ich noch nie was mit gemacht, aber soll ja weitgehend Arduino-kompatibel sein? und 3 UARTS sind ja mehr als genug :slight_smile:

Der STM32F103 als 'BluePill' Variante ist etwas schwieriger ans Laufen zu bringen, da er meines Wissens immer ohne Bootloader geliefert wird. Den muss man erst draufbringen. Als 'Maple Mini' ist er besser Arduino-kompatibel ( mit Bootloader und Arduino-Pinnumerierung auf dem Board ). Aber leider nur vom FC zu bekommen.

Hallo,

habe meinen frischen Nano Every soeben frisch verlötet und bin am testen, extra für das Forum gekauft. Hatte bis jetzt einen nackten ATmega4808 und einen 4809 auf einem ATmega4809 Curiosity Nano Board in der Mache. Hatte auch das MCUdude Package hier und da probiert, was soweit auch klappte. Jetzt war ich am testen mit dem Arduino Nano Every wegen der 3 Seriellen und muss feststellen, funktioniert nicht wie beschrieben. Entweder verstehe ich die Doku falsch oder ... Momentan bekomme ich nur Null Terminatoren ausgegeben aber keinen Text.

Demzufolge muss ich mit der Empfehlung erstmal zurückrudern bis das geklärt ist. Tut mir leid, ich dachte das wäre alles glasklar mit der Doku und dem Every. Das wäre jetzt doof wenn das nicht klappt.

siehe #18.

Danke Euch für die guten Tipps! Ich habe inzwischen - weil ich die Teile da hatte - die 2-Nanos-Variante zusammengesteckt und werde damit meine Versuche machen. Für die finale Lösung gefällt mir der Every schon sehr gut, auch weil ich mir da einen Spannungsregler sparen kann. Wenn ich den mit der alternativen Firmware auch in der Platformio-IDE beackern kann, ist der ideal. Ansonsten werde ich mich auf den STM32 begeben.
Danke nochmal!

Hallo,

Entwarnung :slight_smile: , es funktionieren alle 3 seriellen Schnittstellen.

Standardmäßig hat der Nano Every 2 serielle Schnittstellen. Eine liegt auf USB und die zweite auf den Pins D1/D0. MCUdude hat noch die Möglichkeit des Pinroutings eingebaut. Damit kann man die USB Serielle auch auf die Pins umlegen und zusätzlich steht eine dritte Serielle zur Verfügung.

Ein Codebsp. für alle 3 Seriellen auf den Pins.

/*
  IDE 1.8.13
  Arduino Nano Every
  https://github.com/MCUdude/MegaCoreX
*/


void setup (void)
{
  Serial.swap(1);
  Serial.begin(9600);         // swapped USB to Pin Tx D9, Rx D10
  Serial.println("\nStart");
  
  Serial1.begin(9600);        // default Pin Tx D1, Rx D0
  Serial1.println("\nStart");

  Serial2.swap(1);
  Serial2.begin(9600);        // swapped to Pin Tx D2, Rx D7
  Serial2.println("\nStart");
}

void loop (void)
{
  serialOutput(500);
}


// ****** Funktionen ******

void serialOutput(const unsigned int interval)
{
  static unsigned long lastMillis = 0;
  
  unsigned long ms = millis();

  if (ms - lastMillis >= interval)
  {
    lastMillis = ms;
    Serial.println("Ich bin Serial.0");
    Serial1.println("Ich bin Serial.1");
    Serial2.println("Ich bin Serial.2");
  }
}

Super, dass das klappt - ist definitiv eine Option.

Aktuell scheitere ich an den Basics und weiß nicht, ob ich verblödet bin… >:(

Ich versuche ganz banal, einen weiteren Nano als Simulator für den MODBUS zu benutzen. Der soll auf Knopfdruck einen MODBUS-Request an den einen Nano des 2-Nano-Setups senden. Ich kriege es nicht hin… RX soll D8, TX D9 sein. Auf dem Empfänger Nano genauso, TX/RX sind natürlich gekreuzt.

Code auf dem Simulator (gestrippt):

#include <Arduino.h>
#include <SoftwareSerial.h>

SoftwareSerial MODBUS(8, 9);

// -----------------------------------------------------------------------------
// Debounce routine for button. Gets digitalRead() as input.
// -----------------------------------------------------------------------------
bool Debouncer(bool raw)
{
  static uint16_t State = 0;
  State = (State<<1)|(!raw)|0xE000;
  return(State==0xF000);
}

void setup() 
{
  // Button
  pinMode(3, INPUT);

  pinMode(8, INPUT);
  pinMode(9, OUTPUT);

  // Start MODBUS
  MODBUS.begin(19200);

  Serial.begin(9600);
  Serial.println("");
}

void loop() 
{
  if(Debouncer(digitalRead(3)))
  {
    // Button pressed. Send MODBUS request
...
    Serial.println("Send...");
    MODBUS.write(inPacket, inPacketLen);
  }
  // Response coming in?
  if(MODBUS.available())
  {
    Serial.println("Wait...");
...
    Serial.println(" done.");
  }
}

Da ist schon irgendwas faul. Eine LED mit Vorwiderstand, testweise an Pin D9 gegen GND angeschlossen, ist dauer-an, also liegt an D9 konstant HIGH - passt irgendwie nicht, oder?
Im Serial Monitor sehe ich das “Send…”, sobald ich den Button drücke, aber das war es dann auch schon. Ich habe keine Idee, was ich da verbockt habe.