Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: I2CSlaveComm.cpp
- 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