Making a loop loop

Hi everyone

New to Arduino and new to forum. Also new to Arduino code but can code other languages.

I have thrown this together by modifying code online.

It does what I want to do except for one thing, it runs and then stops after two iterations.

Why? Is there a buffer I need to flush? Have I misunderstood code?

Also, am sure this can be tidied up so feel free to suggest alternatives.

Thanks
Aaron

// Arduino with load cell


 /* 
  Connect 5V on Arduino to VCC on Relay Module
  Connect GND on Arduino to GND on Relay Module 
  Connect GND on Arduino to the Common Terminal (middle terminal) on Relay Module. */

#define CH1 8   // Connect Digital Pin 8 on Arduino to CH1 on Relay Module Draft
#define CH2 9  // Pin 9 to CH2 Relay module front gate


// Put two known loads on the sensor and take readings. Put those values
// here.
float aReading = 192.0;
float aLoad = 15000; // g
float bReading = 344.0;
float bLoad = 24300; // g

long time = 0;
int interval = 20000; // Take a reading every x ms
int analogPin = 0; //connect the input from sensor load cell
int analogPin1 = 1; // this is the IR sensor on the draft. COde so that when it >500, draft gate sensor goes low.
int analogPin2 = 2; // this is the IR sensor. Code so htat when it >500, the gate sensor goes low.
int input;

void setup() {
  Serial.begin(9600);

  //Setup all the Arduino Pins
   pinMode(CH1, OUTPUT);
   pinMode(CH2, OUTPUT);


        
   //Turn OFF any power to the Relay channels
   digitalWrite(CH1,LOW);
   digitalWrite(CH2,LOW);

}

void loop() {

  float newReading = analogRead(0);
  float newReading2 = analogRead(0);
  // should now have two readings from load cell
  
  // Calculate load based on A and B readings above
  float load = ((bLoad - aLoad)/(bReading - aReading)) * (newReading - aReading) + aLoad;
  float load2 = ((bLoad - aLoad)/(bReading - aReading)) * (newReading2 - aReading) + aLoad;

do
{
  float newReading = analogRead(0);
  float newReading2 = analogRead(0);
  // should now have two readings from load cell
  
  // Calculate load based on A and B readings above
  float load = ((bLoad - aLoad)/(bReading - aReading)) * (newReading - aReading) + aLoad;
  float load2 = ((bLoad - aLoad)/(bReading - aReading)) * (newReading2 - aReading) + aLoad;
//should now have two readings to compare

}

 while ( load != load2);

 Serial.print("#S|CAPTURE|[");
Serial.print(load);
Serial.println("]#");


}

Why do you define variables input, interval, analogPin, analogPin1, analogPin2 and then never use them?

There are a lot of things wrong with the code bellow

do
{
  float newReading = analogRead(0);
  float newReading2 = analogRead(0);
  // should now have two readings from load cell
  
  // Calculate load based on A and B readings above
  float load = ((bLoad - aLoad)/(bReading - aReading)) * (newReading - aReading) + aLoad;
  float load2 = ((bLoad - aLoad)/(bReading - aReading)) * (newReading2 - aReading) + aLoad;
//should now have two readings to compare

}

 while ( load != load2);
  1. it uses floats but analogRead() returns an int!

  2. Because of the nature of floats they should not be compared with == as they will almost always be different. The inverse applies to !=

  3. You must never (as a newbie) write something which loops waiting for an external condition to be meet. This is a blocking function and will fuck you up

Mark

holmes4:
There are a lot of things wrong with the code bellow

Is that something that you use to forge code?

?

EDIT :slight_smile:

Mark

Thanks all

There is more code to this but did not put it in. Just wanted to get this working first.

What I wanted this to eventually do is once sheep walk on a scale, you get two readings the same (so it shows that you have at least some consistency), then the front gate of the weigh crate will open and shut, then depending on weight the sheep will be drafted for sale or returned to a paddock This will hook into pneumatic solenoids that control pneumatic cylinders that operate the gates.

So aarg hopefully that answers your question

holmes 4 - that was code i ripped from the net. other points noted.

if anyone has some constructive tips on getting a consistent reading from a scale while an animal is moving around on it, feel free to share.

Thanks
Aaron

The loop within a loop seems very strange. I see why you might want it, but what is the first set of readings for (at the top of the loop)? It's just a duplication of what's in the do loop.

It wouldnt work without them. I figured I needed to specify before I put them in the dowhile loop.

Back to the original question, is there any reason this only runs half a dozen times?

AaronS76:
It wouldnt work without them. I figured I needed to specify before I put them in the dowhile loop.

Do you mean, wouldn't compile without them?

What do you mean, specify? If you mean declare them, you definitely don't need an assignment statement with the declaration.

I don't like the dismissive flavour of your, "now let's get back to the original question". It often helps to clear away some weeds, to catch the game. :slight_smile:

Fair call on the dismissive flavour. Apologies.

Yes. Would not compile without them declared above.

that you have at least some consistency)

You can't do it. Have you ever tried to weigh a moving animal on any kind of scale? The reading will always bounce around as the animal moves.

Mark

I think a better (and simpler) way to do the code in the Original Post is

void loop() {

  float newReading = analogRead(0);
  float newReading2 = analogRead(0);
  // should now have two readings from load cell
 
  // Calculate load based on A and B readings above
  float load = ((bLoad - aLoad)/(bReading - aReading)) * (newReading - aReading) + aLoad;
  float load2 = ((bLoad - aLoad)/(bReading - aReading)) * (newReading2 - aReading) + aLoad;

 if( load == load2) {

    Serial.print("#S|CAPTURE|[");
    Serial.print(load);
    Serial.println("]#");
 }


}

However it is very unlikely that two float values will be identical so you should use integers of a suitable length.

I agree with @holmes4 about the problem of weighing animals. The best you will get is two readings within an acceptable range of each other. Maybe an average of (say) 5 readings would be better?

...R

Thanks Mark

If I had about $5k handy I could walk into a shop a buy an off the shelf kit. I use them at work with RFID tags so we can track weight gains/losses on specific animals but this is for my own farm. Somehow the magic off-the-shelf boxes deem that the reading is "stable" and beeps to let you know it logged it.

EDIT. Thanks Robin2. Will look into averaging or when the average value has a certain error around it.

void loop() {

  float newReading = analogRead(0);
  float newReading2 = analogRead(0);
  // should now have two readings from load cell

  // Calculate load based on A and B readings above
  float load = ((bLoad - aLoad) / (bReading - aReading)) * (newReading - aReading) + aLoad;
  float load2 = ((bLoad - aLoad) / (bReading - aReading)) * (newReading2 - aReading) + aLoad;

This creates 4 variables.

  do
  {
    float newReading = analogRead(0);
    float newReading2 = analogRead(0);
    // should now have two readings from load cell

    // Calculate load based on A and B readings above
    float load = ((bLoad - aLoad) / (bReading - aReading)) * (newReading - aReading) + aLoad;
    float load2 = ((bLoad - aLoad) / (bReading - aReading)) * (newReading2 - aReading) + aLoad;
    //should now have two readings to compare

  }

This again has 4 variables; they are not the same variables as the ones that you created previously; those will only be accessible inside the loop.

  while ( load != load2 );

I will not be able to predict if the code will use the load and load2 that are created first (at the beginning of loop()) or the ones that are created inside the do/while. But removing the first ones results in a compile error and hence this means that the code uses the variables that were declared first (at the beginning of loop()) and not the ones that were used inside the loop.

Below a slightly better version of loop(). I do not know if it solves your issue.

void loop() {

  float newReading;
  float newReading2;
  float load;
  float load2;

  do
  {
    newReading = analogRead(0);
    newReading2 = analogRead(0);
    // should now have two readings from load cell

    // Calculate load based on A and B readings above
    load = ((bLoad - aLoad) / (bReading - aReading)) * (newReading - aReading) + aLoad;
    load2 = ((bLoad - aLoad) / (bReading - aReading)) * (newReading2 - aReading) + aLoad;
    //should now have two readings to compare

  }

  while ( load != load2);

  Serial.print("#S|CAPTURE|[");
  Serial.print(load);
  Serial.println("]#");


}
while ( abs(load - load2) > threshold);

Many thanks to all.

Robin2 your code loops it now and sterretje you explained why my code was so c*&p.

It works at the moment because i have a stable power supply so it is easy for loads to equal. In the real world I think I need to look at averaging. Setting a trigger of a minimum weight to start the procedure.

aarg. If that does what I think it does. Very nice.

Appreciate the assistance.

AaronS76:
i have a stable power supply so it is easy for loads to equal

Equality between floating point numbers has little or nothing to do with the power supply. It is the way the values are stored. For example the number 5 might be stored as either 4.9999999999997 or 5.0000000002 and they would not be considered equal.

...R

Hi all

Resurrecting this thread instead of starting another. Apologies if this is incorrect, happy to start another if needed.

I have had some success with my project to weigh and autodraft sheep but have hit a wall. Entire code is below (but note this code does not have scales integrated I have stipulated the load variables to see how it runs). The wall I have hit is I have put an IR sensor to close the draft gate but for this to work the sheep needs to be passing the sensor at the same time the sensor is read. Can anyone give me any tips on how to keep the gate open and then when the IR sensor detects the sheep it then shuts the gate? Alternatively I can just put in a delay to hold it open for a specified period. Happy to explain stuff if need be.

Actually kind of hooked on this. I think the next thing will be a weatherstation.

Thanks and regards
Aaron

#include <Hx711.h>
//NNED TO PUT CODE IN HERE
// Arduino with load cell

Hx711 scale(A2, A3);
/*
  Connect 5V on Arduino to VCC on Relay Module
  Connect GND on Arduino to GND on Relay Module
  Connect GND on Arduino to the Common Terminal (middle terminal) on Relay Module. */

long time = 0;
int interval = 2000; // Take a reading every x ms. Is this in library?
int fPin = 2;
int bPin = 3;
int dPin = 4;
int buzzPin = 5;
int analogPin = 4;
int val = 0;

void setup()

{
  Serial.begin(9600);

  scale.setScale(-0.1);
  
  //Setup all the Arduino Pins
  pinMode(fPin, OUTPUT); //Relay output for front gate (ENTER)
  pinMode(bPin, OUTPUT); //Relay output for back gate (EXIT)
  pinMode(dPin, OUTPUT); //Relay output for draft gate
  pinMode(buzzPin, OUTPUT); //Buzzer to acknowledge logging of weight

  //Set any power to the Relay channels where required
 
  digitalWrite(fPin, LOW); // Cylinder extended gate open when LOW 
  digitalWrite(bPin, HIGH); //Cylinder retracted gate closed when HIGH
  digitalWrite(dPin, LOW); //Cyliner extended animals not drafted
  digitalWrite(buzzPin, HIGH); //Buzzer off





}
void loop()

{


float load = 10000;
float load2 = 30000;

  Serial.println(load);
  Serial.println(load2);

 if((load2 - load) > 5000 and load2 > 10000) // if the second load is 5 kg greater than first and the load 2
 //is greater than 10 kg then wait 2 seconds and close front gate

{
  delay(2000);
  digitalWrite(fPin, HIGH);
  Serial.println("entrance shut");





float load3 = 46000;
float load4 = 46180;

if (load3 - load4  < 200) // take two more measurements. if these are within 200 g of each other
  //write to serial port

{  
    
    Serial.print("#S|CAPTURE|[");
    Serial.print((load3 + load4)/2);
    Serial.println("]#");

    digitalWrite(buzzPin, LOW);
    delay(1000);
    digitalWrite(buzzPin, HIGH);
    digitalWrite(bPin, LOW);
    Serial.println("exit open"); //all good up to here


    
    if((load3 + load4)/2 > 45000)

{
    
   digitalWrite(dPin, HIGH); // drafted when over 45 kg
   Serial.println("Draft open");

   float load5 = 30000;
   float load6 = 10000;

if(load5 - load6 > 15000)

{
   delay(1000); 
   digitalWrite(bPin, HIGH);
   Serial.println("exit shut");
   digitalWrite(fPin, LOW);
   Serial.println("entrance open");
}}}}   
 
  if(analogRead(analogPin) > 400)

{
  val = analogRead(analogPin);
  digitalWrite(dPin, LOW);
  Serial.println(val);
  Serial.println("draft shut");



}

}

I'm not even going to try to study code with "}}}}"

Use the AutoFormat tool to lay out your code in a readable style.

I would expect an Arduino to be able to check the sensor hundreds or thousands of times while a sheep is passing - they don't move very fast.

...R

OK.

The only way I could get this to work was by nesting If functions. Hence the }}}}.

Autoformat tool. A novel idea. Will see if I can find out what it is.

Thanks
A