if and

I have hit a problem within my project.
My project is a Bluetooth thermostat controlling three elements everything works with the exception of ON OFf via temp, I can turn elements on and off wireless via button press on the LCD shield, however not with the thermostat.
My goal is that the command for elements is only sent when

state[0] = 11;

So in effect power setting can be chosen and remain off until the above is true
the full code is

#include <LiquidCrystal.h>
uint8_t state[1];

volatile float temp = 0.0;
volatile float set_tmp = 20.0;
volatile int i = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int read_buttons(void)
{
  int key_read = analogRead(0);

  if (key_read > 900)  return 0;  //NONE
  if (key_read < 50)   return 1;  //Right  0
  if (key_read < 180)  return 2;  //UP  132
  if (key_read < 360)  return 3;  //Down 310
  if (key_read < 530)  return 4;  //Left 482
  if (key_read < 770)  return 5;  //Select  722
  return 0;                       //NONE
}

void setup(void)

{
  state[0] = 0;
  Serial.begin(38400);

  Serial.println("0");


  lcd.begin(16, 2);    // set up the LCD's number of columns and rows:

  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("Room");
  lcd.setCursor(7, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print("C");

}

void loop(void)

{
  char key = read_buttons();
  if (key == 2)
  {
    set_tmp = set_tmp + 0.5;
    delay(10);
  }

  if (key == 3)
  {
    set_tmp = set_tmp - 0.5;
    delay(10);
  }
  if (key == 5)
  {
    Serial.println("1");
    delay(100);
    lcd.setCursor(10, 0);
    lcd.print("500W ");
  }
  if (key == 4)
  {
    Serial.println("2");
    delay(100);
    lcd.setCursor(10, 0);
    lcd.print("1000W");
  }
  if (key == 1)
  {
    Serial.println("3");
    delay(100);
    lcd.setCursor(10, 0);
    lcd.print("2000W");
  }

  { temp = 0;
    for (i = 0; i < 64; i++)
    {
      temp = temp + ((float)analogRead(1) * 494.3 / 1023);
    }


    temp = round(temp / 64 * 10) / 10;

    lcd.setCursor(5, 0);
    lcd.print(temp, 0);

    if (temp < (set_tmp - 0.1))
    {
      state[0] = 11;

      lcd.setCursor(0, 1);
      lcd.print("ON");

      delay(100);
    }
    else if (temp > (set_tmp + 0.1))
    {
      state[0] = 0;

      lcd.setCursor(0, 1);
      lcd.print("OFF ");

      delay(100);
    }

    lcd.setCursor(5, 1);
    lcd.print(set_tmp, 0);
    lcd.print((char)223);
    lcd.print("C");

    // Remote role


  }
}

Thanks in advance

uint8_t state[1];

One element arrays are silly.

My goal is that the command for elements is only sent when

Since you only diddle with the value in the array when the temperature is above the set point by a small amount, or below the set point by a small amount, there seems no point in having a useless array.

What "command for elements" are you talking about? Where is it sent?

What have to tried, in terms of "sending" the "command for elements" when state[0] is 0?

PaulS:

uint8_t state[1];

One element arrays are silly.
Since you only diddle with the value in the array when the temperature is above the set point by a small amount, or below the set point by a small amount, there seems no point in having a useless array.

What "command for elements" are you talking about? Where is it sent?

What have to tried, in terms of "sending" the "command for elements" when state[0] is 0?

The command for element is

if (key == 5)
  {
    Serial.println("1");
    delay(100);
    lcd.setCursor(10, 0);
    lcd.print("500W ");

I have tried

if (key == 5 && (state[0] = 11));

I have tried

So, I have to wonder why you used == between key and 5, but = between state[0] and 11.

I also have to wonder why your if statement has a ; at the end.

PaulS:
So, I have to wonder why you used == between key and 5, but = between state[0] and 11.

I also have to wonder why your if statement has a ; at the end.

I have tried various permutations trying to get it to work

if (key == 5 && (state[0] == 11))

As well as dozens of other statements I am too embarrassed to admit to

As well as dozens of other statements I am too embarrassed to admit to

But, you've only shown one, out of context, formulated incorrectly, with no Serial.print() statements before it so you can KNOW what is being tested, and no discussion about what actually happened.

So, I can't see how we can help.

PaulS:
But, you've only shown one, out of context, formulated incorrectly, with no Serial.print() statements before it so you can KNOW what is being tested, and no discussion about what actually happened.

So, I can't see how we can help.

Sorry my head is spinning
The full section is

  if (key == 5 && (state[0] == 11))
  {
    Serial.println("1");
    delay(100);
    lcd.setCursor(10, 0);
    lcd.print("500W ");
  }

It compiles fine, uploads fine I can still select watt output ie 500 1000 2000w however when state ==11 nothing happens and the mega freezes.

On the receiver side I have three LEDs that light as per digitalwrite from received serial these stay lit even when button is released. I have just thought there is no debounce on the transmitter to remember last button pressed so the statement if (key == 5 && (state[0] == 11)) would only be correct if that button was held down when when state (0) ==11 ?

The full section is

That is still a snippet. Post ALL of your code.

I still do not understand why you have a one element array. That offers no advantage over a scalar variable. Nor does it have a meaningful name.

PaulS:
That is still a snippet. Post ALL of your code.

I still do not understand why you have a one element array. That offers no advantage over a scalar variable. Nor does it have a meaningful name.

The controller is for an electric heater in a RV with three wattage options, 500w 1000w and 2000w, once set these do not change nor need to be changed after initial set up the remote does not change wattage output with thermostat.

If thermostat is OFF

state[0] = 0;

the command

Serial.println("0");

(turns everything OFF) needs sending
however if thermostat is ON

state[0] = 11;

then either

Serial.println("1");
Serial.println("2");

or

Serial.println("3");

depending on the preselected value needs sending

Hope this helps, full code is posted at the top of this page

I can't see that the value of state[0] relates to the state of a thermostat. The value may mean that heatIsNeeded, or not. So, the very fact that there is confusion means that state is a crappy name.

state[] does NOT need to be an array. I should, in fact, have a type of bool, not uint8_t.

You need to separate defining the value of heatIsNeeded from using the value of heatIsNeeded.

Once you have done that,

   if(heatIsNeeded)
   {
      // Send the appropriate value
   }

Now, the main problem with your code is that once a key is pressed to define the heat level, you throw that value away at the end of loop(). So, on the next iteration, you have no idea what value to send to get the amount of heat desired.

You need a global variable, or a static variable in loop(), heatLevel, that is set/changed when one of the keys is pressed, and that is used in the if statement above to define the appropriate value to send.

Finally, I've never seen a serial heater before, so Serial.print() to control the heater does not make sense.

andi968:
Sorry my head is spinning

So is mine

andi968:
It compiles fine, uploads fine I can still select watt output ie 500 1000 2000w however when state ==11 nothing happens and the mega freezes.

What is the Mega; the device that you have shown the code for? If so, is the BT module connected to Serial? If so, why do you throw away debugging options by not using e.g. Serial1 and keeping Serial available for debugging. If not, what is the Mega?

andi968:
On the receiver side I have three LEDs that light as per digitalwrite from received serial these stay lit even when button is released. I have just thought there is no debounce on the transmitter to remember last button pressed so the statement

The code that you show sends a number (as text). If the buttons are not debounced that should not really pose an issue, the code will just send e.g. a 1, send nothing, send a 1, send nothing etc till the bouncing has finished and next permanently sends a 1 as long as the button is pressed. This will more than likely be repeated when the button is released.

So it depends on the receiver (is that an Arduino or some dedicated hardware?) what happens.

You also don't send something to the receiver that something needs to be switch off (only in setup). You only send a 'power level command' when a button is pressed; how does the receiver know that it needs to be off if you don't tell it to switch off when the temperature is high enough?

Note: analysis based on code in opening post.

So it depends on the receiver (is that an Arduino or some dedicated hardware?) what happens.

You also don't send something to the receiver that something needs to be switch off (only in setup). You only send a 'power level command' when a button is pressed; how does the receiver know that it needs to be off if you don't tell it to switch off when the temperature is high enough?

Note: analysis based on code in opening post.

[/quote]

The receiver is also a Mega replacing a convoluted switch system and works fine manual selection of power level.
I am now looking at a simple menu with three options at startup 500w,1000w and 2000w and then in the loop run the thermostat section of code and then send the command as and when required

I wonder if what you're calling state[0] = 11 is really binary 3 (00000011)? Need to see your complete program.

andi968:
I am now looking at a simple menu with three options at startup 500w,1000w and 2000w and then in the loop run the thermostat section of code and then send the command as and when required

And that is the code that you have presented in the opening post? As I indicated, it only sends power levels (500/1000/2000) when you press a button. I guess that it needs to send a '0' if the temperature raises above the set temperature (which it does not).

To understand what needs to happen in the program that is the subject of this thread, you need to provide the receiver code as the sender and receiver work together.

sterretje:
And that is the code that you have presented in the opening post? As I indicated, it only sends power levels (500/1000/2000) when you press a button. I guess that it needs to send a '0' if the temperature raises above the set temperature (which it does not).

To understand what needs to happen in the program that is the subject of this thread, you need to provide the receiver code as the sender and receiver work together.

I have now gone down the line of debouncing the value, now I cannot get it to compile :frowning:

#include <LiquidCrystal.h>
boolean lastButton;
boolean currentButton = false;
boolean ledOn = false;
int count = 0;



uint8_t state[1];

volatile float temp = 0.0;
volatile float set_tmp = 20.0;
volatile int i = 0;


LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int read_buttons(void)
{
  int key_read = analogRead(0);

  if (key_read > 900)  return 0;  //NONE
  if (key_read < 50)   return 1;  //Right  0
  if (key_read < 180)  return 2;  //UP  132
  if (key_read < 360)  return 3;  //Down 310
  if (key_read < 530)  return 4;  //Left 482
  if (key_read < 770)  return 5;  //Select  722
  return 0;                       //NONE
}

void setup(void)

{
  state[0] = 0;
  Serial.begin(38400);

  Serial.println("0");


  lcd.begin(16, 2);    // set up the LCD's number of columns and rows:

  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("Room");
  lcd.setCursor(7, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print("C");

}
boolean debounce(boolean last)
{
  char key = read_buttons();
  boolean current = read_buttons();
  if (last != current)
  {
    delay(5);
    current = read_buttons();
  }

  return current;



  {


  }


}
void loop(void)

{

  lastButton      = currentButton;
  currentButton   = debounce(lastButton);

  if ( lastButton == false && currentButton == true )
  {
    if ( count == 0 )
    {
      count++;
      lcd.print("500W ");
    }
    else if ( count == 1 )
    {
      count++;
      lcd.print("1000W ");
    }
    else if ( count == 2 )
    {
      count = 0;
      lcd.print("2000W ");
    }
  }
}
}
  { temp = 0;
    for (i = 0; i < 64; i++)
    {
      temp = temp + ((float)analogRead(1) * 494.3 / 1023);
    }


    temp = round(temp / 64 * 10) / 10;

    lcd.setCursor(5, 0);
    lcd.print(temp, 0);

    if (temp < (set_tmp - 1.1))
    {
      state[0] = 11;

      lcd.setCursor(0, 1);
      lcd.print("ON ");
      Serial.println( count);//wattage setting 1=500 2=1000 3=2000
      delay(100);
    }
    else if (temp > (set_tmp + 1.1))
    {
      state[0] = 0;

      lcd.setCursor(0, 1);
      lcd.print("OFF ");
      Serial.println("0");
      delay(100);
    }

    lcd.setCursor(5, 1);
    lcd.print(set_tmp, 0);
    lcd.print((char)223);
    lcd.print("C");

    {
      char key = read_buttons();
      if (key == 2)
      {
        set_tmp = set_tmp + 0.5;
        delay(10);
      }

      if (key == 3)
      {
        set_tmp = set_tmp - 0.5;
        delay(10);
      }
     
      


    }
  }

Are my glasses that dirty or didn't you include the error?

Still WHY the array with one element!?!?!

It would appear that the Serial print statement is controlling the behavior of the receiver.

I guess that it needs to send a '0' if the temperature raises above the set temperature (which it does not).

Or an 11 if the temperature is low, or if the thermostat is supposed to be on. You send neither of these commands. All you send is theSerial.println("0") in setup.

if (temp < (set_tmp - 0.1))
    {
      state[0] = 11;

     // Serial.println("11"); //needs to be added?


      lcd.setCursor(0, 1);
      lcd.print("ON");

      delay(100);
    }
    else if (temp > (set_tmp + 0.1))
    {
      state[0] = 0;

     // Serial.println("0"); //needs to be added?

      lcd.setCursor(0, 1);
      lcd.print("OFF ");

      delay(100);
    }

As suggested, please show the receiver code.

outsider:
I wonder if what you're calling state[0] = 11 is really binary 3 (00000011)? Need to see your complete program.

Hi, state (0) is zero it sends command ok to receiver. The full code is at the top of the thread, thanks for the input.

septillion:
Are my glasses that dirty or didn't you include the error?

Now managed to suss it out and compiled, Can anyone tell me how to read just the select button to change setting, as it stands every button changes the count

#include <LiquidCrystal.h>
boolean lastButton;
boolean currentButton = false;
boolean ledOn = false;
int count = 0;



uint8_t state[1];

volatile float temp = 0.0;
volatile float set_tmp = 20.0;
volatile int i = 0;


LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int read_buttons(void)
{
  int key_read = analogRead(0);

  if (key_read > 900)  return 0;  //NONE
  if (key_read < 50)   return 1;  //Right  0
  if (key_read < 180)  return 2;  //UP  132
  if (key_read < 360)  return 3;  //Down 310
  if (key_read < 530)  return 4;  //Left 482
  if (key_read < 770)  return 5;  //Select  722
  return 0;                       //NONE
}

void setup(void)

{
  state[0] = 0;
  Serial.begin(38400);

  Serial.println("0");


  lcd.begin(16, 2);    // set up the LCD's number of columns and rows:

  // Print a message to the LCD.
  lcd.setCursor(0, 0);
  lcd.print("Room");
  lcd.setCursor(7, 0);
  lcd.print((char)223);
  lcd.setCursor(8, 0);
  lcd.print("C");

}
boolean debounce(boolean last)
{
  char key = read_buttons();
  boolean current = read_buttons();
  if (last != current)
  {
    delay(5);
    current = read_buttons();
  }

  return current;



  {


  }


}
void loop(void)

{

  lastButton      = currentButton;
  currentButton   = debounce(lastButton);

  if ( lastButton == false && currentButton == true )
  {
    if ( count == 0 )
    {
      count++;
      lcd.print("500W ");
    }
    else if ( count == 1 )
    {
      count++;
      lcd.print("1000W ");
    }
    else if ( count == 2 )
    {
      count = 0;
      lcd.print("2000W ");
    }
  }

  { temp = 0;
    for (i = 0; i < 64; i++)
    {
      temp = temp + ((float)analogRead(1) * 494.3 / 1023);
    }


    temp = round(temp / 64 * 10) / 10;

    lcd.setCursor(5, 0);
    lcd.print(temp, 0);

    if (temp < (set_tmp - 1.1))
    {
      state[0] = 11;

      lcd.setCursor(0, 1);
      lcd.print("ON ");
      Serial.println( count);//wattage setting 1=500 2=1000 3=2000
      delay(100);
    }
    else if (temp > (set_tmp + 1.1))
    {
      state[0] = 0;

      lcd.setCursor(0, 1);
      lcd.print("OFF ");
      Serial.println("0");
      delay(100);
    }

    lcd.setCursor(5, 1);
    lcd.print(set_tmp, 0);
    lcd.print((char)223);
    lcd.print("C");
  }
    {
      char key = read_buttons();
      if (key == 2)
      {
        set_tmp = set_tmp + 0.5;
        delay(10);
      }

      if (key == 3)
      {
        set_tmp = set_tmp - 0.5;
        delay(10);
      }
     
      


    }
  }

Solution nearly there

Can anyone tell me how to read just the select button to change setting

Not until you get rid of that stupid one element array.