Arduino a/c control by temperature - arduino

I need to power on my a/c when the temperature is lower than a number and viceversa power off it when the temperature become higher than another number. So I've tried this sketch
if (DHT.temperature,1 >= 0 && DHT.temperature,1 <=18)
irsend.sendRaw(ON, sizeof(ON)/sizeof(int),khz);
else if
irsend.sendRaw(OFF, sizeof(OFF)/sizeof(int),khz);
but it send the OFF command every loop cycle given that the temperature don't change immediately. Is possible to send the ON and OFF command only once for cycle and wait that it change for send the other command? I've thinked to store the last sent command but I don't know how to do. Thanks

You haven't written your if statement properly. Also add a test for if it is on already. You can do it like this:
This will have to be a global variable so it doesn't get destroyed outside your loop below.
boolean isOn = false;
This can go directly into your void loop() or another other function so you can call it as needed.
if (tempCondition && (!isOn)){
irsend.sendRaw(ON, sizeof(ON)/sizeof(int),khz);
isOn = true;
}
else if (othertempCondition && isOn) {
irsend.sendRaw(OFF, sizeof(OFF)/sizeof(int),khz);
isOn = false;
}
This will test the temperature and if true it will check if it needs to toggle using the isOn boolean.
If you want to supply the temperature ranges I can help complete the temp condition portions if you need it.

Related

Arduino: while (Serial.available()==0) gives input

I am trying to input GPS coordinate into the serial monitor to use in my drone project
However, whenever I try to input GPS coordinate, it automatically writes one of the GPS coordinates without my input. For example, GPS latitude is shown as 0.00, but the program waits for GPS Longitude info.
For a detailed situation please look at the picture attached.
int GPSNumCor;
void setup() {
// put your setup code here, to run once:
Serial.begin (115200);
Serial.print("What is the number of your GPS Coordinate? ");
while (Serial.available() == 0);
GPSNumCor = Serial.parseInt();
Serial.println(GPSNumCor);
delay (200);
float GPSLat[GPSNumCor], GPSLon[GPSNumCor];
for (int i = 0; i < GPSNumCor; i++)
{
if (i == 0)
{
Serial.println("What is your 1st GPS Coordinate");
}
if (i == 1)
{
Serial.println("What is your 2nd GPS Coordinate");
}
if (i == 2)
{
Serial.println("What is your 3rd GPS Coordinate");
}
if (i > 2)
{
Serial.print("What is your ");
Serial.print(i + 1);
Serial.println(" th GPS Coordinate");
}
delay(200);
Serial.print ("Latitude: ");
while (Serial.available() == 0);
GPSLat[i] = Serial.parseFloat();
Serial.println(GPSLat[i]);
Serial.print("Longitude: ");
while (Serial.available() == 0);
GPSLon[i] = Serial.parseFloat();
Serial.println(GPSLon[i]);
}
}
It has to wait for all input until I make an input to the program, but it does not wait.
I know while (Serial.available()==0) is a way to go, but I do not know why it would not work.
First, there's no reason to use while (Serial.available() == 0);. The parseFloat function you are about to use waits for data to be available and, if it didn't, merely checking for zero wouldn't be sufficient anyway because that would stop waiting as soon as a single character was available.
So here's why that while loop is a bad idea:
If you really do need to wait for the input before calling parseFloat, this won't do it. It only waits until at least one character is received and the coordinates may be more than one character.
The parseFloat function doesn't return until it has read an entire float anyway. So it already waits for you.
But that's not your problem. Think about the input stream, say it's "11.0<newline>22.0newline44.0". Where is the code to read the spaces between those numbers? When parseFloat tries to read a space, it returns a zero, as the documentation says. That's why you're getting zeroes -- you don't have any code to do anything with the separators between the floats.
Think about how parseFloat must work when it reads "12.34newline". First it reads the 1 and has no idea whether that's the whole number of not, so it keeps checking. Then it reads the "2.34" and still has no idea it has the whole number. Not until it sees the newline does it know that 12.34 is the correct float to return. But it does not consume the newline. Why? Because that might mean something.
With the code you showed, your next call to parseFloat will then try to read the newline and see that this is not a valid character to be part of a floating point number. So, as the documentation says, it will return zero.
Look closely at parseFloat's documentation to find out how to correctly match the delimiters in your serial stream. The parseFloat function has the ability to behave differently, consuming and ignoring delimeters rather than returning zero.
I don't know how it work, I just add Serial.read() in every time I want to read.
If u don't want to add Serial.read(), u can also use old version like 1.6.0, it still work fine but it don't work when u make like C# Serial app.
Just add Serial.read(), it work fine every place.
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
while(Serial.available()==0){}
int r=Serial.parseInt();
Serial.println(r);
Serial.read(); // it work fine
while(Serial.available()==0){}
int g=Serial.parseInt();
Serial.println(g);
Serial.read();
}
In the Serial Monitor window, in the drop-down menu on the bottom-right, change from "Newline" to "No line ending" and that will solve the problem (by preventing the Serial Monitor from automatically entering zero value(s)).
Both the parseInt() and parseFloat() have a hard time reading other data types (this also includes white spaces such as new lines) than the ones specified, and as a result they automatically return zero.
Reference: This page on Programming electronics offers valuable, detailed explanations (look for a paragraph with bold text):
https://www.programmingelectronics.com/parseint/

Capacitive Touch Sensor: "When touched for 100 ms"

I'm facing a programming question in which I want to trigger some code whenever a capacitive touch sensor has been touched for 100 ms (to distinguish false positives in my prototype). My sensor is touched by this code
if (digitalRead(touchPin))
Now whenever it has been touched for 100ms I want some other code (for instance, activating a LED) to run. I can't really seem to find a solution because my startTime = millis() variable keeps resetting.
Does anyone know how to tackle this problem?
You need a bool variable, to store last state (TRUE if touched and FALSE if not)
Also, you need to store time when it has been changed to TRUE. Time could be taken by millis() function
If your bool variable is true, check, if time passed is more than your 100 ms.
So:
// In your global scope:
...
// Last touch state
bool isTouched = FALSE;
// time, when last touch happened
int touched_t = 0;
// In your loop:
...
bool isTouchedNow = (digitalRead(touchPin) == HIGH);
// Touch state is changed till last measure:
if (isTouchedNow != isTouched)
{
// Set "last isTouched state" to new one
isTouched = isTouchedNow;
// If it wasn't touched before, store current time (else zero):
touched_t = isTouched ? millis() : 0;
}
else //If touch state isn't changed till last time:
{
//If state was "touched" and now it "touched", and 100ms has passed:
if (isTouched && touched_t > 0 && millis() - touched_t > 100)
{
// Call your function, that should be called,
// whan sensor is touched for 100 ms (activate a LED of something)
DOTHESTUFF();
}
}
...

LED from Arduino board doesn't switch off using the click of a button

So I've been busy dealing with my programming homework during the afternoon, and I cannot seem to solve the issue in the code found below.
The exercise is that I need to toggle a LED by the press of a button. In my code, the LED goes on when I click the button, but it doesn't turn off when I click the button again.
int pinButton = 5;
int LED = 10;
int currentState;
int previousState;
void setup() {
Serial.begin(9600);
pinMode(pinButton, INPUT);
pinMode(LED, OUTPUT);
}
void toggleLed(){
if (previousState == 1 && currentState == 0){
digitalWrite(LED, HIGH);
Serial.println(currentState);
Serial.println(previousState);
delay(100);
} else {
digitalWrite(LED, LOW);
Serial.println(currentState);
Serial.println(previousState);
delay(100);
}
}
void loop() {
int currentState = digitalRead(pinButton);
if (currentState == 0 && previousState == 1) {
Serial.println("Knop is losgelaten");
toggleLed();
}
previousState = currentState;
}
I guess that in the first if statement the else code block doesn't make sense, because in this case previousState and currentState will always be 1 and 0 respectively.
Do you guys have any tips?
This Arduino is an Arduino Uno by the way.
I can see in your code, that you are not switching the light off again after you pressed the Button. It would have gone off if you would have put the if statement into a "while" statement.
EDIT: Expanded on most points to address the additional questions in the comments.
You have two different variables named currentState, a global one and one local to loop(). The global one is defined near the top of the program, not inside another function. In loop(), you start with this line:
int currentState = digitalRead(pinButton);
Because you've included the int there, this actually creates a second variable that happens to have the same name as the global one. The values of the two versions of currentState can change independently. Within loop(), every time you reference currentState, you'll be referencing the local copy. Everywhere else (like in toggleLed) will be referencing the global copy. If you just wanted to set the global one (which is what I assume you meant to do), then you need to drop the int:
currentState = digitalRead(pinButton);
This will change the global version of currentState without creating a new one.
You're not doing any debouncing, so you could see sporadic results depending upon the type of button. With many buttons and switches, the transition between on and off can be noisy. Debouncing filters out that noise. Edit: The delay in toggleLed() is probably sufficient to debounce, but usually debouncing is done before responding to a state change.
You should probably initialize previousState. Since it's a global, and globals have static storage duration, and it's not otherwise initialized, the system will ensure that it's initialized to 0. Explicit initialization would be more obvious to anyone who has to read the code, especially if they don't know all the rules of C as well. Also, you probably want to initialize it to LOW rather than 0. Which leads to my final point.
The return value of digitalRead() is HIGH or LOW. On the Uno, it probably doesn't matter that you use 1 or 0 instead of HIGH or LOW, but I believe it might matter if you ever port your code to certain other boards. The HIGH and LOW constants exist to hide details, but that helps only if you use them consistently. Using HIGH and LOW some of the time and 1 and 0 other times just makes it harder for people to understand your code, and it might cause portability problems if you ever want to try your code on a different board.
You could achieve that by reading the state of the pin defined as 'LED'. If it is in a HIGH state, turn it LOw and vice versa.
void toggleLed(){
// check if pin state is low, turn it on
if (digitalRead(LED) == 0)
digitalWrite(LED, HIGH);
} else {
digitalWrite(LED, LOW);
}
}

How do I use a variable from another class in Unreal Script?

I am working on a game, and that game has a battery life function for a flash light. Basically, when the flash light is turned on, it reduces the life and when it's off, it stops.
But to achieve this, I need to access a variable that will determine whether or not the flash light is turned on or off.
var UTWeap_FlashLight light; // declaring a new variable from the class UTWeap_FlashLight.uc
// reduces battery life of the flash light
exec function ReducePower()
{
if(light.bCheck==true)
{
if(0<power) // loops till power 1 is = 0
{
power--; // reduce the value of power
if(power==0) // if it equals 0
{
power2 = power2 - 1; // set power2 to it's own value - 1
power=100; // reset power back to 100
}
}
}
}
but whenever I compile the code, it tells me that it can't find the variable bCheck, meaning I can't check whether or not the flash light is on. I want to call that variable from this class
UTWeap_FlashLight.uc
exec function TurnOff()
{
if(!Flashlight.LightComponent.bEnabled)
{
Flashlight.LightComponent.SetEnabled(true);
bCheck = true;
}
else
{
Flashlight.LightComponent.SetEnabled(false);
}
}
this part of the code is where I turn on/off the flash light. When I turn it on, I want to set bCheck to 1 so I can then later use it as a condition to detect whether or not the flash light is on. But I can't use the variable, it will just not change it's value. I later found out you CAN'T use variables from other classes, which is pretty dumb. Any help appreciated.
Well, I figured out how to use variables from other classes in unreal script.
IF you're wondering how to do the same use this:
class'<yourclassname>'.default.<yourvariablename>; // remove the < >

Basic PIC Programming issues

I am writing PIC code in C and encountered the following problems:
When I write my delay as _delay_ms(500), my code doesn't compile, it says it didn't recognize this instruction. I am using MPLAB.
I want to write a program that would count how many time the push button is pressed then return that value and display it using LED's. I know how to display it, but not how to make the program to wait for the push of the push button on the pickit.
main()
{
TRISA=0;//Sets all ports on A to be outputs
TRISB=1;//Sets all ports on B to be inputs
for(;;){
if(PORTBbits.RB0==1){//When the button is pressed the LED is off
PORTAbits.RA1 =0;
count=count+1;
}
else{
PORTAbits.RA1=1;
count = count +1;
}
if (count > 20){//if count =20 aka 20 button presses the LED turns on
PORTAbits.RA0=1;
}
else{
PORTAbits.RA0=0;
}
}
}
There are a few issues:
Assuming you're using a PIC24 or a dsPIC, you need to include libpic30.h
Before you include libpic30.h you need to #define FCY to be your instruction rate so that the delay takes the correct number of cycles. See the comments in the libpic30.h file for details.
The function is __delay_ms not _delay_ms. Note that there are two underscores at the beginning.
The name is all lower case, not Delay_ms as in your comment.
You need to add delay in your code when you detect a key is pressed. As you are saying the _delay_ms(500) is not recognized, You can try something like following:
unsigned char x;
// Just waste a few cycles to create delay
for (x = 0; x < 100; x++)
{
// No operation instruction
Nop();
}
You can create your own delay function with specific number of iterations of this for loop. Measure the exact delay created by this function using a profiler if you need. IMO any arbitrary delay, like say 100 iterations as stated above shall work.

Resources