The operation < cannot accept the arguments: , [["�"]], [80]

BLUETOOTH DATA RECEPTION ERROR WITH ARDUINO AND PULSE SENSOR!

HI! I dont know if this error is because i making something wrong with data rececption or a im made a bad program in app inventor :frowning:

im making an app for can see a cardio frequency value (this is sensed by a pulse sensor). i added can see the max frequency or min frequency (i can know the value if i put mi age and select woman or men, THIS NOT DEPEND OF THE SENSOR).

the problem is when i push bottom "body state" i can see the "min" and "max" frequency. but the value in labels "ACTUAL FC" and "CORPORAL STATUS" depend on the sensor. but the value isnt sended, i see a: "?" and the legend THE OPERATION CANNOT ACCEPT THE ARGUMENTS?, 80.

for the arduino code i usE the librarie "pulse sensor playground" from pulsesensor. For send the value i open de monitor serie of arduino and i can see the sensed values. But when i push the "enter" (keyboard) the value is send to screen of app inventor, but i see a "?"

can please someone help me?

links to images

APP INVENTOR SCREEN

APP INVENTOR CODE

THE ARDUINO CODE

`#define USE_ARDUINO_INTERRUPTS true // Set-up low-level interrupts for most acurate BPM math.
#include <PulseSensorPlayground.h> // Includes the PulseSensorPlayground Library.

// Variables
const int PulseWire = 0; // PulseSensor PURPLE WIRE connected to ANALOG PIN 0
const int LED13 = 13; // The on-board Arduino LED, close to PIN 13.
int Threshold = 550; // Determine which Signal to "count as a beat" and which to ignore.
// Use the "Gettting Started Project" to fine-tune Threshold Value beyond default setting.
// Otherwise leave the default "550" value.

PulseSensorPlayground pulseSensor; // Creates an instance of the PulseSensorPlayground object called "pulseSensor"

void setup() {

Serial.begin(9600); // For Serial Monitor

// Configure the PulseSensor object, by assigning our variables to it.
pulseSensor.analogInput(PulseWire);
pulseSensor.blinkOnPulse(LED13); //auto-magically blink Arduino's LED with heartbeat.
pulseSensor.setThreshold(Threshold);

// Double-check the "pulseSensor" object was created and "began" seeing a signal.
if (pulseSensor.begin()) {
Serial.println("We created a pulseSensor Object !"); //This prints one time at Arduino power-up, or on Arduino reset.
}
}

void loop() {

int myBPM = pulseSensor.getBeatsPerMinute(); // Calls function on our pulseSensor object that returns BPM as an "int".
// "myBPM" hold this BPM value now.

if (pulseSensor.sawStartOfBeat()) { // Constantly test to see if "a beat happened".

Serial.println(myBPM); // Print the value inside of myBPM.
}

delay(20); // considered best practice in a simple sketch.

}

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.

Also, check if a message is a number before trying to do a comparison (<) of the message against a number. Your starting announcement is not a number.

Hello Abi Miranda

I think ABG has covered most corners. However, This line in the Sketch:

That's not really true, especially so considering the purpose of your App. I think you should use elapsed milliseconds instead as this will give the best chance of a fast exchange of data - which is a little bit of a problem, because with the Sketch Loop running at 20 millis, the App Loop needs to run at max 15 millis which is not long at all to process the data. It could be an issue because the Clock Timers are based on Android System timers which are low priority. So you will need to use trial and error tests to get a smooth and reliable exchange of data. Another consideration is that the human eye cannot tolerate watching a value change so fast (15 millis). So you could consider redesigning your App to receive 60 values, take the average of those values and display that average every minute.

Your App Block Code is expecting to receive more than one value per data packet sent, but the Arduino is only sending one value per data packet, hence the List Error.

Example milliseconds elapsed:

//ArduinoToApp.ino  02/03/2021 02:38:48

//Fake data stream to demo elapased milliseconds timing


//vars
unsigned long lgUpdateTime;

void setup()
{
               Serial.begin(9600);
               lgUpdateTime = millis();
}

void loop()
{
	           if(millis() - lgUpdateTime > 19)           //Loop approx every 20 milliseconds
               {
                         lgUpdateTime = millis();

                         if (Serial.connected())
                         {
                                   //Bluetooth to App
                                   Serial.print("Hello");
                                   Serial.println();        //This last line tells App "End of Data" = Ascii LineFeed Char Number 10
                         }
               }
}

thanks ABG !!! I saw the tutorial and it helped me a lot! someone once told me that tx is with tx and rx with rx :x: !! Thanks!!

thankyou Chris!! now i can see values !! im made an error. i changed the value 4000 to 20! but i follow your steps :slight_smile: and now its better!!