Skip to main content
Tweeted twitter.com/StackArduino/status/868700796057210880
Remove irrelevant tag
Link
Code Gorilla
  • 5.6k
  • 1
  • 16
  • 31
Source Link
Hasan
  • 1.5k
  • 14
  • 28

Serial data affected by interrupt

In my recent project, I have done everything means capture serial data and split it out in proper form.

Until now everything is fine. But when I add another portion of code which contains Interrupt. Now, whenever Interrupt come into the picture, my incoming serial data totally destroy. And when I remove that interrupt portion then everything is fine. But this interrupt is also given one my reading(RPM READING).

I tried out detachinterrupt function, it disables my interrupt then I can't get my RPM READING.

I also tried out interrupts() and noInterrupts() function. But I don't get any results. I think I'm not able to utilize my code with this function.

Here, below my whole code which is a little bit lengthy. But, it's necessary.

#include<LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 7, 6, 5, 4);

String data_TPS_Json = "";
String data_MAP_Json = "";
String data_LOAD_TM_Json = "";

String data_LOAD_RI_Json = "";
String data_RPM_Json = "";
String data_INJECTION_TIME_Json = "";

String response = "";
bool begin = false;

char in;
int len = 0;

float TPS_Json;
float MAP_Json;
float LOAD_TM_Json;

float LOAD_RI_Json;
float RPM_Json;
float INJECTION_TIME_Json;

//----------------------------For MAP calculation----------------------------//
float MAP_MIN = 0.85;
float MAP_MAX = 1.90;

int LOAD_MIN_MAP[] = {1, 2};
int LOAD_MAX_MAP[] = {3, 4};

float mMAP[2] = {};
float yMAP[2] = {};

int i, j, a;
float MAP, mFinalMAP, yFinalMAP;

//----------------------------For TPS calculation----------------------------//
float TPS_MIN = 0.00;
float TPS_MAX = 5.00;

int LOAD_MIN_TPS[] = {1, 3};
int LOAD_MAX_TPS[] = {2, 4};

float mTPS[2] = {};
float yTPS[2] = {};

int k, l, b;
float TPS, mFinalTPS, yFinalTPS;

//----------------------------For LOAD calculation---------------------------//
int LOAD_MIN = 2;
int LOAD_MAX = 100;

float injTime_MIN_LOAD[] = {6.20, 6.26};
float injTime_MAX_LOAD[] = {7.80, 8.06};

float mLOAD[2] = {};
float yLOAD[2] = {};

int m, n, c;
float LOAD, mFinalLOAD, yFinalLOAD;

//----------------------------For RPM calculation----------------------------//
const int kPinRPM = 3;        // RPM / Digital Pin 3
const int RPMInterrupt = 1;   // RPM's interrrupt pin
byte engineCylinders = 2;         // Engine cylinders = 4;
byte engineCycles = 4;            // Engine cycle = 2
int refreshInterval = 750;        // Milliseconds between sensor updates
unsigned long previousMillis = 0;
volatile int RPMpulses = 0,  RPM0 = 0;
int RPM, Final_RPM;

int RPM_MIN = 400;
int RPM_MAX = 6000;

float injTime_MIN_RPM[] = {6.20, 7.80};
float injTime_MAX_RPM[] = {6.26, 8.06};

float mRPM[2] = {};
float yRPM[2] = {};

int o, p, d;
float mFinalRPM, yFinalRPM;

//------------------------For GAS PRESSURE calculation-----------------------//
float minPosVolGas = 0.00;
float maxPosVolGas = 2.50;

float minInjPerPos = 0.35;
float maxInjPerPos = 0.00;

float minNagVolGas = 2.50;
float maxNagVolGas = 5.00;

float minInjPerNag = 0.00;
float maxInjPerNag = 0.25;

float GAS_Pressure, mGasPos, mGasNag, yGasPos, yGasNag;

//----------------------For INJECTION TIME calculation-----------------------//
float yInjTime, injTime, gasInjTime;
volatile uint32_t kInjTime = 0;

const int kPinInj = 8;

void setup() 
{
  Serial.begin(9600);
  lcd.begin(16, 2);

  pinMode(kPinRPM, INPUT_PULLUP); // Enable internal pullup
  attachInterrupt(RPMInterrupt, countRPM, FALLING); //Interrupt for RPM

  pinMode(kPinInj, OUTPUT);  
}

void loop() 
{
  //----------------------------MAP----------------------------//
  
  MAP = analogRead(A0) * (5.0 / 1023.0);

  for(a = 0; a < 2; a++)
  {
    mMAP[i] = (LOAD_MIN_MAP[a] - LOAD_MIN_MAP[a]) / (MAP_MAX - MAP_MIN);
    yMAP[j] = mMAP[i] * (MAP - MAP_MIN) + LOAD_MIN_MAP[a];
  }
  
  //----------------------------TPS----------------------------//
  
  TPS = analogRead(A1) * (5.0 / 1023.0);

  for(b = 0; b < 2; b++)
  {
    mTPS[k] = (LOAD_MAX_TPS[b] - LOAD_MIN_TPS[b]) / (TPS_MAX - TPS_MIN);
    yTPS[l] = mTPS[k] * (TPS - TPS_MIN) + LOAD_MIN_TPS[b];
  }
  
  //----------------TPS/MAP CALLIBRATION / LOAD----------------//
  
  mFinalTPS = (yMAP[1] - yMAP[0]) / (TPS_MAX - TPS_MIN);
  yFinalTPS = mFinalTPS * (TPS - TPS_MIN) + yMAP[0];

  mFinalMAP = (yTPS[1] - yTPS[0]) / (MAP_MAX - MAP_MIN);
  yFinalMAP = mFinalMAP * (MAP - MAP_MIN) + yTPS[0];

  LOAD = (yFinalTPS + yFinalMAP) / 2;

  //----------------------------LOAD---------------------------//

  for(c = 0; c < 2; c++)
  {
    mLOAD[m] = (injTime_MAX_LOAD[c] - injTime_MIN_LOAD[c]) / (LOAD_MAX - LOAD_MIN);
    yLOAD[n] = mLOAD[m] * (LOAD - LOAD_MIN) + injTime_MIN_LOAD[c];
  }
      
  //----------------------------RPM----------------------------//
  
  if(millis() - previousMillis > refreshInterval)
  {
    previousMillis = millis();
    RPM =  getRPM();
  }

  for(d = 0; d < 2; d++)
  {
    mRPM[o] = (injTime_MAX_RPM[d] - injTime_MIN_RPM[d]) / (RPM_MAX - RPM_MIN);
    yRPM[p] = mRPM[o] * (RPM - RPM_MIN) + injTime_MIN_RPM[d];
  }
  
  //-----------LOAD/RPM CALLIBRATION / INJECTION TIME----------//

  mFinalLOAD = (yRPM[1] - yRPM[0]) / (LOAD_MAX - LOAD_MIN);
  yFinalLOAD = mFinalLOAD * (LOAD - LOAD_MIN) + yRPM[0];

  mFinalRPM = (yLOAD[1] - yLOAD[0]) / (RPM_MAX - RPM_MIN);
  yFinalRPM = mFinalRPM * (RPM - RPM_MIN) + yLOAD[0];

  yInjTime = (yFinalLOAD + yFinalRPM) / 2;
  injTime = (yInjTime * 1000) / 1000;

  //------------------JSON SERIAL DATA---------------------//

  while(Serial.available() || !begin)
  {
      in = Serial.read();

      if (in == '{')
      {
        begin = true;
      }
    
      if(begin)
      {
        response += (in);
      }

      if(in == '}')
      {
        break;
      }
      
      delay(1);
  }

  len = response.length();

  if(len == 39)
  {
    data_TPS_Json = response.substring(8, 12);
    data_MAP_Json = response.substring(21, 25);
    data_LOAD_TM_Json = response.substring(35, 37);

    jsonMapTps();
  }
  
  if(len == 52)
  {
    data_LOAD_RI_Json = response.substring(9, 13);
    data_RPM_Json = response.substring(22, 26);
    data_INJECTION_TIME_Json = response.substring(46, 50);

    jsonRpmLoad();
  }  

  //------------------------GAS_PRESSURE-----------------------//

  GAS_Pressure =  analogRead(A2) * (5.0 / 1023.0);
 
  mGasPos = (maxInjPerPos - minInjPerPos) / (maxPosVolGas - minPosVolGas);
  yGasPos = mGasPos * (GAS_Pressure - minPosVolGas) + minInjPerPos;
  
  mGasNag = (maxInjPerNag - minInjPerNag) / (maxNagVolGas - minNagVolGas);
  yGasNag = mGasNag * (GAS_Pressure - minNagVolGas) + minInjPerNag;

  if(GAS_Pressure >= 0.00 && GAS_Pressure < 2.50)
  {
    gasInjTime = injTime + (injTime * yGasPos);
  }
  else if(GAS_Pressure >= 2.50 && GAS_Pressure <= 5.00)
  {
    gasInjTime = injTime - (injTime * yGasNag);
  }

  //--------------------Pulse Generation-----------------------//
  
  if((kInjTime > 0) && ((millis() - kInjTime) >= injTime))
  {
    kInjTime = 0;
    digitalWrite(kPinInj, 0);
  }                                  
}

void countRPM()
{
  RPMpulses++;

  digitalWrite(kPinInj, RPMpulses & 1); // Set or clear kPinInj
  if(RPMpulses & 1) 
  kInjTime = millis();  // Store alternate times
}

int getRPM()
{
  Final_RPM = ((RPMpulses * (60000UL / 2) * (engineCycles/engineCylinders)) / refreshInterval);
  RPM0 = RPMpulses &= 1;
  RPMpulses - RPM0;
  return Final_RPM;
}

void jsonMapTps()
{
    TPS_Json = data_TPS_Json.toFloat();
    MAP_Json = data_MAP_Json.toFloat();
    LOAD_TM_Json = data_LOAD_TM_Json.toFloat();
    
    lcd.setCursor(0, 0);
    lcd.print(TPS_Json);
    lcd.setCursor(8, 0);
    lcd.print(MAP_Json);
    lcd.setCursor(0, 1);
    lcd.print(LOAD_TM_Json);  
}

void jsonRpmLoad()
{
    LOAD_RI_Json = data_LOAD_RI_Json.toFloat();
    RPM_Json = data_RPM_Json.toFloat();
    INJECTION_TIME_Json = data_INJECTION_TIME_Json.toFloat();

    lcd.setCursor(0, 0);
    lcd.print(LOAD_RI_Json);
    lcd.setCursor(8, 0);
    lcd.print(RPM_Json);
    lcd.setCursor(0, 1);
    lcd.print(INJECTION_TIME_Json);  
}