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.
Dependencies: mbed
I2CSlaveComm.cpp
- Committer:
- Blanglois
- Date:
- 2018-11-01
- Revision:
- 3:29925a0f88da
- Parent:
- 2:d0308b3aaf69
- Child:
- 4:5f2b51fa096a
File content as of revision 3:29925a0f88da:
#include "mbed.h" #include "I2CSlaveComm.h" I2CSlaveCustom slave(D4, D7); I2CSlaveCustom slave2(D14, D15); //use another I2C to emulate the adc Ticker command_ticker; Ticker flow_ticker; Serial PcUart(USBTX, USBRX); int modeswitch = 1; int saveswitch; int counter = 0; int I2Cswitch = 1; float risetime = 40; float falltime = 20; float plateautime = 10; float steptime = 5; float highvalue = 100; float lowvalue = 20; float stepvalue = steptime * (highvalue - lowvalue) / risetime; float tension = lowvalue; unsigned char PointOnAddress = 0; char buffer[64]; unsigned char ADCValue[2]; #pragma pack(push,1) struct SmartSensorStruct { char crc; ///< Checksum CRC8 char serial[11]; ///< No Série du capteur. Doit demeurer à l'offset 1 dans la structure char gain; ///< Gain à appliquer char sampling_rate; ///< Vitesse de sampling char model; ///< Model de capteur short c1; ///< Consigne c1 de calcul short c2; ///< Consigne c2 de calcul short c3; ///< Consigne c3 de calcul char depth; ///< Profondeur du capteur en mètres ou en pieds short c4; ///< Consigne c4 de calcul 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); int adc = ((1000 * (tensionset - stSensor.c3)) / stSensor.c2) - stSensor.c1; adc = adc / 4; //into low read of the ST 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]; nbRx = slave.getCount(); if (nbRx > 0) //to simulate write on EEPROM need to test { ret = slave.read(buf, nbRx); SaveRamBuffer(PointOnAddress, buf, nbRx); } break; } } void I2C_2Process() { char buf[MAX_WRITE_SIZE + 1]; int rx = slave2.receive(); int nbRx = 0; switch (rx) { case I2CSlave::ReadAddressed: slave2.write((char*)&ADCValue, 2); break; /*case I2CSlave::WriteGeneral: break;*/ case I2CSlave::WriteAddressed: //to empty read buffer we do nothing with the data int ret = slave2.read(buf, 1); nbRx = slave2.getCount(); if (nbRx > 0) //to simulate write on EEPROM need to test { ret = slave2.read(buf, nbRx); } break; } } void I2CSlaveProcess() { I2C_1Process(); I2C_2Process(); } void InitI2CSlaveComm() { slave.address(0xA0); sprintf(stSensor.serial, "2059123456"); stSensor.gain = 0x01; stSensor.sampling_rate = 0x03; stSensor.c1 = -37; stSensor.c2 = 634; stSensor.c3 = -7; stSensor.c4 = -1; stSensor.depth = 0x00; stSensor.model = 2; //Nombre de données à transmettre vers le ST 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 cycle() { if(modeswitch == 3 ) { if(saveswitch == 2) { printf("Tension fall begins\n"); modeswitch = saveswitch; } else if (saveswitch == 1) { printf("Tension rise begins\n"); modeswitch = saveswitch; } counter = 0; } else { if(modeswitch == 1) { printf("High plateau begins\n"); stepvalue = steptime * (lowvalue - highvalue) / falltime; saveswitch = 2; modeswitch = 3; } else if (modeswitch == 2) { printf("Low plateau begins\n"); stepvalue = steptime * (highvalue - lowvalue) / risetime; saveswitch = 1; modeswitch = 3; } } } void commandselect() { if(PcUart.readable()) { char command = PcUart.getc(); switch(command) { case 'w': { I2Cswitch = 0; flow_ticker.detach(); 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("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 seconds\n"); scanf("%s", buffer); steptime = atoi(buffer); printf("Resetting cycle\n"); counter = 0; tension = lowvalue; stepvalue = steptime * (highvalue - lowvalue) / risetime; modeswitch = 1; flow_ticker.attach(&flow, steptime); I2Cswitch = 1; break; } case 'i': { printf("List of parameter values\n"); printf("High tension: %df kPa\n", (int)highvalue); printf("Low tension: %d kPa\n", (int)lowvalue); printf("Cycle rise time: %d seconds\n", (int)risetime); printf("Cycle fall time: %d seconds\n", (int)falltime); printf("Cycle plateau time: %d seconds\n", (int)plateautime); printf("Step time: %d seconds\n", (int)steptime); if(modeswitch == 1) printf("Cycle currently in rising phase\n"); else if(modeswitch == 2) printf("Cycle currently in falling phase\n"); else if(modeswitch == 3) printf("Cycle currently in plateau phase\n"); break; } } } } void flow() { if(modeswitch == 3) { counter += steptime; if(counter >= plateautime) cycle(); } else { tension += stepvalue; setTension(tension); if(modeswitch == 1) printf("Rising, tension = %f\n", tension); if(modeswitch == 2) printf("Falling, tension = %f\n", tension); if(modeswitch == 1 && tension >= highvalue - 0.0001f) { tension = highvalue; cycle(); } else if(modeswitch == 2 && tension <= lowvalue + 0.0001f) { tension = lowvalue; cycle(); } } } int main() { printf("Initiating\n"); InitI2CSlaveComm(); flow_ticker.attach(&flow, steptime); command_ticker.attach(&commandselect, 1); while(1) { if(I2Cswitch == 1) { I2CSlaveProcess(); } } }