software implementing neural network trained on actual motor data

Dependencies:   mbed-dsp mbed NN_lib

Fork of NN_FG_final by Curtis Mattull

Revision:
1:4f5beb9858e7
Parent:
0:34aeffc5e6f0
--- a/main.cpp	Tue Oct 04 23:31:44 2016 +0000
+++ b/main.cpp	Mon Nov 07 22:07:31 2016 +0000
@@ -1,5 +1,5 @@
 //
-// File: ert_main.cpp
+// File: main.cpp
 //
 // Code generated for Simulink model 'neural_network3'.
 //
@@ -11,116 +11,209 @@
 // Embedded hardware selection: ARM Compatible->ARM Cortex
 // Code generation objectives: Unspecified
 // Validation result: Not run
-//
-#include <stddef.h>
-#include <stdio.h>                     // This ert_main.c example uses printf/fflush 
-#include "neural_network3.h"           // Model's header file
+
+//#include <stddef.h>
+//#include <stdio.h>                     // This ert_main.c example uses printf/fflush 
+#include "neural_network_3ph.h"           // Model's header file
 #include "rtwtypes.h"
 #include "mbed.h"
+#include "arm_math.h"
+#include "arm_const_structs.h"
 
-//
-// Associating rt_OneStep with a real-time clock or interrupt service routine
-// is what makes the generated code "real-time".  The function rt_OneStep is
-// always associated with the base rate of the model.  Subrates are managed
-// by the base rate from inside the generated code.  Enabling/disabling
-// interrupts and floating point context switches are target specific.  This
-// example code indicates where these should take place relative to executing
-// the generated code step function.  Overrun behavior should be tailored to
-// your application needs.  This example simply sets an error status in the
-// real-time model and returns from rt_OneStep.
-//
+#define led_on  0x00
+#define led_off 0x01
+
+DigitalOut led_r(PTB22);
+DigitalOut led_g(PTE26);
+DigitalOut led_b(PTB21);
+
+const int FFT_LEN   = 1024;
+const static arm_cfft_instance_f32 *S;
+float samples[FFT_LEN*2];
+float samples_normalized[FFT_LEN*2];
+real_T samples_trimmed[61];
+float magnitudes[FFT_LEN];
+const float dt = 0.001; // sample rate of 1kHz, letting us analyze signals up to 500Hz
+const float acquire_delay = 0.00004;
+const float sample_delay = dt-acquire_delay;
+
+AnalogIn adc_in(PTB2);
+
+void init_fft(int FFT_LEN);
+
 void rt_OneStep(void);
 void rt_OneStep(void)
 {
-  static boolean_T OverrunFlag = false;
+    static int32_t i = 0;
+
+    // '<Root>/Out1'
+    static real_T arg_Out1[2];
 
-  // '<Root>/In1'
-  static real_T arg_In1[200] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-    0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
-
-  // '<Root>/Out1'
-  static real_T arg_Out1[2];
-
-  // Disable interrupts here
+    static real_T max = 0;
+    static real_T min = 0;
+    const float running_thresh = 0.76;
+    
+    //collect imag data in complex form
+    for(i = 0; i< (FFT_LEN*2)+1; i+=2)
+    {   
+        samples[i+1]    = 0.0;                    // imaginary data
+    }
+    
+    //collect real data in complex form 
+    for(i = 0; i< (FFT_LEN*2)+1; i+=2)
+    {   
+        samples[i]      = adc_in.read();   // real data
+        wait(sample_delay); //timestep -40us for reading and storing value
+//        wait(dt);
+    }
+            
+    //find max
+    for(i = 0; i< (FFT_LEN*2)+1; i+=2)
+    {
+        if (samples[i] > max)
+        {
+            max = samples[i];
+        }
+    } 
+ 
+    //find min
+    for(i = 0; i< (FFT_LEN*2)+1; i+=2)
+    {
+        if (samples[i] < min)
+        {
+            min = samples[i];
+        }
+    }       
+    
+    //normalize data
+    for(i = 0; i< (FFT_LEN*2)+1; i+=2)
+    {   
+        samples_normalized[i]      = (samples[i]-min) / (max - min);   // real data
+        samples_normalized[i+1]    = 0.0;                    // imaginary data
+    }    
+    
+    // Calculate complex FFT
+    arm_cfft_f32(S, samples_normalized, 0, 1);
+    
+    // Calculate magnitude of complex numbers output by the FFT.
+    arm_cmplx_mag_f32(samples_normalized, magnitudes, FFT_LEN);
 
-  // Check for overrun
-  if (OverrunFlag) {
-    rtmSetErrorStatus(neural_network3_M, "Overrun");
-    return;
-  }
-
-  OverrunFlag = true;
-
-  // Save FPU context here (if necessary)
-  // Re-enable timer or interrupt here
-  // Set model inputs here
+//    /*20 - 80 Hz  */ 
+    for(i = 0; i< 61; i++)
+    {
+        samples_trimmed[i] = magnitudes[i+20];
+    }
+     
+    //    /* gain, tweaking lead to 17.5 */ 
+    for(i = 0; i< 61; i++)
+    {
+        samples_trimmed[i] = samples_trimmed[i]*17.5;
+    }
+    
+    // Step the model
+    neural_network_custom(samples_trimmed, arg_Out1);
+    
+    // for debugging, print the input to the neural network
+    for(i =0;i<61;i++)
+    {
+        printf("%i \t %f\r\n",i+20, samples_trimmed[i]);
+    }
+    
+    //print the output of the neural network
+    for(i =0;i<2;i++)
+    {
+        printf("output[%i]: %i",i,(int)arg_Out1[i]);
+        printf("\t");
+    }
+    
+    // this was used to determine when the motor was running or not
+    printf("\r\n\r\nsample[0]: %f \r\n",samples[0]);
 
-  // Step the model
-  neural_network3_custom(arg_In1, arg_Out1);
-
-  // Get model outputs here
-    printf("output: %f", arg_Out1);
-  // Indicate task complete
-  OverrunFlag = false;
-
-  // Disable interrupts here
-  // Restore FPU context here (if necessary)
-  // Enable interrupts here
+//     output logic controlling leds
+    if(arg_Out1[0] == 0)   
+    {
+        if (arg_Out1[1] == 0)   // 00   normal mode
+        {                       // green
+            led_r.write(led_off);
+            led_g.write(led_on);
+            led_b.write(led_off);
+        }
+        else if(arg_Out1[1] == 1)   // 01 short circuit fault
+        {                           // red
+            led_r.write(led_on);
+            led_g.write(led_off);
+            led_b.write(led_off);
+        } 
+    }
+    if(arg_Out1[0] == 1)        
+    {
+        if (arg_Out1[1] == 1)   // 11   open circuit fault
+        {                       // yellow
+            led_r.write(led_on);
+            led_g.write(led_on);
+            led_b.write(led_off);
+        }
+    }
+    
+    if(samples[0] < running_thresh) // essentially not running
+    {                               // led off
+        led_r.write(led_off);
+        led_g.write(led_off);
+        led_b.write(led_off);
+    }
+    //end of function
 }
 
-//
-// The example "main" function illustrates what is required by your
-// application code to initialize, execute, and terminate the generated code.
-// Attaching rt_OneStep to a real-time clock is target specific.  This example
-// illustrates how you do this relative to initializing the model.
-//
-int_T main(int_T argc, const char *argv[])
+void init_fft(int FFT_LEN)
 {
-  // Unused arguments
-  (void)(argc);
-  (void)(argv);
+    switch (FFT_LEN)
+    {
+    case 16:
+        S = & arm_cfft_sR_f32_len16;
+        break;
+    case 32:
+        S = & arm_cfft_sR_f32_len32;
+        break;
+    case 64:
+        S = & arm_cfft_sR_f32_len64;
+        break;
+    case 128:
+        S = & arm_cfft_sR_f32_len128;
+        break;
+    case 256:
+        S = & arm_cfft_sR_f32_len256;
+        break;
+    case 512:
+        S = & arm_cfft_sR_f32_len512;
+        break;
+    case 1024:
+        S = & arm_cfft_sR_f32_len1024;
+        break;
+    case 2048:
+        S = & arm_cfft_sR_f32_len2048;
+        break;
+    case 4096:
+        S = & arm_cfft_sR_f32_len4096;
+        break;
+    }
+}
 
-  // Initialize model
-  neural_network3_initialize();
-
-  // Attach rt_OneStep to a timer or interrupt service routine with
-  //  period 0.2 seconds (the model's base sample time) here.  The
-  //  call syntax for rt_OneStep is
-  //
+int main(void)
+{   
+    //initialize leds
+    led_r.write(led_off);
+    led_g.write(led_off);
+    led_b.write(led_off);
+    
+    init_fft(FFT_LEN);
+    
+    //software process defined within rt_onestep()
     for(;;)
     {
         rt_OneStep();
-        wait(0.2);
+        printf("run success!!\r\n");
+        wait(1);
     }
-//  printf("Warning: The simulation will run forever. "
-//         "Generated ERT main won't simulate model step behavior. "
-//         "To change this behavior select the 'MAT-file logging' option.\n");
-  fflush((NULL));
-  while (rtmGetErrorStatus(neural_network3_M) == (NULL)) {
-    //  Perform other application tasks here
-  }
 
-  // Disable rt_OneStep() here
-
-  // Terminate model
-  neural_network3_terminate();
-  return 0;
-}
-
-//
-// File trailer for generated code.
-//
-// [EOF]
-//
+    return 0;
+}
\ No newline at end of file