Hortau / Mbed 2 deprecated Tensiometer_Simulator_waterbench

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();
        }
    }
}