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
}
}
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?
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?
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.
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.
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 ?
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:
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?
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
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
#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);
}
}
}
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);
}
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);
}
}
}