Basic Mid-Level control for the rebuilt MorphGI control unit, using PWM to communicate with the low level controllers.

Dependencies:   ros_lib_kinetic

Revision:
3:c83291bf9fd2
Parent:
2:eea12b149dba
Child:
4:303584310071
--- a/main.cpp	Tue Jul 31 10:44:10 2018 +0000
+++ b/main.cpp	Tue Jul 31 14:30:40 2018 +0000
@@ -4,21 +4,6 @@
 //#include "mbed.h"
 #include "mbed_events.h"
 
-// COMMS
-/*#include "EthernetInterface.h"
-#include "TCPServer.h"
-#include "TCPSocket.h"
-#include <sstream> // stringstream
-#include <vector> // vector
-#include <string.h> // strtok
-const bool IS_DHCP = false;
-#define PORT 80
-struct msg_format {
-    double psi[3][3];
-    //unsigned short duration;
-    double duration;
-} input;*/
-
 //ADC SPI stuff
 #define PREAMBLE 0x06
 #define CHAN_1 0x30
@@ -44,7 +29,7 @@
 #define PATH_SAMPLE_TIME_S 0.05
 
 #define MAX_LENGTH_MM 100.0
-#define MAX_ACTUATOR_LENGTH 50.0
+#define MAX_ACTUATOR_LENGTH 52.2
 #define MAX_SPEED_MMPS 24.3457
 #define PATH_TOLERANCE_MM 0.2 
 
@@ -96,15 +81,36 @@
 
 Serial pc(USBTX, USBRX); // tx, rx for usb debugging
 
-SPI spi(PC_12,PC_11, PC_10); // mosi, miso, sclk
+
+InterruptIn pinGate6(PE_11); //this pin HAS TO BE defined before SPI set up. No Clue Why.
+
+SPI spi(PC_12, PC_11, PC_10); // mosi, miso, sclk
+
+DigitalOut cs_LL[N_CHANNELS] = {PD_15, PE_10, PD_14, PD_11, PE_7, PD_12, PF_10, PD_13};//chip select for low level controller
+DigitalOut cs_ADC[N_CHANNELS] = {PG_12, PG_9, PE_1, PG_0, PD_0, PD_1, PF_0, PF_1}; //chip select for ADC
+
+DigitalOut pinCheck(PE_5);
+
+//InterruptIn pinGate[N_CHANNELS] ={PF_11, PG_14, PF_15, PF_12, PF_3, PF_13, PE_11, PE_13};//gate interrupt pins
 
-DigitalOut cs_LL[N_CHANNELS] = {PF_10, PD_13, PE_7, PD_12, PD_14, PD_11, PD_15, PE_10};//chip select for low level controller
-DigitalOut cs_ADC[N_CHANNELS] = {PF_1, PF_0, PD_1, PD_0, PG_0, PE_1, PG_9, PG_12}; //chip select for ADC
+//WRONG!!!!!!!!!!
+//InterruptIn pinGate[N_CHANNELS] ={PG_11, PG_14, PF_15, PF_12, PF_3, PF_13, PE_11, PE_13};//gate interrupt pins
+//WRONG!!!!!
 
-InterruptIn pinGate[N_CHANNELS] ={PE_11, PE_13, PF_3, PF_13, PF_15, PF_12, PF_11, PG_14};//gate interrupt pins
+//InterruptIn testPinGate(PF_11);
+//these interrupt pins have to be declared AFTER SPI declaration. No Clue Why.
+InterruptIn pinGate0(PF_11);
+InterruptIn pinGate1(PG_14);
+InterruptIn pinGate2(PF_15);
+InterruptIn pinGate3(PF_12);
+InterruptIn pinGate4(PF_3);
+InterruptIn pinGate5(PF_13);
+//InterruptIn pinGate6(PE_11); //
+InterruptIn pinGate7(PE_13);
 
 DigitalOut pinReset(PD_2); //reset pin for all controllers.
 
+
 EventQueue queue(32 * EVENTS_EVENT_SIZE);
 
 Thread t(osPriorityRealtime);
@@ -144,11 +150,12 @@
 
 bool isDataReady[N_CHANNELS]; // flag to indicate path data is ready for transmission to low level.
 
-unsigned int ReadADCPosition(int channel)
+double ReadADCPosition(int channel)
 {
     unsigned int outputA;
     unsigned int outputB;
-    unsigned int output;
+    int output;
+    double dblOutput;
 
     spi.format(8,0);
     spi.frequency(1000000);
@@ -162,15 +169,17 @@
     outputA = outputA & DATA_MASK;
     outputA = outputA<<8;
     output = (outputA | outputB);
-    
-    return output;
+    output = 4095- output;
+    dblOutput = (double) (output - 1504)/4095*100.0;
+    return dblOutput;
 }
     
-unsigned int ReadADCPressure(int channel)
+double ReadADCPressure(int channel)
 {
     unsigned int outputA;
     unsigned int outputB;
-    unsigned int output;
+    int output;
+    double dblOutput;
 
     spi.format(8,0);
     spi.frequency(1000000);
@@ -185,11 +194,13 @@
     outputA = outputA<<8;
     output = (outputA | outputB);
     
-    return output;
+    dblOutput = (double) (output-502)/4095*8.0;
+    return dblOutput;
 }
 
 void SendReceiveData(int channel) 
 {
+    
     //get data from controller
     spi.format(16,2);
     spi.frequency(LOW_LEVEL_SPI_FREQUENCY);
@@ -199,32 +210,74 @@
     cs_LL[channel] = 1;//deselect chip
     isDataReady[channel] = 0;//data no longer ready, i.e. we now require new data
     
-    dblPressure_bar[channel] = ReadADCPressure(channel);
-    dblPosition_mtrs[channel] = ReadADCPosition(channel);
+
     
     //sort out received data
     chrErrorFlag[channel] = intPosSPI_Rx[channel]>>13;
     intPosSPI_Rx[channel] = intPosSPI_Rx[channel] & 0x1FFF;
     dblPosition_mtrs[channel] = (double)intPosSPI_Rx[channel]/8191*(MAX_ACTUATOR_LENGTH/dblActuatorConversion[channel])/1000;
+    //printf("%d, %d\r\n",intPosSPI_Rx[0],intDemandPos_Tx[0]);
+    
+}
+
+void testSendReceiveData() 
+{
+    printf("x\r\n");
+    //get data from controller
+    spi.format(16,2);
+    spi.frequency(LOW_LEVEL_SPI_FREQUENCY);
+    
+    cs_LL[0] = 0;//select relevant chip
+    intPosSPI_Rx[0] = spi.write(intDemandPos_Tx[0]); //transmit & receive
+    cs_LL[0] = 1;//deselect chip
+    isDataReady[0] = 0;//data no longer ready, i.e. we now require new data
+    
+    //sort out received data
+    chrErrorFlag[0] = intPosSPI_Rx[0]>>13;
+    intPosSPI_Rx[0] = intPosSPI_Rx[0] & 0x1FFF;
+    dblPosition_mtrs[0] = (double)intPosSPI_Rx[0]/8191*(MAX_ACTUATOR_LENGTH/dblActuatorConversion[0])/1000;
+    
+    
 }
 
 //common rise handler function 
 
 void common_rise_handler(int channel)
 {
+    pinCheck = 1;
     //check if data is ready for tranmission
     if (isDataReady[channel])
     {
+        
         // Add transmit task to event queue
         ThreadID[channel] = queue.call(SendReceiveData,channel);//schedule transmission
     }
 }
 
+void testRiseFunction(void)
+{
+    pinCheck = 1;
+    //check if data is ready for tranmission
+    if (isDataReady[0])
+    {
+        // Add transmit task to event queue
+        ThreadID[0] = queue.call(testSendReceiveData);//schedule transmission
+    }
+}
+
+void testFallFunction(void)
+{
+    pinCheck = 0;
+    //cancel relevant queued event    
+    queue.cancel(ThreadID[0]);
+}
+
 
 
 //common_fall handler functions
 void common_fall_handler(int channel) 
 {
+    pinCheck = 0;
     //cancel relevant queued event    
     queue.cancel(ThreadID[channel]);
 }
@@ -383,19 +436,22 @@
             //convert to actuator distances
             dblPathToActuator[ii] = dblSmoothPathCurrentPos_mm[ii];
             
-            intDemandPos_Tx[ii] = (int) (dblPathToActuator[ii]/MAX_ACTUATOR_LENGTH)*8191;//convert to a 13-bit number;
+            intDemandPos_Tx[ii] = (int) ((dblPathToActuator[ii]/MAX_ACTUATOR_LENGTH)*8191);//convert to a 13-bit number;
+            
             intDemandPos_Tx[ii] = intDemandPos_Tx[ii] & 0x1FFF; //ensure number is 13-bit 
             
+            dblPressure_bar[ii] = ReadADCPressure(ii);
+            dblPosition_mtrs[ii] = ReadADCPosition(ii);
           
             isDataReady[ii] = 1;//signal that data ready
 
         }
-        
-        //printf("%d, %f,%f,%f, %f\r\n",timer.read_ms(), dblTargetActLen_mm[0] ,dblVelocity_mmps[0], dblLinearPathCurrentPos_mm[0], dblSmoothPathCurrentPos_mm[0]);
+        printf("%f, %d\r\n",dblPathToActuator[0], intDemandPos_Tx[0]); 
+        //printf("%f,%f, %f, %f\r\n", dblTargetActLen_mm[0], dblSmoothPathCurrentPos_mm[0],dblPressure_bar[0], dblPosition_mtrs[0]);
     }
 }
 
-/*void SimulateDemand() // For testing purposes
+void SimulateDemand() // For testing purposes
 {
     int kk = 0;
     while(1)
@@ -404,7 +460,7 @@
         if(kk == 0)
         {
             dblPSI[0][0] = (double) 10.0;
-            dblTargetTime_s = 1.0;
+            dblTargetTime_s = 1.5;
         }
         else
         { 
@@ -422,7 +478,7 @@
     
         Thread::wait(7000);
     }
-}*/
+}
 
 
 
@@ -430,9 +486,18 @@
 
 int main() 
 {
+    for (ii = 0; ii <250; ii++)
+    {
+        pinCheck = 1;
+        wait(0.001);
+        pinCheck = 0;
+        wait(0.001);
+    }
+    
     //initialise relevant variables
     for(ii = 0; ii<N_CHANNELS; ii++)
     {
+        
         //all chip selects in off state
         cs_LL[ii] = 1;
         cs_ADC[ii] = 1;
@@ -445,6 +510,10 @@
     dblPathTolerance = 0.1;//MAX_SPEED_MMPS * PATH_SAMPLE_TIME_S * 1.05; //path tolerance in mm. 
     
     pinReset = 1; //initialise reset pin to not reset the controllers.
+    wait(0.1);
+    pinReset=0; //reset controllers to be safe
+    wait(0.1);
+    pinReset = 1;//ready to go
     
     //say something nice to the user.
     pc.baud(9600);
@@ -456,24 +525,38 @@
     //set up the interrupts
 
     //set up rise interrupts MIGHT NOT NEED TO BE POINTERS
-    pinGate[0].rise(&rise0);
-    pinGate[1].rise(&rise1);
-    pinGate[2].rise(&rise2);
-    pinGate[3].rise(&rise3);
-    pinGate[4].rise(&rise4);
-    pinGate[5].rise(&rise5);
-    pinGate[6].rise(&rise6);
-    pinGate[7].rise(&rise7);
+    //
+    //pinGate[0].rise(&testRiseFunction);
+    //testPinGate.rise(&testRiseFunction);//<working
+    //testPinGate.rise(&rise0);
+    
+    pinGate0.rise(&rise0);
+    /*
+    pinGate1.rise(&rise1);
+    pinGate2.rise(&rise2);
+    pinGate3.rise(&rise3);
+    pinGate4.rise(&rise4);
+    pinGate5.rise(&rise5);
+    pinGate6.rise(&rise6);
+    pinGate7.rise(&rise7);
+    */
     
     //set up fall interrupts MIGHT NOT NEED TO BE POINTERS
-    pinGate[0].fall(&fall0);
-    pinGate[1].fall(&fall1);
-    pinGate[2].fall(&fall2);
-    pinGate[3].fall(&fall3);
-    pinGate[4].fall(&fall4);
-    pinGate[5].fall(&fall5);
-    pinGate[6].fall(&fall6);
-    pinGate[7].fall(&fall7);
+    //
+    //pinGate[0].fall(&testFallFunction);
+    //testPinGate.fall(&testFallFunction); <working
+    //testPinGate.fall(&fall0);
+    
+    pinGate0.fall(&fall0);
+    /*
+    pinGate1.fall(&fall1);
+    pinGate2.fall(&fall2);
+    pinGate3.fall(&fall3);
+    pinGate4.fall(&fall4);
+    pinGate5.fall(&fall5);
+    pinGate6.fall(&fall6);
+    pinGate7.fall(&fall7);
+    */
     
     timer.start();
     
@@ -484,7 +567,7 @@
     
     threadReplan.start(ReplanPath);//start Replanning thread 
      Thread::wait(1);  
-     
+    
       
     while(1) {
         Thread::wait(osWaitForever);