Using virtual signals

Hi everyone! The goal is to monitor my temperature, and once it is 28 deg C or above, it should sound the buzzer ONCE, turn off, and then activate the relay. Everything except the buzzer works fine. I´m sure I´m doing something extremely wrong as it should be straight forward.

I am using a virtual pin named buzz to have some logic in order to try to get the buzzer to sound once only after the temperature threshold is achieved.

I know it is a programming error, as when I test my circuit without loops or limitations on the quantities of times my buzzer sounds, everything works.

Any help is greatly appreciated!!!

#include <HID.h>

int relayPin = 3; // Initialize Relay Pin 3
int buzzer = 5; // Initialize buzzer pin 5
int buzz = 0;
#include <dht_nonblocking.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11

static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );

void setup()
{
  pinMode (relayPin, OUTPUT); // Set Relay Control Pin as Output
  pinMode (buzzer, OUTPUT); // Set buzzer - pin 5 as Output
  Serial.begin(9600);
  pinMode (buzz, OUTPUT);
}
static bool measure_environment( float *temperature, float *humidity )
{
  static unsigned long measurement_timestamp = millis( );

  /* Measure once every four seconds. */
  if ( millis( ) - measurement_timestamp > 3000ul )
  {
    if ( dht_sensor.measure( temperature, humidity ) == true )
    {
      measurement_timestamp = millis( );
      return ( true );
    }
  }

  return ( false );
}
void loop( )
{
  float temperature;
  float humidity;

  /* Measure temperature and humidity.  If the functions returns
     true, then a measurement is available. */
  if ( measure_environment( &temperature, &humidity ) == true )
  {
    Serial.print( "T = " );
    Serial.print( temperature, 1 );
    Serial.print( " deg. C, H = " );
    Serial.print( humidity, 1 );
    Serial.println( "%" );
    if (temperature < 28)
    {
      digitalWrite (buzz, HIGH);
      delay(500);
    }
    if (buzz == HIGH && temperature >= 28)
    {
      tone(buzzer, 1000); // Send 1KHz sound signal
      delay(500);              // keep it on for 1/2 second
      noTone(buzzer);     // Stop sound.
      delay(500);
      digitalWrite (buzz, LOW);
    }
    while (temperature >= 28)
    {
      digitalWrite(relayPin, HIGH);   // turn the fan on
      break;
    }
    if (temperature < 28)
    {
      digitalWrite(relayPin, LOW);   // turn the fan off
    }
  }
}

I am using a virtual pin named buzz

You may think so, but the program you posted is attempting to use a genuine pin numbered 0, which is reserved for the serial port.

This will never be true, because buzz is equal to zero.

if (buzz == HIGH && temperature >= 28)

Use buzz as a variable and set it to 1 or 0 (equivalent to HIGH or LOW). Test "buzz" as you do above.

Sounds good. Thanks for the help!

I updated my code as per jremington´s suggestion (Thank you Sr!), and it is almost working. Now, the problem is that the buzzer keeps sounding as long as the temperature is 28 deg C or above. This is weird as the logic "if (buzz == false && temperature >= 28)" is not being evaluated and I do not understand why. The fan works as intended.

Any ideas?

#include <HID.h>

int relayPin = 3; // Initialize Relay Pin 3
int buzzer = 5; // Initialize buzzer pin 5
boolean buzz = false;
#include <dht_nonblocking.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11

static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );

void setup()
{
  pinMode (relayPin, OUTPUT); // Set Relay Control Pin as Output
  pinMode (buzzer, OUTPUT); // Set buzzer - pin 5 as Output
  Serial.begin(9600);
}
static bool measure_environment( float *temperature, float *humidity )
{
  static unsigned long measurement_timestamp = millis( );

  /* Measure once every four seconds. */
  if ( millis( ) - measurement_timestamp > 3000ul )
  {
    if ( dht_sensor.measure( temperature, humidity ) == true )
    {
      measurement_timestamp = millis( );
      return ( true );
    }
  }

  return ( false );
}
void loop( )
{
label:
  float temperature;
  float humidity;
  /* Measure temperature and humidity.  If the functions returns
     true, then a measurement is available. */
  if ( measure_environment( &temperature, &humidity ) == true )
  {
    Serial.print( "T = " );
    Serial.print( temperature, 1 );
    Serial.print( " deg. C, H = " );
    Serial.print( humidity, 1 );
    Serial.println( "%" );
    delay (1000);
    if (buzz == false && temperature >= 28)
    {
      tone(buzzer, 1000); // Send 1KHz sound signal
      delay(500);              // keep it on for 1/2 second
      noTone(buzzer);     // Stop sound.
      delay(500);
      digitalWrite (buzz, true);
      delay (500);
    }
    if (temperature >= 28)
    {
      digitalWrite(relayPin, HIGH);   // turn the fan on
      delay (500);
    }
    if (temperature < 28)
    {
      digitalWrite(relayPin, LOW);   // turn the fan off
      digitalWrite (buzz, false);
      delay (500);
    }
    goto label;
  }
}
boolean buzz = false;
...
...
digitalWrite (buzz, false);

What's that?

Please, get rid of the goto.

You're still trying to use digitalWrite to set buzz when what you need is a simple = sign. digitalWrite() is for pins not for variables.

Steve

TheMemberFormerlyKnownAsAWOL:

boolean buzz = false;

...
...
digitalWrite (buzz, false);



What's that?

Please, get rid of the goto.

Sure. I just need a solution along with the criticism ;). Thanks though!

slipstick:
You're still trying to use digitalWrite to set buzz when what you need is a simple = sign. digitalWrite() is for pins not for variables.

Steve

Thank you Steve! That clarifies a lot! I will fix it and try it out.

Final code works! It has room for lots of improvements but it works. For some reason, the loop was getting stuck in some cases during my tests (I could not really pinpoint a specific reason) so I had to use the goto function to get it to work. I know the usage of the goto function is frowned upon (and it seems to actually offend some people), but it got my program to work.
Thanks to everyone who helped out! You guys rock! Here it is in case someone finds it helpful.

#include <HID.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <dht_nonblocking.h>

#define DHT_SENSOR_TYPE DHT_TYPE_11
LiquidCrystal_I2C lcd(0x27, 16, 2); //Initialize display @ address 0x27

int relayPin = 3; // Initialize Relay Pin 3
int buzzer = 5; // Initialize buzzer pin 5
boolean buzz = false; // Variable to set buzzer to sound once

static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );

void setup()
{
  pinMode (relayPin, OUTPUT); // Set Relay Control Pin as Output
  pinMode (buzzer, OUTPUT); // Set buzzer - pin 5 as Output
  Serial.begin(9600); // Initialize serial port
  lcd.init();
}
/*Poll for a measurement, keeping the state machine alive.  Returns
   true if a measurement is available.*/

static bool measure_environment( float *temperature, float *humidity )
{
  static unsigned long measurement_timestamp = millis( );

  /* Measure once every four seconds. */
  if ( millis( ) - measurement_timestamp > 3000ul )
  {
    if ( dht_sensor.measure( temperature, humidity ) == true )
    {
      measurement_timestamp = millis( );
      return ( true );
    }
  }

  return ( false );
}
void loop( )
{
label: // Start of the loop
  float temperature;
  float humidity;
  /* Measure temperature and humidity.  If the functions returns
     true, then a measurement is available. */
  if ( measure_environment( &temperature, &humidity ) == true )
  {
    Serial.print( "T = " );
    Serial.print( temperature, 1 );
    Serial.print( " deg. C, H = " );
    Serial.print( humidity, 1 );
    Serial.println( "%" );
    lcd.setBacklight(HIGH);
    lcd.setCursor(0, 0);
    lcd.print("Temp. = ");
    lcd.print(temperature, 1);
    lcd.print(" C");
    delay (1000);
    if (buzz == false && temperature >= 28)
    {
      tone(buzzer, 1000); // Send 1KHz sound signal
      delay(500);              // keep it on for 1/2 second
      noTone(buzzer);     // Stop sound.
      delay(500);
      buzz = true;
      delay (500);
    }
    if (temperature >= 28)
    {
      digitalWrite(relayPin, HIGH);   // turn the fan on
      lcd.setCursor(0, 1);
      lcd.print("FAN ON!!!");
      delay (500);
    }
    if (temperature < 28)
    {
      digitalWrite(relayPin, LOW);   // turn the fan off
      lcd.setCursor(0, 1);
      lcd.print("FAN OFF");
      buzz = false;
      delay (500);
    }
    goto label; // Forcing loop to restart no matter what
  }
}

Please - get rid of the goto.