MPU 6050 moving ball

Hi everyone. I'm pretty new to MIT App inventor so any help would be really great. Im trying to make a game, something like a game of tag with an arduino using an MPU6050 as the gyroscope module and hc-05 as bluetooth module. Similar to the one where the ball gets to move around using the phone's orientation sensor, when I move the mpu6050 around, the ball will also move. I have followed some tutorials on receiving data from the arduino but most of them are being printed as text. As there will be some computations involved, I need it to be stored as an integer. Here is a snippet of the part where I get to receive the data. I did some few changes which I think is right based on the tutorials I saw. Whenever I pres the player 1 ready button, I get the error yail divide. Can anyone help, what should I change?

Screenshot 2021-08-08 155731

Hyphenation should work with text as well. I think there is a space between 1502 and 1497.
The problem is your blocks are not receiving data correctly and maybe not sending them correctly from arduino.
Show your arduino code responsible for sending data. I will see if need improvement and will adjust the blocks accordingly.

Generally, the blocks should be modified according to this:

error

In arduino, send data according to this scheme:

Serial.print(dataX);
Serial.print("|");
Serian.println(dataY);

Thank you very much for your reply. Sorry I forgot to attach the code. As seen below, I have already made the format you suggested when I was having the error I mentioned.

#include <SoftwareSerial.h>
#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;
SoftwareSerial MyBlue(0, 1); // RX | TX

// Timers
unsigned long timer = 0;
float timeStep = 0.01;

// Pitch, Roll and Yaw values
byte pitch = 0;
byte roll = 0;

int count;

void setup()
{
Serial.begin(9600);
MyBlue.begin(9600);

Serial.println("Initialize MPU6050");
while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
{
Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
delay(500);
}

pinMode(LED_BUILTIN, OUTPUT);

digitalWrite(LED_BUILTIN, HIGH);
mpu.calibrateGyro(); //Calibrate gyroscope
digitalWrite(LED_BUILTIN, LOW);

mpu.setThreshold(3); //Set threshold/sensitivity

Serial.println("Ready to connect\nDefualt password is 1234 or 000");
}

void loop()
{
timer = millis();

// Read normalized values
Vector norm = mpu.readNormalizeGyro();

// Calculate Pitch, Roll and Yaw
pitch = pitch + norm.YAxis * timeStep;
roll = roll + norm.XAxis * timeStep;

// Output raw
MyBlue.print(pitch);
MyBlue.print("|");
MyBlue.println(roll);

Serial.print(pitch);
Serial.print("|");
Serial.println(roll);
// Wait to full timeStep period
delay((timeStep * 1000) - (millis() - timer));
}

Sending data in arduino code looks ok. Modify only the blocks. Modification consists in setting "DelimiterByte" to 10, and append "-1" to the block receiving text data.
Still as to the value. Pitch is probably the value of Y in arduino, and the roll is X. However, in blocks you have the opposite.

Please see the Delimiter article in FAQ

Be sure to use println() at the end of each message to send from the sending device, to signal end of message. 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.

Oh. Thank you! I might have missed it in the code. As for the delimieterbyte, I did what abg said to chance it in the properties, do I have to do it again on the blocks? Also, when I change the "bytesavailable to receive" to -1, I dont seem to receive any data.

If you set it in properties, you don't have to do it in blocks. Show again all your blocks and arduino code.

Ok. Thank you very much for your patience with me. :slight_smile:

#include <SoftwareSerial.h>
#include <Wire.h>
#include <MPU6050.h>

MPU6050 mpu;
SoftwareSerial MyBlue(0, 1); // RX | TX

// Timers
unsigned long timer = 0;
float timeStep = 0.01;

// Pitch, Roll and Yaw values
byte pitch = 0;
byte roll = 0;

int count;

void setup()
{
Serial.begin(9600);
MyBlue.begin(9600);

Serial.println("Initialize MPU6050");
while (!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
{
Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
delay(500);
}

pinMode(LED_BUILTIN, OUTPUT);

digitalWrite(LED_BUILTIN, HIGH);
mpu.calibrateGyro(); //Calibrate gyroscope
digitalWrite(LED_BUILTIN, LOW);

mpu.setThreshold(3); //Set threshold/sensitivity

Serial.println("Ready to connect\nDefualt password is 1234 or 000");
}

void loop()
{
if (MyBlue.available())
{
timer = millis();

// Read normalized values
Vector norm = mpu.readNormalizeGyro();

// Calculate Pitch, Roll and Yaw
pitch = pitch + norm.YAxis * timeStep;
roll = roll + norm.XAxis * timeStep;

// Output raw
MyBlue.print(roll);
MyBlue.print("|");
MyBlue.println(pitch);

Serial.print(pitch);
Serial.print("|");
Serial.println(roll);
// Wait to full timeStep period
delay((timeStep * 1000) - (millis() - timer));

}
}

Sorry, I uploaded the wrong image

Still no modifications mentioned above. Also why do you use two bluetooth components. You asked the question in the first post with one component. So first, keep working with one component and with the modifications we recommended. Check if it works, if it works continue with your modifications to build. If you ask a question and we answer, and you modify the blocks a lot in the meantime, we won't get to that.

Also, the above modifications that we have recommended will only work while receiving the text. It won't work with byte picking like you have a block on the right.

Hi everyone, thank you so much for your help. My friends and I were able to fix it. The bluetooth module was actually sending out data too fast and the app is not wble to filter it very good, causing it to register 2 values. The app is a two player game of tag, hence the two blocks in the code. I read before that it was pretty much copy and paste only changing the variables and bluetooth client, so I initially posted only for the player 1.

Hey! Could you please attach the interface of the game?