Empfangsprogramm für Arduino

Nachfolgend das Empfänger-Programm. Am Seriellen Monitor werden die gerechnete und die übertragene Checksumme, das empfangene Telegramm und die empfangenen Messwerte von 2 Sendern mit jedem Sendevorgang angezeigt, sofern die Variable "bool serialMonitor = true" gesetzt ist.


Ebenso wie der Sender, benötigt das Programm die Library VirtuellWire, die die drahtlose Übertragung des Telegramms steuert. Wo man die Library herunterladen kann findet man hier: Fremd-Libraries


Das eingehende Telegramm wird auf Checksumme und Sender-ID überprüft und - sofern alles in Ordnung ist - werden anschließend die Messdaten aus dem Telegramm übernommen. Wie schon beim Sender, nutze ich auch hier einen Pointer auf Byte, um die einzelnen 20 Bytes der 5 Float-Wertes (5 Floatwerte * 4 Bytes je Floatwert) aus dem Sendetelegramm in den Messwert-Zwischenspeicher zu kopieren. In Abhängigkeit der Sender-ID werden dann die Messwerte auf die entsprechenden Messwert-Speicherplätze übertragen und harren dort ihrer weiteren Verwendung.

Somit können zu Testzwecken die vorerst simulierten Messwerte vom Sender zum Empfänger übertagen werden.


Beim Senderprogramm zeige ich auch eine Variante, wo anstelle von Pointer mit Union-Variablen auf die einzelnen Bytes der Floatwerte zugegriffen wird. Diese Methode kann man natürlich auch beim Empfänger anwenden, hier hab ich es aber noch nicht umgesetzt.

Empfangsprogramm mit Verwendung von Pointer:

Neu: Version 2.1 zur I2C-Anbindung an Datenlogger

//Projekt Funkuebertragung
//Empfaenger.cpp
//Code fuer Arduino
//Author Retian
//Version 2.1


//Verwendung von Pointer mit float-Array

#include <VirtualWire.h>
#include <Wire.h>

#define rxLED 3
#define checkSumLED 4
#define rxPin 7

bool serialMonitor = true; //true, wenn Kontrollwerte am Seriellen Monitor ausgegeben werden sollen


//Definiton des Sendertelegramms
#define SenderIDByteAnf 0 //Byte 0-1
#define SenderIDByteEnd 1
#define MessungIDByte 2 //Byte 2 derzeit Reserve (=0)
#define rxWert1ByteAnf 3 //Byte 3-6
#define rxWert1ByteEnd 6
#define rxWert2ByteAnf 7 //Byte 7-10
#define rxWert2ByteEnd 10
#define rxWert3ByteAnf 11 //Byte 11-14
#define rxWert3ByteEnd 14
#define rxWert4ByteAnf 15 //Byte 15-18
#define rxWert4ByteEnd 18
#define rxWert5ByteAnf 19 //Byte 19-22
#define rxWert5ByteEnd 22
//#define Reserve 23
//#define Reserve 24
//#define Reserve 25
#define CheckSumByte 26 //Byte 26
#define CheckSumByteAnf 0
#define CheckSumByteEnd 25

#define receiveCheckTime 20000 //20 Sekunden


unsigned long receiveTime1, receiveTime2;

float rxWert[5]; //Zwischenspeicher für empfangene Werte
float Messwert[10];
byte indexMesswert = -1;

byte *pdummy = NULL; //Pointer mit 1 Byte Laenge auf NULL

//Pointer auf Empfangswert-Array
float *prxWert = &rxWert[0];


String SenderID1 = "#1"; //ID des Sender 1
String SenderID2 = "#2"; //ID des Sender 2
char ZwiBuf[3];
String InString;

const int anzBytes = 27; //Telegrammlaenge

byte receiveCheckSum = 0; //uebertragene Checksumme
byte checkSum = 0; //gebildete Checksumme
bool receiveCheck;


void setup() {
  if (serialMonitor == true) Serial.begin(115200);
  pinMode(rxLED, OUTPUT);
  pinMode(checkSumLED, OUTPUT);
  digitalWrite(rxLED, LOW);
  digitalWrite(checkSumLED, LOW);

  Wire.begin(0x06);
  Wire.setClock(400000);
  Wire.onRequest(requestEvent);
  Wire.onReceive(receiveEvent);

  //Deklarationen Library VirtualWire
  vw_set_rx_pin(rxPin); //Setze rx-Pin
  vw_setup(1000); //Uebertragungsrate 1000 Bit/Sekunde
  vw_rx_start();

  receiveTime1 = millis();
  receiveTime2 = millis();
}


void loop() {
  byte EmpfangBuffer[anzBytes]; //muss lt. VirtualWire im loop stehen!
  byte buflen = anzBytes; //muss lt. VirtualWire im loop stehen!

  for (int i = 0; i < buflen; i++) EmpfangBuffer[i] = 0; //Loesche Empfangsbuffer

  //Warten auf Sendedaten und Speicherung im Empfangsbuffer
  if (serialMonitor == true) Serial.println("Warte auf Senderdaten ...");
  if (vw_wait_rx_max(receiveCheckTime))
  {
    vw_get_message(EmpfangBuffer, &buflen);

    //Wenn Telegramm erhalten, LED (rxLED) 1x blinken
    digitalWrite(rxLED, HIGH);
    delay(10);
    digitalWrite(rxLED, LOW);
    delay(100);

    //Uebertragene Checksumme aus Telegramm
    receiveCheckSum = EmpfangBuffer[CheckSumByte];

    //Checksumme aus Telegrammbytes neu ermitteln
    checkSum = 0;
    for (byte i = CheckSumByteAnf; i <= CheckSumByteEnd; i++)
    {
      CheckByte(EmpfangBuffer[i], i);
    }

    if (serialMonitor == true)
    {
      Serial.print("Checksumme gerechnet / uebertragen: ");
      Serial.print(checkSum);
      Serial.print(" / ");
      Serial.println(receiveCheckSum);
    }

    // Sendertelegramm ueberpruefen: Checksummenvergleich und Anzahl uebertragener Bytes
    if (receiveCheckSum == checkSum && checkSum != 0 && buflen == anzBytes)receiveCheck = true;
    else
    {
      //Wenn Uebertragungsfehler, LED (checkSumLED) 1x blinken
      receiveCheck = false;
      if (serialMonitor == true) Serial.println("Uebertragungsfehler!");
      digitalWrite(checkSumLED, HIGH);
      delay(10);
      digitalWrite(checkSumLED, LOW);
    }

    //Sender Identitaet ueberprüfen, wenn receiveCheck erfolgreich
    if (receiveCheck == true)
    {
      //Sender-ID ueberprüfen
      InString = "";
      for (int i = SenderIDByteAnf; i <= SenderIDByteEnd; i++) InString += (char)EmpfangBuffer[i];

      //Sender ID = Sender 1 oder Sender 2
      if (InString == SenderID1 || InString == SenderID2)
      {
        //Messwerte aus dem Telegramm in die Messwert-Zwischenspeicher schreiben
        pdummy = (byte*)prxWert; //Pointer von dummy auf Adresse von Messwert setzen
        for (int i = rxWert1ByteAnf; i <= rxWert5ByteEnd; i++)
        {
          *pdummy = EmpfangBuffer[i];
          pdummy++;
        }

        //Zeitueberwachung Sender 1 und 2
        if (InString == SenderID1) receiveTime1 = millis();
        if (InString == SenderID2) receiveTime2 = millis();
        if (millis() - receiveTime1 > receiveCheckTime) Serial.println("Sender1 Zeitueberschreitung");
        if (millis() - receiveTime2 > receiveCheckTime) Serial.println("Sender2 Zeitueberschreitung");

        //Uebertragen der Messwert-Zwischenspeicher in die Messwertspeicher
        if (InString == SenderID1)
        {
          for (int i = 0; i < 5; i++) Messwert[i] = rxWert[i];
        }
        if (InString == SenderID2)
        {
          for (int i = 0; i < 5; i++) Messwert[i + 5] = rxWert[i];
        }

        if (serialMonitor == true)
        {
          Serial.print("Telegramm Sender ");
          Serial.print(InString);
          Serial.print(": ");
          for (int i = 0; i < 27; i++)
          {
            Serial.print(EmpfangBuffer[i]);
            Serial.print(" ");
          }
          Serial.println();
          Serial.print("Sender: ");
          Serial.println(SenderID1);
          for (int i = 0; i < 5; i++)
          {
            Serial.print("Messwert");
            Serial.print(i + 1);
            Serial.print(" : ");
            Serial.print(Messwert[i], 4);
            Serial.println();
          }
          Serial.print("Sender: ");
          Serial.println(SenderID2);
          for (int i = 5; i < 9; i++)
          {
            Serial.print("Messwert");
            Serial.print(i + 1);
            Serial.print(" : ");
            Serial.print(Messwert[i], 4);
            Serial.println();
          }
          Serial.print("Messwert10: ");
          Serial.print(Messwert[9], 4);
          Serial.println();
          Serial.println();
        }
      }
    }
  }
  else Serial.println("Sender Zeitueberschreitung");
}


//Checksummenbildung
void CheckByte(byte buf, byte i)
{
  for (int j = 0; j < 8; j++)
  {
    if (bitRead(buf, j) == 1) checkSum += (i + j + 1);
  }
}

void receiveEvent(int anzBytes)
{
  indexMesswert = Wire.read();
  indexMesswert = (indexMesswert >= 0 && indexMesswert < 10) ? indexMesswert : -1;
}

void requestEvent()
{
  String MesswertString;
  char sendArray[10] = {};
  MesswertString = String(Messwert[indexMesswert], 4);
  MesswertString.toCharArray(sendArray, 11);
  Wire.write(sendArray);
}


Zurück zum Sender: Senderprogramm