How to make a Alert when a motor gets disconnected

Hello, I was wondering if there was any way to show a display on the controller of what motor got unplugged when a motor gets disconnected. I am using Vexcode Pro V5 C++.

I havent used c++ much but i have done some things with displays and it is possible to display an image or message on the controller screen so i would advice using something that can detect the brain and if something changes on it (such as the brain screen change to red yellow or orange) it then would broadcast a message to the controller which displays a message of your choice on it again i havent used C++ much so i hope this helps

Thank you, would you have an idea on how to mirror the brain to the controller in code because that is the part I am stuck on?

no images on the controller, only text.

yea, there’s no (official) way to detect the brain screen going orange.

What you need to do is.

create a new task
in a loop, monitor the ā€œinstalled()ā€ status of devices, there’s more than one way to do this but the crudest is simply to use something like (if m1 is a motor).

m1.installed();

if that returns false, and you know it should be true, then send a message to the controller using controller.Screen.print.

have a go yourself but, if I have time, I’ll post a simple example tomorrow.

6 Likes

Thank you
(20 characters)

1 Like

ty you for correcting me and as i said i dont know much about C++

1 Like

How would you create and / or implement a task in vexcode?

I tried this but this nothing showed up on the controller screen when I unplugged the motor. m5 is the motor. Do you know anyway to fix it?

if(m5.installed()) {

}

else {
Controller1.Screen.print(ā€œm5 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

Thank you.
(20 chara)

1 Like

When I tested the code in example one it said ā€œRedefinition of ā€˜main’ (137,5)ā€ in problems. Would you know why it says that, and how to fix it?

Well, it was a standalone example not intended to be added to an existing program. If you did that then you probably ended up with two ā€œmainā€ functions.

2 Likes

Ok. Also I was wondering if there was anyway or if you could tell me what the word "dev " is and what it means and its purpose? In example 2.

I’ll explain tomorrow.

3 Likes

Oh I just realized what dev was its device I didn’t see that my bad. But what is bIsOk supposed to represent or mean?

I’ll explain some of the second example.

int
motorMonitor() {
    bool    bIsOk = true;

motorMonitor will be run as a thread and never exit. bIsOk is a variable (a boolean) used to remember if we sent a ā€œDisconnectedā€ or a ā€œAll Okā€ message to the controller screen.

Often I use what’s known as Hungarian notation for variables, not always, but it’s useful for keeping track of what the type of variable is. That why bIsOk starts with a ā€˜b’.

    V5_DeviceType   types[V5_MAX_DEVICE_PORTS] = {kDeviceTypeNoSensor};

This is an array that used to store the initial type of the device/sensor on each port.

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

This initializes the array.
A vex::device is the base class for all other devices. A vex::motor is a subclass of vex::device. We can create an instance of vex::device for any port and then use that to check the 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++;
            }
          }
      }

this part of the while loop checks each port for a disconnected device. It creates an instance of vex::device for the port, checks the initial type array to see if we expect to detect something, then checks the installed status for that port. installed() will return true if any type of device is connected and false if nothing is connected. We increment the variable notConnected for every port we find that has a disconnected device.

      // 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);
    }

The second part of the while loop decides what, if anything, to send to the controller.

If notConnected is set and bIsOk is true we send the ā€œDisconnectedā€ message and then set bIsOk to false.

If notConnected is zero and bIsOk is false, we send the ā€œAll Okā€ message and set bIsOk back to true.

3 Likes

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