Load cell controlling a relay

Ok so I had this post over in the sensor forum and only got a reply that was anything but help. I am in over my head as I am a newbie to programming but I have been tasked to get this load sensor test operational so I am asking for help in the code to get this going. I have tried many things but cannot get the results that I need. this is what I need to do.

Read load cell using an instrument amp with input on analog read pin 0
calibrating load cell
displaying load cell on 16x2 LCD
This code is written and is working, found code and modified
Now what I want to do from there is where I need help
I need to control the amount of fluid by weight that is to be dispensed from a container that is sitting on the load cell. I need to have the current weight recalculated by a value that can be hard coded in the code. this new weight will be the value that will close a relay to shut off flow from container. I have in my bad code a button that starts the dispensing. I would like for the LCD to show the weight going down when dispensing ,then show the new container weight.Then the same thing the next time the button is pushed. I know I don’t want much but I am stuck.In the spirit of the open source movement I am hoping someone out there can help.

THANK YOU !
Here is the one of many attempts that I have come up with.

// Arduino Load Cell Test
// 07-15-14 16:03 J_W
//Modified 07-21-14
#include <LiquidCrystal.h>
//Put two know loads on Loadcell take readings. Enter values 
float aReading = 77.21;
float aLoad  = 5.0;  //grams
float bReading = 144.0;
float bLoad =10.0;  //grams

long time = 0;
int interval =500; // Take reading every 500ms
int newAmount;
int pushButton =6;
int relay     =7;
int feeding = 42;
int vin;
int newReading;
// Define LCD pins
LiquidCrystal lcd (12,11,3,2,1,0);
void setup() {
  pinMode(pushButton,INPUT);
  pinMode(relay,OUTPUT);
 lcd.begin(16,2);

}

void loop() {
 float newReading = analogRead (0);
 // calculate load based on A and B readings above
 float load = ((bLoad - aLoad )/(bReading - aReading)) * (newReading - aReading) + aLoad;
 vin = analogRead (0);
 //when button is pressed open valve to feed
 while (digitalRead(pushButton)== HIGH){
   feed();
 }
 
 // millis returns the number of Milliseconds since the board started the current program
 if(millis() > time + interval) {
      // Display weight in ml
 lcd.setCursor(1,0);
 lcd.print ("Weight      ml");
 lcd.setCursor(7,1);
 lcd.print(load,3);
   time = millis();
 } 
}
void feed(){
  //reads load cell value puts value in Vin
  vin = newReading ;
  //calculate the amount to deliver
  newAmount = (vin-feeding);
  if(newAmount>vin){
    digitalWrite(relay,HIGH);
  }
  else{
    digitalWrite(relay,LOW);
  }
  if(vin = newAmount){
    digitalWrite(relay,LOW);
  }
}

Loadcell_LCD_Relay.ino (1.42 KB)

Can you explain better this?

JWalt:
(…)
I need to control the amount of fluid by weight that is to be dispensed from a container that is sitting on the load cell. I need to have the current weight recalculated by a value that can be hard coded in the code. this new weight will be the value that will close a relay to shut off flow from container.
(…)

Ok I will try I have a container sitting on the cell . I am reading the container weight. I want to open a solenoid via relay on pin 7 via a push button on pin 6 and a calculation of the container weight and the subtracted value that I have declaired as "feeding". I want to subtract the "feeding value from the current container weight to get the target weight that will shut off the relay. Then the next time I push the button we do the same thing only with the new container weight . All of this "cell reading" I would like to have on the LCD. Thanks so much for the quick reply ! I hope this helps

Try this:

// Arduino Load Cell Test
// 07-15-14 16:03 J_W
//Modified 07-21-14

#include <LiquidCrystal.h>

// Define LCD pins
LiquidCrystal lcd (12, 11, 3, 2, 1, 0);

//Put two know loads on Loadcell take readings. Enter values
float aReading = 77.21;
float aLoad  = 5.0;  //grams
float bReading = 144.0;
float bLoad = 10.0; //grams

long time = 0;
int interval = 500; // Take reading every 500ms
int newAmount;
//int pushButton = 6;
int relay     = 7;
int feeding = 42;
int vin;
int newReading;


///////////////////////////////////////////////////////////////////////////
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 6;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers
///////////////////////////////////////////////////////////////////////////
boolean stateFedding = false;


void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(relay, OUTPUT);
  lcd.begin(16, 2);

}


void loop() {
  float newReading = analogRead (0);

  // calculate load based on A and B readings above
  float load = ((bLoad - aLoad ) / (bReading - aReading)) * (newReading - aReading) + aLoad;
  vin = analogRead (0);   // you don't need this (this value is stored in newReading)


  int reading = digitalRead(buttonPin);

  if (stateFedding == false) { // you don't need to check the button if is already feeding

    if (reading != lastButtonState) {
      lastDebounceTime = millis();
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
      if (reading != buttonState) {
        buttonState = reading;

        if (buttonState == HIGH) {
          stateFedding = true;
        }
      }
    }
  }
  lastButtonState = reading;


  //when button is pressed open valve to feed
  if (stateFedding == true) {
    stateFedding = feed();
  }
}


boolean feed() {
  boolean stateFeed; // this could be done with the global variable 
                     // "stateFedding", but I don't like to use global variables

  //reads load cell value puts value in Vin
  vin = newReading ; // I don't like this!!!

  //calculate the amount to deliver
  //newAmount = (vin - feeding); // I don't like this too!!!
  //if (newAmount > vin) {
  // if feeding is int the same unit than vin the if would be:
  if (vin > feeding) {
    digitalWrite(relay, HIGH);
    stateFeed = true;
  }
  else {
    digitalWrite(relay, LOW);
    stateFeed = false;
  }
  // you don't need this, if newAmount ins not > than vin, is because or is < or is =
  /*
  if (vin = newAmount) {
    digitalWrite(relay, LOW);
  }
  */

  return stateFeed;
}

I add a debouce to the button, from this example:

I delete some things that don’t make sense. I add a few comments to explain a few errors that you had.

Tell me if it work, because I didn’t test it.

luisilva well no its not working . I had to put in the code for the LCD but I was hoping for this sequence of operations:

1)LCD reading current container weight
2) Push button to start the feeding cycle, calculate new target container weight ,open valve (relay HIGH)
LCD regisitering weight going down.
3) new target weight (from load cell) shuts off valve (relay LOW)
4) LCD displays new container weight for next feeding cycle

I can’t say thank you enough for what you have done so far. I am in the US so last night I was pretty much done for the evening and just got back to the computer . I am studying your code trying to learn but this is way to advanced for me to totally understand . I don’t think the calculation of the new container weight is being done as I was expecting the relay to stay energized when I pushed the start button. ( latching) . also the one thing that i am having trouble with on the calculation is what do we calculate the conversion (load) or the reading that the load cell is giving us. I have the int feeding as a value based on the calculated (load). Is this right ? Seems to me that may be why the calculation doesn’t seem to be working.
One other thing that i haven’t had time to figure out is the load cell reading is very stable now than before with my terrible code, can you explain why possibly.

Your help has been wonderful thanks again!

JWalt

// Arduino Load Cell Test
// 07-15-14 16:03 J_W
//Modified 07-22-14

#include <LiquidCrystal.h>

// Define LCD pins
LiquidCrystal lcd (12, 11, 3, 2, 1, 0);

//Put two know loads on Loadcell take readings. Enter values
float aReading = 77.21;
float aLoad  = 5.0;  //grams
float bReading = 144.0;
float bLoad = 10.0; //grams

long time = 0;
int interval = 500; // Take reading every 500ms
int newAmount;
//int pushButton = 6;
int relay     = 7;
int feeding = 2;
int vin;
int newReading;


///////////////////////////////////////////////////////////////////////////
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 6;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers
///////////////////////////////////////////////////////////////////////////
boolean stateFeeding = false;


void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(relay, OUTPUT);
  lcd.begin(16, 2);

}


void loop() {
  float newReading = analogRead (0);

  // calculate load based on A and B readings above
  float load = ((bLoad - aLoad ) / (bReading - aReading)) * (newReading - aReading) + aLoad;
  vin = analogRead (0);   // you don't need this (this value is stored in newReading)
       // Display weight in ml
 lcd.setCursor(1,0);
 lcd.print ("Weight      ml");
 lcd.setCursor(7,1);
 lcd.print(load,3);
   time = millis();


  int reading = digitalRead(buttonPin);

  if (stateFeeding == false) { // you don't need to check the button if is already feeding

    if (reading != lastButtonState) {
      lastDebounceTime = millis();
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
      if (reading != buttonState) {
        buttonState = reading;

        if (buttonState == HIGH) {
          stateFeeding = true;
        }
      }
    }
  }
  lastButtonState = reading;


  //when button is pressed open valve to feed
  if (stateFeeding == true) {
    stateFeeding = feed();
  }
}


boolean feed() {
  boolean stateFeed; // this could be done with the global variable 
                     // "stateFedding", but I don't like to use global variables

  //reads load cell value puts value in Vin
  vin = newReading ; // I don't like this!!!

  //calculate the amount to deliver
  //newAmount = (vin - feeding); // I don't like this too!!!
  //if (newAmount > vin) {
  // if feeding is int the same unit than vin the if would be:
  if (vin > feeding) {
    digitalWrite(relay, HIGH);
    stateFeed = true;
  }
  else {
    digitalWrite(relay, LOW);
    stateFeed = false;
  }
  // you don't need this, if newAmount ins not > than vin, is because or is < or is =
  /*
  if (vin = newAmount) {
    digitalWrite(relay, LOW);
  }
  */

  return stateFeed;
}

Yes, it seems that I forgot about the LCD.
I don't understand what is not working.

When depressing the start button the relay closes but as soon as I release the button the relay opens. Even if I keep the relay closed with the button and the container starts to dispense we get to the weight that the relay should be opening and we just go by it(target weight). I am going to re-calibrate my Load cell and start over with my numbers and see what happens. Man I wish I understood this more .

Thanks again !

JWalt

OK, I see.

Try this:

// Arduino Load Cell Test
// 07-15-14 16:03 J_W
//Modified 07-22-14

#include <LiquidCrystal.h>

// Define LCD pins
LiquidCrystal lcd (12, 11, 3, 2, 1, 0);

//Put two know loads on Loadcell take readings. Enter values
float aReading = 77.21;
float aLoad    = 5.0;  //grams
float bReading = 144.0;
float bLoad    = 10.0; //grams

int interval = 500; // Take reading every 500ms
int newAmount;

int relay   = 7;
int feeding = 2;
int vin;


///////////////////////////////////////////////////////////////////////////
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 6;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers
///////////////////////////////////////////////////////////////////////////
boolean stateFeeding = false;


void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(relay, OUTPUT);
  lcd.begin(16, 2);

}


void loop() {
  vin = analogRead (0);

  // calculate load based on A and B readings above
  float load = ((bLoad - aLoad ) / (bReading - aReading)) * (vin - aReading) + aLoad;

  // Display weight in ml
  lcd.setCursor(1, 0);
  lcd.print ("Weight ");
  lcd.print(load, 3);
  lcd.print (" ml");

  lcd.setCursor(1, 1);
  lcd.print(vin);
  lcd.setCursor(8, 1);
  lcd.print(feeding);


  int reading = digitalRead(buttonPin);

  if (stateFeeding == false) { // you don't need to check the button if is already feeding

    if (reading != lastButtonState) {
      lastDebounceTime = millis();
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
      if (reading != buttonState) {
        buttonState = reading;

        if (buttonState == HIGH) {
          stateFeeding = true;
        }
      }
    }
  }
  lastButtonState = reading;


  //when button is pressed open valve to feed
  if (stateFeeding == true) {
    stateFeeding = feed();
  }
}


boolean feed() {
  boolean stateFeed; // this could be done with the global variable

  if (vin > feeding) {
    digitalWrite(relay, HIGH);
    stateFeed = true;
  }
  else {
    digitalWrite(relay, LOW);
    stateFeed = false;
  }

  return stateFeed;
}

And tell me what happens.

Ok we are closer I see what you have done on the LCD readout cool I like that . But the relay is still not unlatching when I start to dispense. I don't see anything in the boolean feed that will unlatch the relay when we get to the new container weight.
Sorry for not explaining things very well

boolean feed() {
boolean stateFeed; // this could be done with the global variable

if (vin > feeding) {
digitalWrite(relay, HIGH);
stateFeed = true;
}
else {
digitalWrite(relay, LOW);
stateFeed = false;
}

return stateFeed;
}

I need relay to open when it reaches the new container weight ( Container weight -feeding)=new container weight" relay closed"

Possibly another If statement showing cell reading = new container weight

I am slowly getting this you are showing me a lot of new things very exciting

thanks

JWalt

No. The problem was my misunderstood. I do this so that the valve was open until you reach the “feeding”, but you are asking for only release the “feeding” amount.

So, maybe something like this should work:

// Arduino Load Cell Test
// 07-15-14 16:03 J_W
//Modified 07-22-14

#include <LiquidCrystal.h>

// Define LCD pins
LiquidCrystal lcd (12, 11, 3, 2, 1, 0);

//Put two know loads on Loadcell take readings. Enter values
float aReading = 77.21;
float aLoad    = 5.0;  //grams
float bReading = 144.0;
float bLoad    = 10.0; //grams

int interval = 500; // Take reading every 500ms
int newAmount;

int relay   = 7;
int feeding = 2;
int vin;
int startFeed;


///////////////////////////////////////////////////////////////////////////
// constants won't change. They're used here to
// set pin numbers:
const int buttonPin = 6;    // the number of the pushbutton pin
const int ledPin = 13;      // the number of the LED pin

// Variables will change:
int ledState = HIGH;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 50;    // the debounce time; increase if the output flickers
///////////////////////////////////////////////////////////////////////////
boolean stateFeeding = false;


void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(relay, OUTPUT);
  lcd.begin(16, 2);

}


void loop() {
  vin = analogRead (0);

  // calculate load based on A and B readings above
  float load = ((bLoad - aLoad ) / (bReading - aReading)) * (vin - aReading) + aLoad;

  // Display weight in ml
  lcd.setCursor(1, 0);
  lcd.print ("Weight ");
  lcd.print(load, 3);
  lcd.print (" ml");

  lcd.setCursor(1, 1);
  lcd.print(vin);
  lcd.setCursor(8, 1);
  lcd.print(feeding);


  int reading = digitalRead(buttonPin);

  if (stateFeeding == false) { // you don't need to check the button if is already feeding

    if (reading != lastButtonState) {
      lastDebounceTime = millis();
    }

    if ((millis() - lastDebounceTime) > debounceDelay) {
      if (reading != buttonState) {
        buttonState = reading;

        if (buttonState == HIGH) {
          stateFeeding = true;
          startFeed = vin;
        }
      }
    }
  }
  lastButtonState = reading;


  //when button is pressed open valve to feed
  if (stateFeeding == true) {
    stateFeeding = feed();
  }
}


boolean feed() {
  boolean stateFeed; // this could be done with the global variable

  if (vin > startFeed - feeding) {
    digitalWrite(relay, HIGH);
    stateFeed = true;
  }
  else {
    digitalWrite(relay, LOW);
    stateFeed = false;
  }

  return stateFeed;
}
newAmount = (vin-feeding);
 if(newAmount>vin){
    digitalWrite(relay,HIGH);
  }

Under what circumstances, in your code, do you expect this if( ) condition to ever be true ?

The same as this:

  if(vin = newAmount){

luisilva
You got it ! I don't know how to say thank you enough. I am a long way from writing code for something like this but your help has really saved a research project that is running out of money fast! I will continue to look at your code and get a better understanding of how it works its just going to take some time. This is the true spirit of the open source movement with people like you helping someone like me that was sinking fast . Once again thanks !

Respectfully,

JWalt

@hwalt

Can u please share the final code?

@JWalt

can you give the code in full?