Main Content

ThingSpeak Dashboard for Live RUL Estimation of a Servo Motor Gear Train

This example shows how to setup a ThingSpeak™ dashboard to estimate and visualize the Remaining Useful Life (RUL) of a servo motor gear train. A ThingSpeak dashboard consists of a ThingSpeak channel set up with relevant data streams and MATLAB analysis scripts. The MATLAB scripts run real-time in ThingSpeak.

For this example, a set of synthetic motor current signal data is generated that is used to visualize and predict the RUL of the gear train inside the servo. Motor current signature analysis (MCSA) of the current signal driving a hobby servo motor is used to extract frequency-domain (spectral) features from several frequency regions of interest indicative of motor and gear train faults. A single feature or a combination of features are used construct a Health Indicator (HI) for subsequent RUL estimation. MCSA is a useful method for the diagnosis of faults that induce torque or speed fluctuations in the servo gear train, which in turn result in correlated motor current changes. MCSA has been proven to be ideal for motor fault analysis as only the motor current signal is required for analysis, which eliminates the need for additional and expensive sensing hardware. Gear fault detection using traditional vibration sensors is challenging, especially in cases where the gear train is not easily accessible for instrumentation with accelerometers or other vibration sensors.

For more information about the data stream and hardware setup, see Motor Current Signature Analysis for Gear Train Fault Detection and Live RUL Estimation of a Servo Gear Train Using ThingSpeak.

The simplified workflow to estimate and display the RUL of the servo motor gear train includes the following steps:

  1. Set up ThingSpeak dashboard

  2. Periodically generate servo gear train features

  3. Estimate the RUL as the features are generated

  4. Setup RUL alert in ThingSpeak

Dashboard Setup

The first step of creating a dashboard is to setup a ThingSpeak channel with the appropriate channel IDs to stream, analyze and display the data. You can then create relevant MATLAB Analysis scripts as described in the successive sections in this example. For more information on setting up a ThingSpeak channel and to stream your data, see Configure Accounts and Channels (ThingSpeak) and Live RUL Estimation of a Servo Gear Train Using ThingSpeak.

For this example, channel 1558487 was created to run, analyze and display the RUL of the synthetic servo motor data. Run the following command to access this dashboard.

web('https://thingspeak.com/channels/1558487')

dashboard.PNG

ThingSpeak Dashboard - Remaining Useful Life Estimation

Since this example requires the model state to be stored between evaluations, change the Metadata setting of the channel based on the RUL model for this example. You normally do not need to change the Metadata setting when setting up your own ThingSpeak channel.

For this example, assume that an ExponentialDegradationModel was trained with historical data using the fit command. The fit command estimates a prior for the model's parameters based on the historical records in training data. The Prior property of the trained model contains the estimated model parameters Theta, Beta, Rho, etc. For details of these model parameters, see exponentialDegradationModel.

Extract the model's prior from the fitted exponential degradation model and add any fixed parameters (e.g., Phi) as part of the state structure. See the example Update RUL Prediction as Data Arrives for using the fit method to initialize model parameters from training (historical) data.

mdl = exponentialDegradationModel;
state = mdl.Prior;
state.Phi = 0.6931;

For this example, assume that the model parameter priors are set as follows:

state = struct( ...
  'Theta', 0.2790, ...
  'ThetaVariance', 0.0102, ...
  'Beta', 0.1686, ...
  'BetaVariance', 6.5073e-04, ...
  'Rho', -0.9863, ...
  'Phi', 0.6931);

Convert the state structure to a string representation so that you can manually copy it to the channel's Metadata setting.

state = jsonencode(state);

Manually save the resulting model state string into the Metadata setting of the channel:

Generate Synthetic Servo Motor Features

For this example, the next step is to generate synthetic servo motor features and save the values to the ThingSpeak channel as separate fields. For your use case, you can use feature values from a Cloud source or compute them from real-time hardware streaming data.

The synthetic motor signal data being generated in this example utilizes the servo motor and gear train specifications listed below. The servo consists of four pairs of meshing nylon gears as illustrated in the figure below. The pinion P1 on the DC motor shaft meshes with the stepped gear G1. The pinion P2 is a molded part of the stepped gear G1 and meshes with the stepped gear G2. The pinion P3, which is a molded part of gear G2, meshes with the stepped gear G3. Pinion P4, which is molded with G3, meshes with the final gear G4 that is attached to the output shaft. The stepped gear sets G1 and P2, G2 and P3, and G3 and P4 are free spinning gears − that is, they are not fixed to their respective shafts. The set of gears provides a 278:1 reduction going from a motor speed of about 6117 rpm to about 22 rpm at the output shaft when the DC motor is driven at 5 volts.

For more information about the hardware model, see Live RUL Estimation of a Servo Gear Train Using ThingSpeak.

servoExample5.png

The following table outlines the tooth count and theoretical values of output speed, gear mesh frequencies, and cumulative gear reduction at each gear mesh.

sourceServoSpecTable-01.png

The ThingSpeak dashboard for this example uses the following three MATLAB Analysis scripts:

  • Generate Synthetic Servo Motor Features

  • Calculate Remaining Useful Life Estimate

  • Send RUL Alert

You can use the MATLAB Analysis App to explore and analyze the data stored in your ThingSpeak channel. For more information, see MATLAB Analysis App (ThingSpeak).

You can find the above MATLAB scripts associated with channel 1558487 in the current directory of this example.

The following MATLAB Analysis App (ThingSpeak) code is associated with the Generate Synthetic Servo Motor Features script. Use TimeControl App (ThingSpeak) to run the script every 5 minutes to trigger the computation of new servo motor features from available or synthetic data. The Generate Synthetic Servo Motor Features script is associated with a TimeControl configured as follows:

timecontrol_settings.PNG

The contents of the Generate Synthetic Servo Motor Features script are as follows:

Simulate time-domain motor features

For the servo motor used in the example, the motor winding current fluctuates between 308 mA and 320 mA, and the speed fluctuates between 20 rpm and 23 rpm.

motorCurrent = 308 + 12*rand(1);
rpm = 20 + 3*rand(1);

Simulate frequency domain features of the motor current

The power spectrum amplitudes at motor shaft frequencies (1xFS1 and 2xFS1) and the total band power are simulated as follows:

Input the parameters to simulate complete degradation of the servo motor over the course of a full day.

dStart = dateshift(datetime, "start", "day");
dNow = datetime;
dayScale = seconds(dNow - dStart) / (24*3600);

Peak power spectrum amplitude at the first harmonic of the motor shaft frequency (1xFS1) changes linearly between -30 dB and 10 dB as degradation increases. Add white noise to simulate more realistic sensor data. For more information about the frequencies, see Live RUL Estimation of a Servo Gear Train Using ThingSpeak.

peak1FS1 = -30 + (10+30)*dayScale + randn(1);

Peak power spectrum amplitude at the second harmonic of the motor shaft frequency (2xFS1) changes linearly between -20 dB and 0 dB as degradation increases. Add white noise to simulate more realistic sensor data.

peak2FS1 = -20 + (0+20)*dayScale + randn(1);

Total band power of the motor current changes exponentially between 1 and 13 as degradation increases and failure is assumed to occur at the threshold value 13. Add white noise to simulate more realistic sensor data. Use the band power as the health index for RUL estimations.

phi = 0.5;
theta = 0.5;
threshold = 13;
beta = log((threshold-phi) / theta);
bandPower = phi + theta * exp(beta*dayScale + randn(1)/10);

Configure the Channel ID and the Write API Key values

Replace the [] with channel ID to write data to your ThingSpeak dashboard:

writeChannelID = [];

Enter the Write API Key between the quotes:

writeAPIKey = '';

Write the features to the channel specified by the writeChannelID variable.

features = [peak1FS1, peak2FS1, bandPower, motorCurrent, rpm];
fields = 1:numel(features);
thingSpeakWrite(writeChannelID, features, 'Fields', fields, 'WriteKey', writeAPIKey);

The features will be displayed in the fields 1-5 of your ThingSpeak channel:

`

Total Band Power Chart

Calculate Remaining Useful Life Estimate

Next, setup a MATLAB Analysis App (ThingSpeak) script that calculates the remaining useful life of the servo motor using the total band power of the motor current as the health indicator. The script also saves the RUL estimate to the ThingSpeak channel in the field Remaining Useful Life (hr).

The following MATLAB Analysis App (ThingSpeak) code is associated with the Calculate Remaining Useful Life Estimate script. Use the React App (ThingSpeak) control that runs whenever a new, valid feature value is added to the Total Band Power field of your channel.

rul_react_settings.PNG

Configure the channel ID and then read the API key values

Replace the [] with channel ID to read data from your ThingSpeak channel.

readChannelID = [];

If your channel is private, then enter the Read API Key between the quotes.

readAPIKey = '';

For this example, the Total Band Power feature is stored in field 3 of the channel.

fieldID = 3;

Read the data since the last servo motor replacement

For the example, we assume that the servo motor fails and is replaced every 24 hours at 12:00 AM.

dStart = dateshift(datetime, "start", "day");
dNow = datetime;
range = [dStart, dNow];

Read feature data and remove any invalid or empty values.

data = thingSpeakRead(readChannelID, 'Fields', fieldID, ...
  'ReadKey', readAPIKey, 'DateRange', range, 'OutputFormat', 'timetable');
data = rmmissing(data);

Return if there is no valid data available, for example, right after the servo motor was replaced.

if isempty(data)
  return;
end

Construct the exponential degradation model

Use the Total Band Power as the health index and compute the current RUL estimate of the servo motor. Reload from channel Metadata setting the initial state of the model parameters obtained from fitting historical data to the degradation model. Use the prior parameters to initialize the degradation model before estimating a new RUL value from available data.

state = loadModelState();
mdl = exponentialDegradationModel( ...
  'Theta', state.Theta, ...
  'ThetaVariance', state.ThetaVariance, ...
  'Beta', state.Beta, ...
  'BetaVariance', state.BetaVariance, ...
  'Phi', state.Phi, ...
  'Rho', state.Rho, ...
  'NoiseVariance', 0.1, ...
  'SlopeDetectionLevel', [], ...
  'LifeTimeVariable', data.Properties.DimensionNames{1}, ...
  'LifeTimeUnit', "hours", ...
  'DataVariables', data.Properties.VariableNames{1});

Set RUL degradation threshold for the health index (Total Band Power).

threshold = 13;

The data here is not historical data, but rather recent real-time observations of the servo motor features recorded in the fields of the ThingSpeak channel.

Update the degradation model using available feature values since the servo motor was last replaced. Then, compute the current RUL estimate based on the failure threshold.

update(mdl, data)
rul = hours(predictRUL(mdl, threshold));

Configure the Channel ID and the Write API Key values

Replace the [] with channel ID to write data to your ThingSpeak channel.

writeChannelID = [];

Enter the Write API Key between the quotes.

writeAPIKey = '';

Write the updated RUL estimate to the channel specified by the writeChannelID variable. For this example, the RUL estimate value is stored in field 6 of the ThingSpeak channel.

fieldID = 6;
thingSpeakWrite(writeChannelID, rul, 'Fields', fieldID, 'WriteKey', writeAPIKey);

Field 6 of the channel tracks the RUL estimates for the servo motor:

field6.PNG

RUL Estimate Chart

Add a Field Value Gauge widget to display the current RUL estimate. For more information, see Channel Display Widgets (ThingSpeak).

RUL Estimate Gauge

Send RUL Alert

You can also setup a MATLAB Analysis App (ThingSpeak) script to send an RUL status alert to the channel about the impending servo failure.

The following MATLAB Analysis App (ThingSpeak) code is associated with the Send RUL Alert script. Use React App (ThingSpeak) control to send a text message alert (as a status update in the channel) every 10 minutes while the current RUL estimate for an impending failure is determined to be less than 4 hours. If the RUL estimate is less than 8 hours, a warning message is displayed.

rulAlert_react_settings.PNG

Configure the Channel ID value

Replace the [] with channel ID to read data from your ThingSpeak channel.

readChannelID = 1558487;

In this example, the RUL estimate is stored in field 6 of the channel.

fieldID = 6;

Read recent RUL estimates and remove any invalid or empty values.

data = thingSpeakRead(readChannelID, 'Fields', fieldID, 'NumPoints', 10, ...
  'OutputFormat', 'timetable');
data = rmmissing(data);

Configure the Write API Key value

Enter the Write API Key value between the quotes:

writeAPIKey = '';

Post status update message to your ThingSpeak channel.

url = sprintf('https://api.thingspeak.com/update.json');
if data.RemainingUsefulLifehr(end) <= 4 
  msg = sprintf("ALERT: %3.1f hours to failure detected at %s", ...
    data.RemainingUsefulLifehr(end), string(datetime));
elseif data.RemainingUsefulLifehr(end) <= 8
  msg = sprintf("WARNING: %3.1f hours to failure detected at %s", ...
    data.RemainingUsefulLifehr(end), string(datetime));
else
  msg = sprintf("HEALTHY: More than %3.0f hours to failure as of %s", ...
    data.RemainingUsefulLifehr(end), string(datetime));
end

try
  webwrite(url, 'api_key', writeAPIKey, 'status', msg);
catch E
  fprintf("Failed to send alert:\n %s\n", E.message);
end

Any alerts for a pending failure are shown in the Channel Status Updates view:

status_new.png

Channel Status Update Window

This functionality can be replaced with code to send text messages, emails, or Twitter updates instead. For more information, see ThingTweet App (ThingSpeak) and ThingHTTP App (ThingSpeak).

Alternatively, use the following code to send an email alert. For more information and an example, see Alerts API (ThingSpeak) and Analyze Channel Data to Send Email Notification (ThingSpeak)

sendAlertEmail(data.RemainingUsefulLifehr(end));

Email Alert Message

Supporting Functions

The loadModelState function loads the model state (i.e., the prior for the model parameters) from the Metadata setting of the channel and converts it to a MATLAB variable (struct). You can access the following MATLAB scripts in the working directory of this example.

function state = loadModelState()
% Configure the Channel ID.
% Replace the [] with channel ID to read data from:
readChannelID = [];

% Read the stored RUL model initialization state from the Metadata field of the
% channel specified by the 'readChannelID' variable.
url = sprintf('https://api.thingspeak.com/channels/%d/feeds.json', readChannelID);
response = webread(url, 'metadata', 'true', 'status', 'true', 'results', 30);

state = jsondecode(response.channel.metadata);
end

The sendALertEmail function sends an alert email indicating the estimated RUL value.

function sendAlertEmail(rul)
alertMessage = sprintf("ALERT: %3.1f hours to failure detected.", rul);
alertSubject = sprintf("Pending servo motor failure");

% Configure the Alert API Key value.
% Enter the Alert API Key between the quotes below:
alertAPIKey = '';
options = weboptions("HeaderFields", ["ThingSpeak-Alerts-API-Key", alertAPIKey ]);

alertURL = "https://api.thingspeak.com/alerts/send";
try
  webwrite(alertURL, "body", alertMessage, "subject", alertSubject, options);
catch E
  fprintf("Failed to send alert:\n %s\n", E.message);
end
end

See Also

| | | | | (ThingSpeak) | (ThingSpeak) | (ThingSpeak) | (ThingSpeak) | (ThingSpeak)

Related Topics