Hello coding community. I am very new to the coding universe (because I am a ME major) and am working on my capstone project. I have no coding experience before this endeavor. I have a Load cell and a TFT touch screen that are controlled by two buttons. What I need to happen is when I press one button, the load cell takes 100 + samples and stores the values into an array. once the array is full, I need the load cell to stop running. Then, once the other button is pressed, the maximum value of this array to be displayed on the screen. Then, if the first button is pushed again, the cycle repeats. I have made good progress but I am stuck. I cannot get the load cell to stop reading and have it input the recorded values into an array. Any words of wisdom to help?
#include <MCUFRIEND_kbv.h>
#include <Adafruit_GFX.h>
#include <HX711.h>
#define calibration_factor -7050.0
#define DOUT 31
#define CLK 33
//pins:
const int HX711_dout = 31; //mcu > HX711 dout pin
const int HX711_sck = 33; //mcu > HX711 sck pin
int MeasuredForces[33];
unsigned int j = 0;
//HX711 Amp scale
HX711 scale;
//buttons:
int buttonRead = 53; //define input pin for Read push button
int buttonDisplay = 51; //define input pin for Display push button
int button1OLD = LOW;
int button2OLD = LOW;
int button1 = LOW;
int button2 = LOW;
int MaxForce;
//LCD
MCUFRIEND_kbv tft;
#define BLACK 0x0000 /* 0, 0, 0 */
#define WHITE 0xFFFF /* 255, 255, 255 */
void setup() {
Serial.begin(9600);
pinMode(buttonRead, INPUT);
pinMode(buttonDisplay, INPUT);
uint16_t ID = tft.readID();
tft.begin(ID);
tft.fillScreen(BLACK);
}
void loop() {
button1 = digitalRead(buttonRead);
button2 = digitalRead(buttonDisplay);
if (button1 == HIGH && button2 == LOW)
{
button1OLD = button1;
button2OLD = LOW;
}
if (button1 == LOW && button2 == HIGH)
{
button1OLD = LOW;
button2OLD = button2;
}
if (button1OLD == HIGH) {
scale.begin(DOUT, CLK);
scale.set_scale(calibration_factor);
scale.tare();
for (j=0; j < 33; j++){
Serial.print("Reading: ");
Serial.print(scale.get_units(), 1);
Serial.print(" lbs");
Serial.println();
MeasuredForces[j] = scale.get_units();
}
}
if (button2OLD == HIGH) {
MaxForce = max(MeasuredForces[j], MaxForce);
tft.setRotation(1);
tft.setTextColor(WHITE);
tft.setTextSize(10);
tft.setCursor(100, 130);
tft.print(MaxForce);
}
}`
Please read the instructions on how to use this forum and post code. Then remove the code from your text and post properly. A schematic may be helpful but not needed at this point as it appears the hardware is operating properly.
If you only need to know the maximum value you don't need an array.
Something like this will do the job:
void loop() {
// erase screen (?)
// begin scale
// tare
// etc
// wait for button 1 press
// read 100 times, taking note of max value
// wait for button 2 press
// display max value on screen
// wait until
// user dismisses the screen? (how?)
// a given time interval passes?
}
Just note that between the tare() operation and the first measure the user must be able to place the mass to be weighed on the scale. If you do not need to tare the scale before each weighing, the tare() operation can be moved to setup() and done only once. You can also add a tare button.
Certainly these two belong in the setup() as they need to be executed only once:
Ok. This was a lot closer than I had it. the only issue now is when I hit button 2, it displays the number of samples taken, not the max value from the array. Any idea how to fix this problem? Thanks for the help.
But as @mancera1979 said, if you ONLY want the maximum value you don't even need the array. Just keep track of the maximum value when reading and display that.
What this does is to reserve 33 memory slots to store an integer on each slot.
MeasuredForces[0]
refers to the first slot, and
MeasuredForces[32]
Refers to the last slot, which is the 33rd slot.
What would
MeasuredForces[33]
refer to?
It refers to the 34th slot. But your array has only 33 slots, so this is out of the array bounds. No problem, for c++ this refers to j, which is stored in the 2 bytes that follow your array. j is the 34th slot! Then, MeasuredForces[33] is another name for j.
Now let's look at the value of j. After
for (j = 0; j < 33; j++){
...
}
j equals 33.
So, by the time you execute
MaxForce = max(MeasuredForces[j], MaxForce);
MaxForce is 0 and MeasuredForces[j], which is MeasuredForces[33] is j, which is 33.
Then the instruction becomes
I only need the max value, but I would have no idea how to code something like that. Most of the coding I have "learned" has been looking at sample codes then snipping out the parts I need. Is keeping track of the max value a "better" or more efficient way to run the program?
.. and if you wanted to get rid of the array altogether then change this...
MeasuredForces[j] = scale.get_units();
MaxForce = max(MeasuredForces[j], MaxForce); // Keep track of maximum
to this...
MaxForce = max(scale.get_units(), MaxForce); // Keep track of maximum
There may be some benefit in leaving the array. If you ever wanted to determine other values like minimum, or average, or median, then you have all the information available.