Smart Meter auslesen und RF433 beißt sich

Hallo Forum,
ich habe ich ein Problem mit meinem Nano.
Ich nutze Serial um den Zähler auszulesen mit einem IR-Lesekopf.
Da habe ich mich an einem der Skripte hier aus dem Forum orientiert.
Dann habe ich noch RF433 Sender und Empfänger um die aktuell anliegende Leistung am Zähler zu senden.
Beides funktioniert für sich gut, aber die Kombination klappt nicht.
Wenn ich den Code nur SML lesen lasse, dann findet er einwandfrei die Leistung und wenn ich nur die Demo von Sender/Empfänger laufen lassen, dann eben so.
Wenn ich nun aber den Empfänger den Zähler auslesen lasse, dann hört er auf zu senden.
Ich hab den auslese code ein zweites mal geschrieben, diesemal String-basiert. Ich habe statt der RCswitch Bibliothek die VirtualWire eingebunden. Ich habe den Pin gewechsel um an einem anderen Port aktiv zu sein.
Es klappt nicht und ich habe keine Ahnung warum.
Weis einer von euch von Kompatibiltäts-Problemen von Serial und RF433 ?

Sendertest mit RCswitch (klappt)

#include <RCSwitch.h>


// Verbindungen zum Uno
// GND > D4
// VCC > D3
// Daten > D7

byte ledstate=0;
// char *msg = "Hallo Welt";// Nachricht
RCSwitch mySwitch = RCSwitch();
 
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(7, OUTPUT);
//  pinMode(4, OUTPUT);   // GND 0V
  digitalWrite(4, LOW);
//  pinMode(3, OUTPUT);   // VCC 5V
//  digitalWrite(3, HIGH);
  mySwitch.enableTransmit(7);
}
 
void loop(){
  mySwitch.send(5393, 24);
  delay(1000);  
  mySwitch.send(5396, 24);
  delay(1000);
   
  //if the LED is off turn it on and vice-versa:
  if (ledstate == LOW) {
    ledstate = HIGH;
  } else {
    ledstate = LOW;
  }  
  digitalWrite(LED_BUILTIN, ledstate);
//  digitalWrite(2, ledstate);
}

Empfängertest RCswitch (klappt)

#include <RCSwitch.h>

// 433 MHz Sender
//
// Matthias Busse 16.5.2014 Version 1.0

// Verbindungen zum Uno
// GND > D5
// VCC > D6
// Daten > D7

int led = 13;
int data = 2;
bool Mode=0;
RCSwitch mySwitch = RCSwitch();

void setup(){
 Serial.begin(9600);
 pinMode(led, OUTPUT);
 pinMode(data, INPUT);
 mySwitch.enableReceive(0);  // Receiver on interrupt 0 => that is pin #2 nano
 digitalWrite(data, LOW);  // Daten
}

void loop() {     // data lesen und LED entsprechend schalten
  if (mySwitch.available()) {
    Mode = !Mode; //toggel Led if Message recieved
    Serial.print("Received ");
    Serial.print( mySwitch.getReceivedValue() );
    Serial.print(" / ");
    Serial.print( mySwitch.getReceivedBitlength() );
    Serial.print("bit ");
    Serial.print("Protocol: ");
    Serial.println( mySwitch.getReceivedProtocol() );
    mySwitch.resetAvailable();
  }
  digitalWrite(led, Mode);
}

Sender Virtual Wire (klappt)

#include <VirtualWire.h>
// 433 MHz Sender mit der VirtualWire Library  V 1.27

int power1=909;
int power2=303;
bool ledstate=LOW;
 
void setup() {
  pinMode(7, OUTPUT);
  vw_setup(500);       // Bits pro Sekunde
  vw_set_tx_pin(7);     // Datenleitung
}
 
void loop(){
//  vw_send((uint8_t *)msg, strlen(msg));
  vw_send((byte *) &power1, sizeof(power1)); 
  vw_wait_tx();                         // warten bis alles übertragen ist
  delay(1000);
  vw_send((byte *) &power2, sizeof(power2)); 
  vw_wait_tx();                         // warten bis alles übertragen ist
    //if the LED is off turn it on and vice-versa:
  if (ledstate == LOW) {
    ledstate = HIGH;
  } else {
    ledstate = LOW;
  }  
  digitalWrite(LED_BUILTIN, ledstate);
}

Empfänder mit Virtual Wire (klappt)

#include <VirtualWire.h>
bool Mode=0;
int transmit;
    
void setup() {
  Serial.begin(9600);
  vw_setup(500);
  vw_set_rx_pin(2); 
  vw_rx_start(); 

  Serial.println("Value : ");
}

void loop() {

  byte wireless = sizeof(int);
  vw_wait_rx();
  if (vw_get_message((byte *) &transmit, &wireless)) {
    Serial.println(transmit); 
    Serial.println(transmit*2);
    Mode = !Mode;
  }
  digitalWrite(LED_BUILTIN, Mode);
}

LEider komme ich hier an den 9000 Zeichen limit - Vriante 1 gibt vielleicht im 2ten Post

2te, kleinere Variante, stringbasiert, Virtual Wire, klappt auch nicht.
Hier ist auch noch Serial abgescahltet im Zeitpunkt des Sendens. In dieser Variante habe ich auch der Senderdemo mal den Sendebefehlt eingeführt und übertrage nicht den SML Wert (zum Test, aber klappt auch nicht).

#include <VirtualWire.h>

String inputString="";            // Eingabe String Daten
bool stringComplete=false;        // String abgeschlossen
String powerString;
char charBuf[8];
int value;
bool Mode=0;
int power1=909;
int power2=303;


void setup() {
  Serial.begin(9600);            // Baud
  inputString.reserve(64);        // 64 Byte Platz für den Seriellen Text
  vw_setup(500);       // Bits pro Sekunde
  vw_set_tx_pin(7);     // Datenleitung
}

void loop() {
  if(stringComplete) {
    Serial.end();
    Serial.print("String : ");      // String ausgeben
    Serial.println(inputString);  
    //Serial.println(inputString.length()); 
    int powerTag = inputString.indexOf("070100100700FF0101621B520055");
    //Serial.print("powerTag ");
    //Serial.println(powerTag);
    powerString=inputString.substring(powerTag+28, powerTag+28+8);
    Serial.println(powerString);
    //für Konvertierung in Dec   
    for(int y = 0; y< 9; y++){ 
      charBuf[y]=powerString[y]; 
    }
    value = strtoul(charBuf, NULL, 16);  
    //Endlich abgeschlossen
    Serial.println(value);
    //vw_send((byte *) &value, sizeof(value)); 
    //vw_wait_tx();                         // warten bis alles übertragen ist

    vw_send((byte *) &power1, sizeof(power1)); 
    vw_wait_tx();                         // warten bis alles übertragen ist
    delay(1000);
    vw_send((byte *) &power2, sizeof(power2)); 
    vw_wait_tx();  
    
    
    Mode = !Mode;
    stringComplete=false;
    inputString="";
    digitalWrite(LED_BUILTIN, Mode);
    Serial.begin(9600); 
  }
}

void serialEvent() {
// Wird aufgerufen wenn an RX Daten angekommen sind, ausserhalb von loop().
// Ein delay() in loop() kann die Datenübernahme verzögern.
// Der Arduino RX Buffer ist standardmässig 64 Zeichen groß, kann aber ggf. vergrößert werden.
  while(Serial.available()) {        // bis alle Zeichen im RX Buffer ausgelesen sind
    char inChar=(char)Serial.read(); // ein Zeichen im RX Buffer auslesen
    if(inputString.length()==720) {             // String Ende erkennen
      stringComplete=true; 
    }
    else {                            // Zeichen anhängen
      inputString+=inChar; 
    }
  }
}

Zur Vollständigkeit noch Variante 1, SML geht, Senden nicht (mit Snapshot vom Zähler)

#include <VirtualWire.h>

// Verbindungen zum Uno
// GND > GND
// VCC > VCC
// Daten > D7

byte inByte; //byte to store the serial buffer
byte smlMessage[1000];

// const byte snapshot[]=    {0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01, 0x76, 0x05, 0x00, 0x51, 0xAD, 0x9E, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x01, 0x01, 0x76, 0x01, 0x01, 0x05, 0x00, 0x1B, 0x39, 0xE0, 0x0B, 0x09, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x2D, 0x41, 0x96, 0x01, 0x01, 0x63, 0x4E, 0xC0, 0x00, 0x76, 0x05, 0x00, 0x51, 0xAD, 0x9F, 0x62, 0x00, 0x62, 0x00, 0x72, 0x63, 0x07, 0x01, 0x77, 0x01, 0x0B, 0x09, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x2D, 0x41, 0x96, 0x07, 0x01, 0x00, 0x62, 0x0A, 0xFF, 0xFF, 0x72, 0x62, 0x01, 0x65, 0x00, 0x2B, 0xC9, 0xB3, 0x7A, 0x77, 0x07, 0x81, 0x81, 0xC7, 0x82, 0x03, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x04, 0x49, 0x53, 0x4B, 0x01, 0x77, 0x07, 0x01, 0x00, 0x00, 0x00, 0x09, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x0B, 0x09, 0x01, 0x49, 0x53, 0x4B, 0x00, 0x04, 0x2D, 0x41, 0x96, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x00, 0xFF, 0x65, 0x00, 0x01, 0x01, 0xA2, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x7E, 0x32, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x01, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x7E, 0x32, 0x01, 0x77, 0x07, 0x01, 0x00, 0x01, 0x08, 0x02, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x77, 0x07, 0x01, 0x00, 0x02, 0x08, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x1F, 0x76, 0x01, 0x77, 0x07, 0x01, 0x00, 0x02, 0x08, 0x01, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x1F, 0x76, 0x01, 0x77, 0x07, 0x01, 0x00, 0x02, 0x08, 0x02, 0xFF, 0x01, 0x01, 0x62, 0x1E, 0x52, 0xFF, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x77, 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00, 0x55, 0xFF, 0xFF, 0xFC, 0x10, 0x01, 0x77, 0x07, 0x81, 0x81, 0xC7, 0x82, 0x05, 0xFF, 0x01, 0x01, 0x01, 0x01, 0x83, 0x02, 0x42, 0xAF, 0xCD, 0xD4, 0x23, 0x10, 0x90, 0x3E, 0x8F, 0x0A, 0xDC, 0x62, 0x58, 0x7B, 0xAE, 0xC7, 0x9C, 0xB7, 0xA5, 0x8B, 0xD8, 0x82, 0x86, 0xB4, 0x52, 0x0C, 0x63, 0x2C, 0x05, 0xE2, 0xAB, 0xB3, 0xD7, 0xA8, 0x2B, 0xCE, 0x26, 0xD4, 0x32, 0x16, 0x3C, 0xB6, 0x36, 0xAC, 0xD4, 0x4E, 0xCC};


const byte startSequence[] = { 0x1B, 0x1B, 0x1B, 0x1B, 0x01, 0x01, 0x01, 0x01 };//start sequence of SML protocol
//const byte stopSequence[]  = { 0x1B, 0x1B, 0x1B, 0x1B, 0x1A };//end sequence of SML protocol
const byte powerSequence[] = { 0x07, 0x01, 0x00, 0x10, 0x07, 0x00, 0xFF, 0x01, 0x01, 0x62, 0x1B, 0x52, 0x00, 0x55 }; //sequence preceeding the current "Wirkleistung" value (4 Bytes)
int smlIndex;//index counter within smlMessage array
int startIndex;//start index for start sequence search
int stopIndex;//start index for stop sequence search
int stage;//index to maneuver through cases
int currentpower; //variable to hold translated "Wirkleistung" value
int indexSnap;
int record=0;
byte ledState=0;
byte power[4]; //array that holds the extracted 4 byte "Wirkleistung" value



void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
//  while (!Serial) {
//    ; // wait for serial port to connect. Needed for native USB port only
//                  }
  pinMode(7, OUTPUT);
  vw_setup(500);       // Bits pro Sekunde
  vw_set_tx_pin(7);     // Datenleitung
     }
     
void loop() {
//  delay(50);
//  inByte=snapshot[indexSnap];
//  indexSnap++;
//  if (indexSnap == sizeof(snapshot)){
//    indexSnap=0;
//  }
  //Serial.println(stage);
  switch (stage) {
    case 0:
      findStartSequence();
      break;
    case 1:
      findPowerSequence();
      break;
    case 2:
      extractPowerSequence(); //look for power sequence and extract
      break;
    case 3:
      publishMessage();
      break;
  }
}
void findStartSequence() {
  while (Serial.available()){
    inByte = Serial.read();//read serial buffer into array     
       if (inByte == startSequence[startIndex])//in case byte in array matches the start sequence at position 0,1,2...
        {
          smlMessage[startIndex] = inByte;//set smlMessage element at position 0,1,2 to inByte value
//          Serial.println(startIndex);
          startIndex =  (startIndex +1) %1000;

          if (startIndex == sizeof(startSequence))//all start sequence values have been identified
          {
           Serial.println("Start found");
//            mySwitch.send(1, 16); //16=bit
            stage = 1;
         
          smlIndex = startIndex;
         
                    startIndex = 0;
          }
        }
        else {
          startIndex = 0;
        }
  }
}
void findPowerSequence() {
  while (Serial.available())
  {
    inByte = Serial.read();
  }
    smlMessage[smlIndex] = inByte;
//    mySwitch.send(2, 16); //16=bit
    Serial.print("smlIndex");
    Serial.println(smlIndex);
//    Serial.println(powerSequence[stopIndex]);
//    Serial.println(inByte);
    smlIndex++;
//    if (inByte == stopSequence[stopIndex])
    if (inByte == powerSequence[stopIndex])
    {
//      Serial.println(stopIndex);
      stopIndex++;
      Serial.println(stopIndex);
//      if (stopIndex == sizeof(stopSequence))      
      if (stopIndex == sizeof(powerSequence))
      {
        //stage = 2;
        stopIndex = 0;
        Serial.println("Found Powersequnce");
//        mySwitch.send(5, 16); //16=bit
        record=1;
      }
    }
    else {
      if (record>0 && record<5){ //since we have the starting point, we add another 4 bytes with the power message 
        record++;
//        mySwitch.send(6, 16); //16=bit
        if (record==4){
          stage = 2;
          stopIndex = 0;
          record= 0;
          }
        }


      else{
            stopIndex = 0;
            record= 0;
      }
    }
}

void extractPowerSequence() {
  byte temp; //temp variable to store loop search data
 startIndex = 290; //start at position 0 of exctracted SML message

 smlMessage[smlIndex++] = inByte;
 
for(int x = 0; x < sizeof(smlMessage); x++){ //for as long there are element in the exctracted SML message
    temp = smlMessage[x]; //set temp variable to 0,1,2 element in extracted SML message
    if (temp == powerSequence[startIndex]) //compare with power sequence
    {
      startIndex++;
      if (startIndex == sizeof(powerSequence)) //in complete sequence is found
      {
        for(int y = 0; y< 4; y++){ //read the next 4 bytes (the actual power value)
//          Serial.println("power[y]");
          power[y] = smlMessage[x+y+1]; //store into power array
//          Serial.println(power[y],HEX);
        }
        stage = 3; // go to stage 3
        startIndex = 0;
      }
    }
    else {
            startIndex = 0;
    }
  }

   currentpower = (power[0] << 24 | power[1] << 16 | power[2] << 8 | power[3]); //merge 4 bytes into single variable to calculate power value
}
void publishMessage() {
//Serial.end();
Serial.print("Leistung: ");
Serial.println(currentpower);
currentpower=currentpower*-1;
//vw_send((byte *) &currentpower, sizeof(currentpower)); 
//vw_wait_tx();                         // warten bis alles übertragen ist

if (ledState == LOW) {
  ledState = HIGH;
} else {
  ledState = LOW;
}
digitalWrite(LED_BUILTIN, ledState);
// clear the buffers
smlIndex = 0;
memset(smlMessage, 0, sizeof(smlMessage));
memset(power, 0, sizeof(power));
stage = 0; // start over
//Serial.begin(9600);
}

Ich verstehe deinen Aufbau nicht.
Male doch mal ein Blockschaltbild auf, wie du alles angeschlossen hast.

Grundsätzlich gibt es keine Probleme mit serial/softwareserial und im Zusammenhang mit RCswitch oder VirtualWire.

Ich habe alle diese Libraries schon in Kombination am Laufen gehabt bzw. in Projekten auch in Funktion.

Welche und wieviele Controller hast du für das Projekt.

Hallo HotSystems,
Fritzing habe ich leider nicht drauf.
Generell ist an dem problematischen Sender nicht viel dran:
Ein USB-Netzteil versorgter Arduino Nano, ein IR Lesekopf mit RX und TX direkt an die Pins, die Versorgung an die 5V/GND Leitung der Nano-Platine, dito mit dem billigen RF Sender, der dann noch den Datenpin an Pin7 verbunden hat.

An der Hardware kann es eigentlich nicht liegen, denn das Demo Sender/Empfänger Programm funktionieren einwandfrei, sowohl RCswitch als auch Virtual Wire.
Erst mit dem zusätzlichen Code des SM klappt das senden nicht mehr.
Ich hab das schon hin und her geflasht aus Mistrauen, aber die Demo läuft immer super.
Es muss an meinem Code liege - dabei halte ich den für nicht so komplex.

Ich hab zum Testen auch mal mit dem Serial Monitor einfach den Block des Zählers gesendet, also die HW nicht am Zähler gehabt, klappt mit dem Rechnen der Leistung, doch es sendet nicht. Und das finde ich ziemlich gemein, denn die LED blinkt, also er ist definitiv an der Stelle im Code. Und selbst die Demo-Befehle an diese Stelle geschrieben senden kein Signal.

Wenn ich das jetzt verstehe, willst du das Array "Snapshot" direkt versenden ?
Warum das ?

Was genau steht da drin ?

Es wäre schön gewesen, wenn Du den Sketch auf das Nötigste hättest runtergebrochen.
die vielen auskommentierten Zeilen machen das lesen extrem schwer.

minimax2020:
Zur Vollständigkeit noch Variante 1, SML geht, Senden nicht (mit Snapshot vom Zähler)

int stage;//index to maneuver through cases

//Serial.println(stage);
 switch (stage) {
   case 0:
     findStartSequence();
     break;
   case 1:
     findPowerSequence();
     break;
   case 2:
     extractPowerSequence(); //look for power sequence and extract
     break;
   case 3:
     publishMessage();
     break;
 }

Ich suche vergebens:

  • mit welchem Wert wird stage initialisiert
  • was passiert, wenn stage nicht 0 bis 3

In der anderen Variante:

Hier ist auch noch Serial abgescahltet im Zeitpunkt des Sendens.

void loop() {

if(stringComplete) {
    Serial.end();
    Serial.print("String : ");      // String ausgeben
    Serial.println(inputString);

Drei grosse Fragezeichen

Schade das der TO meine Fragen nicht mehr beantwortet hat.
Ich verstehe nicht, welche Daten übertragen werden., da der Sketch sehr unübersichtlich ist.

Meine Vermutung ist, das Array soll übertragen werden, obwohl eine Berechnung vorher stattfinden könnte.
Dann nur das Ergebnis übertragen.

Alles nur Vermutung.

(deleted)

Sorry, der TO hängt nicht den ganzen Abend im Internet.
Nein nein, das Array ist viel zu groß, ich will nur 4 byte übertragen, 16bit würden auch reichen.

Ich hab absichtlich den ganzen Code gepostet, damit nix in die Suppe spuckt was ich nicht zeige.

Der Ablauf der Ausleseprogramme ist so:

Die kleine Variante liest in der void serialEvent() (getriggert durch den UART, muss nicht aufgerufen werden) den Puffer voll, bis dieser 720 Nachrichten angehängt hat.
Dann setzt er das stringComplete=true; und fängt in der Mainloop an zu laufen.
Da habe ich den String mir als über Serial mit mal anzeigen lassen - dann aber Serial abgeschalltet damit es beim senden nicht stören kann.
Er sucht im String nach der Sequenz für die Leistung, diese wird dann in den powerString geschreiben,
welchen ich dann in Dec umwandle und in value abgelegt wird.
value soll dann gesendet werden.

Die große Variante lauscht dem hex-Strom so lange bis sie den Header hört, dann schaltet sie um auf die Suche nach der Sequenz für die Leistung und zeichnet die Nachricht auf. Hat sie die gefunden lädt er noch 4 Byte mit der eigentlichen Zahl hinterher. Im nächsten Schritt sucht er nach der Zahl in der Nachricht (currentpower) und wandelt dieser um in ein Integer und sendet diese - theoretisch.

Beide Programme lesen erfolgreich den Wust und finden die Leistung.
Alles rechnet richtig, nur das Senden geht nicht.

Ich nehme an es ist ein Zeitproblem, irgend etwas unterbricht den Sendevorgang. Denn das LED umschalten klappt sehr gut. Und nur die kleinen Demo-Programme allein laufen auch gut, mit erfolgreichem Senden und Empfangen.
Ich versuche in der nächsten freien Zeit mal ein SoftwareSerial zu nutzen.

Der HC12 Vorschlag ist gut, aber bevor ich das mache baue ich 2 Arduinos ein, die "Unterhalten" sich dann per ADC und PWM. Einer liest den Zähler und baut eine analoges Signal daraus, der 2te liest es ein und sendet.

Ich würde mich sehr für euren Code mit Serial und einem extra RF433 interessieren.
Ich verstehe nämlich überhaupt nicht warum das nicht klappt und falls ihr etwas ähnliches schon getan habt, dann würde ich gern mal sehen.

minimax2020:
Sorry, der TO hängt nicht den ganzen Abend im Internet.

Und beantwortet meine Fragen auch nicht.

Mach mal aus:

int currentpower; //variable to hold translated "Wirkleistung" value
long currentpower; //variable to hold translated "Wirkleistung" value

my_xy_projekt:
Und beantwortet meine Fragen auch nicht.

Eine undefinierte Variable wird in der Arduino IDE immer mit null initialisiert, nach meiner Erfahrung.
Case kann keinen anderen Wert annehmen - ja, man könnte den ganzen Code sicherer programmieren.
Aber daran liegt nicht mein Sende-Problem.

my_xy_projekt:
Mach mal aus:

int currentpower; //variable to hold translated "Wirkleistung" value
long currentpower; //variable to hold translated "Wirkleistung" value

Hm, Danke, das war in der Tat schlampig. Ich hab es geändert, aber das Sende-Problem besteht.

Nicht mal die eingefügten Zeilen aus der Demo funktionieren

int power1=909;
int power2=303;
    vw_send((byte *) &power1, sizeof(power1)); 
    vw_wait_tx();                         // warten bis alles übertragen ist
    delay(1000);
    vw_send((byte *) &power2, sizeof(power2)); 
    vw_wait_tx();

Ich werde mal den Code zerschnipseln und auf Basis der Demo Stück für Stück wieder einfügen, bis er aussteigt.

Wenn ich die Senderoutine in die Hauptschleife packe, dann funktioniert das senden,
dafür die Serielle Übertragung zerstört. Meist kommt nichts oder wenn dann nur Datenmüll in meinen String.

#include <VirtualWire.h>
// 433 MHz Sender mit der VirtualWire Library  V 1.27

String inputString="";            // Eingabe String Daten
bool stringComplete=false;        // String abgeschlossen
String powerString;
char charBuf[8];
long value=0;
int power1=909;
int power2=303;
bool Mode=0;
 
void setup() {
  Serial.begin(9600);            // Baud
  pinMode(7, OUTPUT);
  vw_setup(500);       // Bits pro Sekunde
  vw_set_tx_pin(7);     // Datenleitung
}
 
void loop() {
  if(stringComplete) {
    //Serial.print("String : ");      // String ausgeben
    //Serial.println(inputString);  
    //Serial.println(inputString.length()); 
    int powerTag = inputString.indexOf("070100100700FF0101621B520055");
    powerString=inputString.substring(powerTag+28, powerTag+28+8);
    Serial.println(powerString);
    //für Konvertierung in Dec   
    for(int y = 0; y< 9; y++){ 
      charBuf[y]=powerString[y]; 
    }
    value = strtoul(charBuf, NULL, 16);  
    //Endlich abgeschlossen
    Serial.println(value);

        
    Mode = !Mode;
    stringComplete=false;
    inputString="";
    digitalWrite(LED_BUILTIN, Mode);

  }
  vw_send((byte *) &value, sizeof(value)); 
  vw_wait_tx();                         // warten bis alles übertragen ist
  //Serial.print(stringComplete);      // Sehen ob die Schleife lief ausgeben
}

void serialEvent() {
// Wird aufgerufen wenn an RX Daten angekommen sind, ausserhalb von loop().
// Ein delay() in loop() kann die Datenübernahme verzögern.
// Der Arduino RX Buffer ist standardmässig 64 Zeichen groß, kann aber ggf. vergrößert werden.
  while(Serial.available()) {        // bis alle Zeichen im RX Buffer ausgelesen sind
    char inChar=(char)Serial.read(); // ein Zeichen im RX Buffer auslesen
    if(inputString.length()>719) {             // String Ende erkennen
      stringComplete=true; 
    }
    else {                            // Zeichen anhängen
      inputString+=inChar; 
    }
  }
}

Ich denke Serial und RCswitch/VirtualWire sind miteinander verknüpft und lassen sich nicht zusammen nutzen (zumindest auf einem Nano, hat ja nur eine). Ich versuche mal per Software Serial einen Umweg zu gehen.

Gelöst !
Naja, nicht ganz, mir ist auch nicht klar warum es geht, aber ich habe nun eine extra-schleife mit extra-bit erstellt. Von der Logik her macht es doch keinen Unterschied ob ich in meiner Berechnungsschleife noch das Senden mit einbaue. Aber scheinbar tut es das doch. Und ich bin noch auf RCswitch gewechselt, denn das hat stabiler die Zahlen übertragen.

Also, falls jemand auch mal ein Lastmanagement selbst bauen möchte und keine Kabel durch das Haus ziehen, hier wäre mal der Grundstein. Allerdings sind die SML-Messages von den Zähler verschieden, doch der SML OBIS-Code müsste immer gleich sein. Man muss die Sequenz anpassen falls er nicht in Wh zählt, das steht nämlich auch im header.

#include <RCSwitch.h>

String inputString="";            // Eingabe String Daten
bool stringComplete=false;        // String abgeschlossen
bool RFsend=false;
String powerString;
char charBuf[8];
long value=0;
bool Mode=0;
RCSwitch mySwitch = RCSwitch();
 
void setup() {
  Serial.begin(9600);            // Baud
  pinMode(7, OUTPUT);
  mySwitch.enableTransmit(7);
}
 
void loop() {
  if(stringComplete) {
    //Serial.print("String : ");      // String ausgeben
    //Serial.println(inputString);  
    //Serial.println(inputString.length()); //Sehen welche Länge der Buffer hat 
    int powerTag = inputString.indexOf("070100100700FF0101621B520055"); //Suchen wo die Leistung steht
    powerString=inputString.substring(powerTag+28, powerTag+28+8); //Sich die 4 Bytes mit der Leistung holen
    //Serial.println(powerString);
    
    //für Konvertierung in Dec   
    for(int y = 0; y< 9; y++){ 
      charBuf[y]=powerString[y]; 
    }
    value = strtoul(charBuf, NULL, 16);//geht leider nur als char, deshlab die for Schleife  
    //Endlich abgeschlossen
    
    Serial.println(value);

        
    Mode = !Mode;
    digitalWrite(LED_BUILTIN, Mode);
    stringComplete=false;
    inputString="";
    RFsend=1;

  }
  if(RFsend) {
    Serial.end(); 
    mySwitch.send(value, 16);                       // warten bis alles übertragen ist
    Serial.begin(9600); 
    //Serial.print(stringComplete);      // String ausgeben
    RFsend=0;
  }
}

void serialEvent() {
// Wird aufgerufen wenn an RX Daten angekommen sind, ausserhalb von loop().
// Ein delay() in loop() kann die Datenübernahme verzögern.
// Der Arduino RX Buffer ist standardmässig 64 Zeichen groß, kann aber ggf. vergrößert werden.
  while(Serial.available()) {        // bis alle Zeichen im RX Buffer ausgelesen sind
    char inChar=(char)Serial.read(); // ein Zeichen im RX Buffer auslesen
    if(inputString.length()>719) {             // String Ende erkennen
      stringComplete=true; 
    }
    else {                            // Zeichen anhängen
      inputString+=inChar; 
    }
  }
}

minimax2020:
Ich denke Serial und RCswitch/VirtualWire sind miteinander verknüpft und lassen sich nicht zusammen nutzen (zumindest auf einem Nano, hat ja nur eine). Ich versuche mal per Software Serial einen Umweg zu gehen.

Wieso sind die miteinander verknüpft ?
Das sind eigenständige Libraries, die man auch zusammen nutzen kann.

Es laufen bei mir einige Projekte, die beide Libraries problemlos nutzen.

Du musst es nur richtig machen.
Auch auf einem Nano läuft es, das ist auch nur ein Atmega328p.

Ob das allerdings Sinn macht, steht auf einem anderen Blatt.

minimax2020:
Gelöst !

Fürs kompilieren die ausführliche Ausgabe aktiviert und bekommst keine roten Warnungen etc. beim kompilieren?
Dann soll es so sein.

minimax2020:
Eine undefinierte Variable wird in der Arduino IDE immer mit null initialisiert, nach meiner Erfahrung.
....

Das gilt nur für globale Variable.

Und nix war es. Die Lösung klappt nur auf dem Schreibtisch, wenn kein Dauerfeuer auf RX anliegt.
Am SmartMeter blinkte dann zwar die LED für gefundene Leistung aus dem Zähler, aber gesendet hat er wieder nix.
Nun hab ich sicher nochmal 10h investiert (aber ich bin auch langsam):
SoftwareSerial versucht anstelle echtem UART, das klappte schon öfter.
Dann bin ich beim Lesen über die AltSoftSerial gestolpert, mit der geht es noch besser.
Dann noch kleine Probleme, weil die virtuellen Serial beim lesen von Hex auf ASCII wandeln und bist ich das rausgetüfelt habe warum der Compiler wieder meckert, das dauert.
Nun ist es fast sauber: Er schafft 3 Werte zu rechnen, dann kommt er aus dem Tritt (an der AltSoftSerial, dafür stört die aber das Senden nicht). Aber das gute ist: wenn ich nach dem erfolgreichen lesen Zählers die Schnittstelle aus schalte, einen Delay nehme und wieder anschalte bleibt er am Ball.

Der Code wird ohne Warnung erzeugt, aber ich weis es nicht sauber ist.
Warum sich das beißt, das weis ich nicht. Aber mich würden Projekte interessieren, wo die beiden Libraries aktiv sind und da alles ganz richtig gemacht wurde.

Nun geh ich mal schlafen :slight_smile:

#include <AltSoftSerial.h>

#include <RCSwitch.h>
//#include <SoftwareSerial.h>

String inputString="";            // Eingabe String Daten
bool stringComplete=false;        // String abgeschlossen
bool RFsend=false;
String powerString;
char charBuf[8];
long value=0;
bool Mode=0;
RCSwitch mySwitch = RCSwitch();
//SoftwareSerial mySerial(10, 11); // RX, TX
AltSoftSerial mySerial; // 8 RX, 9 TX
 
void setup() {
  //Serial.begin(9600);            // Baud
  mySerial.begin(9600);
  pinMode(7, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  mySwitch.enableTransmit(7);
  mySwitch.setRepeatTransmit(5);
}
 
void loop() {
  if(stringComplete) {
    //Serial.print("String : ");      // String ausgeben
    //Serial.println(inputString.substring(0,10)); 
    //Serial.println(inputString.length()); //Sehen welche Länge der Buffer hat
    int powerTag = inputString.indexOf("070100100700FF0101621B520055"); //Suchen wo die Leistung steht
    //Serial.println(powerTag);    
    if (powerTag!=-1){
      powerString=inputString.substring(powerTag+28, powerTag+28+8); //Sich die 4 Bytes mit der Leistung holen
      //Serial.println(powerString);
     
      //für Konvertierung in Dec   
      for(int y = 0; y< 9; y++){
        charBuf[y]=powerString[y];
      }
      value = strtoul(charBuf, NULL, 16);//geht leider nur als char, deshlab die for Schleife 
      //Endlich abgeschlossen
    
      Mode = !Mode;
      digitalWrite(LED_BUILTIN, Mode);

    }
    RFsend=1;
    stringComplete=false;
    inputString="";
  }
  
  if(RFsend) {
    mySwitch.send(value, 16);            // warten bis alles übertragen ist
    //Serial.print(stringComplete);      // String ausgeben
    RFsend=0;
    mySerial.end();           //Pause einlegen, sonst kommt der aus dem Tritt beim lesen
    delay(4250);
    mySerial.begin(9600);
  }
    if(mySerial.available()) {        // bis alle Zeichen im RX Buffer ausgelesen sind
    int inByte = mySerial.read();

    char tmp[16];                     //byte in string wandeln zum anhängen an großen String
    sprintf(tmp, "%.2X",inByte);
    
    if(inputString.length()>719) {    // String Ende erkennen
      stringComplete=true;
    }
    else {                            // Zeichen anhängen
      inputString+=tmp;
      //Serial.print(inputString);
    }
  }
}

/*
void serialEvent() {
// Wird aufgerufen wenn an RX Daten angekommen sind, ausserhalb von loop().
// Ein delay() in loop() kann die Datenübernahme verzögern.
// Der Arduino RX Buffer ist standardmässig 64 Zeichen groß, kann aber ggf. vergrößert werden.
  while(Serial.available()) {        // bis alle Zeichen im RX Buffer ausgelesen sind
    char inChar=(char)Serial.read(); // ein Zeichen im RX Buffer auslesen
    if(inputString.length()>719) {             // String Ende erkennen
      stringComplete=true;
    }
    else {                            // Zeichen anhängen
      inputString+=inChar;
    }
  }
}
*/

Was ich jetzt rauslese, ist dein Problem, dass du dauernd Daten sendest.
Ist das erforderlich ?

Und hier noch mal die Bitte: Zeichne ein Blockschaltbild, ich verstehe deinen Aufbau nicht.

Du kannst es auch per Papier und Bleistift malen. Aber bitte so, dass man es auch versteht.

Und hier mal ein Beispiel eines meiner Projekte, welches mit 2 mal SoftwareSerial und 1 mal RCSwitch arbeitet.
Und das schon seit einigen Jahren problemlos.
Die Ansteuerung funktioniert per RS232 von einem entfernten WebServer der die Schaltsignale von der Weboberfläche per serial liefert.

Sketch wurde auf das nötigste gekürzt.

#include <RCSwitch.h>                         // Library RCSwitch.h, Code zum Schalten
#include <SoftwareSerial.h>
SoftwareSerial ethSerial (2, 3);              // RX, TX
SoftwareSerial rc_Serial (4, 5);              // RX, TX
RCSwitch mySwitch = RCSwitch();               // Output Daten = 6; Sender
const byte led = 13;
const byte txvc = 7;


// fs20 Adresse
int my_hc[ ] = {0xAA, 0xCC}; //Dieter

//Kanaladressen des UART FS20
const int my_ro1 = 0x00;
const int my_ro2 = 0x01;
const int my_ro3 = 0x02;
const int my_ro4 = 0x03;
const int my_ro5 = 0x04;
const int my_ro6 = 0x05;
const int my_ro7 = 0x06;
const int my_ro8 = 0x07;

char c_inChar;
String s_input;
unsigned int i_input;


void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);
  pinMode (txvc, OUTPUT);
  
  Serial.println("Goodnight moon!");
  ethSerial.begin(57600);                     // Serial zum Ethernet-Modul
  rc_Serial.begin(9600);                      // Serial zum 868 MHz-Funk-Modul

  mySwitch.enableTransmit(6);
  // Optional set pulse length.
  mySwitch.setPulseLength(180);                 //Welpe=185; Steckdosen=170; normal=320, 280 für Steckdosen
  // Optional set number of transmission repetitions.
  mySwitch.setRepeatTransmit(15);    //15
  // Optional set protocol (default is 1, will work for most outlets)
  // mySwitch.setProtocol(1);  
}

void loop() { 
  
  ethSerial.listen();
  while (ethSerial.available() > 0) {
    c_inChar = ethSerial.read();              // Speichere das empfangene Zeichen in der Variablen c_inChar.
    Serial.print(c_inChar);
    
    s_input.concat(c_inChar);                 // Füge das Zeichen an den String an, damit wir den kompletten Text erhalten.
    if (c_inChar == '\n') {                   // War das letzte Zeichen ein CR (Carriage Return)?
      char c_Input[6];
      s_input.toCharArray(c_Input, 5);
      i_input = atoi(c_Input);
      s_input = "";                           // Lösche den String für die nächste Nachricht.
    }

    switch (i_input) {
      case 9101:
        digitalWrite(led, HIGH);
        Serial.print(F("Lampe ein: "));
        Serial.println(i_input);
        i_input = 0;
        SendFS20Cmd(my_hc[0], my_hc[1], my_ro1, 0x11);      //schalte Lampe
        break;

      case 9001:
        // weitere Steuersequenzen
        break;

      case 9106:
        digitalWrite(led, HIGH);
        Serial.print(F("Laterne ein: "));
        Serial.println(i_input);
        i_input = 0;
        SendRCCmd(5264835);                                   //Laterne an
        break;

      case 9006:
        digitalWrite(led, LOW);
        Serial.print(F("Laterne aus: "));
        Serial.println(i_input);
        i_input = 0;
        SendRCCmd(5264844);                                   //Laterne aus
        break;

      case 9107:
        // weitere Steuersequenzen
        break;

      case 9007:
        // usw.
        break;
    }
  }
}


//---------------------------------------------------------------------------------
//Funktion SendFS20Command, mit Parameter (H-Code 1 + 2, Kanaladresse, Befehl)
void SendFS20Cmd(int fs20_HC1, int fs20_HC2, int fs20_KAdr, int fs20_Cmd)
{
  digitalWrite(led, HIGH);   // Sender einschalten
  delay(100); // Wait for 0,1 seconds
  //hier werden FS20 Signale gesendet
  rc_Serial.write(0x02);
  //.....
  // Sender ausschalten
  digitalWrite(led, LOW);
  delay(100); // Wait for 0,1 seconds
}


void SendRCCmd(long RCCode)
{
  digitalWrite(txvc, HIGH);   // Sender einschalten
  digitalWrite(led, HIGH);   // Sender einschalten
  for (int i = 0; i < 4; i++) {
    mySwitch.send(RCCode, 24);
    delay(10);
  }
  digitalWrite(led, LOW);
  digitalWrite(txvc, LOW);   // Sender ausschalten
}

Hi Hot System,
danke für deinen Code, ich finde so stark unterscheiden wir uns aber nicht.
Du nutzt sogar doppelt den Softwareserial.
Ich denke das es einfach nicht klappt da der IR lesekopf vom Stromzähler (Iskra ehz-edl mt681) ein RX Dauerfeuer bekommt,
dabei unterbricht er dann das Ansteuern des Senders.
Wobei die Baudrate zeitlich betrachtet überhaupt kein Problem darstellen sollte.
Naja, das Ding läuft nun schon ein paar Wochen und funktioniert nun stabil.

Arduino Nano
IR Lesekopf +-----------------+ RC433 Sender
+--+ | |

    • | | +----------+
    • | |XXXXXXXXXXXX| |
      +--+ | | +----------+
      X | | RX
      XXXXXXXXXXXXXX +-----------------+ Vcc
      RX Pin 8 RX Pin 7 RX GND
      TX Pin 9 TX
      Vcc
      GND

Schade, das ASCII-Bild wird leider durch die ForenSW zerstört

minimax2020:
Naja, das Ding läuft nun schon ein paar Wochen und funktioniert nun stabil.

Schade, das ASCII-Bild wird leider durch die ForenSW zerstört

Wenn du dein ASCII-Bild direkt einfügst, sollte es besser aussehen.

Super, dass es jetzt funktioniert und danke für deine Rückmeldung.