Gabrielle Martin-Fortier / Mbed 2 deprecated Tensiometer_Simulator_waterbench

Dependencies:   mbed

Revision:
8:e82e5b78dbbd
Parent:
7:8698d17a0168
Child:
9:d2b700d42dbe
diff -r 8698d17a0168 -r e82e5b78dbbd I2CSlaveComm.cpp
--- a/I2CSlaveComm.cpp	Fri Nov 23 14:29:57 2018 +0000
+++ b/I2CSlaveComm.cpp	Mon May 06 20:26:33 2019 +0000
@@ -1,31 +1,73 @@
 #include "mbed.h"
 #include "I2CSlaveComm.h"
-
+ 
 I2CSlaveCustom slave(D4, D7);
 I2CSlaveCustom slave2(D14, D15); //use another I2C to emulate the adc
-
-AnalogIn relay(A0);
-
+ 
 Ticker command_ticker;
 Ticker flow_ticker;
 
+DigitalIn mybutton(USER_BUTTON);
+DigitalOut myled(LED1);
+ 
 Serial          PcUart(USBTX, USBRX);
 
-float startvalue = 2;
-float currentvalue = 2;
+int current_tensiometer = 0; // Two possible sensors with different patterns
+
+float tension;
 
-float risestepvalue = 0.2;
-float fallstepvalue = 0.2;
-float steptime = 1;
-
-bool isloopdone = 0;
-bool pauseswitch = 1;
-
+int modeSwitch = 1;
+int saveSwitch = 0;
+float counter = 0;
+ 
 unsigned char PointOnAddress = 0;
-
+ 
 char buffer[64];
 
 unsigned char ADCValue[2];
+
+struct CycleValues {
+    float riseTime;
+    float fallTime;
+    float plateauTime;
+    float stepTime;
+ 
+    float highValue;
+    float lowValue;
+    float stepValueRise;
+    float stepValueFall;
+    int offset; //Number of steps
+};
+
+struct CycleValues tensiometer0 = 
+    {
+        .riseTime = 2700,
+        .fallTime = 900,
+        .plateauTime = 0,
+        .stepTime = 30,
+        .highValue = 42,
+        .lowValue = -3,
+        .stepValueRise = tensiometer0.stepTime * (tensiometer0.highValue - tensiometer0.lowValue) / tensiometer0.riseTime,
+        .stepValueFall = tensiometer0.stepTime * (tensiometer0.lowValue - tensiometer0.highValue) / tensiometer0.fallTime,
+        .offset = 0
+    };
+    
+struct CycleValues tensiometer1 =
+    {
+        .riseTime = 1200,
+        .fallTime = 480,
+        .plateauTime = 60,
+        .stepTime = 30,
+        .highValue = 38,
+        .lowValue = 0,
+        .stepValueRise = tensiometer1.stepTime * (tensiometer1.highValue - tensiometer1.lowValue) / tensiometer1.riseTime,
+        .stepValueFall = tensiometer1.stepTime * (tensiometer1.lowValue - tensiometer1.highValue) / tensiometer1.fallTime,
+        .offset = 0
+    };
+    
+struct CycleValues tensiometers[2] = {tensiometer0, tensiometer1};
+struct CycleValues tensiometer = tensiometers[current_tensiometer];
+ 
 #pragma pack(push,1)
 struct SmartSensorStruct {
   char crc;           ///< Checksum CRC8
@@ -41,24 +83,24 @@
   unsigned long  code;///< Code de détection du type de smartSensor (Salinité ou Tension)
 }SmartSensorStruct_packed;
 #pragma pack(pop)
-
+ 
 struct SmartSensorStruct stSensor;
-
+ 
 char RAMBuffer[256]; //simulate EEPROM
-
+ 
 void DoCRC8(char* a_crc8, char b)
 {
   char i, j;
-
+ 
   for (i = 0; i < 8; b >>= 1, i++) {
-
+ 
     j = (b ^ (*a_crc8)) & 1;
     (*a_crc8) >>= 1;
-
+ 
     if (j) (*a_crc8) ^= 0x8C;
   }
 }
-
+ 
 void setTension(double value)
 {
     int tensionset = (int)(value*100); 
@@ -68,48 +110,48 @@
     ADCValue[0] = (adc >> 8)&0xFF;
     ADCValue[1] = (adc)&0xFF;
 }
-
+ 
 char ComputeCRC8(char *buff, char len, char start_data)
 {
   char crc8 = 0;
   DoCRC8(&crc8, start_data);
   while (len--) DoCRC8(&crc8, *buff++);
-
+ 
   return crc8;
 }
-
-
+ 
+ 
 void SaveRamBuffer(char address, char* value, unsigned char length)
 {
-
+ 
     unsigned char i;
     for(i = 0; i < length; i++)
         RAMBuffer[address + i] = value[i];
 }
-
+ 
 void SaveData(char add, long value)
 {
     SaveRamBuffer(add, (char*)&value, 4);
 }
-
+ 
 void I2C_1Process()
 {
     char buf[MAX_WRITE_SIZE + 1];
      int nbRx = 0;
-
+ 
      for(int i = 0; i < MAX_WRITE_SIZE; i++) buf[i] = 0;    // Clear buffer
-
+ 
      int rx = slave.receive();
-
+ 
      switch (rx)
      {
          case I2CSlave::ReadAddressed:
             slave.write(&RAMBuffer[PointOnAddress], 0xFF - PointOnAddress);
          break;
+         
          /*case I2CSlave::WriteGeneral:
-
-
          break;*/
+         
          case I2CSlave::WriteAddressed:
              int ret = slave.read(buf, 1);     
              PointOnAddress = buf[0];
@@ -122,7 +164,7 @@
          break;
      }
 }
-
+ 
 void I2C_2Process()
 {
      char buf[MAX_WRITE_SIZE + 1];
@@ -134,8 +176,8 @@
             slave2.write((char*)&ADCValue, 2);
          break;
          /*case I2CSlave::WriteGeneral:
-
-
+ 
+ 
          break;*/
          case I2CSlave::WriteAddressed:
          //to empty read buffer we do nothing with the data
@@ -148,13 +190,13 @@
          break;
      }
 }
-
+ 
 void I2CSlaveProcess()
 {
     I2C_1Process();
     I2C_2Process();
 }
-
+ 
 void InitI2CSlaveComm()
 {
     slave.address(0xA0);
@@ -170,61 +212,44 @@
     stSensor.code = 0xFFFF; //Type of sensor
     stSensor.crc = ComputeCRC8(((char *)&stSensor)+1, sizeof(SmartSensorStruct_packed) - 7, 0);
     SaveRamBuffer(0, (char*)&stSensor, sizeof(SmartSensorStruct_packed));
-
+ 
     slave2.address(0x90);
 }
-
-void setparameters()
+ 
+void cycle() 
 {
-    printf("Setting parameters\n");
-    
-    do
+    if(modeSwitch == 3 )
     {
-        printf("Enter starting tension in kPa\n");
-        scanf("%s", buffer);
-        
-        if(atof(buffer) == 0 && strcmp(buffer,"0") != 0)       
-            printf("Error: invalid input\n");
-        if(atof(buffer) < -1 || atof(buffer) > 10)
-            printf("Error: tension out of range [-1:10]\n");
-    } while(atof(buffer) == 0 && strcmp(buffer,"0") != 0 || atof(buffer) < -1 || atof(buffer) > 10);
-        
-    startvalue = atof(buffer);    
-        
-    do
-    {
-        printf("Enter step time in seconds\n");
-        scanf("%s", buffer);
+        if(saveSwitch == 2)
+        {
+            printf("Tension fall begins\n");
+        }
+        else if (saveSwitch == 1)
+        {
+            printf("Tension rise begins\n");
+        }
         
-        if(atof(buffer) <= 0)
-            printf("Error: invalid input\n");
-    } while(atof(buffer) <= 0);
-
-    steptime = atof(buffer);
-    
-    do
+        counter = 0;
+        modeSwitch = saveSwitch; 
+ 
+    }
+    else
     {
-        printf("Enter falling step value in kPa\n");
-        scanf("%s", buffer);
-        
-        if(atof(buffer) <= 0)
-            printf("Error: invalid input\n");
-    } while(atof(buffer) <= 0);
-
-    fallstepvalue = atof(buffer);
-    
-        do
-    {
-        printf("Enter rising step value in kPa\n");
-        scanf("%s", buffer);
-        
-        if(atof(buffer) <= 0)
-            printf("Error: invalid input\n");
-    } while(atof(buffer) <= 0);
-
-    risestepvalue = atof(buffer);
+        if(modeSwitch == 1)
+        {
+            printf("High plateau begins\n");
+            saveSwitch = 2;
+            modeSwitch = 3;
+        }
+        else if (modeSwitch == 2)
+        {
+            printf("Low plateau begins\n");
+            saveSwitch = 1;
+            modeSwitch = 3;
+        }
+    }
 }
-
+ 
 void commandselect()
 {
     if(PcUart.readable())
@@ -232,116 +257,203 @@
         char command = PcUart.getc();
         switch(command)
         {        
-            case 'p':
-            {
-                if (!pauseswitch)
-                {
-                    pauseswitch = 1;
-                    printf("Paused\n");
-                }
-                else
-                {
-                    pauseswitch = 0;
-                    printf("Resumed\n");
-                }
-                break;
-            }
         
             case 'w':
             {
                 flow_ticker.detach();                
+                printf("Setting parameters\n");
                 
-                setparameters();
-                        
-                printf("Resetting cycle\n");
+                printf("Enter tension high value in kPa\n");
+                scanf("%s", buffer);
+                tensiometer.highValue = atoi(buffer);
+                
+                printf("Enter tension low value in kPa\n");
+                scanf("%s", buffer);
+                tensiometer.lowValue = atoi(buffer);
+                
+                printf("Enter tension rise time in seconds\n");
+                scanf("%s", buffer);
+                tensiometer.riseTime = atoi(buffer);
                 
-                pauseswitch = 1;                
-                currentvalue = startvalue;
-                setTension(currentvalue);
+                printf("Enter tension fall time in seconds\n");
+                scanf("%s", buffer);
+                tensiometer.fallTime = atoi(buffer);
+                
+                printf("Enter plateau time in seconds\n");
+                scanf("%s", buffer);
+                tensiometer.plateauTime = atoi(buffer);
                 
-                printf("Use command 'p' to resume cycling\n");
+                printf("Enter step time in seconds\n");
+                scanf("%s", buffer);
+                tensiometer.stepTime = atoi(buffer);
                 
-                flow_ticker.attach(&flow, steptime);
+                printf("Resetting cycle\n");
+                counter = 0;
+                tension = tensiometer.lowValue;
+                modeSwitch = 1;
+                
+                flow_ticker.attach(&flow, tensiometer.stepTime);
                 break;
             }
             
             case 'i':
             {
                 printf("List of parameter values\n");
-                printf("Start value: %01f kPa\n", startvalue);
-                printf("Rising step value: %01f kPa\n", risestepvalue);
-                printf("Falling step value: %01f kPa\n", fallstepvalue);
-                printf("Step time: %d seconds\n", (int)steptime);
-
-                if(relay.read() >= 0.1f)
+                printf("High tension: %d kPa\n", (int)tensiometer.highValue);
+                printf("Low tension: %d kPa\n", (int)tensiometer.lowValue);
+                printf("Cycle rise time: %d seconds\n", (int)tensiometer.riseTime);
+                printf("Cycle fall time: %d seconds\n", (int)tensiometer.fallTime);
+                printf("Cycle plateau time: %d seconds\n", (int)tensiometer.plateauTime);
+                printf("Step time: %d seconds\n", (int)tensiometer.stepTime);
+                if(modeSwitch == 1)
+                    printf("Cycle currently in rising phase\n");
+                else if(modeSwitch == 2)
                     printf("Cycle currently in falling phase\n");
-                else
-                    printf("Cycle currently in rising phase\n");
-                    
-                if(pauseswitch)
-                    printf("Cycle currently in pause\n");
-                else
-                    printf("Cycle currently active\n");
+                else if(modeSwitch == 3)
+                    printf("Cycle currently in plateau phase\n");
                 break;
             }      
         }
     }
 }
-
+ 
 void flow()
 {
-    if(pauseswitch)
-        return;
+    if(modeSwitch == 3)
+    {
+        counter += tensiometer.stepTime;
+        
+        if(counter >= tensiometer.plateauTime)
+            cycle();
+    }
     else
     {
-        if(relay.read() >= 0.1f)
+        if(modeSwitch == 1)
+        {
+            tension += tensiometer.stepValueRise;
+            printf("Rising, tension = %f\n", tension);
+        }   
+        if(modeSwitch == 2)
         {
-            if(currentvalue <= 0.201f)
-                currentvalue = currentvalue/2;
-            else
-                currentvalue -= fallstepvalue;
-            setTension(currentvalue);
-            printf("Falling, tension = %f\n", currentvalue);
+            tension += tensiometer.stepValueFall;
+            printf("Falling, tension = %f\n", tension);
+        }
+        
+        setTension(tension);
+               
+        if(modeSwitch == 1 && tension >= tensiometer.highValue - 0.001f)
+        {
+            tension = tensiometer.highValue;
+            cycle();
+        }
+        else if(modeSwitch == 2 && tension <= tensiometer.lowValue + 0.001f)
+        {
+            tension = tensiometer.lowValue;
+            cycle();
         }
-    
-        else
-        {
-            currentvalue += risestepvalue;
-            setTension(currentvalue);
-            printf("Rising, tension = %f\n", currentvalue);
-        }        
+    }
+}
+
+void setStartingValue()
+{
+    int numberOfSteps = (tensiometer.riseTime + tensiometer.fallTime + (2 * tensiometer.plateauTime)) / tensiometer.stepTime;
+    printf("Total number of steps : %i\n", numberOfSteps);
+    printf("Lenght of cycle (seconds) : %f\n", numberOfSteps * tensiometer.stepTime);
+    int offset = tensiometer.offset % numberOfSteps;
+    printf("Offset after modulo : %i\n", offset);
+    if (offset * tensiometer.stepTime <= tensiometer.riseTime)
+    {
+        tension = tensiometer.lowValue + (tensiometer.offset * tensiometer.stepValueRise);
+    }
+    else if (offset * tensiometer.stepTime > tensiometer.riseTime && offset * tensiometer.stepTime <= (tensiometer.riseTime + tensiometer.plateauTime))
+    {
+        tension = tensiometer.highValue;
+        modeSwitch = 3;
+    }
+    else if (offset * tensiometer.stepTime > (tensiometer.riseTime + tensiometer.plateauTime) && offset * tensiometer.stepTime <= (tensiometer.riseTime + tensiometer.plateauTime + tensiometer.fallTime))
+    {
+        tension = tensiometer.highValue + (tensiometer.offset * tensiometer.stepValueFall);
+        modeSwitch = 2;
     }
+    else
+    {
+        tension = tensiometer.lowValue;
+        modeSwitch = 3;
+    }
+    printf("Starting tension : %f\n", tension);
+    switch (modeSwitch)
+    {
+        case 1:
+            printf("Starting phase : rising\n");
+            break;
+        case 2:
+            printf("Starting phase : falling\n");
+            break;
+        case 3:
+            printf("Starting phase : plateau\n");
+    }
+}
+
+void resetCycle()
+{
+    printf("Beginning simulation, tensiometer #%i\n", current_tensiometer);
+    modeSwitch = 1;
+    saveSwitch = 0;
+    counter = 0;
+    setStartingValue();
+    flow_ticker.attach(&flow, tensiometer.stepTime);
+    command_ticker.attach(&commandselect, 1);
 }
 
 int main()
 {
-   do
-    {
-        printf("Set parameters? (y/n)\n");
-        scanf("%s", buffer);
-        
-        if(strcmp(buffer,"y") == 0 || strcmp(buffer,"Y") == 0)
-        {       
-            setparameters();
-            isloopdone = 1;
-        }
-        else if(strcmp(buffer,"n") == 0 || strcmp(buffer,"N") == 0)
-        {
-            printf("Default parameters maintained\n");
-            isloopdone = 1;
-        }
-        else
-            printf("Error: invalid input\n");
-    } while(isloopdone != 1); 
+    /*
+    printf("Setting parameters\n");
+                
+    printf("Enter tension high value in kPa\n");
+    scanf("%s", buffer);
+    highValue = atoi(buffer);
+    
+    printf("Enter tension low value in kPa\n");
+    scanf("%s", buffer);
+    lowValue = atoi(buffer);
+    
+    printf("Enter tension rise time in seconds\n");
+    scanf("%s", buffer);
+    riseTime = atoi(buffer);
     
-    printf("Beginning simulation\n");
-    printf("Use command 'p' to begin cycling\n");
+    printf("Enter tension fall time in seconds\n");
+    scanf("%s", buffer);
+    fallTime = atoi(buffer);
+    
+    printf("Enter plateau time in seconds\n");
+    scanf("%s", buffer);
+    plateauTime = atoi(buffer);
+    
+    printf("Enter step time *in milliseconds*\n");
+    scanf("%s", buffer);
+    stepTime = (float)atoi(buffer)/1000;
+    
+    tension = lowValue;
+    stepValue = stepTime * (highValue - lowValue) / riseTime;
+    */
     
     InitI2CSlaveComm();
-    flow_ticker.attach(&flow, steptime);
-    command_ticker.attach(&commandselect, 1);
+    resetCycle();
+    
     while(1)
     {
-            I2CSlaveProcess();
+        if (mybutton == 0) // Button is pressed
+        { 
+            myled = !myled; // Toggle the LED state
+            wait(0.2); // 200 ms
+        }
+        if (!current_tensiometer == myled)
+        {
+            current_tensiometer = myled;
+            tensiometer = tensiometers[current_tensiometer];
+            resetCycle();
+        }
+        I2CSlaveProcess();
     }
 }
\ No newline at end of file