Graphing data received via Bluetooth from Arduino not graphing what I was expecting(?)

Hi guys, I'm trying to graph some data I am receiving over Bluetooth from an Arduino Nano 33 IOT.

I can pair and connect to my mobile device, it's just the data being graphed is not what I thought it would be.

The code I am using is in the attached txt file. The blocks I am using are attached too, along with a screen recording of what I am receiving.

Arduino Bluetooth Code.txt (561 Bytes)

Any ideas on what I need to change / what i am actually plotting? Open to any questions too!

Cheers :sunglasses:

Apologies, forgot to attach blocks, here they are:

I see in your code

  float     aR = 353;
  float     aL = 0;
  float     bR = 520;
  float     bL = 2.5;

void setup() {

  pinMode(NINA_RESETN, OUTPUT);   
  digitalWrite(NINA_RESETN, HIGH);

    Serial.begin(115200);
    SerialNina.begin(115200);

     delay(2000); //Delay 2 seconds to allow for user to get ready
}

void loop() {

  float curReading = 1023 - analogRead(0); // Take reading of analog pin 0 of Arduino
  float load = ((bL - aL)/(bR - aR)) * (curReading - aR) + aL;

  SerialNina.println(load);
  Serial.println(load);
  delay(100);
  
}

You are using println(load), so it is being sent as text with NL line delimiters.
If you send text, use the ReceiveText block to receive it.

You lack any inner loop delays, so you will flood AI2.

Here is the standard advice for Delimiters:

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.

1 Like

Hi ABG, thank you for your reply.

I believe I understand what your saying. Essentially add a delay until a response is detected?

I've read and attempted to implement the delimiter article. Does this look correct?

I've set the Delimiter attribute to 10.

I do not plan on sending multiple data values per message, just the one float. However, if you believe it's worth looking into I most certainly can :slight_smile:

No.

The delay() was needed in the void loop(), and looking back at your code, I see it now.
I don't know why I missed it.

However, the requirement that AI2 delay less for its reception Clock Timer than the transmitting (100 ms) loop still stands, otherwise the AI2 app will see data pile up in its BlueTooth input buffer.

So the bottom line:
Set the Clock1 milliseconds attribute to something less than 100, like 50.
The transmission code looks okay.

By the way, 9600 bps is the usual default bit rate, in case your data does not get through.
You might be asking for too much in your 115200 bps setting.
On the other hand, it might work okay.
Tests will prove me right or wrong.

Ok. I'll change the TimerInterval in Clock1 to 50, then I'll test it with 9600 and 115200bps

Thanks for your help, will let you know what happens.

Kept it at 115200bps and changed the TimerInterval to 50.

Now I get this error displaying and refreshing every 100ms, with the '78' going up by 1 every refresh, and the '205' switching between '205' and '202'. Not sure whats going on here, will keep looking into it:

I've included the aia file too, in case you wanted a better look.
Load_Read.aia (6.3 KB)

Edit: I believe the error is telling me the global X_before variable is not quite right. The edit I made to the X_before variable must be incorrect. Any idea what's gone wrong?

Here is your original Clock1.Timer:

Here is my revised version:

What I changed:

  • ripped out that BT Read Unsigned Bytes (bytes are in range 0-255, so you were graphing the ASCII codes of the digits in your reading, one by one)
  • read your blocks (it's a nasty job, but SOMEONE has to do it)
  • renamed that X_before to X_before_increment, to better understand it (before WHAT?)
  • brought the before logic together with the boundary test

What I did NOT do:

  • fit the expected Y values into the range 1-Canvas1.Height

All blocks are draggable into the Blocks Editor

2 Likes

Thank you ABG, I appreciate the help. I apologise if I've come across as senseless.

I understand what you've done and the silly mistake I made myself.

Hopefully I can finish it without any more problems.

Cai

If you have any more problems, you can ask :slight_smile:

1 Like

I made the changes and started receiving a similar error (photo attached, blurry and dark as it is refreshing similar to the last error, 250 stayed the same and nothing was appearing in second bracket).

Made some changes myself (attempted to fit the expected Y values but nothing seemed change)

I changed the bps to 9600 instead of 115200 and the error disappeared but nothing is being graphed, with or without the changes I made. :thinking:

Please stop with the personal messages.

Any one on the board can answer these, and you go to the back of the line when you do that.

Export your .aia file and upload it here.
export_and_upload_aia

2 Likes

Apologies, I'll stop with the replies.

Here's the changes I made but I must admit I wasn't too sure what you meant by this, or why it was essential:

Here is my attempt at what I thought you meant but, still no luck.

Load_Read.aia (6.4 KB)

Been working on this since yesterday with no luck still. I was reading this piece from the FAQs, and tried a similar approach and attempted implementing the Bluetooth into it, with no luck and a similar error the one I had in my previous error. Except with nothing in the first set of brackets and a 0 in the second.

Returning to my original blocks, I removed the edits I made to the previous post I did as I realised it was wrong. Here is where I am at so far; I am not receiving an error, just nothing is appearing on the graph.

Load_Read.aia (6.3 KB)

Any help greatly appreciated.

Edit: Further reading took me to this edit of the piece from the FAQs. Attempting to modify it has given me an error which I believe is due to the fact the the app I download is not the updated version that I have done, as the error says the MAC address is incorrect. As I am deleting the blocks that contain the MAC address, I cant find why it would say that.

Still no closer in my own app to getting something graphed.

I'm very confused now. I don't see where my project is failing. I'm revisiting my initial arduino code, but it's sending the correct information.

What I've done in the blocks looks correct but Iit's still not working and beginning to annoy me! :joy:

  • fit the expected Y values into the range 1-Canvas1.Height

I believe it has something to do with this but I'm not entirely sure what this means.

I'd like to get this to work when uploading my sketch OTA after I've finished, but I'd like to get this finished first :slight_smile:

.aia file is in my previous post

Here is a version of the .aia that allows you to enter Y values from a text box, to verify that the graphing part works.

I tested it on my phone, and got a graph started, though I had to press Enter too many times for reaching the end of the x axis to see wraparound.
when  btnEnterY .Click do



Load_Read_ABG.aia (6.8 KB)

Ahh I see. Yes the graphing works. But I can't figure out how to graph what is being received via Bluetooth instead. I see you have added the 'to process Y' block but I can't find out how to add that to my own as it doesn't show in my own Procedures block section.

Edit: And I see the extra Y_before_increment to get Y after the canvas draw bit, but not sure why that's there too. I added it with no difference to outcome. So the only difference I can see is that there's something with the fact that it doesn't recognise the received data as graphable but the data inputted manually can be? I'm very confused haha :sweat_smile:

Did you notice how small my Clock1.Timer event got?

Its guts moved into the process procedure,
and were replaced with a call to that process procedure sending it the recently arrived BlueTooth value.

There is a chapter on procedures in the free book at
http://www.appinventor.org/book2
from

I see, I can appreciate how it shortens then loop visually.

I don't understand why you need the Bluetooth if your just going to type the values in anyway.

This was for debugging purposes only.

It's like when you open up some electronics and see extra pins and connectors on the circuit board, to give the repair technician (do they still exist?) a place where they can test voltages or inject signals, to see which parts of the board are working and which are not working.

This is a special case of the more general debugging technique called Divide and Conquer, where you try to divide a complex problem into smaller, simpler problems.

Here; I added the process procedure to separate two different questions:

  • Is the Bluetooth part receiving data at all?
  • Is the graphing part capable of receiving successive Y values and graphing them?

Once we are satisfied with the process procedure, we can make the Horizontal Arrangement holding that text box and Enter button inVisible, so they are there in case we might need them later.