Signal invertieren

Hallo Leute,

ich würde gerne ein Ausgangssignal vom Arduino invertieren.
Das Ganze könnte man mit einem Transistor + 2 Widerstände oder mit einem LL Mosfet + einem Widerstand lösen (hab ich beides getestet und funktioniert auch wuderbar).
Dennoch fänd ich eine softwareseitige Lösung etwas eleganter und es spart auch etwas Platz ein (soll alles in ein kleines Gehäuse).

Das Signal das invertiert werden soll ist das Ausgangssignal an Pin1/Tx.

Serial.write(ZuInvertierendesSignal);

Da es anscheinend nichts gibt, was das “normale” Signal vom Hardware Serial invertiert, hatte ich zuerst die Idee, dass ich das über das SoftwareSerial machen könnte

#include <SoftwareSerial.h>
SoftwareSerial softSerial(10, 11, true);

Der 3. Parameter setzt hier das Signal als invertiert.

Problem dabei:
Ich muss 8 kontinuierliche PWM Signale schnell auslesen können.
Das mache ich mit Interrupts der PinChangeInt library

#include <PinChangeInt.h>

// "PWM" input pins 
uint8_t PWM_Channel_1_Pin = 2;

// storage for PWM values and time
volatile uint16_t PWM_Channel_1_Value = 0;
volatile uint16_t PWM_Channel_1_prev_time = 0;

uint8_t latest_interrupted_pin;
//Interrupt functions
void PWM_1_rising()
{
 latest_interrupted_pin=PCintPort::arduinoPin;
 PCintPort::attachInterrupt(latest_interrupted_pin, &PWM_1_falling, FALLING);
 PWM_Channel_1_prev_time = micros();
}

void PWM_1_falling() {
 latest_interrupted_pin=PCintPort::arduinoPin;
 PCintPort::attachInterrupt(latest_interrupted_pin, &PWM_1_rising, RISING);
 PWM_Channel_1_Value = micros()-PWM_Channel_1_prev_time;
}

void setup()
{
 pinMode(PWM_Channel_1_Pin, INPUT); digitalWrite(PWM_Channel_1_Pin, HIGH);
 PCintPort::attachInterrupt(PWM_Channel_1_Pin, &PWM_1_rising, RISING);

 Serial.begin(115200);
}

void loop()
{
 ZuInvertierendesSignal = PWM_Channel_1_Value;
 Serial.write(ZuInvertierendesSignal);  
}

Am Serial-Ausgang dieses Beispiels sollte dann “irgendwie” alles invertiert ausgegeben werden.

Hat jemand eine Idee, wie sich PinChangeInt.h und SoftwareSerial.h nicht in die Quere kommen?
Aktuell bekomme ich so etwas als Fehler:

C:\Users\X\AppData\Local\Temp\arduino_build_480967\libraries\SoftwareSerial\SoftwareSerial.cpp.o (symbol from plugin): In function `SoftwareSerial::read()':

(.text+0x0): multiple definition of `__vector_3'

C:\Users\X\AppData\Local\Temp\arduino_build_480967\sketch\PWM2SBUS.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

C:\Users\X\AppData\Local\Temp\arduino_build_480967\libraries\SoftwareSerial\SoftwareSerial.cpp.o (symbol from plugin): In function `SoftwareSerial::read()':

(.text+0x0): multiple definition of `__vector_5'

C:\Users\X\AppData\Local\Temp\arduino_build_480967\sketch\PWM2SBUS.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

C:\Users\X\AppData\Local\Temp\arduino_build_480967\libraries\SoftwareSerial\SoftwareSerial.cpp.o (symbol from plugin): In function `SoftwareSerial::read()':

(.text+0x0): multiple definition of `__vector_4'

C:\Users\X\AppData\Local\Temp\arduino_build_480967\sketch\PWM2SBUS.ino.cpp.o (symbol from plugin):(.text+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

Vielen Dank und liebe Grüße!

Du willst also das TX der seriellen Schnittstelle invertieren?

Bist Du sicher daß die Gegenstelle nicht ein RS232 erwartet?
Bitte erklähre genau was du machen willst.

Grüße Uwe

Die Gegenstelle ist eine Flugsteuerung, die ein bestimmtes Sendeprotokoll erwartet (SBUS). Dieses hat eine invertierte Logik und daher muss ich das "zusammengebaute SBUS-Signal" anschließend invertieren.

Ich will nicht unbedingt das TX der seriellen Schnitstelle invertieren, sondern es wäre sogar ganz praktisch (zum debuggen), wenn ich das Signal (z.B. per SoftwareSerial) an einem anderen Pin invertiert ausgeben könnte und fürs debuggen dann zusätzlich auch "normal" am echten HardwareSerial.

In jedem Fall muss ich aber irgendein Serial.write oder softwareSerial.write dazu bekommen das gesamte Signal invertiert auszugeben.

Es bitweise zu invertieren funktioniert natürlich nicht:

ZuInvertierendesSignal = ~PWM_Channel_1_Value;
 Serial.write(ZuInvertierendesSignal);

Weil dann die Lows und Highs dazwischen nicht stimmen und der Flugcontroller das Signal nicht erkennt.

Warum meinst Du denn, unbedingt Serial benutzen zu müssen. wenn Du nur senden willst, schießt Du Dir doch ganz offensichtlich selbst ins Knie, wenn den ganzen Overhead mit Interrupts zum Empfangen mitnimmst.

Von welche Datenrate reden wir hier?

Du hast ein digitales Signal mit 5 V?

Dann leg das an einen (fast) beliebigen Pin, lies den in der Loop einfach ein und gibt den invertierten Wert an einem (fast) beliebigen zweiten Pin wieder aus.

in der Loop steht also

Ausgangspin=!Eingangspin

Oder versteh ich das falsch?

@ElCaron: Wir reden hier von einer baudrate von 100.000 und einem 25byte großen Datenstrang, das alle 7ms gesendet wird.

@Klaus_ww: Nein ich habe ein 8 komplett anders aufgebaute Signale, die ich einlese und zu einem Datenstrang namens SBUS_Packet[25] von 24bytes verarbeite. Das wird dann mittels

Serial.write(SBUS_Packet, 25);

ausgegeben

Ich wollte nur als Rückmeldung geben, dass das HardwareSerial ja bekanntlich nicht invertiert werden kann und das SoftwareSerial von mir die "even"-Parität und 2 End-Bits spendiert bekommen hat. Problem war dabei aber, dass etwa jedes 6. Signal verloren ging und die baud von 100.000 einfach zu schnell ist um dabei was brauchbares über SoftSerial auszugeben.

Daher bin ich bei der Hardwarelösung mit MOSFET und 10K Widerstand zum invertieren geblieben