BluetoothSenden/Empfangen+Pumpensteuerung

Hallo,
ich habe ein akutes Problem bei der Verheiratung von 2 Codes:
1.Anwendung: Ich möchte über Bluetooth Sensordaten auslesen und Eingaben machen.

2.Anwendung: Ich möchte über 2 Gebläse und eine Pumpe ansteuern über eine Bluetooth Konsole vom Handy.

Ich werde noch wahnsinnig, weil beide codes für sich tadellos funktionieren.

CODE1:
</#include <SoftwareSerial.h>

SoftwareSerial BTserial(8, 9); // RX, TX

char c=' ';

boolean NL = true;

void setup()

{

Serial.begin(9600);

Serial.print("Sketch: "); Serial.println(FILE);

Serial.print("Uploaded: "); Serial.println(DATE);

Serial.println(" ");

BTserial.begin(9600);

Serial.println("BTserial started at 38400");

Serial.println(" ");

}

void loop()

{

// Read from the Bluetooth module and send to the Arduino Serial Monitor

if (BTserial.available())

{

c = BTserial.read();

Serial.write(c);

}

// Read from the Serial Monitor and send to the Bluetooth module

if (Serial.available())

{

c = Serial.read();

BTserial.write(c);

// Echo the user input to the main window. The ">" character indicates the user entered text.

if (NL) { Serial.print(">"); NL = false; }

Serial.write(c);

if (c==10) { NL = true; }

}

}
/>

CODE2:

</#define PUMPE 5
#define GEBLAESE1 6
#define GEBLAESE2 7

int i;
char sendeInhalt = ' ';

void setup() {
pinMode(PUMPE, OUTPUT);
pinMode(GEBLAESE1, OUTPUT);
pinMode(GEBLAESE2, OUTPUT);
Serial.begin(9600);
}

void loop() {

if (Serial.available() > 0) //"wenn ein Datenpaket geliefert wird"
{
sendeInhalt = Serial.read(); //liest die Daten

if (sendeInhalt == '1') { analogWrite(PUMPE,255); //half speed
Serial.println ("Pumpe an");
} //Pumpe an 

if (sendeInhalt == '0') { analogWrite(PUMPE, 0); 
Serial.println ("Pumpe aus");
}  //Pumpe aus

if (sendeInhalt == 'A') { analogWrite(GEBLAESE1,255); //half speed
Serial.println ("Geblaese1 an");
} //Pumpe an 

if (sendeInhalt == 'B') { analogWrite(GEBLAESE1, 0); 
Serial.println ("Geblaese1 aus");
}  //Pumpe aus

if (sendeInhalt == 'C') { analogWrite(GEBLAESE2,255); //half speed
Serial.println ("Geblaese2 an");
} //Pumpe an 

if (sendeInhalt == 'D') { analogWrite(GEBLAESE2, 0); 
Serial.println ("Geblaese2 aus");
}  //Pumpe aus

Serial.flush(); //seriellen Puffer löschen
}

}
/>
Ich wollte beide Codes durch eine Oder Bedingung verknüpfen
ungefähr so:
if (BTserial.available() || Serial.available())
das funktioniert aber nicht ..
Jemand eine Idee, wie ich beide verheiraten könnte?
Gruß
Rimbo

Nicht nur.
Du kommentierst etwas, was aber anders im Code dargestellt ist
Pume an, wenn da Gebläse steht, ist genauso kontraproduktiv, wie half Speed wenn Du den PWM mit 255 beschreibst.
Und irgendwie kann ich aus Deinem BT-Code nicht erkennen, was Du da vorhast.
In deinem BT inititialisierst Du die Schnittstelle mit 9600 kommentierst aber 38400 usw...

Ich entnehme jetzt mal, das Du sowohl via Serial, als auch via BT Deine Pumpe(n) / Gebläse steuern willst.
Und offensichtlich willst Du auf dem SerMon sehen, was Du da machst.

Hier mal umgeschrieben - kompiliert fehler- und warnungsfrei.

// Forensketch auf zwei Schnittstellen Zeichen lesen
// https://forum.arduino.cc/t/bluetoothsenden-empfangen-pumpensteuerung/1058030

#include <SoftwareSerial.h>
SoftwareSerial BTserial(8, 9); // RX, TX
char myChar;
boolean NL = true;

const byte PUMPE = 5;
const byte GEBLAESE1 = 6;
const byte GEBLAESE2 = 7;

int i;
char sendeInhalt = ' ';

void setup()
{
  Serial.begin(9600);
  BTserial.begin(9600);
  Serial.println(F("Start..."));
  Serial.println(__FILE__);
  Serial.println( __TIMESTAMP__);
  pinMode(PUMPE, OUTPUT);
  pinMode(GEBLAESE1, OUTPUT);
  pinMode(GEBLAESE2, OUTPUT);
}

void loop()
{
  if (Serial.available() > 0) //"wenn ein Datenpaket geliefert wird"
  {
    myChar = Serial.read(); //liest die Daten
  }
  else if (BTserial.available() > 0)
  {
    myChar = BTserial.read();
  }
  switch (myChar)
  {
    case '1':
      analogWrite(PUMPE, 255);           //half speed
      Serial.println (F("Pumpe an"));    //Pumpe an
      break;
    case '0':
      analogWrite(PUMPE, 0);
      Serial.println (F("Pumpe aus"));   //Pumpe aus
      break;
    case 'A':
      analogWrite(GEBLAESE1, 255); //half speed
      Serial.println (F("Geblaese1 an"));  //Pumpe an
      break;
    case 'B':
      analogWrite(GEBLAESE1, 0);
      Serial.println (F("Geblaese1 aus"));  //Pumpe aus
      break;
    case 'C':
      analogWrite(GEBLAESE2, 255); //half speed
      Serial.println (F("Geblaese2 an"));  //Pumpe an
      break;
    case  'D':
      analogWrite(GEBLAESE2, 0);
      Serial.println (F("Geblaese2 aus"));   //Pumpe aus
      break;
  }
}

Das passiert nur wenn du weiterhin ganz auf die schnelle hier was änderst da was änderst ohne wirklich zu verstehen was du da machst.

Wenn man das Problem lösen will muss man es analysieren.
Durch serielle Debugausgaben. (Mehrzahl an ganz viielen Stellen etwas ausgeben
um wirklich nachvollziehen zu können was passiert.

Bei Programmieren gilt es ganz besonders

Besonders schnell ist in Wirklichkeit besonders langsam.
vgs

Ja, das ist sehr treffend gesagt :stuck_out_tongue_winking_eye: Schnellschüße sind meistens Schüße in den Ofen, oder ins eigene Knie. Man verbringt viel Zeit damit, diese tollen Einfälle dann wieder zu finden und Rückgängig zu machen, wenn das Programm danach noch schlechter läuft. Ich habe mir angewöhnt, zumindest einen Block hier zu haben, auf dem ich solche Schnellschüße nortiere. So kann ich sie wieder auffinden, wenn sie nichts taugen.

Hi,
vielen Dank! Es läuft! Ihr seid die besten Coaches, das Feedback nehme ich mir zu Herzen
Ich weiß, unsauber zusammen geräubert... wir sind gerade in einem zeitlich angespannten Projekt und müssen abliefern auf einen bestimmten Tag und ich hab nur noch rudimentäre C Kenntnisse aus der Uni von vor 8 Jahren.

Mit dem CASE ist es auf jedenfall deutlich übersichtlicher.

2 Themen hätte ich noch:

  1. der Befehl wird jeweils 5 mal hintereinander geprinted.

Sieht dann so aus.

  1. Der Text wird nicht rückübertragen in die Konsole auf dem Handy?

Ich wollte jetzt das zweite Problem angehen, in dem ich nochmal in jedem CASE-Teil die Bluetoothausgabe zurückschreibe, damit ist dann komischerweise auch die 5-Fach wiederholung weg, aber in der BT Konsole kommt dennoch nichts an.

Wo hab ich den Denkfehler?

  switch (myChar)
  {
    case '1':
      analogWrite(PUMPE, 255);          
      Serial.println (F("Pumpe an"));    //Pumpe an
      BTserial.println ("Pumpe an");
      break;
    case '0':
      analogWrite(PUMPE, 0);
      Serial.println (F("Pumpe aus"));   //Pumpe aus
      BTserial.println ("Pumpe an");
      break;

DAANKE!

Gruß
Rimbo

Nein, wird er nicht.
Die Ausgabe wird 4mal wiederholt.

Und gleich mal als Hinweis: stell Dir vor, das nicht jeder den Inhalt Deines Bildes sieht.
Die Ausgaben des Seriellen Monitors lassen sich ebensogut kopieren und hier in Codetags einfügen.

Warum das so ist, kannst Du mit Logikdenken rausfinden.
Vom Prinzip her ist es ganz einfach.
Du liest von der seriellen Schnittstelle ein Zeichen.
Auf dieses Zeichen reagierst Du.
Dadurch das Du erst auf erfolgreiche Prüfung, ob im seriellen Puffer mindestens ein Zeichen ist, reagierst, bleibt der Inhalt von myChar solange erhalten.
Wenn Du die Prüfung .available() > 0verzichtest, bekommst Du bei fehlendem Inhalt ein -1 zurück, womit der vorherige Inhalt gelöscht ist.

Hab ich mal gemacht und da ich heute im raten ganz gut war, gleich noch in die jeweiligen Funktionen aufgeteilt um den Spaghetticode aufzulösen.

Für die BT-Ausgabe kommt im Setup eine zusätzliche Zeile rein, um sicher zu gehen, das die Ausgabe wenigstens funktioniert.
Du musst also in jedem Fall die Zeile BT-Start...via BT ausgegeben bekommen.
Wenn das nicht kommt, ist was faul.

Da Du nicht erklärt hast, warum Du analogWrite mit 0/255 nimmst, habe ich das auf digitalWrite umgeschrieben.

Hinweis: zusätzlich ist eine Ausgabe drin, die Dir ausgibt, was Du empfangen hast.
Beachte, das auch alle Steuercodes mit ausgegeben werden!
Mach was draus.

// Forensketch auf zwei Schnittstellen Zeichen lesen
// https://forum.arduino.cc/t/bluetoothsenden-empfangen-pumpensteuerung/1058030

#include <SoftwareSerial.h>
SoftwareSerial BTserial(8, 9); // RX, TX
int myChar;
constexpr byte outputSize = 3;
constexpr byte outputPin[outputSize] = {5, 6, 7};
constexpr char output[outputSize][15] = {"Pumpe", "Gebläse 1", "Gebläse 2"};
uint8_t outputLevel[outputSize] = {0, 0, 0};

void setup()
{
  Serial.begin(9600);
  BTserial.begin(9600);
  Serial.println(F("Start..."));
  BTserial.println(F("BT-Start..."));
  Serial.println(__FILE__);
  Serial.println( __TIMESTAMP__);
  for (byte b = 0; b < outputSize; b++)
  { pinMode(b, OUTPUT); }
}


void loop()
{
  readIn();
  switchOut();
  printOut();
}

void readIn()
{
  myChar = Serial.read(); //liest die Daten
  if (myChar != -1)
  {
    Serial.print(F("Found char on serial: 0x"));
    Serial.println(myChar, HEX);
  }
  else
  {
    myChar = BTserial.read();
    if (myChar != -1)
    {
      Serial.print(F("Found char on BT: 0x"));
      Serial.println(myChar, HEX);
    }
  }
}
// *INDENT-OFF*
void switchOut()
{
  switch (myChar) 
  {
    case '1': digitalWrite(outputPin[0], HIGH); break; // Pumpe
    case '0': digitalWrite(outputPin[0], LOW);  break;
    case 'A': digitalWrite(outputPin[1], HIGH); break; // Gebl 1
    case 'B': digitalWrite(outputPin[1], LOW);  break;
    case 'C': digitalWrite(outputPin[2], HIGH); break; // Gebl 2
    case 'D': digitalWrite(outputPin[2], LOW);  break;
  }
}
// *INDENT-ON*

void printOut()
{
  static bool lastSwitch[outputSize] = {false};
  for (byte b = 0; b < outputSize; b++)
  {
    if (lastSwitch[b] != digitalRead(outputPin[b]))
    {
      lastSwitch[b] = !lastSwitch[b];
      Serial.print(output[b]);
      Serial.println(lastSwitch[b] ? " ein" : " aus");
      BTserial.print(output[b]);
      BTserial.println(lastSwitch[b] ? " ein" : " aus");
    }
  }
}