Bluetooth Client Polling Rate

From the Help Documentation:
PollingRate
Returns the configured polling rate value of the Bluetooth Client.

It doesn't return anything, it is a value that the App Developer can input in the Attributes palette.

However - it should tell us what exactly the Polling Rate is.

My Guess: When scanning for Bluetooth devices that could be connected to, i.e. how many attempts to collect each device address. Or perhaps how many times it will test for incoming bytes. Per second? Per millisecond?

Please update the Help.

2 Likes

The PollingRate property is actually for the purposes of integrating with the Chart component, but it was written before we did a fairly major overhaul to how the documentation gets generated from the source code. That change causes the Javadoc information to get used for describing properties, and here you're seeing how that Javadoc was written internally and hasn't been updated to reflect the procedural changes.

Normally, the BluetoothClient only reads data from the connected peripheral when you call one of the Read methods on the component. To support realtime graphing of data in the Chart component, the PollingRate property was added to periodically read data from the client and report that to a connected ChartData2D component. In hindsight, as the design for the system evolved it would have probably been better to make this property be a property of the ChartData2D when a BluetoothClient is specified as the component's Source. This is what happens with other components, like the Spreadsheet or Web components.

1 Like

(added to FAQ)

Everyone has been using a clock for that purpose. What are the Polling Rate's units of time?

1 Like

Milliseconds

Has anyone actually used the polling rate to produce a decent chart live?

Here's the documentation Evaldas wrote:

@elatoskinas Do you happen to have any test projects still for the BluetoothClient integration with Charts?

That documentation should be published, it's gold dust.

(copied from

)

(part 1, too large to fit in board post)

(App Inventor Charts Documentation

Overview

Summary

In the App Inventor Charts project, two new components have been added - the Chart and the Data.

The Chart component is a single component which represents a single Chart. Multiple Chart types can be selected, including Line, Area, Scatter, Bar and Pie Charts. The Chart component is responsible for the Chart’s visual appearance and type.

The Data component represents a single Data Series in the Chart itself. For instance, if the Chart type is selected to be the Line Chart, a single Data component represents one line in the Chart. This component is responsible for holding the data and managing all manipulation of the data.

Basics

Using the Chart

Summary

The new components can be found under the Charts category in the Palette, as seen in Figure 1.

Figure 1: Charts category in the Palette

Upon adding the Chart component to the Viewer, we will then see an empty Chart, as seen in Figure 2.

Figure 2: Empty Chart as seen in the Viewer

To add a Data Series to the Chart, the Data components can be dragged and dropped onto the Chart directly (see Figure 3). In Figure 3, we can also see how the Chart looks like with a single Data component attached to it.

Figure 3: Dragging & dropping the Data component onto a Chart

In addition, multiple Data Series can be dragged onto the Chart:

Figure 4: Multiple Data components attached to a Chart

At this point, the Chart has a single Data Series component. The styling of the Data and Chart components can be done via the Designer properties, as we will see in the Customization section.

Types

Summary

The most important property of the Chart components is the Type, which determines what type of data the Chart plots, and how it looks like visually.

The property cannot be changed via the blocks, and has to be set via the Properties menu, as shown in Figure 6.

Figure 5: Chart type selection

Currently, there are five types of Charts available -- Line, Area, Scatter, Bar and Pie.

Line Chart

Summary

Figure 6: LIne Chart

The Line Chart is a type of Chart that plots lines. The Chart’s data points consist of numerical x and y values, and the points are plotted continuously on a line.

Each Data Series corresponds to a Line.

Area Chart

Summary

Figure 7: Area Chart

The Area Chart is also a Line Chart, but a fill effect is applied underneath the lines of the Chart. This Chart shares all the characteristics of the Line Chart.

Scatter Chart

Summary

Figure 8: Scatter Chart

The Scatter Chart is a type of Chart that plots individual data points. The Chart’s data points consist of numerical x and y values (same as the Line Chart), but the points are not plotted continuously, and lines do not connect the points.

Each Data Series corresponds to a single set of points.

Bar Chart

Summary

Figure 9: Bar Chart

The Bar Chart is a type of Chart that plots bars. The Chart’s data points also consist of numerical x and y values, however, the x value is a whole, non-negative number. The x value, in a way, can be thought of as an index to the Chart, since x values are integers. Each data point corresponds to a single bar.

Each Data Series corresponds to a set of bars, and the bars are grouped together in the same positions.

Pie Chart

Summary

Figure 10: Pie Chart

The Pie Chart is a type of Chart that plots a circular graph divided into slices. The Chart’s data entries consist of an x value which is a text value, and a numerical y value. The x value represents the label (or the name) of the entry, while the y value represents the value itself. Each data entry corresponds to a single slice of a Pie Chart ring.

Each Data Series corresponds to a single ring in the Pie Chart. A Pie Chart with more than one Data Series is called a concentric Pie Chart.

Manipulating Data

The component responsible for handling the Data in the Chart is the Data component. Manipulating data in a Data component changes that single Data Series.

Adding Entries

Summary

The simplest way to add entries to a Data component is to use the AddEntry block of the component. For instance, if we would like to add a point to a Line Chart with an x value of 2, and a y value of 3, we would use the following block:

Figure 11: Add Entry block

Note that the block only adds data to that single Data component (Data Series), meaning that other Data Series would require the block to be specified for them separately.

If we would like to add the same value of x = 1, and y = 2 to 3 Data Series, we would specify the blocks as follows:

Figure 12: Importing multiple entries with Add Entry blocks

List Importing

Summary

Suppose that now we would like to add multiple entries to a Data Series at once, and we specify the following blocks:

Figure 13: Importing 5 entries with Add Entry blocks

A simpler way to do so is via the ImportFromList block, which takes a single List as input. The format of the List is that each element of the List should also be a List, which contains 2 values -- one for the x value (the first value), and one for the y value (the second value).

The same 5 blocks can be expressed in 1 as follows:

Figure 14: Importing multiple Entries with the Import From List block

Removing Entries

Summary

Suppose we add two entries, as follows:

Figure 15: Adding two entries, one of which will be removed

After some time, we would like to remove one of the entries we added. This is possible via the RemoveEntry block, which will then remove the Entry:

Figure 16: Remove Entry block

Finding Entries

Summary

The Data component also has blocks to help finding and retrieving entries.

The most simple block is the GetAllEntries block:

Figure 17: Get All Entries block

This block will return a List of entries, where each entry is a List formatted in the same way as we formatted the entries in the ImportFromList method.

In the case where we would like to know if a specific entry exists, we have the DoesEntryExist block, which takes in an x and y value as input, and returns true if the entry exists in the Data Series, and false otherwise.

Figure 18: Does Entry Exist block

Finally, there are two more blocks to retrieve all entries with the specified x and y value:

Figure 19: Get Entries With X Value Block

Figure 20: Get Entries With Y Value Block

The format of the returned result is the same as the GetAllEntries block.

Customization

Data

Colors

Summary

The color of the Data components can be changed via the Color property (as seen in Figure 21)

Figure 21: Color Property

Alternatively, a List of Colors can be specified via the Colors property setter block to set multiple colors to one Data Series (see Figure 22)

Figure 22: Colors Property

The Chart in the application will then look as shown in Figure 23.

Figure 23: Data Series with multiple Colors

Label

Summary

The label of the Data Series in the Legend can be changed via the Label property, as shown in Figure 24.

FIgure 24: Label Property

Line Type

Summary

If the type of the Chart is either Line or Area, the LineType property shows up in the Data component (see Figure 25). This changes the way the lines are drawn (as shown in Figure 26).

Figure 25: Line Type Property

Figure 26: Line types

Point Shape

Summary

If the type of the Chart is the Scatter Chart, the pointShape property shows up in the Data component (see Figure 27). This changes the shape of the points of the Scatter Charts (as shown in Figure 28).

Figure 27: Point Shape Property

Figure 28: Point shapes

Chart

Description

Summary

The description (title) of the Chart can be changed via the Description property, as shown in Figure 29.

Figure 29: Description property

Background Color

Summary

The background color of the Chart can be specified via the BackgroundColor property, as seen in Figure 30.

Figure 29: BackgroundColor property

Legend Enabled

Summary

The legend of the Chart can either be enabled or disabled via the LegendEnabled property. Figure 31 shows the difference between the property being on and off.

Figure 30: Legend enabled/disabled example. The Legend is enabled on the left, and disabled on the right.

Grid Enabled

Summary

Provided that the type of the Chart selected is an axis-based Chart type (either Line, Area, Scatter or Bar), the GridEnabled property shows up, which specifies whether the grid of the Chart should be drawn. Figure 32 shows the difference between the property being on and off.

Figure 30: Grid enabled/disabled example. The Grid is enabled on the left, and disabled on the right.

Labels

Summary

If the Chart’s selected type is an axis-based Chart (either Line, Area, Scatter or Bar), the Labels property can be used to set custom labels to the x axis. The labels are applied in order starting from the x value of 0 (the second label gets applied to an x value of 1, the third to an x value of 2, and so on). See Figure 31 for an example of the property block, and Figure 32 for how the labels are applied.

Figure 31: Chart Labels property setter block

Figure 32: Custom x axis labels (as set in Figure 31). The x value of 0 is mapped to A, the x value of 1 is mapped to B, 2 to C and 3 to D.

Provided that there are not enough labels, simply the numeric x value is then used instead (see Figure 33)

Figure 33: Example of more x values than labels available. X values which do not have a corresponding label are replaced with the numeric value.

An alternative to using the Labels property setter block is using the LabelsFromString Designer property which allows specifying a CSV formatted String as shown in Figure 34, producing the labels as shown in Figure 35.

Figure 34: LabelsFromString property example value

Figure 35: Resulting labels from the property set in Figure 34

Pie Radius

Summary

If the “Pie” Chart type is selected, the Pie Radius property shows up in the Designer properties (as shown in Figure 35). The property specifies the Pie Chart fill in percentage, meaning that the lower the percentage, the hollower the Pie Chart. Figure 36 illustrates the difference between some value choices. The property’s value is a number from 0 to 100.

Figure 36: Pie Radius property

Figure 37: Pie Chart appearance with different Pie Radius values

Chart Data Sources

ElementsFromPairs

Summary

The most simple way to specify the Data to use for the Data component is by using the ElementsFromPairs Designer property. The property’s value is specified as a CSV formatted String, where each 2 values, in order, are considered as one entry (one for the x value, and one for the y value). An example of this is shown in Figure 38.

Figure 38: ElementsFromPairs property example value

The result of the property value shown in the figure above is shown in Figure 39. Note how from the ElementsFromPairs String input, the values 0,5 are used to construct an entry with the x value of 0, and a y value of 5. The next two values, 1,3, are used to construct an entry with the x value of 1, and a y value of 3. Finally, an entry with an x value of 2 and a y value of -3 is added to the Data Series.

Figure 39: Data values as set by the ElementsFromPairs property (in Figure 38)

Data Sources

Summary

With the introduction of the Data component, various components are compatible with the Data component as Data Sources. These components include TinyDB, CloudDB, DataFile, Web, BluetoothClient, AccelerometerSensor, GyroscopeSensor, Pedometer, OrientationSensor, LocationSensor and ProximitySensor. Each component will be covered in its own corresponding section in the document.

To simplify the process of Data importing, the Data component comes with corresponding Designer properties. The core property is the Source property, as seen in Figure 40.

Figure 40: Source property

Alongside the Source property, a DataSourceValue property has been introduced to specify the value that should be imported from the Data Source to the Data Series (see Figure 41). The DataSourceValue expected input is different for each Data Source, and will be explained in more depth in the individual Data Source component descriptions.

Figure 41: DataSourceValue property

Finally, with regards to Chart Data Source property setting, two new blocks have been introduced.

The first block is the ChangeDataSource method, which is the equivalent of setting the Source property in the Designer properties with the corresponding DataSourceValue (see Figure 42)

Figure 42: Change Data Source block

The second block is the RemoveDataSource method, which completely unlinks the Source component from the Data Series. Since there are components which may update data dynamically (such as real time Data Sources), this method is useful to stop data importing completely from the Source.

Figure 43: Remove Data Source block

1 Like

(part 2)

TinyDB

Summary

The TinyDB component can be used as a Data Source by using values identified by tags. In order to use values of TinyDB in the Charts, the values have to be Lists containing List entries with 2 entries each (as shown in Figure 44). We have seen this format before in the ImportFromLists block example.

Figure 44: TinyDB compatible value format

Provided a value of the valid format is stored in the tag value, the value can then be imported as follows:

Figure 45: ImportFromTinyDB block example

In order to use the TinyDB as a Source via either the ChangeDataSource block, or the Source property, the DataSourceValue (or the key value) has to be the tag to use from the TinyDB component (in this case, we have used “tag”)

Lastly, if the TinyDB component is used as a Source either via the Source property or the ChangeDataSource block, any changes made to the value will be reflected in the Data Series (old values will be removed, and the new values will be added).

CloudDB

Summary

The CloudDB component is used in the same fashion as the TinyDB component. The format of the values can be seen in Figure 46, and the block for importing the values can be seen in Figure 47.

Figure 46: CloudDB compatible value format

Figure 47: ImportFromCloudDB block example

With regards to using the CloudDB component as a Source, whenever the DataChanged event occurs, the Data Series which uses the corresponding value in the CloudDB component will respond to the changes automatically.

Data File

Summary

Together with the Chart components, the Data File component has been introduced which allows reading in CSV or JSON formatted files which can then be used to easily access data, as well as easily import data from files to Chart Data Series.

To use the DataFile component, first it has to be added to the palette. After adding the DataFile, a file has to be loaded to the DataFile. This can be done via the ReadFile block, as shown in Figure 48. The format of the ReadFile Source is the same as of the File component’s ReadFrom block.

Figure 48: ReadFile block

Alternatively, a file can be selected via the SourceFile Designer property (see Figure 49)

Figure 49: DataFile SourceFile property

The DataFile also comes with three property getters (as seen in Figure 50)

Figure 50: DataFile properties

Since the DataFile accepts either CSV or JSON files, the DataFile reads in the columns and rows from the file, which can then be accessed via the Columns and Rows properties. The ColumnNames property holds the names of each column.

All three properties return Lists. The Columns and Rows List entries consist of Lists, and the ColumnNames entries consist of text entries. The indexes of Columns, Rows and ColumnNames match, but the order is not ensured in the case of JSON files (but it is in the case of CSV files)

Figure 51 and 52 represent what a row, a column and a column name corresponds to in both CSV and JSON files.

Figure 51: CSV Rows, Columns and Column Names example

Figure 52: JSON Rows, Columns and Column Names example. The data stored in the shown JSON file is equivalent to the CSV example in Figure 51.

Since the DataFile reads the columns and rows from the data, the data is imported to the Data Series by specifying the columns (column names) to use for both x and y values, as shown in Figure 53.

Figure 53: Import From Data File block

Alternatively, a column name can be left blank to use default values (see Figure 54). For example, if the x column is left blank, but a y column is specified with 5 entries, then the x values of the entries will be set to 0, 1, 2, 3 and 4, in that order.

Figure 54: Import From Data File block using blank column

In order to import data from a Data File via the ChangeSource block, the key value has to be a CSV formatted text value, as shown in Figure 55.

Figure 55: Change Data Source block for Data File

In order to use default values (blank columns), simply add a comma right away without any text value (see Figure 56)

Figure 56: Change Data Source block for DataFile with blank column

Finally, if using the Source property via the Designer, and a SourceFile is set to the DataFile, the columns can be selected via designated DataFile column properties (see Figure 57)

Figure 57: DataFile column properties

Provided that the SourceFile has been loaded, and the file contained valid data, the dropdown menu for selecting the columns should display all the columns of the file (see Figure 58). In addition, the “None” property selection is treated as the blank column option which uses default values instead.

Figure 58: DataFile Column property dropdown

Web

Summary

The Web component behaves in a similar way as the DataFile, exceptexpect that data is retrieved from online sources. The basic principle behind Web component importing is that the retrieved content should be either CSV or JSON files.

In order to import data via the Web component, first the Web component should be set up as usual, and the Get method should be used (as in Figure 59)

Figure 59: Web component Get block

After the Get block is used, the data can be imported to the Data Series via the designated block (see Figure 60)

Figure 60: Import From Web block

Here, the columns should be specified in the same way as for the Data File component.

When using the Web component as a Source in the Designer properties, Web column properties will become visible, which have to be filled in manually (see Figure 61)

Figure 61: Web column properties

If the Web component is used as a Source for the Data Series, whenever the Get block is called again, the data is updated in the Data Series as well.

Bluetooth

Summary

In order to import real time data via Bluetooth, the BluetoothClient component should be used either via the Source property, or the ChangeDataSource block.

First, it is important to set the corresponding DelimiterByte in the BluetoothClient component (see Figure 62). This byte is used to separate each individual incoming value (which also has to be taken care of on the Bluetooth client side)

Figure 62: BluetoothClient DelimiterByte property example

The key value (or the DataSourceValue) for the case of Bluetooth data importing corresponds to the prefix of the data. For example, if the data were to be retrieved in the format t:5, the prefix t: could be specified to properly retrieve the value 5 as the data (Figure 63 shows an example of the setup). However, if the data is retrieved as numeric values (simply 5, for example), then the DataSourceValue should be left empty.

It is important to note that the BluetoothClient acts as a real time Data Source. As soon as data is available, the data is read, and sent to the Data Series. This means that Read blocks will no longer function on the BluetoothClient, since it is being read by the Data Series. However, as many Data Series as needed may make use of a single BluetoothClient (even with multiple prefixes). Incoming values with prefixes that do not match the Data component’s DataSourceValue are ignored by that Data Series (but are sent to all Data Series using the BluetoothClient as a Source).

Figure 63: BluetoothClient Source property settings example

Accelerometer Sensor

Summary

The Accelerometer Sensor can only be used either via the Source property, or the ChangeDataSource block. Data is sent from the sensor to the Data Series dynamically as soon as the value updates.

The Accelerometer Sensor has 3 valid key (DataSource) values:

  • X - x dimension acceleration
  • Y - y dimension acceleration
  • Z - z dimension acceleration

An example is shown in the figure below:

Figure 64: Accelerometer Sensor as a Data Source example

Gyroscope Sensor

Summary

The Gyroscope Sensor can only be used either via the Source property, or the ChangeDataSource block. Data is sent from the sensor to the Data Series dynamically as soon as the value updates.

The Gyroscope Sensor has 3 valid key (DataSource) values:

  • X - x angular velocity
  • Y - y angular velocity
  • Z - z angular velocity

An example is shown in the figure below:

Figure 65: Gyroscope Sensor as a Data Source example

Pedometer

Summary

The Pedometer can only be used either via the Source property, or the ChangeDataSource block. Data is sent from the sensor to the Data Series dynamically as soon as the value updates.

The Pedometer has 3 valid key (DataSource) values:

  • WalkSteps
  • SimpleSteps
  • Distance

An example is shown in the figure below:

Figure 66: Pedometer as a Data Source example

Orientation Sensor

Summary

The Orientation Sensor can only be used either via the Source property, or the ChangeDataSource block. Data is sent from the sensor to the Data Series dynamically as soon as the value updates.

The Orientation Sensor has 3 valid key (DataSource) values:

  • azimuth
  • pitch
  • roll

An example is shown in the figure below:

Figure 67: Orientation Sensor as a Data Source example

Location Sensor

Summary

The Location Sensor can only be used either via the Source property, or the ChangeDataSource block. Data is sent from the sensor to the Data Series dynamically as soon as the value updates.

The Location Sensor has 4 valid key (DataSource) values:

  • longitude
  • latitude
  • altitude
  • speed

An example is shown in the figure below:

Figure 68: Location Sensor as a Data Source example

Proximity Sensor

Summary

The Proximity Sensor can only be used either via the Source property, or the ChangeDataSource block. Data is sent from the sensor to the Data Series dynamically as soon as the value updates.

The Proximity Sensor requires the Data Source value of “distance” in order to produce real time data.

(Image to be updated)

Figure 69: Proximity Sensor as a Data Source example

1 Like

(AI2 Charts Usage Guide added to FAQ)

I found one write-up for the test project that I was testing against, with sample Arduino code and rough sketch of the setup: see blog post (the 'Example' section)

I will try to see if I can find the actual project file