Character modified in Bluetooth

Dear @Jon1,
the baudrate betwen HC0x and Arduino board is the same for both Tx and Rx always. That is: if you set 9600 baud, this speed applies to both directions. In my knowledge any UART (Universal Asynchronous Receiver and Transmitter) works always with the same speed in Tx and Rx.
The HC05 isn't a BLE device, but also newest Pads (I'm using in my latest applications some LENOVO M8 3rd Gen) can work with both LE and standard BT's. So if your app uses the standard BTclient blocks, without the need of specific extensions, it should work fine (I never used extensions for my BT app's). You can have a look to my .aia annexed: this code works in conjunction with an ELM327 to connect a diagnostic port of my car. Also in this case the BT is a standard one.
CAN_207_GPS1_23112022.aia (3.9 MB)
Maybe is a bit complicated but if you have time, try to give it a sight.
Though, I'm roughly convinced that the problem could be a HW one (have you the possibility to use another HC05 ?) due to its randomicity.

Ciao ciao, Ugo.

Alright, fine. :+1:

I also thought that if BLE and BTclassic were not compatible at all, it wouldn't work at all. But as you say, I use the standard AI2 BT client, without extension, and I still manage to use the HC-05 with my v4+BLE tablet...
Thanks for your .aia, i would take a look at it (I can't guarantee that I'll be able to decrypt it perfectly :grinning_face_with_smiling_eyes:)

Unfortunately I only have this one... :unamused: Do you think it could be faulty? Do you think I should buy another?
Should I perhaps do before a test with the TeraTerm software that you advised me (by the way, do you have a link to a small tutorial on its use with AI2).
I don't know what you think about this, but is it possible that AI2 is sending wrong values :thinking:?

Thanks to you!

What Ugo means is your hardware includes components that can emit interference (even the cables have this potential). So a neat, carefully designed assembly is always a good thing, not just to preserve a good signal but to avoid causing a fire!

2 Likes

Dear @Jon1,
yes, before buying a new HC05, please try with the TeraTerm SW and verify whether the AI2 is sending correctly (I suppose yes, but "never say never" :slight_smile: ).
And, yes, what Chris says better than me (he is of mother tongue English, while I'm italian...) is that some parasitic capacitance could be created simply also by long wires, that can behave like "antennas". Since you have relays, though they could have free-wheeling diodes, they can emit EM interferences while releasing the contact (probably not, if the current they switch if of some milliamps, but, again, "who knows ?").
In a nutshell:

  1. try with Teraterm,
  2. try to "clean" the layout by shortening the wires as possible
  3. while doing the 2) also check the grounding and the power supply (the power supplied by a USB port might not be sufficient)
  4. just use the "basic" BT blocks of AI2 (BT client side): to interface a standard HC05 they are enough
    Last but not least...cross your fingers and ask Santa to gift you a working system .... :santa: :santa: :santa:

Merry Christmas to all readers.
Ciao, ugo.

1 Like

I completely agree. I will try to do my best for the storage, in order to avoid any problems... :ok_hand:

Well, an idea came to me! :roll_eyes:

I made a simple assembly to test if my HC-05 was defective. I took an Arduino Uno board and just plugged my HC-05 into it, nothing else. With a small program that works well, I just printed in the serial monitor what I wanted, and...---> Apparently I get all the values without problem! :hushed:
(Watch the video at the end of my post. I lowered the quality to be able to post it here).
You see that I have no errors!

What I know :

  • The problem does not come from AI2
  • No HC-05

So, as you told me, it could come from:

  • Material interference.
  • Problem in my Arduino code
  • Anything else?

Anyway thank you for your help ! :+1:

(Grazie Molto)

The arduino code I used for this test:

#include <SoftwareSerial.h>
SoftwareSerial bluetooth(2,3);      // (RX, TX) (pin Rx BT, pin Tx BT)
char messageRec;                         // Variable charactere message echanger Bluetooth <-> Arduino

bool boucle = 0;


//===================================================================================================================================//
//======================================================    VOID SETUP   ============================================================//
//===================================================================================================================================//


void setup() {

  Serial.begin(9600);                      // Ouvre le port série USB avec vitesse 9600 bauds
  bluetooth.begin(9600);                   // Ouvre le port série BlueT avec vitesse 115200 bauds
 
  } // Fin Setup



//===================================================================================================================================//
//=======================================================    VOID LOOP   ============================================================//
//===================================================================================================================================//



void loop() {

  if(bluetooth.available()){                          // Si Bluetooth recois qql ch
  messageRec = bluetooth.read();                      // lire le message recus et le stocker dans variable messageRec
  Serial.print(messageRec);
  boucle = 0;
  }

  if (messageRec=='*' && boucle ==0){ 
  Serial.println("");
  boucle = 1;  
  }

} // Fin loop




The video:

Hi @Jon1,
that's definitely a good idea !!!
And the result is very encouraging.
So, both AI2 code and HC05 are innocent :slight_smile: .
Honestly the variable boucle is useless in your simple code, since (as far as I understand) you want to make a println() at the end of the AI2 message, which is already closed by the "*".
Anyway, now you can increase step-by-step the HW surrounding the prototype, always leaving the same sample code.
If you modify only the HW, while maintaining steady the SW, you have only one variable (the HW).
At last: I see that you use the white "fast prototype board" (so do I, typically): right with these devices it can happen that some parasitic capicitance can arise: the inner layout of the connecting tracks, most probably featuring a chessboard structure, can lead to a cross-talk between the tracks themselves, thus rising electric noise on fast signals (though a 9600 baud serial line is not that fast).
I believe that from now on the road to the success is a bit easier.
A presto, Ugo.

1 Like

Dear @Jon1,
while I was looking for a lowpass filter algorithm, I encountered this topic:

Probably is not your case, but to read it, it takes a few minutes and it could give you some indication.
Ciao, Ugo.

1 Like

Hi Ugo!

I left the project aside for several days.
Today I am back at it.

Honestly the variable boucle is useless in your simple code, since (as far as I understand) you want to make a println() at the end of the AI2 message, which is already closed by the "*".

Thank you for the info! :+1: I made the modification. I put it here if it can help someone one day (untested):

#include <SoftwareSerial.h>
SoftwareSerial bluetooth(2,3);      // (RX, TX) (pin Rx BT, pin Tx BT)
char messageRec;                         // Variable charactere message echanger Bluetooth <-> Arduino



//===================================================================================================================================//
//======================================================    VOID SETUP   ============================================================//
//===================================================================================================================================//


void setup() {

  Serial.begin(9600);                      // Ouvre le port série USB avec vitesse 9600 bauds
  bluetooth.begin(9600);                   // Ouvre le port série BlueT avec vitesse 115200 bauds
 
  } // Fin Setup



//===================================================================================================================================//
//=======================================================    VOID LOOP   ============================================================//
//===================================================================================================================================//



void loop() {

  if(bluetooth.available()){                          // Si Bluetooth recois qql ch
  messageRec = bluetooth.read();                      // lire le message recus et le stocker dans variable messageRec
  Serial.print(messageRec);
  }

  if (messageRec=='*'){ 
  Serial.println("");
  }

} // Fin loop

Anyway, now you can increase step-by-step the HW surrounding the prototype, always leaving the same sample code.
If you modify only the HW, while maintaining steady the SW, you have only one variable (the HW).

I started my research with this method. I removed almost everything and left what was needed to run the HC-05:

I've done several tests, and I think I'm getting a bit closer to the problem.

Software level:

  • AI2: I didn't touch anything.
  • Arduino program: I didn't touch anything (I just changed the "int nmbPas" variable to "long nbmPas", to be able to write a number with more than 5 digits)

Hardware Level:

  • I removed everything except what is needed to run the HC-05.

Result:

So at this point sending data every 100 milli interferes with receiving data sent by AI2.

However, I put in my code a condition:

  • If the message received is "$",
  • Stop sending it every 100mili ("arretTemps" variable)
  • And do what I ask of you
    .
  • If the message is "*",
  • Resume sending every 100 millis
  • And do what I ask of you

(I deleted a few lines to make it easier to read)





  
//--------------------------ENVOIS TOUTE LES 100 MILLIS MESSAGE BLUETOOTH-----------------------------------------------------//
                                                                                                                              //
 if(millis() - lgUpdateTime > 100 && arretTemps==0) {lgUpdateTime = millis(); messBT();} //Loop approx every 100 milliseconds //
                                                                                                                              //
//----------------------------------------------------------------------------------------------------------------------------//






  if(bluetooth.available()){                          // Si Bluetooth recois qql ch
  messageRec = bluetooth.read();                      // lire le message recus et le stocker dans variable messageRec
                                                                                          //
  if (messageRec=='$'){                                                                   //
   arretTemps = 1;   //Arrêt envoye bluethoot position moteur XYZR toute les 100mili.s    //
   boucleString = 1;                                                                      //
  }                                                                                       //
                                                                                          //
  if (boucleString==1){                                                                   //
    stringBtPas = stringBtPas + messageRec;                                               //
    Serial.print("stringBtPas = ");                                                       //
    Serial.println(stringBtPas);                                                          //
  }                                                                                       //
                                                                                          //
  if (messageRec=='*'){                                                                   //
    stringBtPas = stringBtPas.substring(1, stringBtPas.length()-1);                       //
    //Serial.print("stringBtPas* = ");                                                    //
    //Serial.println(stringBtPas);                                                        //
    nmbPas=stringBtPas.toInt();                                                           //
    Serial.print("nmbPas = ");                                                            //
    Serial.println(nmbPas);                                                               //
    arretTemps = 0;   //Reprise envoye bluethoot position moteur XYZR toute les 100mili.s //
    stringBtPas="";   // rénitialisation stringBtPas, quand reçois "*"                    //        
  }                                                                                       //
                                                                                          //
//----------------------------------------------------------------------------------------//

  } // Fin BT

But even with that, I have a fake character...

I advance….

I do not exclude that later, the cables, and/or a bad Gnd, can also cause interference...

while I was looking for a lowpass filter algorithm, I encountered this topic:

Thank you for this article! :+1:
If I'm not mistaken, apparently the person had parasites due to the triggering of the contactor...

This will be monitored! :face_with_monocle:

Hello Chris Ward,

could you get more info on this?

That should be the case, but manufacturers of Tablets do not pay attention to such details, it's all about sales and profits.

Info on what? :thinking:

123
Were you able to get more info?

It is actually the number of milliseconds between each 'poll' (see if there is data to receive). The intention is to use this value instead of a Clock Timer and it was introduced for live chart drawing.

Dear @Jon1,
nice to read you again.
So if I correctly understand, your tests lead to this result: if your Arduino sends characters to AI2 while it is receiving, the received characters are sometimes corrupted.
I see that you use the library SoftwareSerial to allow the real HW serial (Tx and Rx on pins 0,1 if you use a UNO) to monitor the received data on the PC. This is typical, but I'm not pretty sure how this library works when a transmission, in your case triggered by the millis() is executed while receiving was already in progress.
I see also that you have implemented a sort of handshake by using the $ and * characters, but this has no effect. What I normally do is the contrary: the handshake is implemented on the AI2 app: which polls for BT characters until are received. As soon as the BT frame has been completely received, you have 100 ms free to send data from the AI2 to your arduino.
In this case (supposing that your app is not consuming more than 100 ms to send its own message), you don't overlap the Arduino transmission with the one coming from the Ai2 app.
In other words: you have to synchronize the AI2 transmission as soon as a BT frame from Arduino is received and finished. For example, in AI2, put a clock of 10 ms to see if there are BT characters available: if yes, stay there until the frame has been completely received, then before exiting from the clock you send the data of AI2 to the Arduino (within 100 ms, of course :slight_smile:). On the contrary, if no characters are available, you can exit immediately the 10 ms clock and you can do something else in your AI2 app (for example update the UI).
Another hypotesis is to don't send the mirror of the characters to the PC and avoid using the SoftwareSerial (of course you have to re-map the pins).
De toute façon, je crois que tu ira arriver au sommet bientot ... :+1: :muscle: :slight_smile:

Ciao, Ugo.

PS : a major change could be to pass directly to an Arduino Mega (4 HW serial lines) or to an ESP32 (the BT interface is already on board)....
.

1 Like

Good !

I think I found the solution!! :grinning_face_with_smiling_eyes: :tada:

I have had an idea. :thinking:

Since the HC-05 is constantly sending data (motor positions every 100 milis), this must conflict when it receives something.
The HC-05 cannot send and receive data at the same time, it affect the data.

So I said to myself :face_with_monocle:, I only have to send the position of the motors when they are moving, and therefore when they are stopped, send nothing, and the HC-05 would be free to receive something.

Well that's what I did in my code.

Basically I asked like this:

  • If motor X is running → Sends its position (and therefore if it is not running, nothing happens)
  • Same for the 4 motors.

And so when I type something on my tablet, as the motors are not running, and therefore no data is sent by Bluetooth, well I have more parasites!!! :+1:

To be seen over time and with more tests, but it seems to work.

In conclusion :

I think I had characters parasites, because the HC-05 was constantly sending something.
So when I sent data to it, it probably caused a character error.

My solution is to stop sending data all the time, but leave the HC-05 "free" when I send a character to it.

In the end, "receiving and sending" at the same time, on the HC-05, apparently causes problems.

Thanks to Ugo uskiara, ChrisWard, Juan_Antonio, for taking the time to help me!

(The project is not finished, and the problem too! :grinning_face_with_smiling_eyes: Soon!)

1 Like

Dear @Jon1,
happy that it works. Glad having been of some help.
Ciao ! :+1:

Hi Jon

Uskiara noticed that earlier, #post58:

Think of a Bluetooth signal as water running through a pipe - it can't go in both directions at the same time. There are possibilities with an extra port on the board and a second App Inventor BT Client, but your project does not need that complexity.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.