Some help, please - unexpected behavior when interfacing load cell and keypad

Oay, this is going to be a bit of a novel, but please bear with me. I've been working on this for a while, and have tried a lot to get it working.

I've been in the process of building a powder trickler system for the past 3 months based around a Mega 2560 clone. The plan is to have the motor driver, load cell, keypad and LCD screen all controlled by the Arduino in a way that allows for standalone use.

My project consists of:

  • Storm Interface 720BLK 16 key matrix keypad
  • Sparkfun HX711 breakout
  • Sparkfun Serial-enabled 16x2 LCD screen
  • NEMA17 stepper motor
  • Big Easy Driver
  • Generic 100g load cell (I also have 50g and 500g cells on hand)

The hardware is all assembled (at least as far as the first prototype is concerned), and I have been able to get each of the individual components working on their own (though I haven't written the motor portion yet, I've been able to use sample code), and it's a pretty trivial matter to get the LCD working with the right libs (I even got bored and wrote out code to vary the backlight brightness). The trouble comes in when I try to add the scale functionality in on top of the keypad code.

I didn't write the keypad code; I actually pulled it from an older post on this site, where someone needed to input multi-digit sequences (I think they were building a lock or something). However, it was pretty easy to adapt it to my needs (or so I thought). The way it's written, the keypad keeps waiting for input until the # key is pressed, then it returns the integer value of whatever key combination the user presses - pretty straightforward.

Except when I add the scale code, the load cell doesn't update unless I press #, in which case it updates once, until I press it again. That's not practical, and it has a nasty habit of zeroing out the variable in the loop() function that's set to catch the readings. If I remove the call to GetNumber(), the load cell fires right up, and behaves properly.

I thought I might be able to use interrupts, so in looking over those in hopes of finding some sample code around which I could write a replacement for the GetNumber() function, I came across this blog post detailing a pseudo-interrupt event built into the keypad library. I gave it a go, and my limited test seemed to work - the load cell measured unimpeded, and I was able to put some digits up on the LCD screen (and moved my backlight code over as part of my test, which also worked). However, I don't think I'm remotely close to where the code needs to be to do what I want. I tried expanding it to look more like GetNumber(), and I even tried using the event to call GetNumber().

Anyway, this is the part where I ask for guidance. Please, any ideas you might have, I'd be grateful. I'm so close to getting it working I can taste it. And that is a frustrating feeling.

Okay, so it seems my code is too long to add in one post.

Here’s my code as it stands right now (1 of 2):

#include <kissStepper.h>
#include <HX711.h>
#include <SerLCD.h>
#include <SoftwareSerial.h>
#include <Keypad.h>

#define RX 2
#define LOAD_CELL_DAT 14
#define LOAD_CELL_CLK 15
#define EN 28
#define MS1 27
#define MS2 29
#define MS3 30
#define RST 26
#define STP 3
#define DIR 4

const uint16_t motorFullStepsPerRev=200;

kissStepper motor(
  kissPinAssignments(DIR,STP,EN,MS1,MS2,MS3),
  kissMicrostepConfig(MICROSTEP_8)
  );

HX711 scale(LOAD_CELL_DAT,LOAD_CELL_CLK);
float calibration_factor=-2600;
float reading;
float v1 = 0;
//int v2 = 0;
//int v3 = 0;
float target=0;

int i=0,num=0;
const long interval=1000;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads

char hexaKeys[ROWS][COLS] = 
{
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {5,6, 12, 11}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 8,9,10}; //connect to the column pinouts of the keypad
Keypad key = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS );
SoftwareSerial lcdserial(0,RX);
SerLCD lcd(lcdserial);

int getaverageweight(int x)
{
  float weight=0,average=0,sum=0;
  for(i;i<=x;i++)
  {
    weight=scale.get_units();
    sum=sum+weight;
  }
  average=sum/x;
  return average;
}
void currentcharge()
{
  lcd.setPosition(2,0);
  lcd.print("Current:");
  lcd.setPosition(2,8);
  // 0.
  //average=getaverageweight(10);
  lcd.print(reading,1);
  //lcd.print(average);
  
}
void targetcharge()
{
  lcd.setPosition(1,0);
  lcd.print("Target:");
  lcd.setPosition(1,7);    //change cursor position on LCD to after 
  Serial.print(target);    //Print variable "target" to the serial monitor for troubleshooting/verification purposes
  lcd.print(target,1);     //PRint target 
}


void setup()
{                           
  Serial.begin(9600);
  lcdserial.begin(9600);
  motor.begin(MICROSTEP_8,200);
  lcd.begin();
  lcd.displayOn();
  scale.set_scale(calibration_factor);
  scale.tare();
  lcd.setBacklight(157);
  lcd.print("LCD initialized");                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
  delay(1000);
  lcd.clear();
  key.addEventListener(keypadEvent);                       
}

void loop()
{
   reading=scale.get_units();
   //v1 = GetNumber();        //Get raw data from keypad\
   //v1=key.getKeys;
   target=v1*0.1;           //multiply by 0.1 to get a number with tenths
   //target=num*0.1;
   //target=GetNumber();
   char state=key.getKeys();
   targetcharge();
   currentcharge();
   lcd.setPosition(2,8);
   lcd.print(reading,1);
   //if(currentweight<=(target-2)
   //{
    
   //}
}

(2 of 2)

int GetNumber()
{
   int num=0,num1=0;
   char customKey = key.getKey();
   targetcharge();
   currentcharge();
   //if(customKey)
   //{
   
   while(customKey != '#')
   {
      //currentcharge();
      switch (customKey)
      {
         //case NO_KEY:
            default:
            {
            //currentcharge();
            break;
            }

         case '0': case '1': case '2': case '3': case '4':
         case '5': case '6': case '7': case '8': case '9':
            num = num * 10 + (customKey - '0');
            //num1=num*0.1;
            //lcd.print(num1);
            break;

         case '*':
            {
            num = 0;
            lcd.clear();
            targetcharge();
            currentcharge();
            break;
            }
         case 'A':
         {
            Serial.println("YES");
            lcd.print("YES");
            break;
         }
         case 'B':
         {
          scale.tare();
          break;
         }
         case 'C':
         {
          lcd.clear();
          currentcharge();
          targetcharge();
          break;
         }
         case 'D':
         {
              if(i==0)
                {
                  i=i+1;
                  lcd.setBacklight(130);
                  lcd.clear();
                  lcd.print("Backlight off");
                  delay(interval);
                  lcd.clear();
                  targetcharge();
                  currentcharge();
                  //if(currentMillis-previousMillis>interval)
                  //Serial.println(i);
                break;
                }
              else if(i==1)
                {
                  lcd.setBacklight(140);
                  i=i+1;
                  lcd.clear();
                  lcd.print("Backlight Low");
                  delay(interval);
                  lcd.clear();
                  targetcharge();
                  currentcharge();
                  //Serial.println(i);
                break;
                }
            else if(i==2)
                {
                  lcd.setBacklight(150);
                  i=i+1;
                  lcd.clear();
                  lcd.print("Backlight Medium");
                  delay(interval);
                  lcd.clear();
                  targetcharge();
                  currentcharge();
                  //delay(interval);
                  //Serial.println(i);
                break;
                }
             else if(i==3)
                {
                  lcd.setBacklight(157);
                  i=i+1;
                  lcd.clear();
                  lcd.print("Backlight Max");
                  //lcd.print("Brightness 3");
                  delay(interval);
                  lcd.clear();
                  targetcharge();
                  currentcharge();
                  //Serial.println(i);
                  i=0;
                  break;
                }
                else break;
                
                /*if('C'&&'1')
                {
                    if(bpresses==0)
                  {
                    lcd.displayOff();
                    lcd.setBacklight(140);
                    bpresses=bpresses+1;
                  }
                  else if(bpresses==1)
                    {
                      lcd.clear();
                      lcd.displayOn();
                      lcd.print("LCD On");
                      delay(interval);
                      bpresses=0;
                    }
                }*/
         }
      }

     customKey = key.getKey();
     //currentcharge();
   }
    
   return num;
}
void keypadEvent(KeypadEvent keystate)
{
  //int num;
  char button=key.getKeys();
  switch(key.getState())
  {
    default:
    break;

    case PRESSED:
    v1=GetNumber();
    break;
    /*switch(keystate)
    {
      default:
      break;
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
      //lcd.print("YES");
      {
      num=num*10+(button-'0');
      //lcd.setPosition(1,7);
      //lcd.print(num);
      break;
      }
      case 'B':
      {
        if(i==0)
                {
                  i=i+1;
                  lcd.setBacklight(130);
                  lcd.clear();
                  lcd.print("Backlight off");
                  delay(interval);
                  lcd.clear();
                  targetcharge();
                  currentcharge();
                  //if(currentMillis-previousMillis>interval)
                  //Serial.println(i);
                break;
                }
              else if(i==1)
                {
                  lcd.setBacklight(140);
                  i=i+1;
                  lcd.clear();
                  lcd.print("Backlight Low");
                  delay(interval);
                  lcd.clear();
                  targetcharge();
                  currentcharge();
                  //Serial.println(i);
                break;
                }
            else if(i==2)
                {
                  lcd.setBacklight(150);
                  i=i+1;
                  lcd.clear();
                  lcd.print("Backlight Medium");
                  delay(interval);
                  lcd.clear();
                  targetcharge();
                  currentcharge();
                  //delay(interval);
                  //Serial.println(i);
                break;
                }
             else if(i==3)
                {
                  lcd.setBacklight(157);
                  i=i+1;
                  lcd.clear();
                  lcd.print("Backlight Max");
                  //lcd.print("Brightness 3");
                  delay(interval);
                  lcd.clear();
                  targetcharge();
                  currentcharge();
                  //Serial.println(i);
                  i=0;
                  break;
                }
                else break;
      }
    }*/
  }
  //return num;
}
int bpresses=0;
/*void getcurrentweight()
{
  if(
}