Glitched data printing using bluetooth

Hi, im having a trouble with printing data from the arduino to my phone, but somehow its very glitchy.
Its a test for my MPU6050 and i want to print my results on the phone
Heres some code and a picture of my problem

arduino code:

#include <MPU6050.h>
MPU6050 mpu;

#define EXPIRED                    true
#define stillTIMING                false

#define LEDon                      HIGH   
#define LEDoff                     LOW

#define PUSHED                     HIGH    
#define RELEASED                   LOW

#define CLOSED                     LOW   
#define OPEN                       HIGH

#define ENABLED                    true
#define DISABLED                   false

#define YES                        true
#define NO                         false

const float thresholdForce = 5.0;
const unsigned long resetInterval = 500;
static float peakForce = 0, lastPeakForce = 0;
static unsigned long lastPeakMs = 0;


//const int arraySize = 200; //array size
//float dataArray[arraySize]; // array for storing values
//byte currentIndex = 0; // current index of the array

struct makeTIMER
{
  unsigned long Time;           //when the TIMER started
  unsigned long Interval;       //delay time in ms which we are looking for
  bool          timerFlag;      //is the TIMER enabled ? ENABLED/DISABLED
  bool          Restart;        //restart this TIMER ? YES/NO

  //****************************************
  //fuction to check if the TIMER is enabled and check if the TIMER has expired
  bool checkTIMER()
  {
    //*********************
    //is this TIMER enabled and has this TIMER expired ?
    if (timerFlag == ENABLED && millis() - Time >= Interval)
    {
      //*********************
      //should this TIMER restart again?
      if (Restart == YES)
      {
        //restart this TIMER
        Time = millis();
      }

      //this TIMER is enabled and has expired
      return EXPIRED;
    }

    //this TIMER is disabled and/or has not expired
    return stillTIMING;
  } //END of   checkTime()
}; //END of   struct makeTIMER

makeTIMER forceChecker =
{
  0, 500ul, ENABLED, NO      //Time, Interval, timerFlag, Restart
};

makeTIMER delayValue =
{
  0, 25ul, ENABLED, NO      //Time, Interval, timerFlag, Restart
};

void setup() {
  Serial.begin(115200);
  Serial.begin(9600);
  
  Wire.begin();
  mpu.initialize();
  
  //measure range of mpu6050(±16g)
  mpu.setFullScaleAccelRange(3);

  delay(1000);
}

void loop(){

  int16_t ax, ay, az;
  mpu.getAcceleration(&ax, &ay, &az);
  
  // measuring accel
  float gForceX = (float(ax) / 32767.0) * 16.0;
  float gForceY = (float(ay) / 32767.0) * 16.0;
  float gForceZ = (float(az) / 32767.0) * 16.0;
  
  float accelX = gForceX * 9.81;
  float accelY = gForceY * 9.81;
  float accelZ = gForceZ * 9.81;
  float accelTotal = (sqrt(pow(accelX, 2) + pow(accelY, 2) + pow(accelZ, 2))) - 9.81;
  //accelTotal = 1+analogRead(A0)*4.0/1023; // simulate with A0 pot


  float myForce = accelTotal;

  if (myForce > thresholdForce && myForce > peakForce){
    peakForce = myForce;
    lastPeakForce = peakForce;
    lastPeakMs = millis();
    Serial.println(lastPeakForce);
    forceChecker.Time = millis();
    
  }
//  if(millis() - lastPeakMs > resetInterval && peakForce > 0){
  if(forceChecker.checkTIMER() && peakForce > 0){
    peakForce = 0;
    Serial.println(lastPeakForce); //print on phone
  }
}

Designer:

Picture of my problem:

(Canned Reply: ABG - Download those blocks and post them here)

Please download and post each of those event block(s)/procedures here ...
P.S. These blocks can be dragged directly into your Blocks Editor workspace.

See Download Block Images for a demo.

(Canned Reply: ABG- Export & Upload .aia)
Export your .aia file and upload it here.
export_and_upload_aia

1 Like

Why ?
image
This isn't the solution to your problem, but.... :wink:
Then, please follow @ABG's hints.

1 Like

Oh dont mind this, this relates to my mpu6050

receive_test.aia (2.2 KB)
here you go

So, you want to get just one number at a time?

If so,

Be sure to use println() at the end of each message to send from the sending device, to signal end of message.

Only use print() in the middle of a message.

Be sure not to println() in the middle of a message, or you will break it into two short messages and mess up the item count after you split the message in AI2.

Do not rely on timing for this, which is unreliable.

In the AI2 Designer, set the Delimiter attribute of the BlueTooth Client component to 10 to recognize the End of Line character.
BlueToothClient1_Properties
Also, return data is not immediately available after sending a request,
you have to start a Clock Timer repeating and watch for its arrival in the Clock Timer event. The repeat rate of the Clock Timer should be faster than the transmission rate in the sending device, to not flood the AI2 buffers.

In your Clock Timer, you should check

  Is the BlueTooth Client still Connected?
  Is Bytes Available > 0?
     IF Bytes Available > 0 THEN
       set message var  to BT.ReceiveText(-1) 

This takes advantage of a special case in the ReceiveText block:

ReceiveText(numberOfBytes)
Receive text from the connected Bluetooth device. If numberOfBytes is less than 0, read until a delimiter byte value is received.

If you are sending multiple data values per message separated by | or comma, have your message split into a local or global variable for inspection before trying to select list items from it. Test if (length of list(split list result) >= expected list length) before doing any select list item operations, to avoid taking a long walk on a short pier. This bulletproofing is necessary in case your sending device sneaks in some commentary messages with the data values.

Some people send temperature and humidity in separate messages with distinctive prefixes like "t:" (for temperature) and "h:" (for humidity).
(That's YAML format.)

The AI2 Charts component can recognize these and graph them. See Bluetooth Client Polling Rate - #12 by ABG

To receive YAML format messages, test if the incoming message contains ':' . If true, split it at ':' into a list variable, and find the prefix in item 1 and the value in item 2.

1 Like

wait is this the code in arduino?

ok what if my project has 4 modes, each mode has only one number

ohh i get it, its like this right?

im not really understand this, can you show me an example of this?

can you show me an example of this, i do understand this but dont really know what to do with this useful information

it solved the problemm!!! but can you show me more about how to put like strings, am i simply gonna put the strings inside the code then print it out just like the numbers?

can you show me how to print more than 1 values?, the reason why i decided to give this example to you is because i have my big project but theres a problem, its in Vietnamese so i was too lazy to translate everything about it and then give it to you. anyways thank you so much for helping me out, really appreciate you! :hearts:

Here are some examples in blocks for you, starting with the simplest case and working on upwards in complexity:

Here is a simple BlueTooth text receiver sample, for single value per line:
blocks
initialize global message to


You pretty much have that already, but you will need to capture into a message variable before you can get to the next level, multiple readings per message:

Here is an updated blocks sample illustrating these ideas ...

BlueTooth_delimiter_sample.aia (3.4 KB) global message

P.S. These blocks can be dragged directly into your Blocks Editor workspace.

Dragging blocks

In your case, you would need 4 Labels, for x,y,z,power results, and
you would need to print 4 values separated by commas ending with a println() to send the message.

Do you plan on graphing the values in the app?
I have another sample for that.

2 Likes

The more text you send, the harder it is for the receiver to decode it.
Keep it simple, and follow a pattern like comma separated numbers if you can.

The receiving app can always add its own text for display later.

1 Like

This sample is ONLY for if you need to graph 4 values as they arrive:

If you want to send your temperature and humidity on separate lines, you could alternatively send tag:value pairs, like
T:98.6\n
H:100\n
which would arrive individually if you use Delimiter 10 (\n).
Your AI2 logic would look like

if BT.bytesAvailable > 0 then
  set local message to BT.ReadText(-1)   (to get only 1 line)
  if contains(message, ":") then
      set local splits to split message at ":"
      If (select item 1 of splits) = "T" then
         set LabelTemperature.Text to (select item 2 of splits)
      else if (select item 1 of splits) = "H" then
         set LabelHumidity.Text to (select item 2 of splits)
     else set LabelWhatHappenned to local message
end if

I do not have a Charts sample for this yet, but the capability is documented way at the bottom of the Charts Usage Guide in

1 Like

Thank you so much, this will be very useful for my current project and also my future projects!

I dont have

so as long as i keep it really simple like this right?
Mode: Force
Result: 123,45

That's not simple.
It looks complicated to me.

Its info is spread out over multiple lines, needed for a single reading of Force?
The word Result is just boiler plate, causing extra work to strip it off.
The comma between 123 and 45 looks suspiciously like a French decimal point.
Which is it, a list separator, or a decimal separator?

Why not just send
Force:123.45
?

1 Like

ohh ok, thank you so much for the advice, ill try my best to simplified my entire project