Explore IOT Kit - Home Security Alarm - Undefined Reference to `onMessageChange()

I'm following the steps to complete the Home Security Alarm project from the Explore IOT Kit at https://explore-iot.arduino.cc/iotsk/module/iot-starter-kit/lesson/home-security-alarm. When I try to verify the code in the section titled "Gradually building code", I receive the error below.

/usr/local/bin/arduino-cli compile --fqbn arduino:samd:mkrwifi1010 --libraries /home/builder/opt/libraries/latest --build-cache-path /tmp --output-dir /tmp/668236519/build --build-path /tmp/arduino-build-B22E7D25C445DA4A4FD5F653EC977F14 /tmp/668236519/Untitled_jul24a

Using library SNU at version 1.0.2 in folder: /home/builder/.arduino15/packages/arduino/hardware/samd/1.8.12/libraries/SNU

Using library adafruit_sleepydog_library_1_6_1 at version 1.6.1 in folder: /home/builder/opt/libraries/adafruit_sleepydog_library_1_6_1

/tmp/arduino-build-B22E7D25C445DA4A4FD5F653EC977F14/sketch/objs.a(Untitled_jul24a.ino.cpp.o): In function `initProperties()':

/tmp/668236519/Untitled_jul24a/thingProperties.h:20: undefined reference to `onMessageChange()'

collect2: error: ld returned 1 exit status

Error during build: exit status 1

Any ideas on why this is happening?

1 Like

It looks like there's a mistake in the code you didn't post.

Understood. Below is the code that generates the error.

/*
  Sketch generated by the Arduino IoT Cloud Thing "EIoTK_Activity_05"
  https://create.arduino.cc/cloud/things/c32e4fe4-1356-4837-84d5-c20909211d99
 
  Arduino IoT Cloud Properties description
 
  The following variables are automatically generated and updated when changes are made to the Thing properties
 
  String message;
  bool alarm;
 
  Properties which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/
 
#include "thingProperties.h"
#include <Arduino_MKRIoTCarrier.h>
MKRIoTCarrier carrier;
 
int pir = A5;
bool pirState = LOW;
 
//Colors
uint32_t colorRed = carrier.leds.Color(0, 255, 0);   //RED
uint32_t colorGreen = carrier.leds.Color(255, 0, 0);  //GREEN
 
void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  pinMode(pir, INPUT);
 
  initProperties(); // defined in thingProperties.h
  
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  CARRIER_CASE = false;
  carrier.begin();
  
  setDebugMessageLevel(4);   //Get Cloud Info/errors , 0 (only errors) up to 4
  ArduinoCloud.printDebugInfo();
  
  while (ArduinoCloud.connected() != 1) {
    ArduinoCloud.update();
    carrier.display.setTextSize(3);
    carrier.display.setCursor(20, 70);
    carrier.display.println("Waiting For");
    carrier.display.setCursor(5, 110);
    carrier.display.println("Connection...");
    delay(500);
  }
}
 
void loop() {
  ArduinoCloud.update();
  // Your code here
 
  //reading the status of the PIR sensor
  pirState = digitalRead(pir);
 
  //checking if the PIR sensor has detected movement
  if (pirState == HIGH) {
    alarm = true;
  }
 
  //Dashboard check
  //when the alarm has not been triggered and it is off
  if (alarm == false) {
    carrier.display.fillScreen(ST77XX_BLACK);
    carrier.display.setCursor(30, 100);
    carrier.display.setTextSize(3);
    message = "Everything is good!";
    carrier.leds.fill((colorGreen), 0, 5);
    carrier.display.println(message);
    carrier.leds.show();
  }
 
  //When the alarm has been triggered and it is on
  //The alarm will be on until the user goes to cloud's dashboard to turn it off
  else {
    carrier.display.fillScreen(ST77XX_BLACK);
    carrier.display.setCursor(30, 100);
    carrier.display.setTextSize(2);
    message = "Warning! We have detected a person";
    carrier.leds.fill((colorRed), 0, 5);
    carrier.display.println(message);
    carrier.leds.show();
    //When motion is detected
  }
  
  Serial.println(pirState);
  delay(1000);
}
 
 
void onAlarmChange() {
  // Do something
}

It looks like a function named onMessageChange is declared in thingProperties.h. You probably have to define it in your sketch (or remove the declaration).

What happens when you add the following to your sketch?

void onMessageChange() {}

This worked. Thank you.

It looks like your thingProperties.h file is referencing onMessageChange() and you implemented the function onAlarmChange() instead. Go into the thingProperties.h file and change 'onMessageChange' to 'onAlarmChange`.

Background: In your thingProperties.h file there is a function 'initProperties()' which calls the function ArduinoCloud.addProperty() to add your property handlers. For example:

#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>

#define THING_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
#define BOARD_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

void onSwitchButtonChange();
void onColorChange();

bool switchButton;
CloudLocation location;
CloudColor color;

void initProperties() {
  ArduinoCloud.setThingId(THING_ID);
  ArduinoCloud.addProperty(switchButton, WRITE, ON_CHANGE, onSwitchButtonChange);
  ArduinoCloud.addProperty(location, READ, ON_CHANGE);
  ArduinoCloud.addProperty(color, READWRITE, ON_CHANGE, onColorChange);
}

  WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_SSID, SECRET_PASS);

Please mark the most helpful post as the solution, it prevents other people spending time on a solved issue.

Understood. Thank you.

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