String to 'char*' problem. Syringe pump project

They're not - don't forget it's I2C :grin:

right, I just had a look at the library and they indeed have the whole shield behind I2C

so the getButtonState() function dealing with the button needs to be rewritten using the readButtons() function from the library and the enum needs to be modified
enum listOfButtons {RIGHT, UP, DOWN, LEFT, SELECT, NA};to match Adafruit's values

something like this would probably do the trick

enum listOfButtons {RIGHT=0x02, UP=0x08, DOWN=0x04, LEFT=0x10, SELECT=0x01, NA=0x20};
...
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
...

void getButtonState()
{
  uint8_t button = lcd.readButtons();
  if (button == NA) {
    lastButton = NA;
    buttonState = RELEASE;
  } else if (button != lastButton) {
    lastButton = button;
    buttonState = RELEASE;
    buttonPressTime = millis();
  }
  else if (millis() - buttonPressTime > LONGPRESSDELAY) buttonState = LONGPRESS;
  else if (millis() - buttonPressTime > DEBOUNCEDELAY && buttonState == RELEASE) buttonState = SHORTPRESS;
}

Thank you for your great help.
After a weekend of chasing error messages, I at least have something that responds. The only problem is that the response seems pretty random. I can only bring up a few of the menu items, and after a few clicks, I get stuck in an empty window. The only way to get out is a reset.
As an example, it always starts at "infuse" after a reset, but after clicking away from it, I can never bring up Infuse again without resetting.


#include <EEPROM.h>
#include <Adafruit_RGBLCDShield.h>
#include <Wire.h>
#include <utility/Adafruit_MCP23017.h>




/********************************************************************
          BASIC SETTINGS
********************************************************************/

// Stepper motor
#define NOFMICROSTEPS 16      // The number of microsteps per step
#define NOFSTEPSPER360 200    // The number of steps per revolution
#define MAXRPM 240            // Maximum RPM (rotations per minute)
#define INVERTDIRECTION true // If the carriage moves in the opposite direction, change to 'false'

// Leadscrew
#define MMPER360 2            // Leadscrew pitch, mm per revolution

// Arduino pins
#define STEP_PIN 2            // STEP pin (A4988)
#define DIRECTION_PIN 3       // DIR pin (A4988)
#define ENABLE_PIN 12         // EN pin (A4988)
#define ENDSTOP_PIN1 A1       // Endstop pin (forward movement)
#define ENDSTOP_PIN2 A2       // Endstop pin (backward movement)
#define BUZZER_PIN 11         // Buzzer pin
#define BUTTONS_PIN A0        // Button pin (lcd keypad shield)

/********************************************************************/



#define DEBOUNCEDELAY 50
#define LONGPRESSDELAY 450
#define AUTOCHANGINGDELAY 300

#define NITEMS 43

#define LINK2S 12
#define LINK2E 13
#define LINK2V 20
#define LINK2T 21
#define LINK2F 22
#define LINK2DIA 41
#define LINK2LPV 42


Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
struct MenuItem
{
  uint8_t button[4];
  uint8_t type;
  const char *text;
  uint8_t address;
  uint32_t value;
};

enum listOfButtons {RIGHT = 0x02, UP = 0x08, DOWN = 0x04, LEFT = 0x10, SELECT = 0x01, NA = 0x20};





enum listOfButtonStates {RELEASE, SHORTPRESS, MEDIUMPRESS, LONGPRESS};
enum listOfPrograms {CHANGEVALUE = 200, SELECTFROMLIST, INFUSEVOLUME, INFUSETIME, REFILLVOLUME, REFILLFULL, CYCLEMODE, FIRMWAREINFO};
enum listOfItemTypes {TEXT, LIST, VOLUME, TIME, FLOWRATE, LENGTHPERVOLUME, DIAMETER};

const char firmwareInfo[] = "0.9a";
const uint16_t volumeDivider[2] = {1000, 1};
const uint16_t timeDivider[3] = {1, 60, 3600};
const uint16_t flowrateDivider[4] = {60000, 1000, 60, 1};
const float stepsPERmm = NOFSTEPSPER360 / MMPER360;

MenuItem items[NITEMS];
uint8_t lastButton = NA;
uint8_t buttonState = RELEASE;
uint32_t buttonPressTime = 0;
uint8_t currentItem = 1;
float coef;
uint8_t endStopPin;
volatile uint32_t ustepCounter;
uint32_t ustepCounterLimit;

uint32_t getValue(uint8_t itemNo);
void changeValue();
void setValue(uint8_t itemNo, uint8_t digits[8]);
void selectFromList();
void calculateActualValue(uint8_t itemNo);
void recalculateSyringe(uint8_t itemNo);
void printScreen();
void printUnits();
void printFirmwareInfo();
void printTimeAndVolume(uint16_t pumpingTime, uint32_t pumpingVolume);
void showScreensaver();
void readFromEEPROM(uint8_t itemNo);
void writeToEEPROM(uint8_t itemNo);
void getButtonState();
uint16_t valueDivider (uint8_t n);
uint8_t getElementNo(uint8_t linkToList);
void waitingForButton(uint8_t buttonCode, uint8_t itemNo);
void beep (uint16_t delayOn = 15, uint16_t delayOff = 100);
bool checkEndstop(int8_t pumpingDirection);
void infuseVolume();
void infuseTime();
void refillVolume();
void refillFull();
void pumpSingly(int8_t pumpingDirection, uint32_t flowrate, uint32_t volume);
void pumpContinuously();
uint8_t pump(uint32_t flowrate, uint32_t volume);



/********************************************************************
  setup
********************************************************************/
void setup()
{
  lcd.begin(16, 2);

  pinMode(STEP_PIN, OUTPUT);
  pinMode(DIRECTION_PIN, OUTPUT);
  pinMode(ENABLE_PIN, OUTPUT);
  pinMode(ENDSTOP_PIN1, INPUT_PULLUP);
  pinMode(ENDSTOP_PIN2, INPUT_PULLUP);
  pinMode(BUZZER_PIN, OUTPUT);

  digitalWrite(ENABLE_PIN, HIGH);

  items[1]  = {5, 0, 2, 0, TEXT, "Infuse"};
  items[2]  = {7, 1, 3, 0, TEXT, "Refill"};
  items[3]  = {9, 2, 4, 0, TEXT, "Cycle Mode"};
  items[4]  = {10, 3, 0, 0, TEXT, "Settings"};
  items[5]  = {15, 0, 6, 1, TEXT, "Target Volume"};
  items[6]  = {16, 5, 0, 1, TEXT, "Target Time"};
  items[7]  = {17, 0, 8, 2, TEXT, "Full Refill"};
  items[8]  = {18, 7, 0, 2, TEXT, "Target Volume"};
  items[9]  = {19, 0, CHANGEVALUE, 3, FLOWRATE, "infuse flow:", 1, 120000000};
  items[10] = {20, 0, 11, 4, TEXT, "Units"};
  items[11] = {23, 10, 12, 4, TEXT, "Syringe"};
  items[12] = {25, 11, 13, 4, LIST, "Sound", 2};
  items[13] = {27, 12, 14, 4, LIST, "EEPROM", 3};
  items[14] = {FIRMWAREINFO, 13, 0, 4, TEXT, "Firmware"};
  items[15] = {29, 0, CHANGEVALUE, 5, VOLUME, "volume:", 4, 1000000};
  items[16] = {30, 0, CHANGEVALUE, 6, TIME, "time:", 5, 60000};
  items[17] = {REFILLFULL, 0, CHANGEVALUE, 7, FLOWRATE, "flowrate:", 6, 2000000};
  items[18] = {31, 0, CHANGEVALUE, 8, VOLUME, "volume:", 7, 1000000};
  items[19] = {CYCLEMODE, 0, CHANGEVALUE, 9, FLOWRATE, "refill flow:", 8, 2000000};
  items[20] = {32, 0, 21, 10, LIST, "Volume Units", 9};
  items[21] = {34, 20, 22, 10, LIST, "Time Units", 10};
  items[22] = {37, 21, 0, 10, LIST, "Flowrate Units", 11};
  items[23] = {41, 0, 24, 11, TEXT, "Diameter"};
  items[24] = {42, 23, 0, 11, TEXT, "Length/Volume"};
  items[25] = {SELECTFROMLIST, 0, 26, 12, TEXT, "on"};
  items[26] = {SELECTFROMLIST, 25, 0, 12, TEXT, "off"};
  items[27] = {SELECTFROMLIST, 0, 28, 13, TEXT, "on"};
  items[28] = {SELECTFROMLIST, 27, 0, 13, TEXT, "off"};
  items[29] = {INFUSEVOLUME, 0, CHANGEVALUE, 15, FLOWRATE, "flowrate:", 12, 2000000};
  items[30] = {INFUSETIME, 0, CHANGEVALUE, 16, FLOWRATE, "flowrate:", 13, 2000000};
  items[31] = {REFILLVOLUME, 0, CHANGEVALUE, 18, FLOWRATE, "flowrate:", 14, 2000000};
  items[32] = {SELECTFROMLIST, 0, 33, 20, TEXT, "mL"};
  items[33] = {SELECTFROMLIST, 32, 0, 20, TEXT, "uL"};
  items[34] = {SELECTFROMLIST, 0, 35, 21, TEXT, "s"};
  items[35] = {SELECTFROMLIST, 34, 36, 21, TEXT, "min"};
  items[36] = {SELECTFROMLIST, 35, 0, 21, TEXT, "h"};
  items[37] = {SELECTFROMLIST, 0, 38, 22, TEXT, "mL/s"};
  items[38] = {SELECTFROMLIST, 37, 39, 22, TEXT, "mL/min"};
  items[39] = {SELECTFROMLIST, 38, 40, 22, TEXT, "uL/s"};
  items[40] = {SELECTFROMLIST, 39, 0, 22, TEXT, "uL/min"};
  items[41] = {0, 0, CHANGEVALUE, 23, DIAMETER, "diameter:", 15, 11284};
  items[42] = {0, 0, CHANGEVALUE, 24, LENGTHPERVOLUME, "length/volume:", 16, 10000};

  for (uint8_t i = 1; i < NITEMS; i++)
  {
    if (items[i].type != TEXT) readFromEEPROM(i);
  }

  recalculateSyringe(LINK2DIA);
  beep();
  showScreensaver();
}



/********************************************************************
  loop
********************************************************************/
void loop()
{
  uint8_t nextItem;
  getButtonState();
  if (buttonState == SHORTPRESS && lastButton != SELECT)
  {
    buttonState = MEDIUMPRESS;

    nextItem = items[currentItem].button[lastButton];
    if (nextItem != 0 && nextItem < 200)
    {
      currentItem = nextItem;
      printScreen();
    }
    else if (nextItem == CHANGEVALUE) changeValue();
    else if (nextItem == SELECTFROMLIST) selectFromList();
    else if (nextItem == INFUSEVOLUME) infuseVolume();
    else if (nextItem == INFUSETIME) infuseTime();
    else if (nextItem == REFILLVOLUME) refillVolume();
    else if (nextItem == REFILLFULL) refillFull();
    else if (nextItem == CYCLEMODE) pumpContinuously();
    else if (nextItem == FIRMWAREINFO) printFirmwareInfo();
  }
}



/********************************************************************
  getValue
********************************************************************/
uint32_t getValue(uint8_t itemNo)
{
  uint16_t divider = valueDivider(items[itemNo].type);
  uint8_t lastDigitIncrement = 0;
  if ( uint16_t(items[itemNo].value % divider) > divider / 2) lastDigitIncrement = 1;

  if (items[itemNo].value / divider > 99999999)
  {
    items[itemNo].value = divider * 99999999;
    return 99999999;
  }
  else return (items[itemNo].value / divider) + lastDigitIncrement;
}



/********************************************************************
  changeValue
********************************************************************/
void changeValue()
{
  uint8_t digits[8];
  uint32_t value = getValue(currentItem);
  for (int8_t i = 7; i >= 0; i--)
  {
    digits[i] = uint8_t(value % 10);
    value /= 10;
  }

  lcd.setCursor(0, 1);
  for (int8_t i = 0; i < 4; i++) lcd.print(digits[i]);

  lcd.setCursor(0, 1);
  lcd.cursor();
  int8_t i = 0;
  while (i >= 0 && i < 8)
  {
    getButtonState();
    if (buttonState == SHORTPRESS || buttonState == LONGPRESS)
    {
      if (lastButton == UP) digits[i] = (digits[i] + 1) % 10;
      else if (lastButton == DOWN) digits[i] = (digits[i] + 9) % 10;
      lcd.print(digits[i]);

      if (lastButton == RIGHT) i++;
      else if (lastButton == LEFT) i--;

      if (i == -1 && buttonState != SHORTPRESS) i++;
      if (i == 8 && buttonState != SHORTPRESS) i--;

      if (i < 5)lcd.setCursor(i, 1);
      else lcd.setCursor(i + 1, 1);

      if (buttonState == SHORTPRESS) buttonState = MEDIUMPRESS;
      else if (buttonState == LONGPRESS)
      {
        uint32_t nextMillis = millis() + AUTOCHANGINGDELAY;
        while (nextMillis > millis() && buttonState == LONGPRESS) getButtonState();
      }
    }
  }

  if (i == 8)
  {
    bool isSame = true;
    value = getValue(currentItem);
    for (int8_t j = 7; j >= 0 && isSame == true; j--)
    {
      if (digits[j] != uint8_t(value % 10)) isSame = false;
      value /= 10;
    }

    bool isZero = true;
    for (int8_t j = 7; j >= 0 && isZero == true; j--)
    {
      if (digits[j] != 0) isZero = false;
    }

    if (isSame == false && isZero == false)
    {
      setValue(currentItem, digits);
      beep();
    }
  }

  lcd.noCursor();
  lcd.setCursor(0, 1);
  printScreen();
}



/********************************************************************
  setValue
********************************************************************/
void setValue(uint8_t itemNo, uint8_t digits[8])
{
  uint32_t value = 0;
  for (int8_t i = 0; i < 8; i++) value = value * 10 + digits[i];

  uint16_t divider = valueDivider(items[itemNo].type);
  if (4294000000 / divider < value) items[itemNo].value = 4294000000;
  else items[itemNo].value = value * divider;

  if (itemNo == LINK2LPV || itemNo == LINK2DIA)
  {
    recalculateSyringe(itemNo);
    writeToEEPROM(LINK2LPV);
    writeToEEPROM(LINK2DIA);
  }
  else writeToEEPROM(itemNo);
}



/********************************************************************
  selectFromList
********************************************************************/
void selectFromList()
{
  uint8_t parentItem = items[currentItem].button[LEFT];
  items[parentItem].button[RIGHT] = currentItem;
  writeToEEPROM(parentItem);
  beep();
  currentItem = parentItem;
  printScreen();
}



/********************************************************************
  calculateActualValue
********************************************************************/
void calculateActualValue(uint8_t itemNo)
{
  if (items[itemNo].type == FLOWRATE)
  {
    float maxFlowrate = 1e9 * MAXRPM * MMPER360 / (float)items[LINK2LPV].value;
    if ((float)(items[itemNo].value) > maxFlowrate) items[itemNo].value = (uint32_t)maxFlowrate;

    float ustepsPERmin = coef * NOFMICROSTEPS * (float)items[itemNo].value;
    if (ustepsPERmin < 14.4) ustepsPERmin = 14.4;
    float multiplier;
    if (ustepsPERmin >= 229) multiplier = 15000000;
    else multiplier = 937500;
    float tempFloat = multiplier / ustepsPERmin;
    uint16_t countsPERustepActual = (uint16_t)(tempFloat + 0.5);
    tempFloat = multiplier / (float)countsPERustepActual;
    tempFloat /= (float)(coef * NOFMICROSTEPS);
    items[itemNo].value = (uint32_t)tempFloat;
  }

  else if (items[itemNo].type == VOLUME)
  {
    uint32_t nSteps = (uint32_t)(coef * (float)items[itemNo].value + 0.5);
    float tempFloat = (float)nSteps / coef;
    items[itemNo].value = (uint32_t)tempFloat;
  }

  else if (items[itemNo].type == TIME)
  {
    if (items[itemNo].value > 59994000) items[itemNo].value = 59994000;
    items[itemNo].value -= (items[itemNo].value % 1000);
  }
}



/********************************************************************
  recalculateSyringe
********************************************************************/
void recalculateSyringe(uint8_t itemNo)
{
  if (itemNo == LINK2LPV)
  {
    float temp = 1128379 / sqrt((float)items[LINK2LPV].value);
    items[LINK2DIA].value = uint32_t(temp + 0.5);
  }
  else if (itemNo == LINK2DIA)
  {
    float temp = 1128379 / (float)items[LINK2DIA].value;
    temp *= temp;
    items[LINK2LPV].value = uint32_t(temp + 0.5);
  }

  coef = ((float)items[LINK2LPV].value * stepsPERmm) * 1e-9;
}



/********************************************************************
  printScreen
********************************************************************/
void printScreen()
{
  lcd.clear();
  lcd.setCursor(0, 0);

  if (items[currentItem].type == TEXT || items[currentItem].type == LIST)
  {
    lcd.print(F("> "));
    lcd.print(items[currentItem].text);

    if (items[currentItem].button[DOWN] != 0 && items[currentItem].button[DOWN] < 200)
    {
      lcd.setCursor(0, 1);
      lcd.print(F("  "));
      lcd.print(items[items[currentItem].button[DOWN]].text);
    }
  }

  else
  {
    calculateActualValue(currentItem);
    uint32_t value = getValue(currentItem);
    char outputLine[10] = "    0.000";
    for (int8_t i = 8; i >= 0 && value > 0; i--)
    {
      if (i != 5)
      {
        outputLine[i] = char((value % 10) + '0');
        value /= 10;
      }
    }

    lcd.print(items[currentItem].text);
    lcd.setCursor(0, 1);
    lcd.print(outputLine);
    printUnits();
  }
}



/********************************************************************
  printUnits
********************************************************************/
void printUnits()
{
  lcd.print(F(" "));
  if (items[currentItem].type == VOLUME) lcd.print(items[items[LINK2V].button[RIGHT]].text);
  else if (items[currentItem].type == TIME) lcd.print(items[items[LINK2T].button[RIGHT]].text);
  else if (items[currentItem].type == FLOWRATE) lcd.print(items[items[LINK2F].button[RIGHT]].text);
  else if (items[currentItem].type == LENGTHPERVOLUME)
  {
    lcd.print(F("mm/"));
    lcd.print(items[items[LINK2V].button[RIGHT]].text);
  }
  else if (items[currentItem].type == DIAMETER) lcd.print(F("mm"));
}



/********************************************************************
  printFirmwareInfo
********************************************************************/
void printFirmwareInfo()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("version:"));
  lcd.setCursor(0, 1);
  lcd.print(F("  "));
  lcd.print(firmwareInfo);

  waitingForButton(LEFT, currentItem);
}



/********************************************************************
  printTimeAndVolume
********************************************************************/
void printTimeAndVolume(uint16_t pumpingTime, uint32_t pumpingVolume)
{
  char outputLine[17] = "  0:00    0000xL";
  outputLine[14] = items[items[LINK2V].button[RIGHT]].text[0];

  uint8_t pointLocation;
  if (pumpingVolume < 100000)pointLocation = 3;
  else if (pumpingVolume < 1000000)
  {
    pointLocation = 4;
    pumpingVolume /= 10;
  }
  else
  {
    pointLocation = 6;
    pumpingVolume /= 100;
  }
  if (pointLocation < 6)outputLine[pointLocation + 8] = '.';
  uint16_t timeDivider;
  for (int8_t i = 5; i >= 0; i--)
  {
    if (pumpingTime > 0 && i != 3)
    {
      if (i == 4) timeDivider = 6;
      else timeDivider = 10;
      outputLine[i] = uint8_t(pumpingTime % timeDivider) + '0';
      pumpingTime /= timeDivider;
    }

    if (pumpingVolume > 0 && i != pointLocation)
    {
      outputLine[i + 8] = uint8_t(pumpingVolume % 10) + '0';
      pumpingVolume /= 10;
    }
  }

  lcd.setCursor(0, 1);
  lcd.print(outputLine);
}



/********************************************************************
  showScreensaver
********************************************************************/
void showScreensaver()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(F("   OpenSP 0.9   "));
  lcd.setCursor(0, 1);
  lcd.print(F("www.mass-spec.ru"));
  currentItem = 1;
  waitingForButton(NA, currentItem);
}



/********************************************************************
  getButtonState
********************************************************************/
void getButtonState()

{
  uint8_t button = lcd.readButtons();
  if (button == NA) {
    lastButton = NA;
    buttonState = RELEASE;
  } else if (button != lastButton) {
    lastButton = button;
    buttonState = RELEASE;
    buttonPressTime = millis();
  }
  else if (millis() - buttonPressTime > LONGPRESSDELAY) buttonState = LONGPRESS;
  else if (millis() - buttonPressTime > DEBOUNCEDELAY && buttonState == RELEASE) buttonState = SHORTPRESS;
}





/********************************************************************
  valueDivider
********************************************************************/
uint16_t valueDivider (uint8_t itemType)
{
  if (itemType == VOLUME) return volumeDivider[getElementNo(LINK2V)];
  else if (itemType == TIME) return timeDivider[getElementNo(LINK2T)];
  else if (itemType == FLOWRATE) return flowrateDivider[getElementNo(LINK2F)];
  else if (itemType == LENGTHPERVOLUME) return 1000 / volumeDivider[getElementNo(LINK2V)];
  else if (itemType == DIAMETER) return 1;
  return 1;
}



/********************************************************************
  getElementNo
********************************************************************/
uint8_t getElementNo(uint8_t linkToList)
{
  uint8_t uppermostItem = items[linkToList].button[RIGHT];
  uint8_t elementNo = 0;
  while (items[uppermostItem].button[UP] != 0)
  {
    uppermostItem = items[uppermostItem].button[UP];
    elementNo++;
  }
  return elementNo;
}



/********************************************************************
  waitingForButton
********************************************************************/
void waitingForButton(uint8_t button, uint8_t itemNo)
{
  if (button == NA) while (buttonState != SHORTPRESS) getButtonState();
  else while (buttonState != SHORTPRESS || lastButton != button) getButtonState();
  buttonState = MEDIUMPRESS;
  currentItem = itemNo;
  printScreen();
}



/********************************************************************
  beep
********************************************************************/
void beep (uint16_t delayOn, uint16_t delayOff)
{
  uint8_t daughterItem = items[LINK2S].button[RIGHT];
  if (items[daughterItem].text == "on")
  {
    digitalWrite(BUZZER_PIN, HIGH);
    delay(delayOn);
    digitalWrite(BUZZER_PIN, LOW);
    delay(delayOff);
  }
}



/********************************************************************
  checkEndstop
********************************************************************/
bool checkEndstop(int8_t pumpingDirection)
{
  bool canMove = true;
  if (digitalRead(ENDSTOP_PIN1) == LOW && pumpingDirection > 0) canMove = false;
  else if (digitalRead(ENDSTOP_PIN2) == LOW && pumpingDirection < 0) canMove = false;

  if (canMove == false)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    if (pumpingDirection > 0) lcd.print(F("SYRINGE IS EMPTY"));
    else if (pumpingDirection < 0) lcd.print(F("SYRINGE IS FULL"));
    beep(300);
    waitingForButton(LEFT, 1);
    return false;
  }
  else return true;
}



/********************************************************************
  readFromEEPROM
********************************************************************/
void readFromEEPROM(uint8_t itemNo)
{
  if (items[itemNo].type == LIST)
  {
    uint8_t temp;
    EEPROM.get(4 * items[itemNo].address, temp);
    if (temp != 0 && temp + 1 != 0)
    {
      if (items[temp].button[LEFT] == itemNo) items[itemNo].button[RIGHT] = temp;
    }
  }
  else
  {
    uint32_t temp;
    EEPROM.get(4 * items[itemNo].address, temp);
    if (temp != 0 && temp + 1 != 0) items[itemNo].value = temp;
  }
}



/********************************************************************
  writeToEEPROM
********************************************************************/
void writeToEEPROM(uint8_t itemNo)
{
  uint8_t daughterItem = items[LINK2E].button[RIGHT];
  if (!strcmp(items[daughterItem].text, "on") || itemNo == LINK2E)
  {
    if (items[itemNo].type == LIST) EEPROM.put(4 * items[itemNo].address, items[itemNo].button[RIGHT]);
    else EEPROM.put(4 * items[itemNo].address, items[itemNo].value);
  }
}



/********************************************************************
  infuseVolume
********************************************************************/
void infuseVolume()
{
  int8_t pumpingDirection = 1;
  uint32_t flowrate = items[currentItem].value;
  uint32_t volume = items[items[currentItem].button[LEFT]].value;

  pumpSingly(pumpingDirection, flowrate, volume);
}



/********************************************************************
  infuseTime
********************************************************************/
void infuseTime()
{
  int8_t pumpingDirection = 1;
  uint32_t pumpTime = items[items[currentItem].button[LEFT]].value;
  uint32_t flowrate = items[currentItem].value;
  float tempFloat = (float)flowrate * (float)pumpTime;
  tempFloat /= 60000;
  uint32_t volume;
  if (tempFloat > 4294000000) volume = 4294000000;
  else volume = (uint32_t)tempFloat;

  pumpSingly(pumpingDirection, flowrate, volume);
}



/********************************************************************
  refillVolume
********************************************************************/
void refillVolume()
{
  int8_t pumpingDirection = -1;
  uint32_t flowrate = items[currentItem].value;
  uint32_t volume = items[items[currentItem].button[LEFT]].value;

  pumpSingly(pumpingDirection, flowrate, volume);
}



/********************************************************************
  refillFull
********************************************************************/
void refillFull()
{
  int8_t pumpingDirection = -1;
  uint32_t flowrate = items[currentItem].value;
  uint32_t volume = 4294000000;

  pumpSingly(pumpingDirection, flowrate, volume);
}



/********************************************************************
  pumpSingly
********************************************************************/
void pumpSingly(int8_t pumpingDirection, uint32_t flowrate, uint32_t volume)
{
  if (checkEndstop(pumpingDirection) == true)
  {
    pump(pumpingDirection, flowrate, volume);
    beep(300);
    waitingForButton(LEFT, 1);
  }
}



/********************************************************************
  pumpContinuously
********************************************************************/
void pumpContinuously()
{
  int8_t pumpingDirection[2] = {1, -1};
  uint32_t flowrate[2] = {items[items[currentItem].button[LEFT]].value, items[currentItem].value};
  uint32_t volume = 4294000000;
  uint8_t i = 0;

  while (pump(pumpingDirection[i], flowrate[i], volume) != 2)
  {
    i = 1 - i;
    beep();
    delay(1000);
  }

  beep(300);
  waitingForButton(LEFT, 1);
}



/********************************************************************
  pump
********************************************************************/
uint8_t pump(int8_t pumpingDirection, uint32_t flowrate, uint32_t volume)
{
  float tempFloat;

  ustepCounterLimit = (uint32_t)(coef * volume + 0.5);
  ustepCounterLimit *= NOFMICROSTEPS;

  float ustepsPERmin = coef * NOFMICROSTEPS * (float)flowrate;
  if (ustepsPERmin < 14.4) ustepsPERmin = 14.4;
  float multiplier;
  if (ustepsPERmin >= 229) multiplier = 15000000;
  else multiplier = 937500;
  tempFloat = multiplier / ustepsPERmin;
  uint16_t countsPERustepActual = (uint16_t)(tempFloat + 0.5);
  float ustepsPERsActual = multiplier / (float)countsPERustepActual;
  ustepsPERsActual /= 60;

  lcd.clear();
  lcd.setCursor(0, 0);
  if (pumpingDirection > 0)
  {
    endStopPin = ENDSTOP_PIN1;
    if (INVERTDIRECTION == true) digitalWrite(DIRECTION_PIN, LOW);
    else digitalWrite(DIRECTION_PIN, HIGH);
    lcd.print(F(" >> INFUSING >> "));
  }
  else
  {
    endStopPin = ENDSTOP_PIN2;
    if (INVERTDIRECTION == true) digitalWrite(DIRECTION_PIN, HIGH);
    else digitalWrite(DIRECTION_PIN, LOW);
    lcd.print(F(" << REFILLING <<"));
  }
  lcd.setCursor(0, 1);
  printTimeAndVolume(0, 0);

  TCNT1 = 0;
  TCCR1A = 0;
  TCCR1B |= (1 << WGM12);
  if (ustepsPERmin >= 229)
  {
    TCCR1B &= ~( 1 << CS12);
    TCCR1B |= (1 << CS11);
    TCCR1B |= (1 << CS10);
  }
  else
  {
    TCCR1B |= (1 << CS12);
    TCCR1B &= ~( 1 << CS11);
    TCCR1B |= (1 << CS10);
  }

  digitalWrite(ENABLE_PIN, LOW);
  digitalWrite(STEP_PIN, LOW);

  ustepCounter = 1;
  uint32_t ustepCounterActual;
  float coef2 = ((float)items[LINK2LPV].value * stepsPERmm * 1e-9) * (float)valueDivider(VOLUME) * NOFMICROSTEPS * 10;
  bool isManualStop = false;
  uint32_t pumpingVolume;
  uint16_t pumpingTime = 1;
  uint32_t nextMillis = millis() + 1000;
  OCR1A = (countsPERustepActual - 1);
  TIMSK1 |= (1 << OCIE1A);
  while ( (TIMSK1 & (1 << OCIE1A)) )
  {
    getButtonState();
    if (buttonState == SHORTPRESS && lastButton == LEFT)
    {
      buttonState = MEDIUMPRESS;
      lcd.setCursor(0, 0);
      lcd.print(F("  STOP PUMPING? "));
      lcd.setCursor(0, 1);
      lcd.print(F("(YES)       (NO)"));
      while ( (TIMSK1 & (1 << OCIE1A)) )
      {
        getButtonState();
        if (buttonState == SHORTPRESS)
        {
          buttonState = MEDIUMPRESS;
          if (lastButton == LEFT)
          {
            TIMSK1 &= ~( 1 << OCIE1A);
            isManualStop = true;
          }
          else if (lastButton == RIGHT)
          {
            lcd.setCursor(0, 0);
            if (pumpingDirection > 0) lcd.print(F(" >> INFUSING >> "));
            else lcd.print(F(" << REFILLING <<"));
            break;
          }
        }
      }
    }

    if (nextMillis <= millis())
    {
      cli();
      ustepCounterActual = ustepCounter;
      sei();

      pumpingVolume = (uint32_t)(((float)ustepCounterActual / coef2) + 0.5);
      printTimeAndVolume(pumpingTime, pumpingVolume);
      pumpingTime++;
      nextMillis += 1000;
    }
  }

  digitalWrite(ENABLE_PIN, HIGH);

  lcd.setCursor(0, 1);
  pumpingVolume = (uint32_t)(((float)ustepCounter / coef2) + 0.5);
  printTimeAndVolume(pumpingTime, pumpingVolume);


  lcd.setCursor(0, 0);
  if (isManualStop)
  {
    lcd.print(F("  MANUAL STOP   "));
    return 2;
  }
  if (ustepCounterLimit == ustepCounter - 1)
  {
    lcd.print(F("    FINISHED    "));
    return 0;
  }
  else
  {
    lcd.print(F("UNEXPECTED STOP "));
    return 1;
  }
}



/********************************************************************
  ISR(TIMER1_COMPA_vect)
********************************************************************/
ISR(TIMER1_COMPA_vect)
{
  digitalWrite(STEP_PIN, HIGH);
  if (ustepCounter == ustepCounterLimit) TIMSK1 &= ~( 1 << OCIE1A);
  if ( digitalRead(endStopPin) == LOW) TIMSK1 &= ~( 1 << OCIE1A);
  delayMicroseconds(10);
  digitalWrite(STEP_PIN, LOW);
  ustepCounter++;
}

in that case there might be other issues with the way this is coded. ideally you should bring it up to the original author, he might have some recommendations

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.