How to make a Alert when a motor gets disconnected

You are starting along the right lines, but it’s going to get a bit more complicated than that.

The checking for a motor being installed needs to be inside a while loop. So as not to interfere with other drive or auton code, it’s probably best to run this in a separate thread. You need to consider that the bandwidth for sending messages to the controller is small, so try and limit how often you send a message, best to just send when the message needs to change rather than constantly. The V5 will not detect an unplugged motor until it has been lost for 1 second, a motor unplugged for a short time and replugged will simply be reinitialized and continue working. So here is a first crude example. It only monitors two motors by name, but could be extended to others. It only detects one disconnect and then stops checking, other logic could be added to improve upon this.

example_1
/*----------------------------------------------------------------------------*/
/*                                                                            */
/*    Module:       main.cpp                                                  */
/*    Author:       james                                                     */
/*    Created:      1/9/2024, 2:10:08 PM                                      */
/*    Description:  V5 project                                                */
/*                                                                            */
/*----------------------------------------------------------------------------*/
#include "vex.h"

using namespace vex;

// A global instance of vex::brain used for printing to the V5 brain screen
vex::brain       Brain;
vex::controller  c1;

// define your global instances of motors and other devices here
vex::motor       m1(PORT16);
vex::motor       m2(PORT17);

int
motorMonitor() {
    bool bDisconnected = false;
    int  portIndex;

    while(1) {
      // only detect first disconnect
      if( !bDisconnected ) {
        // crude, just check each known motor
        if( !m1.installed() ) {
          bDisconnected = true;
          portIndex = m1.index();
        }
        else
        if( !m2.installed() ) {
          bDisconnected = true;
          portIndex = m2.index();
        }

        if( bDisconnected ) {
          c1.Screen.setCursor( 1, 1 );
          c1.Screen.print( "Disconnect");
          c1.Screen.setCursor( 2, 1 );
          c1.Screen.print( "Port %d", portIndex + 1);
        }
      }


      this_thread::sleep_for(100);
    }
}


int main() {
    thread t1(motorMonitor);
   
    while(1) {        
        // Allow other tasks to run
        this_thread::sleep_for(10);
    }
}

A more generic approach would look for any disconnected device and not need to know the type or port number used. Here is an updated monitor thread that looks for any device being unplugged, more complicated and uses APIs that VEXcode generally does not document.

example_2

int
motorMonitor() {
    bool    bIsOk = true;

    V5_DeviceType   types[V5_MAX_DEVICE_PORTS] = {kDeviceTypeNoSensor};

    // learn what is connected initially
    for( int port=PORT1;port<=PORT21;port++) {
      vex::device  dev(port);
      types[port] = dev.type();
    }

    while(1) {
      int notConnected = 0;

      // for all ports on the brain
      for( int port=PORT1;port<=PORT21;port++) {
          // A temporary device of any type
          vex::device  dev(port);
          // do we expect a device on this port
          if( types[port] != kDeviceTypeNoSensor ) {
            // still connected ? 
            if( !dev.installed() ) {
              // no, increase count of disconnected devices.
              notConnected++;
            }
          }
      }

      // display when going from ok to bad
      if( notConnected & bIsOk) {
        c1.Screen.clearLine(3);
        c1.Screen.print( "Disconnected %d", notConnected );
        bIsOk = false;
      }

      // display when going from bad to ok
      if( !notConnected & !bIsOk) {
        c1.Screen.clearLine(3);
        c1.Screen.print( "All Ok");
        bIsOk = true;
      }

      this_thread::sleep_for(100);
    }
}
5 Likes