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-23
- Revision:
- 7:8698d17a0168
- Parent:
- 5:1eb90dace1c7
- Child:
- 8:e82e5b78dbbd
File content as of revision 7:8698d17a0168:
#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; Serial PcUart(USBTX, USBRX); float startvalue = 2; float currentvalue = 2; float risestepvalue = 0.2; float fallstepvalue = 0.2; float steptime = 1; bool isloopdone = 0; bool pauseswitch = 1; 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 setparameters() { printf("Setting parameters\n"); do { 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(atof(buffer) <= 0) printf("Error: invalid input\n"); } while(atof(buffer) <= 0); steptime = atof(buffer); do { 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); } void commandselect() { if(PcUart.readable()) { 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(); setparameters(); printf("Resetting cycle\n"); pauseswitch = 1; currentvalue = startvalue; setTension(currentvalue); printf("Use command 'p' to resume cycling\n"); flow_ticker.attach(&flow, 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("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"); break; } } } } void flow() { if(pauseswitch) return; else { if(relay.read() >= 0.1f) { if(currentvalue <= 0.201f) currentvalue = currentvalue/2; else currentvalue -= fallstepvalue; setTension(currentvalue); printf("Falling, tension = %f\n", currentvalue); } else { currentvalue += risestepvalue; setTension(currentvalue); printf("Rising, tension = %f\n", currentvalue); } } } 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("Beginning simulation\n"); printf("Use command 'p' to begin cycling\n"); InitI2CSlaveComm(); flow_ticker.attach(&flow, steptime); command_ticker.attach(&commandselect, 1); while(1) { I2CSlaveProcess(); } }