Verständnisproblem mit Funk

Hallo Liebe Arduino Community,

ich besitze seit kurzem ein Arduino Uno und Mega da ich einfach lust hatte ein bisschen zu basteln :slight_smile:

Als erstes Projekt habe ich mir eine Wetterstation vorgenommen. Es soll einen Aussensender geben und einen Empfänger mit LCD innen.

Momentan habe ich an meinem Mega die Sensoren und I2C LCD angeschlossen. Das funktioniert auch soweit. Das LCD gibt mir nacheinander die Messwerte Temperatur,Luftfeuchtigkeit,Luftdruck und Regensensor aus.

Jetzt möchte ich aber das der Mega als Aussenstation fungiert, und der Uno innen steht mit LCD und die Daten empfängt.

Ich habe mir 433Mhz Sender+Empfänger gekauft, habe aber keine Ahnung wie ich die Messwerte nun versenden bzw. Empfangen soll.

Ich denke hier findet sich bestimmt jemand der das schonmal gemacht hat

luftdruck-temp-feucht-regen-funktioniert_mit_lcd.ino (4.86 KB)

Willkommen Tobi.

Poste doch bitte deinen Sketch erstmal. Bitte in Code Tags das ist das </> Symbol.

Hättest du nur ein wenig Eigeninitiative gezeigt, hättest du herrausgefunden, dass du für die 433Mhz Sender und Empfänger eine Library wie z.B. “Virtual Wire” benötigst.

Dort kann man auch sehr gut und einfach nachvollziehen, wie das ganze System funktioniert, und wie du von deinem Mega etwas an deinen Uno senden könntest.

Hier wird dir niemand einen Code geben.

Foren sind dazu da, um dir zu helfen, nicht um dir alles vorzumachen.

//-----------------------------Bibliotheken-------------------------------------------------//
//------------------------------------------------------------------------------------------//

#include <MD_DS3231.h> //Bibliothek für Luftdruck
#include <SFE_BMP180.h> //Including BMP180 library
#include "DHT.h" //DHT Bibliothek laden
#include <Wire.h>
#include <LiquidCrystal_I2C.h> //Bibliothek für I2C Display
#include <Time.h> 
//-------------------------------------------//

LiquidCrystal_I2C lcd(0x3E,16,2);
SFE_BMP180 pressure; //Creating an object

#define ALTITUDE 465 //Altitude where I live (change this to your altitude)

#define DHTPIN 13 //Temperatursensor an PIN 13   

#define DHTTYPE DHT11    // Es handelt sich um den DHT11 Sensor

DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit „dth“ angesprochen

int messwert=0; //Unter der Variablen "messwert" wird später der Messwert des Sensors gespeichert.


//-----------------------------SETUP-------------------------------------------------//
//------------------------------------------------------------------------------------------//

void setup() //Hier beginnt das Setup.

{
  lcd.begin(); // LCD Display starten
  
  Serial.begin(9600); //Die Kommunikation mit dem seriellen Port wird gestartet. Das benötigt man, um sich den ausgelesenen Wert im "serial monitor" anzeigen zu lassen.
  
  pinMode(8,OUTPUT);
  
  dht.begin(); //DHT11 Sensor starten

  if (pressure.begin()) //If initialization was successful, continue
    Serial.println("BMP180 init success");
  else //Else, stop code forever
  {
    Serial.println("BMP180 init fail");
    while (1);
  }
}

//-----------------------------REGENSENSOR-------------------------------------------------//
//------------------------------------------------------------------------------------------//

void loop() // Hier beginnt der Hauptteil

 {
 messwert=analogRead(A1); //Die Spannung an dem Sensor wird ausgelesen und unter der Variable „messwert“ gespeichert.

 lcd.setCursor(0,0); // Start LCD erste Zeile
 lcd.print("Regensensor"); // LCD soll Wort Messwert anzeigen
 lcd.setCursor(0,1); // In 2.ter Zeile soll messwert erscheinen
 lcd.print (messwert); // wert soll erscheinen
 delay(6000); // Wartezeit
 lcd.clear(); // LCD löschen

  Serial.print("Feuchtigkeits-Messwert:"); //Ausgabe am Serial-Monitor: Das Wort „Feuchtigkeits-Messwert:" 

  Serial.println(messwert); //und im Anschluss der eigentliche Messwert.

  delay(500); // Zum Schluss noch eine kleine Pause, damit nicht zu viele Zahlenwerte über den Serial-Monitor rauschen.


  if (messwert>50) // wenn regensensor mehr als 50 zeigt
  {
    Serial.print("REGEN!!"); // Wort "REGEN" soll erscheinen
    lcd.clear(); // LCD löschen
    lcd.print("Es regnet"); // Wort "REGEN" soll erscheinen
    
  }

else
{

}
//-----------------------------Temperatur & Luftfeuchtigkeit-------------------------------------------------//
//------------------------------------------------------------------------------------------//
  float Luftfeuchtigkeit = dht.readHumidity(); //die Luftfeuchtigkeit auslesen und unter „Luftfeutchtigkeit“ speichern
  
  float Temperatur = dht.readTemperature();//die Temperatur auslesen und unter „Temperatur“ speichern

    Serial.print("Luftfeuchtigkeit: "); //Im seriellen Monitor den Text und 
  Serial.print(Luftfeuchtigkeit); //die Dazugehörigen Werte anzeigen
  Serial.println(" %");
  Serial.print("Temperatur: ");
  Serial.print(Temperatur);
  Serial.println(" Grad Celsius");

  lcd.setCursor(0,0);
  lcd.print("Luftfeuchtigkeit");
  lcd.setCursor(0,1);
  lcd.print(Luftfeuchtigkeit);
  lcd.print(" %");
  delay(6000);
  lcd.clear();

  lcd.setCursor(0,0);
  lcd.print("Temperatur");
  lcd.setCursor(0,1);
  lcd.print(Temperatur);
  lcd.print(" Grad");
  delay(5000);
  lcd.clear();

//-----------------------------Luftdruck-------------------------------------------------//
//------------------------------------------------------------------------------------------//

 char status;
  double T, P, p0; //Creating variables for temp, pressure and relative pressure
 

  Serial.print("You provided altitude: ");
  Serial.print(ALTITUDE, 0);
  Serial.println(" meters");

  status = pressure.startTemperature();
  if (status != 0) {
    delay(status);

    status = pressure.getTemperature(T);
    if (status != 0) {
      Serial.print("Temp: ");
      Serial.print(T, 1);
      Serial.println(" deg C");

      status = pressure.startPressure(3);

      if (status != 0) {
        delay(status);

        status = pressure.getPressure(P, T);
        if (status != 0) {
          Serial.print("Pressure measurement: ");
          Serial.print(P);
          Serial.print(" hPa");

          p0 = pressure.sealevel(P, ALTITUDE);
          lcd.print("Luftdruck");
          lcd.setCursor(0,1);
          lcd.print(p0);
          lcd.print("  hPa");
          delay (5000);
        }
      }
    }
  }  
  delay(1000);
}

das mit VirtualWire weiß ich schon. Ich habe auch einen Test Sketch aus dem Netz der "Testnachricht" versendet und Seriell ausgibt.

Aber was ich eben nicht verstehe ist, wie ich jetzt die Messdaten verpacke und so versende

Dann Zeig uns dochmal in deinem Sketch wie du es versucht hast. Binde doch erstmal das mit der Testnachricht in deinen funktionierenden Code ein. Dann musst du überlegen wie du die Nachricht versenden kannst.

Du musst deine Messdaten in ein char Array packen.

Ich hab das damals so gemacht:

char *controller;
controller = "1"  ;
vw_send((uint8_t *)controller, strlen(controller));

Die erste Zeile ist die Variablen deklaration. Die 2. Zeile setzt "controller" = 1. Die 3. Zeile sendet die Variable "controller"

Und empfangen wurde das ganze so

  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    if (buf[0] == '1') {

Ist schon ein weilchen her wo ich mit den 433Mhz gespielt habe. Aber damals ging das so ganz super.

Du kannst natürlich noch mehr als nur "1" versenden.

Probiere mal aus, die Beispiel Sketches in dein Projekt einzufügen. Aber am besten sicherst du dir erstmal das ganze vorher ab.

deine Luftfeuchtigkeit und die Temperatur solltest du als uint_16t deklarieren und den Wert mit 100 multiplizieren, dann alle Werte die du übertragen möchtest mit itoa in ein char array wandeln und mit strcpy und strcat zusammensetzen. Dann kannst du das zusammengesetzte char array mit VirtualWire übertragen. Auf der Empfängerseite teilst du das Empfangene char array wieder auf und wandelst es mit itoa wieder in int und teilst Luftfeuchtigkeit und Temperatur durch 100. Edit: und Ändere deine Überschrift von Fuk in Funk.

besser strcpy

Evtl. noch einen Delimiter (z.B. ; ) dazwischen, dann geht es mit strtok auf der Empfängerseite einfacher.

Gruß Tommy

Ihr seit ja echt toll so viele antworten.

Ich bin kein gelernter Programmierer oder ähnliches also muss ich mir das jetzt erstmal ergoogeln und dann werde ich versuchen eure Lösungsansätze einzubinden. Ich danke euch schonmal. Werde mich die nächsten Tage nochmal melden

Ich habe mal einiges zu Zeichenketten in C zusammengeschrieben. Evtl. hilft es Dir.

Gruß Tommy

Wieso der Umweg über Strings? Es werden Bytes übertragen. Man kann daher mehrere Werte auch einfach in einem struct zusammenfassen:

struct Daten
{
  float temp;
  unsigned int feuchte;
  unsigned int druck; 
};

Daten daten;

Oder beliebige andere Datentypen. Das struct muss nur auf beiden Seiten gleich sein

Dann sollte das gehen:

daten.temp = ...;

vw_send((uint8_t *)&daten, sizeof(daten));

Jedenfalls auf der Sende-Seite. Der Empfang sollte aber genauso gehen

Hallo Leute,

kurzer Zwischenbericht:

Ich habe nur mal den DHT11 angeschlossen und versucht diese Daten zu senden bzw. zu empfangen.

Mittlerweile kommt auch was an auf der anderen Seite aber momentan nichts brauchbares :slight_smile:

Code Sender:

#include <DHT.h>
#include <RCSwitch.h>

#define DHTPIN 13 //Temperatursensor an PIN 13   

#define DHTTYPE DHT11    // Es handelt sich um den DHT11 Sensor

DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit „dth“ angesprochen



RCSwitch mySwitch = RCSwitch();
int DHT = 13; //Der Sensor soll am analogen Pin 13 angeschlossen werden. Wir nennen den Pin ab jetzt "TMP36"
int sensorwert; // Erstellen einer Variablen für den Sensorwert.
int temperatur = 0; //Unter der Variablen "temperatur" wird später der Temperaturwert abgespeichert.

void setup() //Hier beginnt das Setup.
{
mySwitch.enableTransmit(10);  // Der Sender wird an Pin 10 angeschlossen


}

void loop()
{ //Mit dieser Klammer wird der Loop-Teil geöffnet.
sensorwert=digital
Read(DHT); //Auslesen des Sensorwertes.
temperatur= map(sensorwert, 0, 410, -50, 150); //Umwandeln des Sensorwertes mit Hilfe des "map" Befehls.
mySwitch.send(temperatur, 24); // Der 433mhz Sender versendet die Temperatur als Dezimalzahl.
delay (1000); // Eine Sekunde Pause.
} //Mit dieser letzten Klammer wird der Loop-Teil geschlossen.

Code Empfänger:

#include <RCSwitch.h>
int LED=12;
RCSwitch mySwitch = RCSwitch();

void setup() 
{
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // Empfänger ist an Interrupt-Pin "0" - Das ist am UNO der Pin2
  pinMode(LED, OUTPUT); //Der Pin mit der LED (Pin12) ist jetzt ein Ausgang.
}

void loop() {
  if (mySwitch.available()) // Wenn ein Code Empfangen wird...
  {
    int value = mySwitch.getReceivedValue(); // Empfangene Daten werden unter der Variable "value" gespeichert.
    Serial.print("Temperatur: ");
    Serial.println( value );
   }
    mySwitch.resetAvailable(); // Hier wird der Empfänger "resettet"
  }

Momentan schwankt die Ausgabe zwischen -50 und -256 Grad :slight_smile: :slight_smile:

Schreibe Dir doch einfach mal Serial.print()/println als Ausgabe auf Senderseite rein, um zu sehen, ob Du überhaupt etwas sinnvolles misst und was Du sendest.

Dann das ganze auf Empfängerseite - was kommt an.

So kannst Du Dich durchhangeln und es erhöht auch Dein Verständnis für die Abläufe.

Deine Temperatur ist 24 Byte lang?

Gruß Tommy

Hi

Vorerst würde ich auch bekannte Daten senden - eine Zahl hochzählen, ein durchlaufendes 'Hello world' - irgend was, was man auf Empfängerseite auch als korrekt übertragen erkennen kann, ohne sämtliche Bits nachgewogen zu haben.

MfG

tobi2017: Ich habe nur mal den DHT11 angeschlossen und versucht diese Daten zu senden bzw. zu empfangen.

Mittlerweile kommt auch was an auf der anderen Seite aber momentan nichts brauchbares :) ....

Was ich absolut nicht versteh, warum du es mit der Library RCSwitch machst ?

RCSwicht ist bestens geeignet, um Schaltvorgänge auszulösen.

Um Messdaten zu übertragen ist die Library "VirtualWire" die geeignetere.

Teste es damit mal. In den Beispielen findest du auch Vorschläge für die Übertragung von Daten.

Edit: Das wurde dir ja auch schon in den Posts #1 und #4 vorgeschlagen. Warum machst du das nicht ?

so jetzt bin ich ein kleines Stück weiter. Mit diesem Code soll er die Daten versenden. Auf dem Seriell Monitor werden die Werte auch richtig angezeigt.

Jetzt weiß ich aber nicht wie ich mit dem Empfänger anfangen soll.

Weiß villeicht jemand weiter?

#include <VirtualWire.h>
#include <DHT.h>

#define DHTPIN 13
#define DHTTYPE DHT11
const int receive_pin = 2;
const byte transmit_pin = 10;

struct Package {
  float temperature ;
  float feuchtigkeit;
} data;

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  dht.begin();
  vw_set_tx_pin(transmit_pin);
  vw_set_ptt_inverted(true);
  vw_setup(500);       // Bits pro sek
}

void loop() {
  readSensor();
  vw_send((uint8_t *)&data, sizeof(data));
  vw_wait_tx();
  delay(2000);
}

void readSensor() {
  Serial.println("DHT22, \t");
  data.temperature = dht.readTemperature();
  Serial.println(data.temperature);
  delay(2000);
  data.feuchtigkeit = dht.readHumidity();
  Serial.println(data.feuchtigkeit);
  delay(2000);
}

Schau nach bei den Beispielen von VirtualWire. Da gibt es einen Empränger-Beispiel-Sketch: receiver.ino

Der Empfang sollte fast genauso gehen. Ist doch aus den Beispielen klar ersichtlich: https://www.pjrc.com/teensy/td_libs_VirtualWire.html

Die Empfangsmethode sieht so aus:

uint8_t vw_get_message (uint8_t *buf, uint8_t *len)

Mit Argumenten dann so:

void loop()
{
   uint8_t = sizeof(data);

   if (vw_get_message((uint8_t *)&data, &len)
   {

   }
}

Tut mir leid aber ich werde aus dem Beispiel Sketch nicht schlau. Ich versteh nicht wie ich diesen nun umbauen muss um die Daten zu empfangen :slightly_frowning_face:

#include <VirtualWire.h>

const int led_pin = 6;
const int transmit_pin = 12;
const int receive_pin = 11;
const int transmit_en_pin = 3;

void setup()
{
    delay(1000);
    Serial.begin(9600); // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_tx_pin(transmit_pin);
    vw_set_rx_pin(receive_pin);
    vw_set_ptt_pin(transmit_en_pin);
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);  // Bits per sec

    vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
  int i;

        digitalWrite(led_pin, HIGH); // Flash a light to show received good message
  // Message with a good checksum received, print it.
  Serial.print("Got: ");
  
  for (i = 0; i < buflen; i++)
  {
      Serial.print(buf[i], HEX);
      Serial.print(' ');
  }
  Serial.println();
        digitalWrite(led_pin, LOW);
    }
}

Ja, das ist der Standard-Beispiel-Sketch zum Empfang. Am Anfang geht es mal darum eine funktionierende Übertragung hinzubekommen. Dazu sollte es reichen, die Pins und Parameter nach deinen Bedürfnissen einzustellen. Zum Beispiel so:

const int led_pin = 13;  // falls du einen UNO verwendest - die eingebaute LED blinkt bei Empfang
const int transmit_pin = 12;  // hier wird nichts angeschlossen
const int receive_pin = 11;  // an Pin 11 das Datensignal deines Empfängers anschließen
const int transmit_en_pin = 3;   // hier wird auch nichts angeschlossen

void setup()
{
    delay(1000);
    Serial.begin(9600); // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_tx_pin(transmit_pin);
    vw_set_rx_pin(receive_pin);
    vw_set_ptt_pin(transmit_en_pin);
    vw_set_ptt_inverted(true); // Required for DR3100 - ausprobieren ob true oder false
    vw_setup(500);  // Bits per sec - diese Geschwindigkeit hast du auch beim Sendesketch eingestellt
    ...

Rest wie oben. Seriellen Monitor auf 9600 stellen. Dann sollte zu empfangen sein, was du mit dem Sender verschickst (Ausgabe in HEX). Wünsche gutes Gelingen! :)

Kann es sein, dass du keine Antennen für den Sender und Empfänger verwendest ?

Die sind aber wichtig. Je Modul ein Stück (17,4 cm) Draht anlöten, das reicht.

Dann habe ich hier ein Tutorial, was auch funktioniert. Die Spannungen (5Volt und GND) der Module kannst du direkt anschließen, das brauchst du nicht über die Arduino-Ausgangspins führen.

Und die Geschwindigkeit der Daten per Funk solltest du auf 2000 Baud (vw_setup(2000)) herabsetzen.

Und diese Anweisungen:

const int transmit_en_pin = 3;
vw_set_ptt_pin(transmit_en_pin);
vw_set_ptt_inverted(true);

kannst du komplett weg lassen.

Und wenn es dann funktioniert, solltest du "Hallo Welt" im Empfänger-Monitor sehen können.