Hello there. I'm an university student taking an opcional class on arduino so my knowledge is not the best. My task is to build a spirometer using Arduino Uni and a Diff Press Click sensor. All of the wiring is done and I'm trying to get the code down. It is supposed to get the data while a button is being pressed. Most of the code is working, the data is getting collected, the algoritm is working and the button is working, but for some reason the data is not being sent to the LCD display. What do I need to change? Thanks (most of the Serial.println() are just to check for some values and to check until which part the code is running)
#include "MCP3221.h"
#include<LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const byte DEV_ADDR = 0x4D; // I2C address of the MCP3221
MCP3221 mcp3221(DEV_ADDR);
unsigned int preply;
unsigned int rwread;
//Variáveis
float inputV = 0; // voltagem lida pelo sensor de pressão, em bits (0 a 1023)
int t = 0; // contador
float V = 0;
float P = 0;
float Q = 0;
float Vol = 0;
//float value[50]; // matriz que guarda os valores do volume
float FCV = 0;
float FEV1 = 0;
//Constantes
float ro = 1.284; // densidade do ar em kg/m3 para 25ºC
float pi=3.1415;
float a1 = pi*(0.016*0.016); //diametro: 32mm
float a2 = pi*(0.004*0.004); //diametro: 8mm
float dt = 0.01;
const byte buttonPin = 7;
//LCD e Sensor
void setup()
{
lcd.begin(16,2);
Wire.begin();
Wire.setClock(100000);
pinMode(buttonPin, INPUT_PULLUP);
while (digitalRead(buttonPin) == LOW)
{}
Serial.begin(9600);
}
unsigned int ping()
{
Wire.beginTransmission(DEV_ADDR);
return Wire.endTransmission();
}
unsigned int readReg16(byte add)
{
unsigned int val = 0x0000;
Wire.beginTransmission(add);
Wire.endTransmission();
Wire.requestFrom((byte)add, (byte)2);
val = Wire.read() << 8;
val += Wire.read();
return val;
}
//Algoritmo
void loop()
{
Serial.println("1");
//Serial.println(value[100]);
while(digitalRead(buttonPin) == HIGH){
inputV = mcp3221.getVoltage(); //em mV
Serial.println(inputV);
V = inputV/1000; //em V
P = abs((V/5-0.5)/0.057)*100;
Q = 1000*a1*sqrt((2*P/(ro*abs(pow(a1/a2,2)-1))));
Vol = Q*dt + Vol;
//value[t]=Vol;
if (t==10) {
FEV1 = Vol;
}
else {
FCV = Vol;
}
t = t + 1;
Serial.println(t);
Serial.println(FEV1,7);
Serial.println(FCV,7);
Serial.println(FEV1/FCV,7);
delay(100); //100ms=0.1s
}
lcd.display();
lcd.setCursor(0,0);
lcd.print("FVC= ");
lcd.print(FCV);
lcd.setCursor(9,0);
lcd.print(" Litros");
lcd.setCursor(0,1);
lcd.print("FEV1= ");
lcd.print(FEV1);
lcd.setCursor(10,1);
lcd.print(" Litros");
delay(5000);
}
Have you tested the display separately with demo code from the LCD library examples?
Yes, the example from the library works fine and even the same code I used here to display the info works in an example that does not have the Button. My best guess is that it has something to do with the way we dealt with the button hold section, probably in the void setup() section, but can't be sure
Next question, have you tested the button switch independently?
Sorry, we really do get a lot of people asking on here that don't do things like that.
How so? If by that you means testing if the button works then yes, the code acts exactly how it's supposed to work, the FEV and FCV values keep printing while the button is being pressed and stop once I let go. It can also reset, so if I press it again the variables go back to 0 and the algorithm does the same thing as before
The last description sounds like it is working. What is wrong? Prints to serial but not display?
The problem is that everything works besides the values actually being sent to and displayed on the LCD Display, it is just blank after I release the button. I keep adding checkmarks to see how far it reads the code and the last thing that is read is the lcd.setCursor(0,0), after that it doesn't read the lcd.print("FVC= ")
Sorry if I'm not being clear, if I replace those last line with this:
lcd.clear();
Serial.print("4");
lcd.setCursor(0,0);
Serial.print("5");
lcd.print("FVC= ");
Serial.print("6");
lcd.print(FCV);
....
it prints the 4 and the 5 but not the 6
I have to admit, that is weird. Does it repeat those actions every 5000ms as programmed? If not, it's crashing maybe due to memory leak caused by MCP and LCD driver memory contention. However, just a guess at this point. Interested to hear whether it loops...
Yes it does. If I press the button again the first "1" on the loop is printed again and everything inside the while() works as it did before
Confused. The only place I see you checking the button is after the "1" is printed, actually the "1" is printed unconditionally every time through loop. So I don't get it. That should not depend on button state.
The "loop" I am talking about is 'loop()', not the while statement that enables readings.
Yes I know, but if the 1 is being printed everytime the button is pressed and it is before and outside of the while cycle it meeans that the loop() loops right?
From what I can see, "1" should be printed every 5 seconds, as long as the button is not pressed. I am assuming that your button is wired to produce a HIGH input when pressed.
Oh then no, the 1 does not show up every 5 seconds! This might be solved if there was another way to do the button part, I think the button code in the setup() section might be causing this. Do you happen to know any other way to do what I'm trying to do with the button?
We need a summary of what it is supposed to do (program operation, flow). The purpose is not self-evident. Since there is some fuzziness about the button, please post a wiring diagram of that.
I will work on that then. I have tested removing those lcd line in the loop() and if I do that the 1 gets printed every 5 seconds
That's great, thanks for working on that. I think, however, explaining the program logic would gain some traction as other people chime in...
I guess, from reply #16, you can safely focus on the LCD code since the failure to print "1" probably means the program has crashed.
Thus the button logic may be a red herring at this point...
One strange thing... once you have run the inner 'while' loop and collected values, you repeatedly output the same values forever on the screen. They don't change. So why are you repeatedly writing the same data there? Or, have I missed something?
So basically when you start it up it's not supposed to do anything. Once you hold the button the objective is to capture voltage values from the pressure sensor every 0.1s and turn them into FCV and FEV1 values through the algorithm I did. When you let go of the button, the values of FEV1 and FCV that were being updated by the algorithm (in the while() cycle) are supposed to be sent and shown in the LCD Display and this is where the problems comes. The final FEV1 and FCV values gotten but the code is not read after (and including) the lcd.print("FVC= ") line
There is no code to support this.
Is this what you want?:
repeat
{
while button is not pressed
{
do nothing
}
while button is pressed
{
take readings and process them
}
display the readings
}
1 Like
Those values are being updated during the while() clycle, I'm just printing them to check if the values are what is expected. After the program is complete, most if not all of the Serial.println() lines are going to be erased
EDIT: I cannot add any more comments because I'm a new user but the previous comment is exactly what I want
EDIT2: I'll do that from now on. But yes, what you wrote is what we need ot happen