1

So I'm making a device that does 3 things,

  1. Measures frequency of an audio signal through a microphone
  2. Checks whether there is a weight placed on a pressure pad (my pressure sensor works through the resistance of the material changing when a weight is placed on it)
  3. Measure ambient room temperature

I have coded each individual section and tested them individually to find them work great, here are the sketches.

Frequency sketch :

// runs every time thru the loop
 setInputState();
 // count every transision HIGH<->LOW
 if (inputState != lastInputState) {
 count++; 
 lastInputState = inputState;
 }
 if (millis() - previousCountMillis >= countMillis) {
 previousCountMillis += countMillis;
 // show Hz on Serial too if available
 Serial.print(count); 
 Serial.println(" Hz");
 ledtest = count;
 // reset to zero for the next half second's sample
 count = 0L;
 }
 if (ledtest >= 400 && ledtest <= 850){
 digitalWrite(A2, HIGH);
 }
 else if (ledtest < 400 || ledtest > 850){
 digitalWrite(A2, LOW);
 }
}

Here is the pressure sensor sketch

int Vin = 5;
float Vout = 0;
float raw1 = 0;
int R1 = 770;
int R2old1 = 0;
int R2new1 = 0;
int R2avg1 = 0;
int pressurelog = 0;
void setup() {
 pinMode(A0, INPUT); //Receive pressure voltage
 pinMode(A1, OUTPUT); //Red led, PRESSURE PAD
}
void loop() {
 raw1 = analogRead(A0);
 Vout = raw1*5/1024;
 R2old1 = Vout*R1/(Vin-Vout);
 raw1 = analogRead(A0);
 Vout = raw1*5/1024;
 R2new1 = Vout*R1/(Vin-Vout);
 R2avg1 = (R2new1+R2old1)/2;
 Serial.print("Resistance: ");
 Serial.println(R2avg1);
 if (R2avg1 >= 1000){
 digitalWrite(A1, LOW);
 pressurelog = 0;
 }
 else if (R2avg1 <= 1000){
 digitalWrite(A1, HIGH);
 pressurelog = 1;
 } 
}

here is the temperature code

float raw = 0;
float tempC = 0;
float tempF = 0;
void setup() {
 pinMode(A5, INPUT);
 pinMode(A1, OUTPUT);
 Serial.begin(9600);
}
void loop() {
 raw = analogRead(A5) * 0.004882814;
 tempC = (raw - 0.5) * 100.0;
 tempF = (180.0/100.0)*tempC + 32.0;
 Serial.print("temp: ");
 Serial.println(tempF);
 delay(1000);
}

I coupled the "void loop" of all three and defined everything and ran the code to give a peculiar output. It does the temp and pressure reporting just fine but seems to constantly skip the frequency measurement. It seems to like doing the pressure and temperature measurement like 50 times then do an audio measurement which doesn't make sense as it should do it sequentially.

I TRIED:

  1. adding a delay between the frequency measurement and the other two. This didn't work as now the audio measurement work, as it relies on the millis () function
  2. adding the 3 components in 3 different functions and calling them sequentially. This results in the exact same stupid output.

Does anyone have an idea or solution?

Combined code: 
int Vin = 5;
float Vout = 0;
float raw1 = 0;
int R1 = 770;
int R2old1 = 0;
int R2new1 = 0;
int R2avg1 = 0;
int pressurelog = 0;
const byte inputPin = 2;
boolean inputState = false;
boolean lastInputState = false;
long count = 0L;
int ledtest = 0L;
unsigned long previousCountMillis = millis();
const long countMillis = 500L;
void setInputState() {
 inputState = digitalRead(inputPin);
}
int crylog = 0;
float raw = 0;
float tempC = 0;
float tempF = 0;
int templog = 0;
void setup() {
 pinMode(inputPin, INPUT); //Receive microphone data
 pinMode(A0, INPUT); //Receive pressure voltage
 pinMode(A1, OUTPUT); //Red led, PRESSURE PAD
 pinMode(A2, OUTPUT); //Blue led, FREQUENCY/CRYING
 pinMode(A3, OUTPUT); //Green led, TEMPERATURE
 pinMode(A4, OUTPUT); //Red led, MAX WARNING
 Serial.begin(115200);
}
void loop() {
 Serial.println("HI");
 Cryometer();
 delay(2);
 Serial.println("YO");
 Pressure();
 Temperature();
 // WARNING SETUP
 if (pressurelog == 1 && templog == 1){
 digitalWrite(A4, HIGH);
 }
 else {
 digitalWrite(A4, LOW);
 }
}
void Pressure() {
 raw1 = analogRead(A0);
 Vout = raw1*5/1024;
 R2old1 = Vout*R1/(Vin-Vout);
 raw1 = analogRead(A0);
 Vout = raw1*5/1024;
 R2new1 = Vout*R1/(Vin-Vout);
 R2avg1 = (R2new1+R2old1)/2;
 Serial.print("Resistance: ");
 Serial.println(R2avg1);
 if (R2avg1 >= 1000){
 digitalWrite(A1, LOW);
 pressurelog = 0;
 }
 else if (R2avg1 <= 1000){
 digitalWrite(A1, HIGH);
 pressurelog = 1;
 } 
}
void Cryometer(){
 // runs every time thru the loop
 setInputState();
 // count every transision HIGH<->LOW
 if (inputState != lastInputState) {
 count++; 
 lastInputState = inputState;
 }
 if (millis() - previousCountMillis >= countMillis) {
 previousCountMillis += countMillis;
 // show Hz on Serial too if available
 Serial.print("Frequency: ");
 Serial.print(count); 
 Serial.println(" Hz");
 ledtest = count;
 // reset to zero for the next half second's sample
 count = 0L;
 }
 if (ledtest >= 400 && ledtest <= 850){
 digitalWrite(A2, HIGH);
 crylog = 1;
 }
 else if (ledtest < 400 || ledtest > 850){
 digitalWrite(A2, LOW);
 crylog = 0;
 } 
}
void Temperature() {
 raw = analogRead(A5) * 0.004882814;
 tempC = (raw - 0.5) * 100.0;
 tempF = (180.0/100.0)*tempC + 32.0;
 Serial.print("Temperature (F): ");
 Serial.println(tempF);
 Serial.println();
 if (tempF >= 75 && ledtest <= 50){
 digitalWrite(A3, HIGH);
 templog = 1;
 }
 else if (ledtest < 50 || ledtest > 75){
 digitalWrite(A3, LOW);
 templog = 0;
 }
}
asked Jun 18, 2019 at 0:35
2
  • 1
    So post your combined code. You also need to combine the setup() functions and make sure you don't have any pin conflicts (hardware) or naming conflicts with your variable names (software) Commented Jun 18, 2019 at 0:43
  • Sorry forgot the combined code, but to answer to rest of your post; I have done all of that and made sure it should run perfect, it seems to execute the frequency analysis perfectly but for some reason just doesn't want to do it with every cycle of doing pressure&temp. Commented Jun 18, 2019 at 1:32

1 Answer 1

1

Your approach is globally sound. However, the code that measures the input frequency is very time sensitive. Thus, you have to make sure this piece of code is never delayed by anything else. This means that everything in your sketch should be fast and non-blocking.

I see a few instances of blocking behaviour you should get rid of: the call to delay() and the serial prints. The first is particularly useless, so just remove it. Printing to the serial port is fine as long as you do not try to print too much. If you try to print at every loop iteration, you end up filling the output buffer. From there on every print becomes a blocking call: the serial library has to wait for the port to send out the data, until there is enough room in the buffer for what you want to send. The solution is to throttle down the output rate by only printing once in a while. You have done this brilliantly in the frequency-meter code:

if (millis() - previousCountMillis >= countMillis) {
 previousCountMillis += countMillis;
 Serial.print("Frequency: ");
 Serial.print(count); 
 Serial.println(" Hz");
 // ...
}

Now you just have to apply the same technique to every instance of Serial.print() and Serial.println(). Well, maybe the "HI" "YO" could just be removed instead...

Once you remove these blocking behaviors from your sketch, it will probably run fast enough for the frequency counting to perform correctly. There is still something you may want to optimize though: the computations in Pressure() are horribly inefficient, especially considering that you have an 8-bit CPU with no hardware floating point support. If you need to average, I suggest you average the analog readings rather than computed resistances. Also note that computing the voltage at the analog pin is completely useless:

void Pressure() {
 int raw = analogRead(A0) + analogRead(A0);
 float R = (float) R1 * raw / (2048 - raw);
 // ...
}

You may even replace float by long if you don't need a resolution better than 1 Ω.

answered Jun 18, 2019 at 9:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.