The operation <= cannot accept the arguments: , [*empty-string*], [35]

This is usually a disaster, because switching screens loses the BlueTooth connection.

Better to stack multiple Vertical Arrangements in the same screen, and show only one at a time.

1 Like

You can measure your input backlog by showing the Bytes Available to Receive in a Label each Timer cycle. It should usually hover around zero until you fall behind. I would guess you can push the Timer to 30 milliseconds, but you have to experiment. Humans can't read faster than that.

1 Like

I made an attempt but it's not working and i'm not sure what's wrong. I followed this guide http://www.appinventor.org/content/howDoYou/UIModules/Scroll but it does not show the blocks used.

The plan is to retain the Bluetooth connection at all times while switching screens. I split all the screen components into 4 main sections vertically. The top section where the Bluetooth Connect logo button (alongside the Status and Incoming Data) should always be displayed between screens as well as the bottom section where there is the Disconnect button. That leaves two sections in between them; the first screen should show the sensor data from the Arduino. When the Controls button is pressed, it should display the second screen which contains the ON and OFF controls to modify the status of the LED on the Arduino. When the Main Screen button is pressed, then it should go back to the first screen to show only the sensor data. I'm not sure if that's even possible to be created in AI2?

I have put all the parts from the first screen grouped under VerticalArrangement1 followed by VerticalScrollArrangement1 which groups all the components of the second screen.



In the Blocks Editor, i added these two:
menubtns
I'm not sure if this is the correct approach. I tested this attempt but it simply shows everything on one screen.

Here is a sample app that runs in one screen, with hidden Arrangement switching...

1 Like

Thank you for the sample. That helped. I used part of the blocks and managed to make it work although i'm in doubt about having to use TinyDB. Is that recommended? The sensor data should not be interrupted while switching between verticalArrangements. At first sight, it seems like the sensor data is coming through but i'm wondering if there are some internal limitations?

Here is the current state of my app:

Also, while using the app, if the Arduino hardware is disconnected (for example, due to a cable coming loose) there is currently no error notification displayed in the app. The displayed sensor data in the app simply doesn't update anymore and the Bluetooth connection status still shows "Connected". Is it possible to add a check so that if the Bluetooth connection is interrupted on the hardware side and no sensor data is being received, then the connection status should show "Disconnected" or "Error" and a connection error notification is displayed in the app?

Hello Shakeel

Should be Serial.println(); inserting your value delimiter there tells the App there is a fourth value following when in fact that's the end of the data, consisting of 3 values.

You are reading from the App and writing to the Serial Monitor and to the App, all on the same channel. The Uno only has one physical channel but you can add a Software Serial via SoftwareSerial.h - that gives you Serial1 to receive from the App and Serial to send to the App. When connected to the App, the Monitor should be redundant, comment out the info being sent to it.

You haven't mentioned what your project actually does - why would you need the App Labels to be updated so often, so quickly? 300ms is far faster than the human eye can tolerate.

1 Like

Yes, there are standard Blocks for that. Before the App checks for bytes available, the connection could be checked.

Hi ChrisWard,

Thank you for pointing out this mistake in the code.

Even though i'm using only the hardware Serial in the Arduino UNO, receiving sensor data and sending commands appear to be working. So, what could be the problem if i just use one Serial instead of an additional Serial as you suggested with the Software Serial?

I am using the Serial Monitor in the app only to check and make sure that Serial data is incoming, especially if there is some hardware problem which disrupts the Bluetooth connection, since the app does not currently correctly detect if the Bluetooth connection is still alive.

I am breaking down the project into small parts and adding new features gradually. The project is basically a small robot with 2 DC motors and it uses an IMU to detect angle of inclination. If the robot is going fast and on uneven ground, then the sensor will detect fast changing angles. If the angle detected is above a specified threshold, then the robot should stop. Using the app, the plan is to control the robot as well as receiving sensor data. So, that's why i am aiming to display fast data output from the sensor in the app. The actual goal is to record the incoming sensor values and store it in a CSV file so that i can make a graph in Excel. Is it possible to implement such a recording feature inside the app? But it would need to work fast enough to record every single Serial data incoming every 300ms or maybe even faster from the Arduino UNO.

I have already added the BluetoothClient1.IsConnected block which should be the one responsible for checking if the Bluetooth connection is still alive every time the Clock1.Timer fires? But for some reason, it doesn't work. The Label1.Text shows "Connected" even after the wires in the Bluetooth module are disconnected.

Since the time interval is so short, it will get to the point where a send from Uno coincides with a send from the App: result = crash. However, see below.

It does work (unless you have a very old phone running an Android version < v4 Ice Cream Sandwich). The issue is your code. You can't use "If not" (too confusing to explain why not, just not!).
Instead, it should be an 'else' from the 'if' that checks the connection.
Snap4

OK - it is not useful to send the angle continuously to the App. If the Robot hits the threshold value, the Uno must stop the Robot. Having stopped, it can tell the App so the User can decide what to do next. With this approach, a single serial channel should be sufficient.

I am using Android 9 on my smartphone. OK, i updated the app blocks. I tested it but if the hardware is disconnected, the status of the Bluetooth connection in the app still shows "Connected".

The next stage of the project would be to use some filters to prevent spikes in the raw angle measurements and instead get a more uniform change in the angles. For example, when the robot car is going fast over a bump, the angle measurement will spike and this could go above the threshold and stop the robot. I want to have a visual in a graph of the raw angle data and the filtered angle data with respect to time, to test the effectiveness of the filters. So, i guess it will probably require an additional serial port via a software serial as you initially suggested? But i am still stuck on a way to record the sensor data reliably.

You haven't shown those Blocks. Also, you have the same "not" error in the Screen Initialize Block.

Record or Store? You could add records to a List in the App and draw a graph from those at the end of a Robot test. Records can be stored/recalled from TinyDb.

I selected the option "Download Blocks as Image" and uploaded it. If you click on the image, it will expand to show all the blocks.

I have fixed it although i don't know what block to put under "then" so i just left it blank. I hope it's not going to create any issues with the app? Here are all the updated blocks.


I tested the updated app, but there are some issues:

  1. The sensor values are not received in the app but the commands sent to the Arduino work. I somehow managed to fix it by removing under Clock1.Timer, the block "set Clock1.TimerEnabled false". Not sure why that was the problem though.
  2. After disconnecting the hardware while the app is running, the Label1.Text still shows "Connected". But then after a few seconds, there is a temporary notification: Error 517: Unable to read: bt socket closed, read return: -1

Isn't that the same? Forgive my ignorance. I am not sure what's the difference. Basically, i am thinking of keeping a list of all the angles data with respect to time. The Arduino is sending a new angle to the app every 300 ms.

OK, i will do some research and report back with my attempt.

Oops you did indeed and the Clock Timer Block is correct.

That goes back to the shared channel I think, though you are having a lot of trouble with what is a fairly common set up that you will find across the Forum in bucket loads.

The disconnect should be detected immediately. There isn't more than one source of power or a capacitor in the mix? What we can do is to add a "get data attempts count". If there is no data after n cycles of the clock, assume the connection has failed.

There are other possibilities concerning a lack of data flowing to the App - firstly, the fact that HC-06 is receiving well does not mean it can send well. Ensure there is nothing in the vicinity of the robot, or a component of the robot, that can interfere with the BT signal (the motors for example). If you have an unused HC-06, try that one - re Patryk's comments, it is possible that the HC-06 is already damaged. I'm an expert at damaging electronics :innocent:

It's very important to keep everything cool. Incorporate a cooling fan into your design (simple DC PC case fans are good). How good are the sensors in terms of quality and reliability?

https://www.professorcad.co.uk/appinventortips#TipsBluetooth

I'm not sure what might still be causing this problem, but i think i found an error (probably unrelated) in the ListPicker1.AfterPicking block. There was a second ListPicker1.Elements block as well as in the ListPicker1.BeforePicking block. I replaced the first original block with the second block.

After looking again at the Arduino code, i think that it is not possible for data to be sent and received at the same time on the Serial channel, since the entire code is running in a loop. So, first, there is always a check done for any data received (command) from the app and then the sensor output data are printed out to be sent to the app for display.

Here is the current state of my app (click on the image to enlarge and see all the blocks). Every time i tried to incorporate the block "set Clock1.TimerEnabled false" somewhere, it ended up with some issues with not being able to read the sensor data.

The Arduino UNO setup is only powered via its USB port through a data cable connected to the PC. No added capacitors. Just a standard HC-06 module connected to the UNO along with a sensor.

There is no communication interference with the Arduino setup. I only have those few electronics turned on and it is right next to my phone. Motors are not connected at this point. I am using the onboard LED of the Arduino to simulate turning on or off the motors. I also tried another HC-06 and also an HC-05 module. Same results. The Arduino is not overheating. The room is also at a relatively cool temperature so i don't think that's the cause. The HC-06 is sending data as expected at 300ms interval from the Arduino and displayed without issues in the app, so i doubt that it's a fault in the HC-06 hardware.

I think the problem might be in the Clock1.Timer block. From my testing, while the app is connected to the Bluetooth module and everything is working in the app, if i simulate a disconnection error, by simply removing the USB cable, then the entire Arduino UNO turns off, but the app is unable to detect the disconnection. My phone uses Android 9 and it is unmodified and working with no issues.
btconnectdetect
After disconnection of power, the incoming sensor data label stays the same in the app and the status of the connection still shows "Connected". The Else condition in the Clock1.Timer block is therefore not being processed for some odd reason. The clock apparently still assumes that the Bluetooth client is still connected, or the BluetoothClient1.IsConnected block is still returning true. Maybe it's a bug in MIT App Inventor 2??

I have tried to come up with a solution, since it seems that for some reason the app and/or my phone is not detecting when the connection has failed.


I only changed the Clock1.Timer block. The label ErrorCount text is set to 0 in the Designer window. If there are 10 or more connection errors, then the status of the connection is set to Disconnected. The clock fires every 100 ms and data is sent from the Arduino every 300 ms, so i think 1 second should be enough to determine if the connection has been interrupted when no data is being received. But even when the connection is successful, no sensor data is received and no commands sent from the app are working. I don't understand why this change broke the app.

When the app connects, the Connection error count quickly increases from 0 to 10 and then the connection status shows Disconnected. During that time, there is no sensor data received in the Serial Data Stream.

I did a search and found this thread Change Text when Bluetooth disconnected so it seems like this problem is actually a limitation of Bluetooth and AI2. Although, there should be a workaround to make this work?

Do you mean you can't do that and so you are going to add software serial, or do you mean it won't happen because of the loops?

That's an issue - not actually getting enough power (I assume the motors do not have a seperate power supply?) See my website here:
https://www.professorcad.co.uk/appinventortips#TipsArduino

Ah, got my head twisted there - I thought the issue was receiving, not sending from the App, sorry.