Arduino Bluetooth Problem

Hi, ich nutze einen Arduino Nano und einen Mega, beide sind über Bluetooth mit dem HM-05 verbunden, ich kann vom Slave(nano) zum Master senden, ich sende Sensordaten zu dem Mega welcher diese mit dem DMX-Shield verarbeitet. Also DMX Channel belegt etc. Soweit alles gut. Mein problem ist, dass ich zwar Daten empfangen kann, aber keine Daten vom Master zum Slave schicken kann, ohne dass dieser sich aufhängt..
Ich möchte auf dem Slave sehen, welcher DMX Channel gerade ausgewählt ist und welchen Wert er hat.

  if (ble.available()) {
    delay(5);
    String receiveMsg = ble.readStringUntil('\n');

Das funktioniert auf dem Master, jedoch nicht auf dem Slave.

String dmxValue = String(dmxChannel[dmxChannelPointer]);
ble.print(dmxChannelPointer + ":" + dmxValue);

So sende ich auch vom Slave und es kommt beim Master an, aber nicht umgekehrt..

Ich muss dem Slave allerdings einen String schicken, da sonst auch der nicht mehr sendet?!

Wenn ich den Master abschalte, sehe ich auf dem Serial Monitor vom Slave, dass dort daten ankommen. Irgendwo hängt sich etwas auf und ich verstehe nicht ganz warum.

moldan:
Mein problem ist, dass ich zwar Daten empfangen kann, aber keine Daten vom Master zum Slave schicken kann, ohne dass dieser sich aufhängt..

Wenn ich den Master abschalte, sehe ich auf dem Serial Monitor vom Slave, dass dort daten ankommen. Irgendwo hängt sich etwas auf und ich verstehe nicht ganz warum.

Wer soll das verstehen, wenn nicht Du?
Ohne vollständigen Code, mindestens vom Nano wird das nichts.
Vermutlich bleibt der irgendwo in einer Endlosschleife kleben.

Sowas lässt sich ggfls. mit einer Heartbeat-Funktion feststellen.

moldan:
Konnte nicht alles aufeinmal posten..

Da ist irgendwas schief gegangen.
Du hast im ersten Codeschnipsel irgendwas doppelt gemanschtes.
Lösch den Code und bau den neu ein.
Das Ganze ino-file (wenn es nicht passt!, weil es zu gross ist), als .txt-Datei als Attachment anhängen.

Ich kenne Master-Slave-Verbindungen so, dass der Master sagt, was er vom Slave will und dieser ihm das dann sendet. Bei Dir scheint das umgekehrt zu sein?

Gruß Tommy

Ok nochmal von vorn.
Ich habe die Bluetooth module Master und Slave getauscht.

Hier ist der DMX-Master mit dem Bluetooth Slave modul..

#include <Conceptinetics.h>
#include <SoftwareSerial.h>



#define DMX_MASTER_CHANNELS   40
#define RXEN_PIN                2


int dmxValues[DMX_MASTER_CHANNELS] = {0};

int roll;
int pitch;


int buttonA;
int buttonB;
int buttonGreen;
int buttonRed;


int colorVal = 1;
int dmxChannel[17] = {0};
int dmxChannelPointer = 5;
boolean mpuToDMX = true;

//Timervariablen
const long interval = 600;
int buttonTime = 0;
unsigned long previousMillis = 0;


DMX_Master       dmx_master ( DMX_MASTER_CHANNELS, RXEN_PIN );
SoftwareSerial ble(10, 11);

// the setup routine runs once when you press reset:
void setup() {

  // Enable DMX master interface and start transmitting
  dmx_master.enable ();
  // Enable bluetooth
  ble.begin(38400);

  dmxChannel[5] = 1;
}

// the loop routine runs over and over again forever:
void loop()
{
  unsigned long currentMillis = millis();

  // If data recieved
  if (ble.available()) {
    delay(5);
    String receiveMsg = ble.readStringUntil('\n');
    

    //reads string and saves to dmx channel values.
    readBleString(receiveMsg);

    // checks if movement is activated.
    //if (mpuToDMX == true) {
    //   roll   = skaleToDMX(roll, 0, 180, 0, 255);
    //   pitch  = skaleToDMX(pitch, 0, 180, 0, 255) + 50; //+50dmx channel val;
    dmxChannel[1] = dmxOverflow(roll);
    dmxChannel[3] = dmxOverflow(pitch);
  }//bluetooth available


  // green button
  //switches the menu
  if (buttonGreen == 0) {

    if (buttonTimer(currentMillis) == true) {
      dmxChannelPointer += 1;
    }
  }  
  // red button
  if (buttonRed == 0) {
    if (buttonTimer(currentMillis) == true) { //button timer
      dmxChannelPointer -= 1;
    }
  }

//channel pointer for switch case between 5 and 11
  if (dmxChannelPointer <= 4) {
    dmxChannelPointer = 11;
  }
  if (dmxChannelPointer >= 12) {
    dmxChannelPointer = 5;
  }

  switch (dmxChannelPointer) {
    case 5:
      // fast color change on channel 5
      buttonWrite(dmxChannelPointer, 4, 1, 48);
      break;

    case 6:
      // change gobo on channel 6
      buttonWrite(dmxChannelPointer, 4, 1, 128);
      break;
    case 7:
      //gobo speed
      buttonWrite(dmxChannelPointer, 8, 128, 253);
      break;
    case 8:
      //laser on channel 16
      buttonWrite(16, 64, 128, 253);  // laser on channel 16
      break;
    case 9:
      //shutter
      buttonWrite(dmxChannelPointer, 4, 0, 255);
      break;
    case 10:
      //dimmer
      break;
    case 11:
      //focus
      buttonWrite(dmxChannelPointer, 1, 0, 255);
      break;
    default:
      // statements
      break;
  }//switch case

  //write DMX data, allways writes last written data.
  writeAllDMX();
  
  //sending data to controller
  String dmxValue = String(dmxChannel[dmxChannelPointer]);
  ble.print(dmxChannelPointer + ":" + dmxValue);
  
  //small delay;
  delay (150);
}

Bluetooth controller:

#include <Wire.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include <Wire.h>


SoftwareSerial ble(4, 5);
String sendMsg;
int dmxChannel;
int dmxValue;
String mpu;


int PIN_EN_OUT =  5;
int PIN_STATE_IN =  4;


int buttonGreen = 10;
int buttonRed = 9;
int buttonA = 11;
int buttonB = 12;


//button state
int buttonGreenstate;
int buttonRedstate;
int buttonAstate;
int buttonBstate;


//Gyro
const int MPU = 0x68; //I2C address of the MPU-6050
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ; //16-bit integers
int AcXcal, AcYcal, AcZcal, GyXcal, GyYcal, GyZcal, tcal; //calibration variables
double t, tx, tf, pitch, roll, yawl;

void setup() {
  ble.begin(38400);
  Serial.begin(250000);
  //Gyro
  Wire.begin(); //initiate wire library and I2C
  Wire.beginTransmission(MPU); //begin transmission to I2C slave device
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true); //ends transmission to I2C slave device



  //Gyro
  Wire.begin(); //initiate wire library and I2C
  Wire.beginTransmission(MPU); //begin transmission to I2C slave device
  Wire.write(0x6B); // PWR_MGMT_1 register
  Wire.write(0); // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true); //ends transmission to I2C slave device


  pinMode(buttonA, INPUT);
  pinMode(buttonB, INPUT);
  pinMode(buttonGreen, INPUT);
  pinMode(buttonRed, INPUT);

  digitalWrite(buttonA, HIGH);
  digitalWrite(buttonB, HIGH);
  digitalWrite(buttonGreen, HIGH);
  digitalWrite(buttonRed, HIGH);

  Serial.println("---------Start----------");
}



void loop() {
  //read sensor data
  Wire.beginTransmission(MPU); //begin transmission to I2C slave device
  Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false); //restarts transmission to I2C slave device
  Wire.requestFrom(MPU, 14, true); //request 14 registers in total




  //Acceleration data correction
  AcXcal = 0;
  AcYcal = 0;
  AcZcal = 0;


  //Gyro correction
  GyXcal = 0;
  GyYcal = 0;
  GyZcal = 0;


  //read accelerometer data
  AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) 0x3C (ACCEL_XOUT_L)
  AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) 0x3E (ACCEL_YOUT_L)
  AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) 0x40 (ACCEL_ZOUT_L)


  //read gyroscope data
  GyX = Wire.read() << 8 | Wire.read(); // 0x43 (GYRO_XOUT_H) 0x44 (GYRO_XOUT_L)
  GyY = Wire.read() << 8 | Wire.read(); // 0x45 (GYRO_YOUT_H) 0x46 (GYRO_YOUT_L)
  GyZ = Wire.read() << 8 | Wire.read(); // 0x47 (GYRO_ZOUT_H) 0x48 (GYRO_ZOUT_L)

  //get pitch/roll
  getAngle(AcX, AcY, AcZ);
  float magnetic_heading = atan2(GyZ, GyX); //returns heading in radians



  buttonAstate = digitalRead(buttonA);
  buttonBstate = digitalRead(buttonB);
  buttonGreenstate = digitalRead(buttonGreen);
  buttonRedstate = digitalRead(buttonRed);

  //building Strings out of data to send via BLE
  String msgA = String(roll);
  String msgB = String(pitch);
  String msgC = String(yawl);
  String msgD = String(buttonAstate);
  String msgE = String(buttonBstate);
  String msgF = String(buttonGreenstate);
  String msgG = String(buttonRedstate);



  String msg = (msgA + ":" + msgB + ":" + msgC + ":" + msgD + ":" + msgE + ":" + msgF + ":" + msgG);

  if (ble.available()) {
    delay(4);
    ble.println(msg);

    Serial.println("ble out");
  }
  
  if (ble.available()) {
    delay(4);
    ble.readString();
  }

  Serial.println("loop");
}

void getAngle(int Ax, int Ay, int Az) {
  double x = Ax;
  double y = Ay;
  double z = Az;

  pitch = atan(x / sqrt((y * y) + (z * z))); //pitch calculation
  roll = atan(y / sqrt((x * x) + (z * z))); //roll calculation
  
  //converting radians into degrees
  pitch = pitch * (180.0 / 3.14);
  roll = roll * (180.0 / 3.14) ;
  
}

void readStringBle(String inputString) {
  //read int values out of substrings
  dmxChannel      =   (getValue(inputString, ':', 0)).toInt();
  dmxValue        =   (getValue(inputString, ':', 1)).toInt();
  mpu             =   (getValue(inputString, ':', 2));

}

String getValue(String data, char separator, int index) {
  int found = 0;
  int strIndex[] = { 0, -1 };
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

Moin,
ich verstehs nicht.
Compiliert der Code bei Dir?
Woher kommt buttonTimer und was macht das?

moldan:

    if (buttonTimer(currentMillis) == true) {

Oh im sorry noch was vergessen..

//cuts bluetooth data string  and save sub strings to values
void readBleString(String inputString) {
  //read int values out of substrings
  roll        =   (getValue(inputString, ':', 0)).toInt() + 50;
  pitch       =   (getValue(inputString, ':', 1)).toInt() + 40;
  buttonA     =   (getValue(inputString, ':', 2)).toInt();
  buttonB     =   (getValue(inputString, ':', 3)).toInt();
  buttonGreen =   (getValue(inputString, ':', 4)).toInt();
  buttonRed   =   (getValue(inputString, ':', 5)).toInt();

}//


//write all DMX channels
void writeAllDMX() {

  //pitch roll
  dmx_master.setChannelValue ( 1,  dmxChannel[1]);
  dmx_master.setChannelValue( 3, dmxChannel[3]);


  //color channel
  dmx_master.setChannelValue ( 5, dmxChannel[5]);
  dmx_master.setChannelValue ( 6, dmxChannel[6]);
  dmx_master.setChannelValue ( 7, dmxChannel[7]);
  dmx_master.setChannelValue ( 16, dmxChannel[16]);
  //shutter
  dmx_master.setChannelValue ( 9, dmxChannel[9]);
  // lamp
  dmx_master.setChannelValue ( 10, dmxChannel[10]);

  dmx_master.setChannelValue ( 11, dmxChannel[11]);
}//

String getValue(String data, char separator, int index) {
  int found = 0;
  int strIndex[] = { 0, -1 };
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}//


boolean mpuDmx() {
  if (buttonA == 0) {
    mpuToDMX = true;
  }
  else if (buttonB == 0) {
    mpuToDMX = false;
  }
}//


int dmxOverflow(int val) {
  if (val >= 256) {
    val = 255;
  } else if (val <= 0) {
    val = 0;
  }
  return val;
}//



//returns true after a button was pressed 300ms ago
boolean buttonTimer( long currentTime) {

    if (currentTime - previousMillis >= interval) { 
     previousMillis = currentTime; 
    return true;
    }
    else return true;

}//


void buttonWrite(int dmxPointer, int val, int mini, int maxi) {
unsigned long currentTimer = millis();
  if (buttonA == 0) {   
    if (buttonTimer(currentTimer) == true) {
      dmxChannel[dmxPointer] += val;

      if (dmxChannel[dmxPointer] >= maxi) {
        dmxChannel[dmxPointer] = mini;
      }
    }
  }

  if (buttonB == 0) {
    if (buttonTimer(currentTimer) == true) {
      dmxChannel[dmxPointer] -= val;
      if (dmxChannel[dmxPointer] <= mini) {
        dmxChannel[dmxPointer] = maxi;
      }
    }
  }
}//