moldan
December 25, 2020, 8:33pm
1
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.
Tommy56
December 25, 2020, 10:07pm
4
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
moldan
December 28, 2020, 8:45am
5
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);
}
moldan
December 28, 2020, 8:57am
6
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) {
moldan
December 28, 2020, 10:27am
8
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;
}
}
}
}//