Seth
Published

C++, Servo Motors, Teknic. com, and the BBB

Did you want a high performance set of instrumentation/machinery via USB from your BeagleBone Black Rev. C along w/ a compiled C++ SDK?

BeginnerProtip1 hour1,248
C++, Servo Motors, Teknic. com, and the BBB

Things used in this project

Hardware components

BeagleBone Black
BeagleBoard.org BeagleBone Black
×1
Power4-Hub
×1
Servo Motor 75vdc
×1
COM Hub
×1
24vdc Power Supply
×1
IPC-5
×1
Misc. Cables
×1

Software apps and online services

Teknic SDK
BeagleBoard.org Debian Buster from BBB.io/latest-images

Hand tools and fabrication machines

Marker

Story

Read more

Code

Homing from their SDK and all from the BBB

C/C++
Here it is...
//*****************************************************************************
// $Archive: /ClearPath SC/Installer/Program Files/Teknic/ClearView/sdk/examples/4b-Example-Homing/Example-Homing.cpp $
// $Revision: 2 $ $Date: 12/09/16 12:23p $
// $Workfile: Example-Homing.cpp $
//*****************************************************************************
//Required include files
#include <stdio.h>  
#include <string>
#include "pubSysCls.h"  
using namespace sFnd;
//*********************************************************************************
//This program will load configuration files onto each node connected to the port, then executes
//sequential repeated moves on each axis.
//*********************************************************************************
#define PORT_NUM            9       //The port's COM number (as seen in device manager)
#define CHANGE_NUMBER_SPACE 2000    //The change to the numberspace after homing (cnts)
#define TIME_TILL_TIMEOUT   10000   //The timeout used for homing(ms)
int main(int argc, char* argv[])
{
                                                //Create the SysManager object.  This will object will coordinate actions among various ports,
                                                // and within nodes.  In this example we use this object to setup and open our port.
    SysManager myMgr;                           //Create System Manager myMgr
    printf("Hello World, I am SysManager\n");   //Print to console
    printf("\n I will now open port \t%i \n \n", PORT_NUM);
    //This will try to open the port.  If there is an error/exception during the port opening
    //the code will jump to the catch loop where detailed information regarding the error will be displayed,
    //otherwise the catch loop is skipped over
    try
    {
        myMgr.ComHubPort(0, PORT_NUM);  //define the first SC Hub port (port 0) to be associated with COM 
                                        //PORT_NUM  (as seen in device manager)
        myMgr.PortsOpen(1);             //Open the first port.
    }
    catch (mnErr theErr)    //This catch statement will intercept any error from the Class library
    {
        printf("Port Failed to open, shutting down\n");
        //This statement will print the address of the error, the error code (defined by the mnErr class), 
        //as well as the corresponding error message.
        printf("Caught error: addr=%d, err=0x%08x\nmsg=%s\n", theErr.TheAddr, theErr.ErrorCode, theErr.ErrorMsg);
        ::system("pause"); //pause so the user can see the error message; waits for user to press a key
        return 0;  //This terminates the main program
    }
    //Once the code gets past this point, it can be assumed that the Port has been opened without issue
    //Now we can get a reference to our port object which we will use to access the node 
    IPort &myPort = myMgr.Ports(0);     //set the reference myPort to refer to port 0 
    //Here we identify the first Node, enable and home the node, then adjust the position reference
    
    try {
            // Create a shortcut reference for the first node
            INode &theNode = myPort.Nodes(0);
            theNode.EnableReq(false);               //Ensure Node is disabled before starting
            
            printf("   Node[0]: type=%d\n", theNode.Info.NodeType());
            printf("            userID: %s\n", theNode.Info.UserID.Value());
            printf("        FW version: %s\n", theNode.Info.FirmwareVersion.Value());
            printf("          Serial #: %d\n", theNode.Info.SerialNumber.Value());
            printf("             Model: %s\n", theNode.Info.Model.Value());
            //The following statements will attempt to enable the node.  First,
            // any shutdowns or NodeStops are cleared, finally the node in enabled
            theNode.Status.AlertsClear();                   //Clear Alerts on node 
            theNode.Motion.NodeStopClear(); //Clear Nodestops on Node               
            theNode.EnableReq(true);                    //Enable node 
            double timeout = myMgr.TimeStampMsec() + TIME_TILL_TIMEOUT; //define a timeout in case the node is unable to enable
                                                                        //This will loop checking on the Real time values of the node's Ready status
            while (!theNode.Motion.IsReady()) {
                if (myMgr.TimeStampMsec() > timeout) {
                    printf("Error: Timed out waiting for Node 0 to enable\n");
                    return -2;
                }
            }
            //At this point the Node is enabled, and we will now check to see if the Node has been homed
            //Check the Node to see if it has already been homed, 
            if (theNode.Motion.Homing.WasHomed())
            {
                printf("Node has already been homed, current position is: \t%8.0f \n", theNode.Motion.PosnMeasured.Value());
                printf("Rehoming Node... \n");
            }
            else
            {
                printf("Node has not been homed.  Homing Node now...\n");
            }
            //Now we will home the Node
            theNode.Motion.Homing.Initiate();
            timeout = myMgr.TimeStampMsec() + TIME_TILL_TIMEOUT;            //define a timeout longer than the longest time possible for the mechanics to reach the homing target
            //This will loop checking on the Real time values of the node's Homing active status
            while (theNode.Motion.Homing.IsHoming() && myMgr.TimeStampMsec() < timeout)
            {
                myMgr.Delay(1);
            }
            //Check to make sure we've homed
            if (theNode.Motion.Homing.WasHomed())
            {
                theNode.Motion.PosnMeasured.Refresh();      //Refresh our current measured position
                printf("Node completed homing, current position: \t%8.0f \n", theNode.Motion.PosnMeasured.Value());
                printf("Soft limits now active\n");
                
            }
            else
            {
                printf("Node did not complete homing:  \n\t -Ensure Homing settings have been defined through ClearView. \n\t -Check for alerts/Shutdowns \n\t -Ensure timeout is longer than the longest possible homing move.\n");
                ::system("pause");
                    return -2;
            }
            //Printing soft limits
            printf("Soft Limit 1 = %d \n ", (int)theNode.Limits.SoftLimit1);
            printf("Soft Limit 2 = %d \n ", (int)theNode.Limits.SoftLimit2);
            printf("Adjusting Numberspace by %d\n", CHANGE_NUMBER_SPACE);
            theNode.Motion.AddToPosition(CHANGE_NUMBER_SPACE);          //Now the node is no longer considered "homed, and soft limits are turned off
            theNode.Motion.Homing.SignalComplete();     //reset the Node's "sense of home" soft limits (unchanged) are now active again
            theNode.Motion.PosnMeasured.Refresh();      //Refresh our current measured position
            printf("Numberspace changed, current position: \t%8.0f \n", theNode.Motion.PosnMeasured.Value());
            printf("Soft Limit 1 = %d \n ", (int)theNode.Limits.SoftLimit1);
            printf("Soft Limit 2 = %d \n ", (int)theNode.Limits.SoftLimit2);
            printf("Disabling Node");
            theNode.EnableReq(false);
        }
    catch (mnErr theErr)
    {
        //This statement will print the address of the error, the error code (defined by the mnErr class), 
        //as well as the corresponding error message.
        printf("Caught error: addr=%d, err=0x%08x\nmsg=%s\n", theErr.TheAddr, theErr.ErrorCode, theErr.ErrorMsg);
        ::system("pause"); //pause so the user can see the error message; waits for user to press a key
        return 0;  //This terminates the main program
    }
        
    // Close down the ports
    myMgr.PortsClose();
    ::system("pause"); //pause so the user can see the program output; waits for user to press a key
    return 0;           //End program

Credits

Seth

Seth

32 projects • 12 followers
Stay there and someone will find you...

Comments