Atlas pH Calibration from UI

I am trying to get the atlas pH probe to calibrate from the UI that I have created. I am building a batch bioreactor and while if it were just myself using it I could use the serial commands, but that isn’t the case.

Here is a link to the pH circuit

The sensor works, and is wired up correctly. I can get readings from it, and send commands to it. But I am having this problem.

I am trying to query the calibration slope, to do this I should send a command to circuit “SLOPE,?” and it should return a value such as ?SLOPE,99.9,99.9 and it does, sometimes.

Here is what I don’t get. If I have the following in my void loop() function it returns a correct slope reading.

void loop() {

  // shows the on/off state of the menu/submenu calls
  #if DEBUG
    Serial.print(F("\nMain Menu: "));
    Serial.print(mainMenu_State);
    Serial.print(F("\nQuick View: "));
    Serial.print(quickDisplay_State);
    Serial.print(F("\nOptions Menu: "));
    Serial.print(options_State);
    Serial.print(F("\nSetpoints Menu: "));
    Serial.print(editSetpoints_State);
    Serial.print(F("\nDetailed Display: "));
    Serial.print(detailedDisplay_State);
    Serial.print(F("\nCalibration Menu: "));
    Serial.print(calibrationMenu_State);
  #endif

  byte z = 0;
  byte code = 0;
  byte inputChar;
  char slope[20]; 
  
  Wire.beginTransmission(pHAddress);
  Wire.write("SLOPE,?");
  delay(500);
  Wire.requestFrom(pHAddress, 20, 1);
  code = Wire.read();
  Serial.print(F("\nResponse Code: "));
  Serial.print(code); 
  
  while (Wire.available()){
   inputChar = Wire.read();
   slope[z] = inputChar;
   z += 1;
   if (inputChar == 0){
    z = 0;
    
    Wire.endTransmission();
    break ;
   }
  }
  Serial.print(F("\nSlope: "));
  Serial.print(slope);
  delay(50000);
  
  // calls the appropriate menu  
  if (mainMenu_State == true)
    mainMenu();
  else if (quickDisplay_State == true)
    displayParameters();
  else if (detailedDisplay_State == true)
    tempDisplay();
  else if (options_State == true)
    optionsMenu();
  else if (editSetpoints_State == true)
    setpointsMenu();  
  else if (primeMenu_State == true)
    pumpPrime();
  else if (calibrationMenu_State == true)
    calibrationMenu();
    
}

If I comment out the following and go directly to the calibration screen for pH it never returns the slope, just the pH reading, which is accurate but not what I want.

Wire.beginTransmission(pHAddress);
  Wire.write("SLOPE,?");
  delay(500);
  Wire.requestFrom(pHAddress, 20, 1);
  code = Wire.read();
  Serial.print(F("\nResponse Code: "));
  Serial.print(code); 
  
  while (Wire.available()){
   inputChar = Wire.read();
   slope[z] = inputChar;
   z += 1;
   if (inputChar == 0){
    z = 0;
    
    Wire.endTransmission();
    break ;
   }
  }
  Serial.print(F("\nSlope: "));
  Serial.print(slope);
  delay(50000);
void pHCalibration(){
  byte z = 0;
  byte code = 0;
  byte inputChar;
  char slope[20];
  boolean endCal = false; 
  

  tft.fillScreen(BLACK);
  tft.setTextSize(2);
  tft.setCursor(0,80);
  tft.print(F("Place pH probe in 7.00 \nbuffer"));
  tft.setCursor(0,130);
  tft.print(F("Press continue to proceed"));
  tft.drawRect(80,160,160,40,GREEN);
  tft.fillRect(81,161,158,38,BLUE);
  tft.setCursor(110,172);
  tft.print(F("Continue"));
  while(!calibrationConfirm(270,380,320,700)){}  
  endCal = pHCalPoint(F("Cal,mid,4.00"));
  if (endCal == true){
    tft.fillScreen(BLACK);
    tft.setTextSize(2);
    tft.setTextColor(RED);
    tft.setCursor(0,100);
    tft.print(F("Calibration Failed! 1"));
    tft.setTextColor(WHITE);
    delay(1000);
    return ;
  }

  tft.fillScreen(BLACK);
  tft.setTextSize(2);
  tft.setCursor(0,80);
  tft.print(F("Place pH probe in 4.00 \nbuffer"));
  tft.setCursor(0,130);
  tft.print(F("Press continue to proceed"));
  tft.drawRect(80,160,160,40,GREEN);
  tft.fillRect(81,161,158,38,BLUE);
  tft.setCursor(110,172);
  tft.print(F("Continue"));
  while(!calibrationConfirm(270,380,320,700)){}
  endCal = pHCalPoint(F("Cal,mid,4.00"));
  if (endCal == true){
    tft.fillScreen(BLACK);
    tft.setTextSize(2);
    tft.setTextColor(RED);
    tft.setCursor(0,100);
    tft.print(F("Calibration Failed! 2"));
    tft.setTextColor(WHITE);
    delay(1000);
    return ;
  }

  tft.fillScreen(BLACK);
  tft.setTextSize(2);
  tft.setCursor(0,80);
  tft.print(F("Place pH probe in 10.00 \nbuffer"));
  tft.setCursor(0,130);
  tft.print(F("Press continue to proceed"));
  tft.drawRect(80,160,160,40,GREEN);
  tft.fillRect(81,161,158,38,BLUE);
  tft.setCursor(110,172);
  tft.print(F("Continue"));
  while(!calibrationConfirm(270,380,320,700)){}
  endCal = pHCalPoint(F("Cal,mid,10.00"));
  if (endCal == true){
    tft.fillScreen(BLACK);
    tft.setTextSize(2);
    tft.setTextColor(RED);
    tft.setCursor(0,100);
    tft.print(F("Calibration Failed! 3"));
    tft.setTextColor(WHITE);
    delay(1000);
    return ;
  }

  Serial.print(F("\nCalibration Complete"));  
  Wire.beginTransmission(pHAddress);
  Wire.write("SLOPE,?");
  delay(1000);
  Wire.requestFrom(pHAddress, 20, 1);
  code = Wire.read();
  Serial.print(F("\nResponse Code: "));
  Serial.print(code); 
  
  while (Wire.available()){
   inputChar = Wire.read();
   slope[z] = inputChar;
   z += 1;
   if (inputChar == 0){
    z = 0;    
    Wire.endTransmission();
    break ;
   }
  }
  Serial.print(F("\nSlope: "));
  Serial.print(slope);
    
  delay(5000);
  mainMenu_State = true;
  calibrationMenu_State = false;
  return ;    
}

boolean calibrationConfirm(int xMin, int xMax, int yMin, int yMax){
  while(true){
  TSPoint p = ts.getPoint();
  pinMode(TXM, OUTPUT);
  pinMode(TYP, OUTPUT);
  if (p.z > 10 && p.x > xMin && p.x < xMax && p.y > yMin && p.y < yMax)
    return true;
  }    
}

boolean pHCalPoint(String calibration){
    
  byte z = 0;
  byte code = 0;
  byte inputChar;
  char sensorInput[20]; 
  
  tft.fillScreen(BLACK);
  tft.setTextSize(2);
  tft.setCursor(0,100);
  tft.print(F("Calibrating"));
  
  for (int x = 0; x<12; x++){
    tft.print(F("."));
    delay(200);    
  }
  
  Wire.beginTransmission(pHAddress);
  Wire.write('r');
  delay(1500);
  Wire.requestFrom(pHAddress, 20, 1);
  code = Wire.read(); 
  Serial.print(F("\nResponse Code: "));
  Serial.print(code); 
  while (Wire.available()){
   inputChar = Wire.read();
   sensorInput[z] = inputChar;
   z += 1;
   if (inputChar == 0){
    z = 0;    
    Wire.endTransmission();
    break ;
   }
  }
  Serial.print(F("\nSensor Output: "));
  Serial.print(sensorInput); 
    
  if (code != 1)
    return true;

  tft.setCursor(0,130);
  tft.print(F("SUCCESS!"));
  delay(1000);  
  
  return false;
}

This no longer works. It just returns the pH reading.
If you notice I am not actually calibrating at this point. I am just querying the pH circuit to send a reading when I call calipHPoint(String). I don’t want to erase the current calibration.

I’ve ommited a lot of code for other sections of the program that I believe to be irrelevant to the issue. I can call the pHCalibration() directly from the main loop, or go through all the menus and it gives me the same problem. I’ve attached the whole program though, in case you want to see it.

Sorry for my coding too, its not the best. This is my first big program.

SBR_V0.6.2.ino (50.6 KB)

Figured it out. It was a pretty stupid error on my part. I needed the commands to be sent with the following

Wire.beginTransmission(pHAddress); Wire.write("Slope,?"); Wire.endTransmission();

I didn't include the Wire.endTransmission until later before. Ugh spent way to much time on this one line!