Meshed Motor Monitoring

Authors:

Carter Floyd, Vladislav Markov, Shawn Hobbs


Project Overview

The Meshed Motor Monitoring system provides a comprehensive solution for monitoring multiple DC motors and reporting statistics to a main database by wireless communication. A GUI is provided for status data visualisation of one motor for demo purposes, which could be expanded to as many data streams as needed. Other advantages include computations at the sensor level on the embedded system, so only useful statistics are reported instead of all measured values.


Components:

  • Arm Mbed LPC1768 (Cortex-M3)
  • Xbee Radio Module (Series 1)
  • ACS712 Current Sensor
  • MH-Electronic Voltage Sensor
  • Piezoelectric Vibration Sensor
  • TMP36GZ Temperature Sensor
  • 5V DC Motor
  • 3.3V DC Motor

Wiring and Setup

Four analog sensors monitor current, voltage, temperature and vibration levels. The data is reported to two XBee modules, referred to as Routers. This incoming data stream is then wirelessly routed via RF communication to a third Xbee module, referred to as a Coordinator. The Coordinator bridges the gap between the sensors and the Mbed where the data is processed, serving as a wireless mediator. A USB connection from the Mbed to a PC provides the necessary connection for Serial communication.

Xbee Radio Module

MbedXbee (Coordinator)
VOUTVCC (p1)
GNDGND (p10)
p8RTS (p16)
p9DOUT (p2)
p10DIN (p3)

ACS712 Current Sensor

ACS712Xbee (Router)3.3V DC Motor
VCC (p8)VCC (p1)
GND (p5)GND (p10)
IP+ (p1)v-
IP- (p3)GND (p10)
VIOUT (p7)AD2 (p18)

MH-Electronic Voltage Sensor

MH-ElectronicXbee (Router)3.3V DC Motor
VCCVCC (p1)
GNDGND (p10)
+v+
-v-
SAD1(p19)

Piezoelectric Vibration Sensor

PiezolectricXbee (Router)
VCCVCC (p1)
GNDGND (p10)
SAD3 (p17)

TMP36GZ Temperature Sensor

TMP36GZXbee(Router)
VOUT (p2)VCC (p1)
GND (p3)GND (p10)
+VS (p1)AD0 (p20)

Software Program

C++ source code , as well as a fully importable library, is provided for integrating the software, hardware, and GUI.

main.cpp

#include "mbed.h"
#include "monitor.h"

Serial pc(USBTX, USBRX);
Serial coordinator(p9, p10);

xbee nodes[DEVS];
//globals
float data[DEVS][4][SAMPLES]; //array to hold all of the data for averaging
float avgs[DEVS][4];  //array to hold averages
uint16_t source; //source id of the node sending data 
//most and least significant bytes of data
uint8_t MSB;
uint8_t LSB;
int num_samples = 0;
//functions 
void check_nodes();
void average();
uint8_t error_check();

int main() 
{
    //loop instantiates and ids all of the nodes in the network
    for(int i=0; i<DEVS; i++)
        nodes[i].id = i+1;
    
    //loop continually checks for data from the nodes
    while(1) {
        check_nodes();
        if(num_samples==SAMPLES){
            average();
            if(error_check()){
                //do something
            }
            num_samples = 0;
            //wait(1);
        }
        num_samples++;          
    }
}

//retrieves a data packet and parses it, then calls the functions to calculate 
//the data
void check_nodes(){
    //check for the begining of the packet
    if(coordinator.readable() && coordinator.getc()==0x7E){
        //discard unecessary bytes from the packet
        coordinator.getc(); //payload length is 2 bytes
        coordinator.getc(); //this is always a constant so it is uneccesary
        coordinator.getc(); //packet type (packets are always data type)
        coordinator.getc();
        //find the source node (-1 to adjust for indexing as coordinator
        //is always node 0
        
        source = coordinator.getc() - 1;
        //discard more unecesary bytes
        for(int i=0; i<5; i++)
            coordinator.getc();
        
        //temperature
        MSB = coordinator.getc();
        LSB = coordinator.getc();
        nodes[source].temp = get_temp(MSB, LSB);
        data[source][0][num_samples] = nodes[source].temp;
        
        //voltage
        MSB = coordinator.getc();
        LSB = coordinator.getc();
        nodes[source].volt = get_volt(MSB, LSB);
        data[source][1][num_samples] = nodes[source].volt;
        
        //current
        MSB = coordinator.getc();
        LSB = coordinator.getc();
        nodes[source].amps = get_amps(MSB, LSB);
        data[source][2][num_samples] = nodes[source].amps;
        
        //vibrations
        MSB = coordinator.getc();
        LSB = coordinator.getc();
        nodes[source].vibs = get_vibs(MSB, LSB);
        data[source][3][num_samples] = nodes[source].vibs;
        
        if(DEBUG){
            //print statements
            pc.printf("TEMP %d: %0.1fC ", nodes[source].id, nodes[source].temp);
            pc.printf("VOLT %d: %0.1fV ", nodes[source].id, nodes[source].volt);
            pc.printf("AMPS %d: %0.1fmA ", nodes[source].id, nodes[source].amps);
            pc.printf("VIBS %d: %0.1fB\r\n", nodes[source].id, nodes[source].vibs);
        }
  
    } 

}

//calculates the averages of the data then sends them to the gui
void average() {
    for(int i=0; i<2; i++){
        float sum = 0;
        for(int j=0; j<SAMPLES; j++){
            sum = sum + data[source][i][j];
        }
        avgs[source][i] = sum;
    }

}

uint8_t error_check(){
    return 0;
}

Import libraryMeshed-Motor-Monitoring

Software implementation of a meshed motor monitoring platform for integration with various hardware sensors.


Graphical User Interface

The GUI allows the user to visually display continuous input data read in from the Mbed's USB virtual serial port and a PC using Serial communication. The host PC triggers the I/O interaction in the forms of voltage, current, temperature, and vibrations, all of which are sensed by the corresponding hardware sensors via the Xbee and the Mbed. A Begin button initiates the readings while an End button ceases the readings.

The GUI is implemented in Microsoft Visual Studio with a Windows Forms App (.NET Framework) written in C#.

Gui Image

Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace sensor_suite
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void main_title_Click(object sender, EventArgs e)
        {

        }

        private void volts_Click(object sender, EventArgs e)
        {

        }

        private void curr_Click(object sender, EventArgs e)
        {

        }

        private void temp_Click(object sender, EventArgs e)
        {

        }

        private void analyze_Click(object sender, EventArgs e)
        {

        }

        private void volts_reading_TextChanged(object sender, EventArgs e)
        {

        }

        private void curr_reading_TextChanged(object sender, EventArgs e)
        {

        }

        private void temp_reading_TextChanged(object sender, EventArgs e)
        {

        }

        private Timer timer1;
        private void retrieve_Click(object sender, EventArgs e)
        {

            timer1 = new Timer();
            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Interval = 1000; // in miliseconds
            timer1.Start();
            serialPort1.Close();
       
        }

        private void meshNet_Click(object sender, EventArgs e)
        {

        }

        private void tempImg_Click(object sender, EventArgs e)
        {

        }

        private void voltsImg_Click(object sender, EventArgs e)
        {

        }

        private void currImg_Click(object sender, EventArgs e)
        {

        }

        private void wirelessImg_Click(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void end_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            node1_v.Text = node1_v.Text;
            node1_a.Text = node1_a.Text;
            node1_t.Text = node1_t.Text;
            node1_vib.Text = node1_vib.Text;
            node2_v.Text = node2_v.Text;
            node2_a.Text = node2_a.Text;
            node2_t.Text = node2_t.Text;
            node2_vib.Text = node2_vib.Text;
        }

   
    private void timer1_Tick(object sender, EventArgs e)
        {
            serialPort1.Open();
            double v1 = get_volts(packet);
            double v2 = get_volts(packet);
            double a1 = get_amps(packet);
            double a2 = get_amps(packet);
            double t1 = get_temp(packet);
            double t2 = get_temp(packet);
            double vib1 = get_vibs(packet);
            double vib2 = get_vibs(packet);

            node1_v.Text = v1.ToString();
            node1_a.Text = a1.ToString();
            node1_t.Text = t1.ToString();
            node1_vib.Text = vib1.ToString();
            node2_v.Text = v2.ToString();
            node2_a.Text = a2.ToString();
            node2_t.Text = t2.ToString();
            node2_vib.Text = vib2.ToString();
        }

     }

}

Video Demonstration


Please log in to post comments.