MIT App Inventor 2 & Highcharts data.csv configuration with RSSI and Distance Variables

Also, I don't see anything wrong with the way the text is formatted, it should work but it doesn't:

I am getting the values exacly in the format you suggested @SteveJG shouldn't it work already?

I don't understand what it doesn't like, my values come exacly as they should based on your example and still doesn't work..




What exacly is the problem with the way the values are formated? I showed all my blocks, even uploaded the project and no one seems to be able to let me know what I am doing wrong, I don't understand why is it so hard to fix my code and sadly no suggestion works.

I tried to list to rows, same error. I feel like this ain't even the problem, something else must be hapening somewhere and I uploaded my project so someone that wants to help may look into it and tell me what I did wrong.

If anyone knows exacly what the problem is please let me know else I won't try anything just to see what happens anymore because my project got messed up and even the csv file check stopped working after all the things we've tried so I went back to the initial version.

Whoever wants to help has my code at their disposal.

DFPS_APP_EN.aia (21.3 KB)

I just realized that always adding a trailing \n to each pair's text is sloppy.
It leaves you with a trailing \n at the end of the CSV table text that might poison any list from csv table block.

Abandoning file storage while accumulating, and replacing it with list row addition should avoid this.

1 Like

My dear, if you mean to delete that block, we already deleted it previously, together with the Join block and global text above, the code returned the same annoying listing error.
Mind you, that is the only place where the "\n" block was used.

My Esp32 ouputs the values to the App in the form of text in exacly this form:



Is this the problem?

Maybe people thought my Esp32 Arduino code delivers CSV or some kind of table, it doesn't. It simply outputs the values by sending text exacly in that form above.

Then the app somehow adds these straight brackets to it and transforms it into some kind of string, without separating the two pairs, and instead of going down it makes it like this:

[-x,x -x,x -x,x]


From what @SteveJG suggested, the correct format would be the one with a comma after the first two values, like this (please correct me if I'm wrong or if this ain't even necessary):

[-x,x , -x,x , -x,x]


I see you are expecting a message delimiter

but I don't see where you have set the BlueTooth Client Delimiter to 10, to catch println() \n.

Oops, never mind, I see it in Screen1.Initialize.

1 Like

If you require screens from my phone as well with how the app works at the moment and what does it shows on my phone screen when pressing the connect button or after connecting please let me know, I understand that without a Bluetooth device like the Esp32 and without having the Arduino code to work with, debugging of my code can be difficult which is why I am willing to do anything I can to assist debugging. In case my Arduino code is needed I can share that here as well, anything just to make it work.

I am checking your code to see if it conforms with TimAI2's ChartMaker Decoded link in

1 Like

Yes, please, it needs to be checked for println() delimiters, exclusion of commentary from the data stream, transmission frequency, and adherence to sending comma delimitted text pairs.

1 Like
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "BluetoothSerial.h" //Header File for Serial Bluetooth, will be added by default into Arduino
#include <esp_gap_bt_api.h>
#include "esp_gap_bt_api.h"
#include <esp_spp_api.h>
#include <esp_gattc_api.h>
#include "sdkconfig.h"
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

uint8_t link_master;
BluetoothSerial SerialBT;
int rssi = 0; //RSSI
int distance = 0; //DISTANCE
byte addr[6] = {0, 0, 0, 0, 0, 0}; //to keep MAC address of the remote device , 8 bit value
static int PAIRING_VARIANT_PIN; //The user will be prompted to enter a pin or an app will enter a pin for user
struct read_rssi_delta_param;
struct esp_bt_gap_cb_param_t::read_rssi_delta_param read_rssi_delta; //read rssi parameter struct
esp_bd_addr_t bda; //remote bluetooth device address
int8_t rssi_delta; //rssi delta value range -128 ~127, The value zero indicates that the RSSI is inside the Golden Receive Power Range, the Golden Receive Power Range is from ESP_BT_GAP_RSSI_LOW_THRLD to ESP_BT_GAP_RSSI_HIGH_THRLD
esp_err_t esp_bt_gap_read_rssi_delta(esp_bd_addr_t remote_addr); //This function is called to read RSSI delta by address after connected. The RSSI value returned by ESP_BT_GAP_READ_RSSI_DELTA_EVT.
BluetoothSerial ESP32Mini_Bluetooth; //Object for Bluetooth
//ESP32Mini_Bluetooth_GAP_READ_RSSI_DELTA_EVT; //read RSSI event
//ESP_BT_GAP_DEV_PROP_RSSI; // Received Signal strength Indication, value type is int8_t, ranging from -128 to 127
//ESP_BT_GAP_RSSI_LOW_THRLD; // Low RSSI threshold
//ESP_BT_GAP_RSSI_HIGH_THRLD; //     RSSI threshold. High RSSI threshold
//esp_bd_addr_t bda; //remote bluetooth device address
//esp_bt_status_t stat; //read rssi status
const int PIN = 32;
const int CUTOFF = -60;
int incoming;
int best;
void setup() {
  ESP32Mini_Bluetooth.setPin("4321"); //This should solve the Secured Pin Connection
  Serial.begin(9600); //Start Serial monitor in 9600 ; this is the line where it initialize serial to 9600 baud speed
  ESP32Mini_Bluetooth.begin("ESP32_Vibration_Control"); //Name of your Bluetooth Signal
  Serial.println("Bluetooth Device is Ready to Pair");
  pinMode (PIN, OUTPUT);//Specify that Vibration Motor pin is output
  esp_bt_gap_register_callback (gap_callback); //register the RSSI callback function by calling this line
  //register SPP service callback to get remote address:
  // //This is Legacy Pairing Code
  //ESP_BT_GAP_PIN_REQ_EVT //Legacy Pairing Pin code request
  //ESP_BT_GAP_CFM_REQ_EVT //Simple Pairing User Confirmation request.
  //ESP_BT_GAP_KEY_NOTIF_EVT //Simple Pairing Passkey Notification
  //ESP_BT_GAP_KEY_REQ_EVT //Simple Pairing Passkey request
void loop() {
  if (SerialBT.hasClient()) { //this is where we get and handle RSSI value
    //when we need RSSI call this:
    esp_bt_gap_read_rssi_delta (addr); //now variable rssi contains RSSI level
    byte b = rssi; //etc....
    if (rssi < -20)
      digitalWrite(PIN, HIGH);
      //ESP32Mini_Bluetooth.println("Vibration Motor ON");
      Serial.print ("PIN turned ON");

    if (rssi > -20)
      digitalWrite(PIN, LOW);
      //ESP32Mini_Bluetooth.println("Vibration Motor OFF");
      Serial.print ("PIN turned OFF");

    if (rssi > -20) {
  distance = 2;
} else if (rssi < -20) {
  distance = 1;
} else {
  distance = 0;
    //ESP32Mini_Bluetooth.print("RSSI: "); //println add linefeed for end of printed string
    //ESP32Mini_Bluetooth.println(rssi); //println add linefeed for end of printed string

      ESP32Mini_Bluetooth.print(", ");
    delay (1000);    //DELAY OF 1 SECONDS
    // Disconnected state
      digitalWrite(PIN, LOW);
      Serial.println ("Disconnected. PIN turned OFF");
      Serial.println (rssi);
      delay(1000); // wait 1s
  if (ESP32Mini_Bluetooth.available()) //Check if we receive anything from Bluetooth // is telling that BT has received some data and it need to be processed
    incoming =; //Read what we recevive
    Serial.print("Received:"); Serial.println(incoming);
    digitalWrite(PIN, best > CUTOFF ? HIGH : LOW);
//RSSI callback function
void gap_callback (esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param)
    rssi = param->read_rssi_delta.rssi_delta; // it checks it has connection
    Serial.print("RSSI Delta: ");
    Serial.println (param->read_rssi_delta.rssi_delta);
//SPP service callback function (to get remote MAC address)
void spp_callback (esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
  if (event == ESP_SPP_SRV_OPEN_EVT)
    memcpy(addr, param->srv_open.rem_bda, 6);

As you can see, I don't know how to implement a formula to estimate and generate a distance value in meters based on the signal strength so I did what I could and wrote a simple aproximation based on on my calibration which is going to be updated with values for each 10 Rssi +/-, manually. If you have any idea how to implement the function and having it to ouput the value after the signal strength that would be a life saver for me.

Besides that, well I did what I could with my knowledge and it took alot of time reading the Esp32 Api in order to get the needed snippets of code for RSSI meassurement and various forum threads and getting snippets of code from here and there but this isn't documented anywhere when it comes to BT Classic so I am surprised I managed to have it work as it works right now it somehow was a miracle that the code snippets I took from the API worked with the rest of the code in order to calculate the RSSI but yup I guess I got extremely lucky.

I don't have any coding knowledge at all but I can kinda guess what does what and when I get stucked I ask around and people are nice and willing to help, that's how I did put everything together for this project.

I've found this article that kinda talks about how its done but not in detail and it's also for BLE:

I reworked your BlueTooth reception timer to directly add rows of pairs to your global variable holding the table (list of lists) that is fed directly to the ChartMaker extension, following the TimAI2 post I mentioned earlier.
Here is what I changed ...

I added a variable to hold the incoming message, to grab it for inspection prior to adding it to the table as a row (list).
global last_message

DFPS_APP_EN_ABG.aia (21.5 KB)

I treat variable DataList as a table (list of lists), and add only pairs to it, working exclusively with lists. I brought in the file output to the inner if/then, to not bother writing when no data was received.

The ChartMaker Clock Timer event feeds global Datalist into CharMaker, no conversion needed.

Global variable DataList is always a list of lists.

1 Like

Oops, it helps to read what you write.
DFPS_APP_EN_ABG.aia (21.5 KB)

I needed to record only perfect pairs.
I moved code up into the inner if/then.

1 Like

I am testing everything right now my dear, I am dying of hapyness to see if it finally works!

Thank you so much!

Coming back with an update in a few minutes!

ESP32Mini_Bluetooth.print(", "); 
delay (1000); //DELAY OF 1 SECONDS

This looks okay for message delimiter \n, data delimiter comma, and pacing.

1 Like

My dear,

Great news! It kinda works, but!

First of all, when I opened the Companion this error appeared on scren:

And then, this appeared on my phone after connecting to the Esp32:

I barely managed to capture a screenshot with the graph! :slight_smile:

The graph is a straight line, it's only appearing for 0.3 seconds or something like that and it quickly dissapears for about 1-2 seconds and so on.

But.. it finally works!!

Also, first of all thank you so much for letting the .csv button function untouched and working, it is displaying the data a bit more different from how it is showned at the bottom of the app (don't know if that is good or bad) but, here it is a screenshot with how it looks when I press the Check Csv button:

My dear, you made it work finally! Can't describe how grateful I am for this and to everyone that contributed with suggestions!

Also, the data at the bottom, it doesn't scroll up automatically with the new values, it gets the first ones then it remains like that, If it is possible update them visibly by scrolling down or simply replacing them with new ones (altough auto scrolling them up would be amazing).


And after I press the Check Csv button, when I am in that view, it doesn't update the received data unless I press the back button and press the Check Csv button again.

Note: When I am in the Check Csv screen/view, I can scroll up and down, it's just that it stops updating when I enter in it, then when I get back I guess it updates and when I enter I see the other values added as well so the list gets bigger and I can scroll up and down.

I have no guess on the undefined error. But last I saw of your app, you had a lot of rubble in it.

if you don't need the file /data.csv, I recommend removing the file component and all its blocks, since you are feeding data directly through global variables.

That diagnostic label can be removed too or hidden, if you are secure on your data. No need for training wheels on the highway.

I didn't touch that. Those ( ) are from sloppy .Elements assignment converting pairs (lists with 2 items) to text to fit into the List Picker displayable Elements. I have an Elements block procedure that can pretty those up if it matters.

Well we kinda tried to work with Highcharts first which requires an CSV listed with values like you did them show for ChartMaker, that is the reason I wanted to keep the make CSV function because I'd like to try and make HighCharts work now, because that is animated.

It's hard to make it work with my knowledge, but this is all I know and have out of it:

It requires these dependencies, which i already have all in a folder and it also requires a file named data.csv that somehow needs to be called or imported from index.htm.

I do not know how to write the line code that does that that's all I need to do in order for it to have it work.

What I've done was taking their working dynamic spline example which uses some kind of function instead of the data.csv, which you can check in the index.htm:

I've tested the chart in my App using the webviewer and it works flawlesly, and yes it's animated and all the good stuff,

it just didn't use my data.csv file because I don't know how to set it up but from what I've understood it's all about writing a line of code in the index.htm file to make it take data from the data.csv instead of the function.

You can find the function used under "series", that is how they call the data being used to generate the chart, and you will see that there it writes data function() instead of using the data.csv.

I uploaded all the required files here including the index.htm in case you have any idea how it's done since now we have working data (data.csv is a test one in that folder, made by me when trying to see if I can make it work locally before in my app but to no success) that data.csv may not even be good)

This is how they recommend working with local CSV's:

If you have any idea how to use it, please let me know my dear!

If I solve this out, then I can die happy lol.

The reason why I have the app making that data.csv file is so that, Highcharts could constantly read it and work based on the values in it, just like ChartMaker does with how we set it up.

It's just that I am clueless about how to make it work with the data.csv generated by the app.
If you upload all the files I shared in MIT 2 and add the index.htm path to a webviewer you will see the example works perfectly and also, all that needs to be done I think is the index.htm file to be modified to use the data.csv generated by our app instead of that function they have down there that generates random values.

I saw some people create an index.js file, call it from inside index.htm file by specifying the path to the index.js and they program the index.js file to work with the csv somehow.

And I think in order for HighCharts to work that data.csv needs to be formatting the values accordinly as well so that would be great if possible to fix it indeed!

@ABG I've also found this example that loads data from a dynamic data.csv file!

Glad that somethings are working finally and you get a basic graph. You have been working hard.

That recommendation was made a long time ago MelodyApril. Please take our advice. Elimination of the part of the app that saves the csv as a file might make a difference in how your app performs.

Make a copy of your app that is running (Projects>Save project as.. ) and remove the File component stuff from the copy. Continue to experiment with Highcharts at your leisure on your original Project. Make an archive aia of your Project (if you change something that creates havoc and can not recover, you still have a usable copy of your app).

1 Like

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