Conflict between BMSerial.h and SoftwareSerial.h librariers

Hey guys,

this is actually my first post on here and I’m fairly new to arduino and c++ as well.

SETUP

I got the Bluefruit connected via Softwareserial according to this wiring diagramm

The controller is connected in packet serial mode.

APPLICATION

I want to control the Roboclaw via the Bluetooth app on my phone that comes with the Bluefruit. The app has a controller mode which sends a UART msg whenever you press or release a button.

link to the app: https://play.google.com/store/apps/details?id=com.adafruit.bluefruit.le.connect&hl=en
CODE

#include <string.h>
#include <Arduino.h>
#include <SPI.h>

#include <SoftwareSerial.h>

#include <RoboClaw.h>
#include “Adafruit_BLE.h”
#include “Adafruit_BluefruitLE_SPI.h”
#include “Adafruit_BluefruitLE_UART.h”

#include “BluefruitConfig.h”
#include <BMSerial.h>
#define address 0x80
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);

Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,
BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);

RoboClaw roboclaw(19,18);
// A small helper
void error(const __FlashStringHelper*err) {
Serial.println(err);
while (1);
}

// function prototypes over in packetparser.cpp
uint8_t readPacket(Adafruit_BLE *ble, uint16_t timeout);
float parsefloat(uint8_t *buffer);
void printHex(const uint8_t * data, const uint32_t numBytes);

// the packet buffer
extern uint8_t packetbuffer;

//
/*!
@brief Sets up the HW an the BLE module (this function is called
automatically on startup)
*/
/
/
void setup(void)
{ roboclaw.begin(38400);
while (!Serial); // required for Flora & Micro
delay(500);

Serial.begin(115200);
Serial.println(F(“Adafruit Bluefruit App Controller Example”));
Serial.println(F("-----------------------------------------"));

/* Initialise the module */
Serial.print(F("Initialising the Bluefruit LE module: "));

if ( !ble.begin(VERBOSE_MODE) )
{
error(F(“Couldn’t find Bluefruit, make sure it’s in CoMmanD mode & check wiring?”));
}
Serial.println( F(“OK!”) );

/* Perform a factory reset to make sure everything is in a known state */
Serial.println(F("Performing a factory reset: "));
if (! ble.factoryReset() ){
error(F(“Couldn’t factory reset”));
}

/* Disable command echo from Bluefruit */
ble.echo(false);

Serial.println(“Requesting Bluefruit info:”);
/* Print Bluefruit information */
ble.info();

Serial.println(F(“Please use Adafruit Bluefruit LE app to connect in Controller mode”));
Serial.println(F(“Then activate/use the sensors, color picker, game controller, etc!”));
Serial.println();

ble.verbose(false); // debug info is a little annoying after this point!

/* Wait for connection */
while (! ble.isConnected()) {
delay(500);
}

Serial.println(F("*****************"));

// Set Bluefruit to DATA mode
Serial.println( F(“Switching to DATA mode!”) );
ble.setMode(BLUEFRUIT_MODE_DATA);

Serial.println(F("*****************"));

}

//
/*!
@brief Constantly poll for new command or response data
*/
/
/
void loop(void)
{
/* Wait for new data to arrive */
uint8_t len = readPacket(&ble, BLE_READPACKET_TIMEOUT);
if (len == 0) return;

/* Got a packet! */
// printHex(packetbuffer, len);

// Buttons
if (packetbuffer[1] == ‘B’) {
uint8_t buttnum = packetbuffer[2] - ‘0’;
boolean pressed = packetbuffer[3] - ‘0’;
if(buttnum==5)
{
if (pressed) {
roboclaw.ForwardM1(address,64); //start Motor1 forward at half speed;

} else {
roboclaw.ForwardM1(address,64); //start Motor1 forward at half speed
}}
}

}

So I pretty much took one of the example codes that came with the Bluefruit to make it work with the app ( example sketch named “controller” to be found Arduino\libraries\Adafruit_BluefruitLE_nRF51\examples\controller), deleted stuff I wouldnt need and added the BMSerial.h and the Roboclaw.h and a few lines of code for the controller. I copied those lines from Arduino\libraries\RoboClaw\examples\PacketSerialSimplePWM.

PROBLEM

Whenever I try to compile the code i get this error message:

Arduino: 1.6.5 (Windows 8.1), Platine: “Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)”

BMSerial\BMSerial.cpp.o: In function __vector_9': C:\Users\User\Documents\Arduino\libraries\BMSerial/BMSerial.cpp:394: multiple definition of __vector_9’
SoftwareSerial\SoftwareSerial.cpp.o:C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial/SoftwareSerial.cpp:227: first defined here
c:/program files (x86)/arduino/hardware/tools/avr/bin/…/lib/gcc/avr/4.8.1/…/…/…/…/avr/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions
BMSerial\BMSerial.cpp.o: In function BMSerial::tx_pin_write(unsigned char)': C:\Users\User\Documents\Arduino\libraries\BMSerial/BMSerial.cpp:334: multiple definition of __vector_10’
SoftwareSerial\SoftwareSerial.cpp.o:C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial/SoftwareSerial.cpp:392: first defined here
BMSerial\BMSerial.cpp.o: In function BMSerial::tx_pin_write(unsigned char)': C:\Users\User\Documents\Arduino\libraries\BMSerial/BMSerial.cpp:334: multiple definition of __vector_11’
SoftwareSerial\SoftwareSerial.cpp.o:C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial/SoftwareSerial.cpp:392: first defined here
collect2.exe: error: ld returned 1 exit status
Fehler beim Kompilieren.

So it seems to me the two libraries BMSerial.h and SoftwareSerial.h are somehow in conflict which each other. I tried avoiding to use the SoftwareSerial.h by wiring the Bluefruit via hardware Serial but that gave me a really strange error some people had before as well, where I just couldn’t upload anything to the arduino, not even an empty code, while I got the bluefruit wired to the hardware serial pins. I’m hoping for a simple solution to fix this error and continue on my project, I would be really glad if you guys could provide some help! Please let me know if you need any more information. Thanks

Attachements
Used libraries including sample sketches

libraries.zip (88.7 KB)

So it seems to me the two libraries BMSerial.h and SoftwareSerial.h are somehow in conflict which each other.

Yes, they are both trying to use the same timer.

I tried avoiding to use the SoftwareSerial.h by wiring the Bluefruit via hardware Serial but that gave me a really strange error some people had before as well, where I just couldn’t upload anything to the arduino, not even an empty code, while I got the bluefruit wired to the hardware serial pins.

So? Disconnect the bluetooth device before uploading code.

I’m hoping for a simple solution to fix this error

You are not going to get one.

Thanks for your quick reply!

So the thing with the hardware serial is i would like the arduino to be accesible for quick code changes without unplugging the protoshield. So what if I somehow create different timers in each library? Are you telling me there is no way to use those two libraries in the same sketch?

So the thing with the hardware serial is i would like the arduino to be accesible for quick code changes without unplugging the protoshield.

Well, I'd like a $1,000,000 in small bills.

So what if I somehow create different timers in each library?

The UNO only has three timers. One of them is used as a clock, by micros(), millis(), etc. You can't use that one. The other two could be used, but they have specific characteristics that may not let them be used interchangeably.

One possibility would be to get a Leonardo, where the pins 0 and 1 are connected to Serial1, not Serial, so the board can still be programmed. The drawback to this is that the Leonardo is retired, so getting one might be a problem.

Another is to get a Mega or DUE that each have 4 hardware serial ports. The drawback to this is that BMSerial seems to be embedded in the RoboClaw library, and it might be difficult to change that library to use a hardware serial instance, instead.

A third possibility is to rewrite the RoboClaw library to use SoftwareSerial, instead of BMSerial. I have no idea whether that is possible, since I have no idea how BMSerial differs from SoftwareSerial.

Hmm OK I see… as I wrote in the first post, we already got a mega 2560.

OK so lets say I wire the bluetooth over the hardwareserial ports and just accept that I can’t upload anything while I got the bluefruit connected.
The sketch will still error because the controller sketch I’m using is using the (I guess it’s a library?) packet.Parser.cpp. It will open up as a tab in the arduino coding window whenever I open the Controller Sketch. Code looks like this:

#include <string.h>
#include <Arduino.h>
#include <SPI.h>
#include <SoftwareSerial.h>

#include “Adafruit_BLE.h”
#include “Adafruit_BluefruitLE_SPI.h”
#include “Adafruit_BluefruitLE_UART.h”

#define PACKET_ACC_LEN (15)
#define PACKET_GYRO_LEN (15)
#define PACKET_MAG_LEN (15)
#define PACKET_QUAT_LEN (19)
#define PACKET_BUTTON_LEN (5)
#define PACKET_COLOR_LEN (6)
#define PACKET_LOCATION_LEN (15)

// READ_BUFSIZE Size of the read buffer for incoming packets
#define READ_BUFSIZE (20)

/* Buffer to hold incoming characters */
uint8_t packetbuffer[READ_BUFSIZE+1];

//
/*!
@brief Casts the four bytes at the specified address to a float
*/
/
/
float parsefloat(uint8_t *buffer)
{
float f = ((float *)buffer)[0];
return f;
}

//
/*!
@brief Prints a hexadecimal value in plain characters
@param data Pointer to the byte data
@param numBytes Data length in bytes
*/
/
/
void printHex(const uint8_t * data, const uint32_t numBytes)
{
uint32_t szPos;
for (szPos=0; szPos < numBytes; szPos++)
{
Serial.print(F(“0x”));
// Append leading 0 for small values
if (data[szPos] <= 0xF)
{
Serial.print(F(“0”));
Serial.print(data[szPos] & 0xf, HEX);
}
else
{
Serial.print(data[szPos] & 0xff, HEX);
}
// Add a trailing space if appropriate
if ((numBytes > 1) && (szPos != numBytes - 1))
{
Serial.print(F(" "));
}
}
Serial.println();
}

//
/*!
@brief Waits for incoming data and parses it
*/
/
/
uint8_t readPacket(Adafruit_BLE *ble, uint16_t timeout)
{
uint16_t origtimeout = timeout, replyidx = 0;

memset(packetbuffer, 0, READ_BUFSIZE);

while (timeout–) {
if (replyidx >= 20) break;
if ((packetbuffer[1] == ‘A’) && (replyidx == PACKET_ACC_LEN))
break;
if ((packetbuffer[1] == ‘G’) && (replyidx == PACKET_GYRO_LEN))
break;
if ((packetbuffer[1] == ‘M’) && (replyidx == PACKET_MAG_LEN))
break;
if ((packetbuffer[1] == ‘Q’) && (replyidx == PACKET_QUAT_LEN))
break;
if ((packetbuffer[1] == ‘B’) && (replyidx == PACKET_BUTTON_LEN))
break;
if ((packetbuffer[1] == ‘C’) && (replyidx == PACKET_COLOR_LEN))
break;
if ((packetbuffer[1] == ‘L’) && (replyidx == PACKET_LOCATION_LEN))
break;

while (ble->available()) {
char c = ble->read();
if (c == ‘!’) {
replyidx = 0;
}
packetbuffer[replyidx] = c;
replyidx++;
timeout = origtimeout;
}

if (timeout == 0) break;
delay(1);
}

packetbuffer[replyidx] = 0; // null term

if (!replyidx) // no data or timeout
return 0;
if (packetbuffer[0] != ‘!’) // doesn’t start with ‘!’ packet beginning
return 0;

// check checksum!
uint8_t xsum = 0;
uint8_t checksum = packetbuffer[replyidx-1];

for (uint8_t i=0; i<replyidx-1; i++) {
xsum += packetbuffer*;*

  • }*

  • xsum = ~xsum;*

  • // Throw an error message if the checksum’s don’t match*

  • if (xsum != checksum)*

  • {*

  • Serial.print("Checksum mismatch in packet : ");*

  • printHex(packetbuffer, replyidx+1);*

  • return 0;*

  • }*

  • // checksum passed!*

  • return replyidx;*
    }
    [/quote]
    To my Understanding this add on sketch creates a kind of buffer for whatever I sent from the Bluefruit as UART.
    Can somebody help me on how to get this to work without the Softwareserial.h?
    I dont necessesarly need to use the controller sketch/app but for example when I send “M1 start full” from my phone I would like the motor to start and Stop when I send another text e.g. “M1 stop”?
    I tried doing that by using the bluefruit UART cmd mode example sketch which prints out everything I send from the phone by playing around with if clauses but I couldn’t make it work cause I can’t figure out on how that sketch actually works :confused: (C:\Users\User\Documents\Arduino\libraries\Adafruit_BluefruitLE_nRF51
    \examples\bleuart_cmdmode). If somebody has a solution to make it work with either the controller sketch without using Softwareserial.h or as I just described with regular UART messages I would appreciate it a lot!
    Thanks!

Soooo I just tried using the UART cmd mode(C:\Users\User\Documents\Arduino\libraries\Adafruit_BluefruitLE_nRF51\examples\bleuart_cmdmode ) configured for hardwareserial( deleted the other lines) together with the BMSerial library and even though I can't exactly see where, this sketch still calls the SoftwareSerial.h at some point and therefore conflicts with the BMSerial...

A Mega has 4 HardwareSerial ports so you can have one connected to the PC for uploading code and displaying debug messages and another for your Bluetooth device. (and still have 2 more unused).

I wonder if my yet another software serial would be a solution if you want to use your Uno.

And PLEASE use the code button </> so that your code looks like this

…R

See, I know I got multiple hardwareserial ports. The thing is, doesn't matter how i connect my devices to the mega, the sketches that I use will always contain (and demand) the softwareserial.h (thats the bluefruit) and the BMSerial.h(Motor controller) even if I both connect them via hardwareserial. So i guess my Question would be right now: Can somebody provide a solution to use the same library for both of them OR get rid of the usage of one of them OR get rid of the conflict those two have with the timer? Thanks for any help, I appreciate it!

The thing is, doesn't matter how i connect my devices to the mega, the sketches that I use will always contain (and demand) the softwareserial.h (thats the bluefruit) and the BMSerial.h(Motor controller) even if I both connect them via hardwareserial.

You need to modify the libraries to NOT use SoftwareSerial OR you need to demand that Adafruit and the RoboClaw people do it.

There is NO way to modify either of the software serial libraries to not use timer 1.

I got that, It's just that I can't do it.. I've never worked with arduino before and am fairly a beginner to c++. Is there a chance anybody on here can help me with that? Internet people, I need you! :wink:

I don't have your hardware or your libraries. If you were interested in lending me the hardware, I'm reasonably confident that I could make copies of both libraries that no longer knew a thing about software serial. PM me, if you want to follow up.

all the libraries are attached to my first post!

all the libraries are attached to my first post!

I guess I missed the part where you attached the hardware. I can't write code when can not test it. I'm just funny that way.

Paul, that (without testing) is the best way to write code imo - if you test it, then it has to work! Where's the fun in that???

DrAzzy:
Paul, that (without testing) is the best way to write code imo - if you test it, then it has to work! Where's the fun in that???

Well, since I generally get paid when the customer accepts the code as working, there is great fun in delivering code that I know will work. Not so much fun with delivering guess-work.

Well yeah, if I’m getting folding green stuff, sure :wink:

But the testing is work, writing code is fun.

Looking at the libraries, I think you’ll have to use hardware serial on one of them, since you’ve got this roboclaw thing connected (right?) and it uses software serial (in this case BMSerial - which looks like a typical software serial implementation) to communicate with the roboclaw. Even aside from the conflicts, it’s best to not have multiple software serial ports at the same time.

Here’s a de-software-seralified library. No idea if it works, ofc :stuck_out_tongue:

Adafruit_BluefruitLE_UART.zip (4.15 KB)

Thanks for the support guys, I will try your library tomorrow! I decided to concentrate on my code without using bluetooth for the last days and came upon another problem.
I'm currently communicating with the roboclaw via Packetserial. And there seem to be a way to get the currents from the motors. I read through the data sheet multiple times and used google but for me as a beginner I couldn't really figure out how to do it.
This is what the data sheet says:

49 - Read Motor Currents
Read the current draw from each motor in 10ma increments. Command syntax:
Send: [Address, 49]
Receive: [M1Cur.Byte1, M1Cur.Byte0, M2Cur.Byte1, M2Cur.Byte0, Checksum]
The command will return 5 bytes. Bytes 1 and 2 combine to represent the current in 10ma increments
of motor1. Bytes 3 and 4 combine to represent the current in 10ma increments of motor2 . Byte 5 is
the checksum

Could someone provide me an example how to exactly send the command and store what I received in two variables?

Thanks!