BMSerial and SoftwareSerial libraries

i everybody,

I need some help concerning a conflict between librairies. I work on an Arduino Uno R3.
Currently, my project consists on receiving data from a sensor, and control a motor with a Roboclaw 2x5A.
My main code with the control of the motor works great, using the BMSerial.h library from Roboclaw (Pololu/Orion).
Nevertheless, I need to integrate another code, which asks my sensor with the command “MSV?\r\n” to receive the data. This code worked great with the SoftwareSerial.h library but now, it’s not possible to send the command “MSV?\r\n”. And I need to make it works with BMSerial to include it in my main code.

My code with SoftwareSerial is :

#include <SoftwareSerial.h>
String chaine1;
String test;
int data;
int i = 0;

SoftwareSerial Poids(7, 6); // RX, TX

void setup()
{
  Poids.begin(38400);
  Serial.begin(38400);
  Serial.println("Test AD104C - Initialisation");
  delay(5);
}

int HBM()
{ chaine1 = "";
  test    = "";
  data = 0;

    Poids.write("MSV?\r\n");

  while (Poids.available() == 0) {} // bloque si pas de DATA / 0 = NULL

  while (Poids.available() != 0)    // on rentre dans la boucle si on a des DATA (10 = LF et 13 = CR)
  {
    data = Poids.read();
    chaine1 += data;
  }

  test = chaine1.substring(16, 20); // on repere les erreurs rencontrées
  if (test.equals("1310"))          // taille trame conforme = on affiche pas si

  { chaine1 = chaine1.substring(0, 20);         // on enleve les CR LF de fin de trame
    int poids = 0;
    poids = 1000000 * ((chaine1.substring(2, 4)).toInt() - 48) + 100000 * ((chaine1.substring(4, 6)).toInt() - 48) + 10000 * ((chaine1.substring(6, 8)).toInt() - 48) + 1000 * ((chaine1.substring(8, 10)).toInt() - 48) + 100 * ((chaine1.substring(10, 12)).toInt() - 48) + 10 * ((chaine1.substring(12, 14)).toInt() - 48) + 1 * ((chaine1.substring(14, 16)).toInt() - 48);
    return poids;
  }
}

void loop()
{
  Serial.println(HBM());
}

My error when I change for the BMSerial library is :

final_AD104C.ino: In function 'float HBM()':
final_AD104C:24: error: invalid conversion from 'const char*' to 'uint8_t {aka unsigned char}' [-fpermissive]
In file included from final_AD104C.ino:1:0:
/Users/coste/Documents/Arduino/libraries/BMSerial/BMSerial.h:110:17: error:   initializing argument 1 of 'virtual size_t BMSerial::write(uint8_t)' [-fpermissive]
  virtual size_t write(uint8_t byte);
                 ^
invalid conversion from 'const char*' to 'uint8_t {aka unsigned char}' [-fpermissive]

Link for BMSerial.cpp and BMSerial.h :BMSerial

Thank you in advance for your help :slight_smile:

If I understand correctly the code you posted with SoftwareSerial works correctly.

And you say that some other code (which you have not posted) works properly with the BMSerial library

Then I don’t understand what you mean by

when I change for the BMSerial library

Do mean that you are trying to use the BMSerial library in place of the SoftwareSerial library in the code you posted ?
OR
Do you mean that you are trying to use BMSerial and SoftwareSerial in the same program.

Please post the code that is causing the problem.

…R

Thank you for your reply :slight_smile: Sorry I’m French and it’s hard for me to explain correctly my problem, but I try :wink:
On my main code (about 600 lines) I use the BMSerial library and all works great but I don’t use the “write” function and I think that I have a problem with this function.

Yes when I say that my code doesn’t work with the BMSerial library, I simply comment the SoftwareSerial include and the declaration of my Serial, like this :

#include <BMSerial.h>
//#include <SoftwareSerial.h>

BMSerial Poids(7, 6); // RX, TX
//SoftwareSerial Poids(7, 6); // RX, TX

This have to work because BMSerial is a modified version of SoftwareSerial.cpp. But it doesn’t.

Moreover, I tried this morning to put this on the .h file :

using Print::write;

I don't have errors anymore, but nothing happens when I look at my terminal.

Moreover, is it possible to use both of these libraries ? If I do some changes.

Thank you in advance for your help

Thanks. You have provided some helpful clarification.

I had a quick look at your link to BMSerial - but it is a Github page and they use that awful pale grey text that gives me a headache. I could not immediately see a description of what is different about it.

Maybe you can post the code as an attachment here so I can read it more easily.

Have you tried using SoftwareSerial in place of BMSerial in the program that works with BMSerial ?

...R

Thank you for you help Robin2 !

If I choose to work with SoftwareSerial in my main code (which works fine with BMSerial), I have a lot of errors that give me a headache too :

Arduino : 1.6.5 Hourly Build 2015/06/10 06:13 (Mac OS X), Carte : "Arduino Uno"

test_bluetooth_moteur_part4.cpp.o: In function `setup':
/Users/coste/test_bluetooth_moteur_part4.ino:72: undefined reference to `BMSerial::begin(long)'
RoboClaw/RoboClaw.cpp.o: In function `RoboClaw::RoboClaw(unsigned char, unsigned char, unsigned long, bool)':
/Users/coste/Documents/Arduino/libraries/RoboClaw/RoboClaw.cpp:6: undefined reference to `BMSerial::BMSerial(unsigned char, unsigned char, bool)'
RoboClaw/RoboClaw.cpp.o: In function `RoboClaw::~RoboClaw()':
/Users/coste/Documents/Arduino/libraries/RoboClaw/RoboClaw.cpp:15: undefined reference to `BMSerial::~BMSerial()'
RoboClaw/RoboClaw.cpp.o: In function `RoboClaw::write_n(unsigned char, ...)':
/Users/coste/Documents/Arduino/libraries/RoboClaw/RoboClaw.cpp:37: undefined reference to `BMSerial::read(unsigned long)'
RoboClaw/RoboClaw.cpp.o: In function `RoboClaw::Read4_1(unsigned char, unsigned char, unsigned char*, bool*)':
/Users/coste/Documents/Arduino/libraries/RoboClaw/RoboClaw.cpp:146: undefined reference to `BMSerial::read(unsigned long)'
/Users/coste/Documents/Arduino/libraries/RoboClaw/RoboClaw.cpp:150: undefined reference to `BMSerial::read(unsigned long)'
/Users/coste/Documents/Arduino/libraries/RoboClaw/RoboClaw.cpp:154: undefined reference to `BMSerial::read(unsigned long)'
/Users/coste/Documents/Arduino/libraries/RoboClaw/RoboClaw.cpp:158: undefined reference to `BMSerial::read(unsigned long)'
RoboClaw/RoboClaw.cpp.o:/Users/coste/Documents/Arduino/libraries/RoboClaw/RoboClaw.cpp:162: more undefined references to `BMSerial::read(unsigned long)' follow
RoboClaw/RoboClaw.cpp.o:(.rodata._ZTV8RoboClaw[vtable for RoboClaw]+0x4): undefined reference to `BMSerial::write(unsigned char)'
RoboClaw/RoboClaw.cpp.o:(.rodata._ZTV8RoboClaw[vtable for RoboClaw]+0x8): undefined reference to `BMSerial::available()'
RoboClaw/RoboClaw.cpp.o:(.rodata._ZTV8RoboClaw[vtable for RoboClaw]+0xa): undefined reference to `BMSerial::read()'
RoboClaw/RoboClaw.cpp.o:(.rodata._ZTV8RoboClaw[vtable for RoboClaw]+0xc): undefined reference to `BMSerial::peek()'
RoboClaw/RoboClaw.cpp.o:(.rodata._ZTV8RoboClaw[vtable for RoboClaw]+0xe): undefined reference to `BMSerial::flush()'
collect2: error: ld returned 1 exit status
Erreur lors de la compilation.

I think the fact that they are using same names of functions create a conflict.

Please find attached the codes of the librairies without awful pale grey :wink:

BMSerial.cpp (20.6 KB)

BMSerial.h (4.3 KB)

SoftwareSerial.cpp (13.2 KB)

SoftwareSerial.h (3.95 KB)

Thanks for the attachments. I can't immediately make sense of the problem I may look at it again tomorrow.

invalid conversion from 'const char*' to 'uint8_t

have you tried changing the type of the data from char to byte ?

Have you tried using both BMSerial and SoftwareSerial in the same program. I suspect there will be a problem, but it may be worth a try.

Another possibility may be to use my yet another software serial alongside BMSerial

...R

Thank you for taking a look at it tomorrow, I really appreciate your help !
Yes I have some basis in C++, and I tried to right the same function but with a const char* parameter but I think I made mistakes. Do you think that this method can work ? (If the code is good obviously …)
Moreover I tried to remplace the BMSerial Write function by the SoftwareSerial Write function (because this one accept a const char* and works great) but it doesn’t work.

Yes I tried to use both of them in the same program but I think there are conflicts between them.

Tomorrow I will try your library (great work !). I will try it with/without BMSerial.h to test it.

Thank you in advance for your answer and your help !

EDIT :

I have seen this in the BMSerial.h :

#ifndef USB_PID_DUE 
 #include <avr/interrupt.h>
 #include <avr/pgmspace.h>
#endif

#ifndef USB_PID_DUE 
#if defined(UBRRH) || defined(UBRR0H)
 #define _BMSERIAL0
#endif
#if defined(UBRR1H)
 #define _BMSERIAL1
#endif
#if defined(UBRR2H)
 #define _BMSERIAL2
#endif
#if defined(UBRR3H)
 #define _BMSERIAL3
#endif
#else
 #define _BMSERIAL0
 #define _BMSERIAL1
 #define _BMSERIAL2
 #define _BMSERIAL3
#endif

#ifdef _BMSERIAL1
 #define _TX3 14
 #define _RX3 15
#endif
#ifdef _BMSERIAL1
 #define _TX2 16
 #define _RX2 17
#endif
#ifdef _BMSERIAL1
 #define _TX1 18
 #define _RX1 19
#endif
#define _TX0 1
#define _RX0 0

#ifndef USB_PID_DUE

So I can’t put my RX and TX on D6 and D7 ? Sorry if I say something wrong but I test everything I can.

EDIT 2 :
Please find attached my test with your library and my project, I tried it but it doesn’t work … I’m not sure that I use it correctly, and if a 38400 baud rate is good.

Clément

final_AD104C.zip (5.05 KB)

Poly34: I tried to right the same function but with a const char* parameter but I think I made mistakes

I did not mean to change the code in the function. I just meant to change the type of variable you pass to the function - in other words, make your code match what the function expects.

I have not had time to look at the code yet - maybe later today.

...R

Hello Robin2

Yes I already tried to do that, but I'm going to re-try it ..

Moreover, I'm sorry but I have edit my previous post with my project and your library, if you want to see it (I'm not sure I use it correctly :/ )

And as always, thank you for your attention and your precious help Robin2

EDIT : Sorry for the double post :/

I try something very curious ...

A command exists for my sensor which is "MSV?O\r\n". This command permits to receive the data continuously.

So, I compiled my program with SoftwareSerial and in the setup part, I wrote Poids.write("MSV?0\r\n");. It works and I received my data continuously in my serial port. I only needed to read the data.

After this, I compiled the same program with BMSerial in the same port, but without Poids.write("MSV?0\r\n"); in the setup part. In my point, now I just need to read the data and I didn't need to write anything ! But ... I received data but not what I expect. I received "1604817648152144176149141138" but it returns "0.00" because my return value is a float, and if a put an object on my sensor, I receive "ovf".

It's maybe not a Write problem ... I'm completely lost.

@Poly34, you need to post the entire program so I can understand the context of your comments.

You probably have this project in your mind full-time. I don't - only for a few minutes each time I look at your Thread.

Sorry but its going to be later this evening before I have time to spend on your questions.

...R

Hi,

I posted my code 2 messages ago but yes sorry for the edit etc … I’m working on it for 1 week and I’m so near to finish my project … It’s frustrating.

I’m going to explain the best I can where I am.

COMMANDS :
Command “MSV?\r\n” : ask the data, the sensor sends it
Command “MSV?0\r\n” : the sensor sends continuously his data without ask him another time.

CODE A : Using SoftwareSerial.h
This code works. During my setup, I write in my serial port the command “MSV?0\r\n”.

#include "SoftwareSerial.h"

String chaine1;
String test;
int data;

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


void setup()
{
  Poids.begin(38400);
  Serial.begin(38400);
  Serial.println("Test AD104C - Initialisation");
  delay(5);
  Poids.write("MSV?0\r\n");
}

float HBM()
{ chaine1 = "";
  test    = "";
  data = 0;

  while (Poids.available() == 0) {} // I read my port

  while (Poids.available() != 0)    // we are IN if we can read DATA (10 = LF et 13 = CR)
  {
    data = Poids.read();
    chaine1 += data;
  }

  test = chaine1.substring(16, 20); // we read CR LF
  if (test.equals("1310"))          // if end=CR LF so my data is good

  { chaine1 = chaine1.substring(0, 20);         // I can convert my ascii data named chaine1 into int data named poids
    int poids = 0;
    poids = 1000000 * ((chaine1.substring(2, 4)).toInt() - 48) + 100000 * ((chaine1.substring(4, 6)).toInt() - 48) + 10000 * ((chaine1.substring(6, 8)).toInt() - 48) + 1000 * ((chaine1.substring(8, 10)).toInt() - 48) + 100 * ((chaine1.substring(10, 12)).toInt() - 48) + 10 * ((chaine1.substring(12, 14)).toInt() - 48) + 1 * ((chaine1.substring(14, 16)).toInt() - 48);
    return (float)(poids / 10.0);
  }
}

void loop()
{
  Serial.println(HBM());
}

The result is :

I put an object and print the weight :
0.90
0.90
0.60
0.50
0.30
2.90
13.00
32.20
58.40
89.10
121.00
152.40
185.10
220.50
257.80
293.40
324.70
352.20
377.20
399.90
420.00
419.80
420.10
420.00

But, I need to use the BMSerial.h library to include this code into my main code (600 lines).
Or use another library which does not create a conflict with the BMSerial library.

CODE B : Using BMSerial.h
It doesn’t work.

#include "BMSerial.h"

String chaine1;
String test;
int data;

BMSerial Poids(9, 8); // RX, TX


void setup()
{
  Poids.begin(38400);
  Serial.begin(38400);
  Serial.println("Test AD104C - Initialisation");
  delay(5);
  Poids.write("MSV?0\r\n");
}

float HBM()
{ chaine1 = "";
  test    = "";
  data = 0;

  while (Poids.available() == 0) {} // I read my port

  while (Poids.available() != 0)    // we are IN if we can read DATA (10 = LF et 13 = CR)
  {
    data = Poids.read();
    chaine1 += data;
  }

  test = chaine1.substring(16, 20); // we read CR LF
  if (test.equals("1310"))          // if end=CR LF so my data is good

  { chaine1 = chaine1.substring(0, 20);         // I can convert my ascii data named chaine1 into int data named poids
    int poids = 0;
    poids = 1000000 * ((chaine1.substring(2, 4)).toInt() - 48) + 100000 * ((chaine1.substring(4, 6)).toInt() - 48) + 10000 * ((chaine1.substring(6, 8)).toInt() - 48) + 1000 * ((chaine1.substring(8, 10)).toInt() - 48) + 100 * ((chaine1.substring(10, 12)).toInt() - 48) + 10 * ((chaine1.substring(12, 14)).toInt() - 48) + 1 * ((chaine1.substring(14, 16)).toInt() - 48);
    return (float)(poids / 10.0);
  }
}

void loop()
{
  Serial.println(HBM());
}

The result is :

Arduino : 1.6.5 Hourly Build 2015/06/10 06:13 (Mac OS X), Carte : "Arduino Uno"

final_AD104C.ino: In function 'void setup()':
final_AD104C:88: error: invalid conversion from 'const char*' to 'uint8_t {aka unsigned char}' [-fpermissive]
In file included from final_AD104C.ino:64:0:
/Users/coste/Documents/Arduino/libraries/BMSerial/BMSerial.h:111:20: error:   initializing argument 1 of 'virtual size_t BMSerial::write(uint8_t)' [-fpermissive]
     virtual size_t write(uint8_t byte);
                    ^
invalid conversion from 'const char*' to 'uint8_t {aka unsigned char}' [-fpermissive]

CODE C : Using your sss library
I tried your library named sss that you gave to me, but I don’t really know how does it works.

byte mesg[16];
byte bytesToSend = 6;
byte sendByte = 'A';

unsigned long curMillis = 0;
unsigned long prevSendMillis = 0;
unsigned long sendIntervalMillis = 2000;

void setup()
{
  sssBegin();
  Serial.begin(38400);
  Serial.println("Test AD104C - Initialisation");
  delay(5);
}

//==================

void sendMessage() {

  if (curMillis - prevSendMillis >= sendIntervalMillis) {
      prevSendMillis += sendIntervalMillis;
      
      for (byte n = 0; n < bytesToSend; n++) {
        mesg[n] = sendByte + n;
      }
      sssWrite(mesg, bytesToSend);
      Serial.println("Message Sent"); 

      sendByte += bytesToSend;
      if (sendByte > 'Z') {
        sendByte = 'A';
      }
  }
}

//==================

void receiveMessage() {
     
   if (sssAvailable() > 0) {
       
      byte bb = sssRead();
      Serial.print((char) bb);
      Serial.print(" ");
      
      if (bb == '>') {
        Serial.println();
      }
    }
}


void loop()
{
  curMillis = millis();
  sendMessage();
  receiveMessage();
}

My terminal printed :

Message Sent
Message Sent
Message Sent
Message Sent
Message Sent

Thank you another time for your help and the time you spend to try to understand my problem Robin2 :slight_smile:

Please find attached my project which contains CODE A,B and C.

final_AD104C.zip (5.13 KB)

Thanks for all that - but perhaps you could hold your breath for 24 hrs while I try to catch up :)

...R

If I try (or succeed !) something, I will post a message. But it's impossible for me to take a break, I really want to finish this, my project represents a lot of work, and it's my last part before succeed ;) Still thank you for your attention Robin2 !

I have tried the code you have posted in Reply #12 - CODE B : Using BMSerial.h It doesn't work.

As far as I can see the reason this line does not work Poids.write("MSV?0\r\n"); is because you must use .write() one character at a time Poids.write('M'); does not cause a compiler error.

My feeling is that the simplest work-around is to use a loop to write the message one char at a time

Another option might be to add a .print() function to the library - but that may take a lot of work. Possibly you could copy code from SoftwareSerial, but as I don't understand the changes in BMSerial it may not be simple.

I will spend a bit more time trying to figure why SoftwareSerial can't work in place of BMSerial.

...R

After a lot of poking around it seems to me you may be using an old version of SoftwareSerial - as posted in Reply #5

It is very different from the version that comes with my Arduino IDE 1.5.6

In "your version" at line 93 there is active_object->stopListening(); which the compiler complains about.

But in the 1.5.6 version line 93 is the middle of a large table of delay values

What version of the Arduino IDE are you using ?

...R

Hello Robin2

I work on Arduino IDE 1.6.5.

I used a simple loop to write the message, my results are :

CODE WITH SoftwareSerial : (if I write "MSV?0\r\n" it works too)

#include "SoftwareSerial.h"

String chaine1;
String test;
int data;

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

void setup()
{
  Poids.begin(38400);    // initialisation of my serial
  Serial.begin(38400);
  Serial.println("Test AD104C - Initialisation");
  delay(5);
}

float HBM()      // function which permits me to have my weight sensor's data (float)
{ chaine1 = "";
  test    = "";
  data = 0;


   Poids.write('M');
   Poids.write('S');
   Poids.write('V');
   Poids.write('?');
   Poids.write('\r');
   Poids.write('\n');
   
   Serial.print('M');  //display when I ask a data from the transducer AD104C
   Serial.print('S');
   Serial.print('V');
   Serial.print('?');
   Serial.print('\r');
   Serial.print('\n');


  while (Poids.available() == 0) {} // I read my port

  while (Poids.available() != 0)    // on rentre dans la boucle si on a des DATA (10 = LF et 13 = CR)
  {
    data = Poids.read();
    chaine1 += data;
    }

  test = chaine1.substring(16, 20); // on repere les erreurs rencontrées
  if (test.equals("1310"))          // taille trame conforme = on affiche pas si

  { chaine1 = chaine1.substring(0, 20);         // on enleve les CR LF de fin de trame
    int poids = 0;
    poids = 1000000 * ((chaine1.substring(2, 4)).toInt() - 48) + 100000 * ((chaine1.substring(4, 6)).toInt() - 48) + 10000 * ((chaine1.substring(6, 8)).toInt() - 48) + 1000 * ((chaine1.substring(8, 10)).toInt() - 48) + 100 * ((chaine1.substring(10, 12)).toInt() - 48) + 10 * ((chaine1.substring(12, 14)).toInt() - 48) + 1 * ((chaine1.substring(14, 16)).toInt() - 48);
    return (float)(poids / 10.0);
  }
}

void loop()
{
  Serial.println(HBM());
}

My result is : (when I put an object (109 grammes) on my sensor)

MSV?
0.20
MSV?
0.80
MSV?
5.10
MSV?
14.50
MSV?
26.70
MSV?
32.20
MSV?
33.90
MSV?
36.20
MSV?
46.10
MSV?
61.50
MSV?
75.30
MSV?
85.60
MSV?
92.60
MSV?
97.90
MSV?
101.80
MSV?
104.40
MSV?
106.30
MSV?
107.40
MSV?
108.20
MSV?
108.60
MSV?
108.80
MSV?
109.00
MSV?
109.10

The same code but with BMSerial :

#include "BMSerial.h"

String chaine1;
String test;
int data;

BMSerial Poids(9, 8); // RX 15 =D9, TX 14=D8 

void setup()
{
  Poids.begin(38400);    // initialisation of my serial
  Serial.begin(38400);
  Serial.println("Test AD104C - Initialisation");
  delay(5);
}

float HBM()      // function which permits me to have my weight sensor's data (float)
{ chaine1 = "";
  test    = "";
  data = 0;

   Poids.write('M');
   Poids.write('S');
   Poids.write('V');
   Poids.write('?');
   Poids.write('\r');
   Poids.write('\n');
   
   Serial.print('M');
   Serial.print('S');
   Serial.print('V');
   Serial.print('?');
   Serial.print('\r');
   Serial.print('\n');

  Serial.println("test1");          // DEBUG
  while (Poids.available() == 0) {} // I read my port
  Serial.println("test2");         // DEBUG
  while (Poids.available() != 0)    // on rentre dans la boucle si on a des DATA (10 = LF et 13 = CR)
  {
    data = Poids.read();
    chaine1 += data;
    }
  //Serial.print(chaine1);
  //Serial.println("test3");
  test = chaine1.substring(16, 20); // on repere les erreurs rencontrées
  if (test.equals("1310"))          // taille trame conforme = on affiche pas si

  { chaine1 = chaine1.substring(0, 20);         // on enleve les CR LF de fin de trame
    int poids = 0;
    poids = 1000000 * ((chaine1.substring(2, 4)).toInt() - 48) + 100000 * ((chaine1.substring(4, 6)).toInt() - 48) + 10000 * ((chaine1.substring(6, 8)).toInt() - 48) + 1000 * ((chaine1.substring(8, 10)).toInt() - 48) + 100 * ((chaine1.substring(10, 12)).toInt() - 48) + 10 * ((chaine1.substring(12, 14)).toInt() - 48) + 1 * ((chaine1.substring(14, 16)).toInt() - 48);
    return (float)(poids / 10.0);
  }
}

void loop()
{
  Serial.println(HBM());
}

My result is :

Test AD104C - Initialisation
MSV?
test1

So I can't display "test2" so I think that I'm still waiting here : "while (Poids.available() == 0) {} // I read my port"

What do you think about it ?

Poly34: The same code but with BMSerial :

It is NOT the same code - look at it carefully.

...R

Yes it is, I just had :

  Serial.println("test1");          // DEBUG
  Serial.println("test2");         // DEBUG

to debug my code because I could not receive data. But it's the same.