how to get values from a function to void loop() ?

Hi all!

I have a question that might sound elementary to someone with coding experience but I'm still new to coding.

I'm using a feather huzzah esp8266 to send and receive data to/from adafruit IO website (IoT).
In their provided examples, they have a function onMessage() that receives data from website if any data is available. The argument for onMessage() is a function that will do what the user needs to do with the data, but does NOT return a value.

calib_test->onMessage(handleMessage2);
Here calib_test is the name of the feed where the data comes from and handleMessage2 is a function that prints the action and the value. (I dont understand the concept of the arrow ->)

And that is my problem right there. I'd like to be able to use the received number from the website to adjust other values that are being sent out (calibrating sensor data based on input from the website).

I would appreciate it if anyone could provide any help!

/************************ Adafruit IO Configuration *******************************/

// Adafruit info
#define IO_USERNAME    ""
#define IO_KEY         ""

/******************************* WIFI Configuration *******************************/

#define WIFI_SSID       ""
#define WIFI_PASS       ""

#include "AdafruitIO_WiFi.h"
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

/************************ Main Program Starts Here *******************************/
#include <ESP8266WiFi.h>          //related to IoT
#include <AdafruitIO.h>
#include <Adafruit_MQTT.h>
#include <ArduinoHttpClient.h>

#include <Arduino.h>              //related to sensor 
#include <Wire.h>
#include "Adafruit_SHT31.h"

/********************************************************************************/


// set up the feeds to adafruit io
AdafruitIO_Feed *hum_test   = io.feed("hum_test");
AdafruitIO_Feed *temp_test  = io.feed("temp_test");
AdafruitIO_Feed *led_test   = io.feed("led_test");
AdafruitIO_Feed *calib_test = io.feed("calib_test");

// initiating the sensor 
Adafruit_SHT31 sht31 = Adafruit_SHT31();

// initiating constatns 
unsigned long previousMillis = 0;           // used to count time in the loop
const long interval = 10000;                // sampling interval of sensor in milli seconds
int cal_val = 0;                            // calibration value

void setup() {

  // start the serial connection
  Serial.begin(115200);
  pinMode(0, OUTPUT);                     // red LED 
  pinMode(2, OUTPUT);                     // blue LED

  // connect to io.adafruit.com
  Serial.print("Connecting to Adafruit IO");
  io.connect();
  
  // set up a message handler for the 'temp_test' feed.
  // the handleMessage function (defined below)
  // will be called whenever a message is
  // received from adafruit io.
  led_test->onMessage(handleMessage);
  calib_test->onMessage(handleMessage2);
  
  // wait for a connection
  while(io.status() < AIO_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  // we are connected
  Serial.println();
  Serial.println(io.statusText());

  if (! sht31.begin(0x44)) {
    Serial.print("Could not find SHT31");
    while (1) delay(1);
  }
 
}

/********************************************************************************/

void loop() {

  // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
  io.run();

  // reading sensor info
  float t  = sht31.readTemperature();
  float h  = sht31.readHumidity() + cal_val;
  float hF = h * 1.8 + 32.0;                              // Celsius to Fahrenheit

  unsigned long currentMillis = millis();
  
  if (currentMillis - previousMillis >= interval) {
    digitalWrite(2, LOW);                                 //turning on blue LED
    previousMillis = currentMillis; 
  
    // printing and uploading sensor info to feeds on Adafruit
    Serial.println("Sending data -> ");
  
      if (! isnan(t)) {
      Serial.print("Temp *C = "); Serial.println(t);
      temp_test->save(t);
      } else {
      Serial.println("Failed to read Tempreture");
      }

      if (! isnan(h)) {
      Serial.print("Hum.  % = "); Serial.println(h);
      hum_test->save(h);
      } else {
      Serial.println("Failed to read Humidity");
      }

  Serial.println();
  //delay(5000);

} else {
  digitalWrite(2, HIGH);                                  //turning off blue LED 
}
}

/********************************************************************************/

// This function is called whenever a 'led_test' message
// is received from Adafruit IO. it is attached to
// the led_test feed in the setup() function above.

void handleMessage(AdafruitIO_Data *data) {

  digitalWrite(0, data->toPinLevel()); 
  int led_test = data->toInt(); 
  
    Serial.print("received LED value <- ");
    Serial.println(led_test);
    Serial.println();
 
}

/********************************************************************************/

// This function is called whenever a 'calib_test' message 
// is recieved from Adafruit IO. it is attached to 
// the calib_test feed in setup() function above.

void handleMessage2(AdafruitIO_Data *data2) {

  int cal_val = data2->toInt();
  Serial.print("received Calibration value <- ");
  Serial.println(cal_val);
  Serial.println();
  //return cal_val;
}

Here calib_test is the name of the feed where the data comes from and handleMessage2 is a function that prints the action and the value.

Or copies it to a global variable or...

I would appreciate it if anyone could provide any help!

There's a hint above. If you need more, a clue-by-four will be used.

jsafavi:
calib_test->onMessage(handleMessage2);
Here calib_test is the name of the feed where the data comes from and handleMessage2 is a function that prints the action and the value. (I dont understand the concept of the arrow ->)

calib_test is the name of a pointer to a feed. If you don't already know what pointers are, start searching Google for references right now because they're one of the first major stumbling blocks for new C/C++ programmers.

Don't read the next paragraph unless you have at least a basic understanding of pointers.

A pointer must be dereferenced. Normally this is done with the * symbol, but in the case where the pointer is to an object it's a bit ugly to use that to get object members. The member operator (.) has higher precedence than dereferencing (*), so if you do *calib_test.onMessage() it will try to do the onMessage first, and the compiler will complain. You can add parentheses to force the correct order: (*calib_test).onMessage(). That's ugly though.

-> is used as the pointer-to-member operator. It dereferences the left-hand pointer before getting the specified member. calib_test->onMessage is equivalent to (*calib_test).onMessage().