Arduino Manager App with BLE and RF24

Ok, I’m having some issues with my project. I am attempting to send data received from a transceiver and pass it to the iOS app Arduino Manager via an Adafruit nRF8001 BLE breakout module. With this, I am only able to get one communication to work at a time (either BLE or RF24, NOT BOTH). I believe this has something to do with the timing of the SPI pins, but I’m not knowledgable enough to figure it out. The code below does not contain sending the received data from the transceiver, but instead just sending a test value of 498 while all the other code is there.

Arduino Uno Code

/*-----( Import needed libraries )-----*/
#include <SPI.h>
#include "RF24.h"  //Transceiver Library
#include "IOSControllerForBluefruit.h" //BLE

/*-----( Declare Constants and Pin Numbers )-----*/

/*-----( Declare objects )-----*/
RF24 myRadio (7, 8); // "myRadio" is the identifier you will use in following methods

/*-----( Declare Variables )-----*/
byte addresses[][6] = {"1Node"}; // Create address for 1 pipe.
// Data that will be received from the transmitter
int msg[1];
int LED1 = 4;
float in, out;
int value = 498;

void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);

  //*******Transeiver********
  myRadio.begin();  // Start up the physical nRF24L01 Radio
  myRadio.setChannel(108);  // Above most Wifi Channels
  myRadio.setPALevel(RF24_PA_MIN);
  myRadio.openReadingPipe(1, addresses[0]); // Use the first entry in array 'addresses' (Only 1 right now)
  myRadio.startListening();

  //*******LED/Buzzer********
  pinMode(LED1, OUTPUT);
}//--(end setup )---


void doWork();
void doSync(char *variable);
void processIncomingMessages(char *variable, char *value);
void processOutgoingMessages();
void deviceConnected();
void deviceDisconnected();
IOSControllerForBluefruit iosController(&doWork, &doSync, &processIncomingMessages, &processOutgoingMessages, &deviceConnected, &deviceDisconnected);



void doWork() {
  // New Main Loop

  if ( myRadio.available()) // Check for incoming data from transmitter
  {
    //while (myRadio.available())  // While there is data ready
    if (myRadio.available())  // While there is data ready
    {
      myRadio.read(msg, 1);
      Serial.println(msg[0]);
      if (msg[0] == 110)
      {
        for (in = 0; in < 6.283; in = in + 0.003) {
          out = sin(in) * 127.5 + 127.5;
          analogWrite(LED1, out);
        }
      }
      else if (msg[0] == 111)
      {
        for (in = 0; in < 6.283; in = in + 0.011) {
          out = sin(in) * 127.5 + 127.5;
          analogWrite(LED1, out);
        }
      }
      else if (msg[0] == 100)
      {
        for (in = 0; in < 6.283; in = in + 0.0009) {
          out = sin(in) * 127.5 + 127.5;
          analogWrite(LED1, out);
        }
      }
      else
      {
        digitalWrite(LED1, LOW);
      }
      delay(100);
    }
  }
  else
  {
    Serial.println("No radio available");
  }

}

void doSync(char *variable) {

  //Serial.print("Sync "); Serial.println(variable);


}

void processIncomingMessages(char *variable, char *value) {

  //Serial.print("Variable "); Serial.print(variable); Serial.print(" "); Serial.print(" Value "); Serial.println(value);


}

void processOutgoingMessages() {

  //Serial.println("Outgoing");
  iosController.writeMessage("Value", value); //Test value of 498
}

void deviceConnected() {

  Serial.println(F("Device Connected"));

}

void deviceDisconnected() {

  Serial.println(F("Device Disconnected"));

}


void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  iosController.loop(); //Goes to .cpp & .h

} //End Loop

//*********( THE END )***********

IOSControllerForBluefruit.cpp (7.99 KB)

IOSControllerForBluefruit.h (3.93 KB)

RF24-master (3).zip (337 KB)

.H File

#ifndef IOSControllerForBluefruit_h
#define IOSControllerForBluefruit_h

// #define DEBUG           // uncomment to enable debugging - You should not need it !

#include <Arduino.h>
#include <utility/My_Adafruit_BLE_UART.h>

#define VARIABLELEN 14
#define VALUELEN 14

class IOSControllerForBluefruit {

private:
char _remainBuffer[128];
bool            _initialized;
bool _connected;

/**
Pointer to the function where to put code in place of loop()
**/
void (*_doWork)(void); 

/*
Pointer to the function where Switches, Knobs and Leds are syncronized
*/
void (*_doSync)(char *variable);

/*
Pointer to the function where incoming messages are processed
*
* variable
*
* value
*
*/
void (*_processIncomingMessages)(char *variable, char *value);

/*
Pointer to the function where outgoing messages are processed
*
*/
void (*_processOutgoingMessages)(void);

#ifdef ALARMS_SUPPORT
/*
Pointer to the function where alerts are processed
*
*/
void (*_processAlarms)(char *alarm);
#endif

/*
Pointer to the function called when a device connects to Arduino
*
*/
void (*_deviceConnected)(void);

/*
Pointer to the function called when a device disconnects from Arduino
*
*/
void (*_deviceDisconnected)(void);

void readVariable(void);

public:

 IOSControllerForBluefruit(  void (*doWork)(void), void (*doSync)(char *variable), 
  void (*processIncomingMessages)(char *variable, char *value),
  void (*processOutgoingMessages)(void),
  void (*deviceConnected)(void),
  void (*deviceDisconnected)(void));
    
 void loop();
 void loop(unsigned long delay);
 
 void writeMessage(const char*variable, float value);
 void writeTripleMessage(const char*variable, float vX, float vY, float vZ); 
 void writeTxtMessage(const char*variable, const char*value);
 
 void log(const char*msg);
 void log(int msg);

 void logLn(const char*msg);
 void logLn(int msg);
 void logLn(long msg);
 void logLn(unsigned long msg);

 void temporaryDigitalWrite(uint8_t pin, uint8_t value, unsigned long ms);
 
 void processIncomingData(char *data, int len);
 
 void connected();
 void disconnected();
 
 
};



#endif

.CPP File

#include "IOSControllerForBluefruit.h"

#define ADAFRUITBLE_REQ 10
#define ADAFRUITBLE_RDY 2     // This should be an interrupt pin, on Uno is #2 or #3
#define ADAFRUITBLE_RST 9

void eventCallback(aci_evt_opcode_t event);
void rxCallback(uint8_t *buffer, uint8_t len);

IOSControllerForBluefruit *myGlobal;

My_Adafruit_BLE_UART BTLEserial = My_Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);

IOSControllerForBluefruit::IOSControllerForBluefruit( 
                             void (*doWork)(void), 
                             void (*doSync)(char *variable),
                             void (*processIncomingMessages)(char *variable, char *value),
                             void (*processOutgoingMessages)(void),
                             void (*deviceConnected)(void),
 void (*deviceDisconnected)(void)
                             )
{
    _doWork = doWork;
    _doSync = doSync;
    _processIncomingMessages = processIncomingMessages;
    _processOutgoingMessages = processOutgoingMessages;
    _deviceConnected = deviceConnected;
    _deviceDisconnected = deviceDisconnected;
    
    _remainBuffer[0] = '';

 _connected = false;  
 _initialized = false;
 
 BTLEserial.setACIcallback(&eventCallback);
 BTLEserial.setRXcallback(rxCallback);
 
 myGlobal = this;
}                             

void IOSControllerForBluefruit::loop() {
     
   if (!_initialized) {
   
   BTLEserial.begin();   
   _initialized = true;
 }     
 
 BTLEserial.pollACI();
 
 _doWork();
 
 BTLEserial.pollACI();
       
   // Write outgoing messages
   if (_connected)
   _processOutgoingMessages();   
}

void IOSControllerForBluefruit::writeMessage(const char*variable, float value)
{
    char buffer[VARIABLELEN+VALUELEN+3];
    char vbuffer[VALUELEN];
    
    if (!_connected)
     return;
            
    dtostrf(value, 0, 3, vbuffer);    
    snprintf(buffer,VARIABLELEN+VALUELEN+3, "%s=%s#", variable, vbuffer); 
    
    BTLEserial.write((uint8_t*)buffer, strlen(buffer)*sizeof(char));
    
    BTLEserial.pollACI(); 
}

void IOSControllerForBluefruit::writeTripleMessage(const char*variable, float vX, float vY, float vZ) {

    char buffer[VARIABLELEN+VALUELEN+3];
    char vbufferAx[VALUELEN];
    char vbufferAy[VALUELEN];
    char vbufferAz[VALUELEN];
    
    if (!_connected)
     return;

    dtostrf(vX, 0, 2, vbufferAx); 
    dtostrf(vY, 0, 2, vbufferAy); 
    dtostrf(vZ, 0, 2, vbufferAz);    
    snprintf(buffer,VARIABLELEN+VALUELEN+3, "%s=%s:%s:%s#", variable, vbufferAx,vbufferAy,vbufferAz); 
        
    BTLEserial.write((uint8_t*)buffer, strlen(buffer)*sizeof(char));
    
    BTLEserial.pollACI(); 
}

void IOSControllerForBluefruit::writeTxtMessage(const char*variable, const char*value) 
{
    char buffer[128];    
        
    if (!_connected)
     return;
        
    snprintf(buffer,128, "%s=%s#", variable, value);
    
    BTLEserial.write((uint8_t*)buffer, strlen(buffer)*sizeof(char));
    
    BTLEserial.pollACI(); 
}

void IOSControllerForBluefruit::log(const char*msg) 
{
 this->writeTxtMessage("$D$",msg);
}

void IOSControllerForBluefruit::log(int msg)
{
 char buffer[11];
 snprintf(buffer,10, "%d", msg);
 
 this->writeTxtMessage("$D$",buffer);
}


void IOSControllerForBluefruit::logLn(const char*msg) 
{
 this->writeTxtMessage("$DLN$",msg);
}

void IOSControllerForBluefruit::logLn(int msg)
{
 char buffer[11];
 snprintf(buffer,10, "%d", msg);
 
 this->writeTxtMessage("$DLN$",buffer);
}

void IOSControllerForBluefruit::logLn(long msg)
{
 char buffer[11];
 snprintf(buffer,10, "%l", msg);
 
 this->writeTxtMessage("$DLN$",buffer); 
}

void IOSControllerForBluefruit::logLn(unsigned long msg) 
{
 char buffer[11];
 snprintf(buffer,10, "%l", msg);
 
 this->writeTxtMessage("$DLN$",buffer);
}

void IOSControllerForBluefruit::temporaryDigitalWrite(uint8_t pin, uint8_t value, unsigned long ms) {

 boolean previousValue = digitalRead(pin);

    digitalWrite(pin, value);
    delay(ms);
    digitalWrite(pin, previousValue);
}

void IOSControllerForBluefruit::connected() {

 _connected = true;
 
 if (_deviceConnected!=NULL)
 _deviceConnected();
}

void IOSControllerForBluefruit::disconnected() {

 _connected = false;
 
 if (_deviceDisconnected!=NULL)
 _deviceDisconnected();
}

void IOSControllerForBluefruit::processIncomingData(char *data, int len) {

 char _variable[VARIABLELEN+1];
 char   _value[VALUELEN+1];
 bool   _var = true;
 uint8_t _idx = 0;
 uint8_t lastPound;

 _variable[0]=''; 
 _value[0]='';

 strncat(_remainBuffer,data,len);
 uint8_t l = strlen(_remainBuffer);
 
 BTLEserial.pollACI(); 

 for(uint8_t i=0; i<l; i++) {
 
 BTLEserial.pollACI(); 
 
 if (_var) {
 
 if (_remainBuffer[i] != '=') {
 
 _variable[_idx++] = _remainBuffer[i];
 } else {
 _variable[_idx] = '';
 _var = false;
 _idx = 0;
 }
 }
 else {
 
 if (_remainBuffer[i] != '#') {
 
 _value[_idx++] = _remainBuffer[i];
 }
 else {
 
 lastPound = i;
 _value[_idx] = '';
 _var = true;
 _idx = 0;
 
 if (strlen(_value)>0 && strcmp(_variable,"100") == 0) {
                                
                 // Process sync messages for the variable _value
                 BTLEserial.pollACI(); 
                 _doSync(_value);
                 BTLEserial.pollACI(); 
            }
            else {
            
             if (strlen(_variable)>0 && strlen(_value)>0) {
                
                // Process incoming messages
                BTLEserial.pollACI(); 
                _processIncomingMessages(_variable,_value);
                BTLEserial.pollACI(); 
             } 
             }
 }
 }
 }

 char tmp[128];
 if (lastPound==l-1){
 _remainBuffer[0]='';
 }
 else {
 strcpy(tmp,&_remainBuffer[lastPound+1]);
 strcpy(_remainBuffer,tmp);
 }
 
 _remainBuffer[0]='';
}
 
void eventCallback(aci_evt_opcode_t event) {
  
    if (event == ACI_EVT_DEVICE_STARTED) {
    
        Serial.println(F("* Advertising started"));
    }
    
    if (event == ACI_EVT_CONNECTED) {
      
 myGlobal->connected();
    }
    
    if (event == ACI_EVT_DISCONNECTED) {
    
     myGlobal->disconnected();
     delay(150);
    }  
}
 
void rxCallback(uint8_t *buffer, uint8_t len) {

 myGlobal->processIncomingData((char *)buffer,len);
 
 BTLEserial.pollACI();
}

Hi dbenedi2,

Have you checked for a conflict on CS of the two boards?

Fab,

For the transceiver, I used pins 7 & 8 for the CE & CSN respectively.

For the nRF8001 BLE I used REQ = 10, RDY = 2, and RST = 9.

I believe the issue is that both chips use pins 11,12, and 13 for mosi,miso,and sck respectively. With this, I utilized this same wiring/setup in order to connect to the iOS app nRF UART for testing purposes. Therefore, the Arduino should be able to transmit through BLE, while receiving data through the transceiver with minimal delay. I think it has something to do with how the IOSControllerForBluefruit library operates compared to using Adafruit_BLE_UART.h. I could be way off. Please let me know if you see an issue! Attached is a poorly drawn diagram. I appreciate any suggestions or further assistance.