I want my code to loop once per millisecond but it only loops every 100. could that be caused by DallasTemperature.h or OneWire.h ?
Yes.
No.
Post your code.
Comment out the temp sensor code with // and find out.
The DallasTemperature offers non-blocking techniques that speed things up greatly. But, without seeing your code, it's impossible to advise on applying them.
but my code is very long and it says not to post long code
anyway here goes
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 13
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int troubleShootingMode = 1;
//Analog Inputs
const int fanInPin = A1;
const int tempInPin = A2;
//Values
int thermometerValue;
int fanInValue;
int tempInValue;
//Digital Inputs
const int modeButtonPin = 2;
const int autoButtonPin = 3;
//Values
int modeButtonValue;
int autoButtonValue;
//Digital Outputs
const int acOutPin = 4;
const int defOutPin = 5;
const int power = 12;
//Values
int acOutValue = 0;
int defOutValue = 0;
//Indicators
const int acIndPin = 6;
const int heatIndPin = 7;
const int defIndPin = 8;
const int autoIndPin = 9;
//Values
int acIndValue = 0;
int heatIndValue = 0;
int defIndValue = 0;
int autoIndValue = 0;
//PWM Outputs
const int fanOutPin = 10;
const int tempOutPin = 11;
//Values
int fanOutValue;
int tempOutValue;
int modeCount = 0;
int mode = 1;
int oldMode = 1;
int autoCount = 0;
int auTo = 1;
int oldAuto = 1;
long multipliedTempOutValue;
void setup() {
pinMode(fanInPin, INPUT);
pinMode(tempInPin, INPUT);
pinMode(modeButtonPin, INPUT);
pinMode(autoButtonPin, INPUT);
pinMode(acOutPin, OUTPUT);
pinMode(defOutPin, OUTPUT);
pinMode(acIndPin, OUTPUT);
pinMode(heatIndPin, OUTPUT);
pinMode(defIndPin, OUTPUT);
pinMode(autoIndPin, OUTPUT);
pinMode(fanOutPin, OUTPUT);
pinMode(tempOutPin, OUTPUT);
Serial.begin (9600);
sensors.begin();
}
//Inputs
void loop() {
digitalWrite(power, 1);
//Input Value Assignment
fanInValue = analogRead(fanInPin);
tempInValue = analogRead(tempInPin);
modeButtonValue = digitalRead(modeButtonPin);
autoButtonValue = digitalRead(autoButtonPin);
tempOutValue = multipliedTempOutValue / 1000;
fanOutValue = fanInValue / 4;
sensors.requestTemperatures();
int thermometerValue = sensors.getTempFByIndex(0);
//Mode Toggle
while (digitalRead(modeButtonPin) == 1 and modeCount < 1) {
modeCount = modeCount + 1;
}
if (digitalRead(modeButtonPin) == 0 and modeCount >= 1) {
mode = oldMode + 1;
modeCount = 0;
}
//Auto Toggle
while (digitalRead(autoButtonPin) == 1 and autoCount < 1) {
autoCount = autoCount + 1;
}
if (digitalRead(autoButtonPin) == 0 and autoCount >= 1) {
auTo = oldAuto + 1;
autoCount = 0;
}
//Manual Code
switch (mode) {
case 1:// A/C
if (auTo == 2) {
mode = 3;
}
acOutValue = 1;
acIndValue = 1;
heatIndValue = 0;
defIndValue = 0;
autoIndValue = 0;
oldMode = 1;
break;
case 2://Heat
if (auTo == 2) {
mode = 3;
}
acIndValue = 0;
heatIndValue = 1;
defIndValue = 0;
autoIndValue = 0;
oldMode = 2;
break;
case 3://No Defrost
defOutValue = 0;
if (auTo == 1) {
mode = 4;
}
acIndValue = 0;
heatIndValue = 0;
defIndValue = 0;
autoIndValue = 0;
oldMode = 3;
break;
case 4://Defrost
defOutValue = 1;
acOutValue = 1;
acIndValue = 0;
heatIndValue = 0;
defIndValue = 1;
autoIndValue = 0;
oldMode = 0;
break;
}
//Auto Code
switch (auTo) {
case 1:
tempOutValue = tempInValue / 4;
oldAuto = 1;
break;
case 2:
if (thermometerValue > tempInValue / 12) {
if (tempOutValue > 0) {
tempOutValue = tempOutValue - 1;
}
acOutValue = 1;
}
if (thermometerValue < tempInValue / 12) {
if (tempOutValue < 255) {
tempOutValue = tempOutValue + 1;
}
acOutValue = 0;
}
autoIndValue = 1;
oldAuto = 0;
break;
}
//Indicator Assignment
if (auTo == 2 and mode != 4) {
acIndValue = acOutValue;
}
//Output Value Assignment
digitalWrite(acOutPin, acOutValue);
digitalWrite(defOutPin, defOutValue);
digitalWrite(acIndPin, acIndValue);
digitalWrite(heatIndPin, heatIndValue);
digitalWrite(defIndPin, defIndValue);
digitalWrite(autoIndPin, autoIndValue);
analogWrite(fanOutPin, fanOutValue);
analogWrite(tempOutPin, tempOutValue);
//Serial Outputs
//Serial.print(" Mode ");
//Serial.println(mode);
//Serial.print(" Auto ");
//Serial.println(auTo);
//Serial.print(" | DefValue ");
//Serial.println(defOutValue);
//Serial.print(" | Fan In ");
//Serial.println(fanInValue);
//Serial.print(" | Fan Out ");
//Serial.println(fanOutValue);
Serial.print(" | Therm ");
Serial.println(thermometerValue);
Serial.print(" | Temp In ");
Serial.println(tempInValue / 12);
Serial.print(" | Temp Out ");
Serial.println(tempOutValue);
//Serial.print(" | AutoI ");
//Serial.print(autoIndValue);
//Serial.print(" | A/C ");
//Serial.print(acIndValue);
//Serial.print(" | Heat ");
//Serial.print(heatIndValue);
//Serial.print(" | Def ");
//Serial.print(defIndValue);
delay(1);
}
the reason i need it to run fast is so that it will sense quick button presses
confusedpotato34:
I want my code to loop once per millisecond but it only loops every 100. could that be caused by DallasTemperature.h or OneWire.h ?
After looking at your code, how do you know? How do you know how long the code takes to execute?
Concerned with code execution time but loaded down with serial prints, which consume lots of clock cycles.
I'd break it down. How long does it take to read the sensor? Just read the sensor, calculate the time taken and serial print the time to the monitor. Also, comment out parts of your code and see if those are time consuming parts.
Idahowalker:
After looking at your code, how do you know? How do you know how long the code takes to execute?Concerned with code execution time but loaded down with serial prints, which consume lots of clock cycles.
I'd break it down. How long does it take to read the sensor? Just read the sensor, calculate the time taken and serial print the time to the monitor. Also, comment out parts of your code and see if those are time consuming parts.
im not certain it takes 100 ms it just looks like about that in the serial monitor
also note that i have commentified most of the serial prints
to measure loop speed put into loop blink diode code in the middle of loop LED on on the end LED off then put oscilloscope on LED pin,move digitalWrite(LED_BUILTIN, HIGH); on up or down you can find out how much time is used by particular part of program.
void loop() {
digitalWrite(power, 1);
//Input Value Assignment
fanInValue = analogRead(fanInPin);
tempInValue = analogRead(tempInPin);
modeButtonValue = digitalRead(modeButtonPin);
autoButtonValue = digitalRead(autoButtonPin);
tempOutValue = multipliedTempOutValue / 1000;
fanOutValue = fanInValue / 4;
sensors.requestTemperatures();
int thermometerValue = sensors.getTempFByIndex(0);
///////////////////////////////////////////////////////////////////////////////////////////////////
digitalWrite(LED_BUILTIN, HIGH);
///////////////////////////////////////////////////////////////////////////////////////////////////
//Mode Toggle
while (digitalRead(modeButtonPin) == 1 and modeCount < 1) {
modeCount = modeCount + 1;
}
if (digitalRead(modeButtonPin) == 0 and modeCount >= 1) {
mode = oldMode + 1;
modeCount = 0;
}
//Auto Toggle
while (digitalRead(autoButtonPin) == 1 and autoCount < 1) {
autoCount = autoCount + 1;
}
if (digitalRead(autoButtonPin) == 0 and autoCount >= 1) {
auTo = oldAuto + 1;
autoCount = 0;
}
//Manual Code
switch (mode) {
case 1:// A/C
if (auTo == 2) {
mode = 3;
}
acOutValue = 1;
acIndValue = 1;
heatIndValue = 0;
defIndValue = 0;
autoIndValue = 0;
oldMode = 1;
break;
case 2://Heat
if (auTo == 2) {
mode = 3;
}
acIndValue = 0;
heatIndValue = 1;
defIndValue = 0;
autoIndValue = 0;
oldMode = 2;
break;
case 3://No Defrost
defOutValue = 0;
if (auTo == 1) {
mode = 4;
}
acIndValue = 0;
heatIndValue = 0;
defIndValue = 0;
autoIndValue = 0;
oldMode = 3;
break;
case 4://Defrost
defOutValue = 1;
acOutValue = 1;
acIndValue = 0;
heatIndValue = 0;
defIndValue = 1;
autoIndValue = 0;
oldMode = 0;
break;
}
//Auto Code
switch (auTo) {
case 1:
tempOutValue = tempInValue / 4;
oldAuto = 1;
break;
case 2:
if (thermometerValue > tempInValue / 12) {
if (tempOutValue > 0) {
tempOutValue = tempOutValue - 1;
}
acOutValue = 1;
}
if (thermometerValue < tempInValue / 12) {
if (tempOutValue < 255) {
tempOutValue = tempOutValue + 1;
}
acOutValue = 0;
}
autoIndValue = 1;
oldAuto = 0;
break;
}
//Indicator Assignment
if (auTo == 2 and mode != 4) {
acIndValue = acOutValue;
}
//////////////////////////////////////////////////////////////////////////
digitalWrite(LED_BUILTIN, LOW);
/////////////////////////////////////////////////////////////////////////
}
It looks to me like the two biggest problems are that you're calling for a temperature measurement on EVERY iteration of the loop() function and you're not using the non-blocking techniques the library provides.
A DS18B20 temperature measurement can take up to 750ms (depending on resolution). Why are you asking for one on every pass through loop()? If you really think the temperature you're measuring will change that quickly, then you're using the wrong type of sensor.
So, the first thing to do is implement a millis()-based timer to take a measurement no more often than every few seconds instead. Also, in your setup() function, set the library's waitForConversion flag to false using the setWaitForConversion() function (see the source code in DallasTemperature.h and DallasTemperature.cpp).
When it's time for a measurement, call the requestTemperatures() function. It will now return immediately after requesting the measurement but not wait for it to finish. Then, use another millis()-based timer to determine when the measurement has finished (see the library's millisToWaitForConversion() function). When that timer expires, you can use the getTempFByIndex() function. This should all be done using non-blocking techniques.
A final optimization would be to use getTempF() instead of getTempFByIndex(). It's significantly faster because it doesn't have to scan the OneWire bus for the correct address first. You must supply getTempF() with your sensor's address. You only need to determine this once, in your setup() function. The library's examples show how to do this.
I think there are also problem with the way you're handling button presses. But, I'd fix the DS18B20 problems first.
also note that i have commentified most of the serial prints
Serial.begin (9600);
:
Serial.print(" | Therm ");
Serial.println(thermometerValue);
Serial.print(" | Temp In ");
Serial.println(tempInValue / 12);
Serial.print(" | Temp Out ");
Serial.println(tempOutValue);
that is still a lot of printing, at a low speed. Since you're essentially printing continuously, Serial.print() will take about 1ms per character. So that's probably 40+ ms, right there.
Although you use "multipliedTempOutValue" for setting up "tempOutValue", and "tempOutValue" gets used all over.. You never once set "multipliedTempOutValue" to anything. Its just un-initilzed value from some RAM location.
-jim lee
jimLee:
Although you use "multipliedTempOutValue" for setting up "tempOutValue", and "tempOutValue" gets used all over.. You never once set "multipliedTempOutValue" to anything. Its just un-initilzed value from some RAM location.
It got set to zero by crt0. It is not uninitialised.
confusedpotato34:
but my code is very long and it says not to post long codethe reason i need it to run fast is so that it will sense quick button presses
Noticed how the help you are now receiving changed to a more informed help, just from posting your code. Isn't that neat how it works?
Have you implemented code to measure the speed of execution? What is the actual time of code execution are you getting. This gives 'us' something to work with and confirms your issue as described.
I do not think your code is taking 100mS to execute, prove it.
Idahowalker:
I do not think your code is taking 100mS to execute, prove it.
The minimum time required for a DS18B20 temperature measurement (at 9-bit resolution) is 94ms. By default, the DallasTemperature blocks for this long while waiting. You can change that behavior as I described in Reply #9.
gfvalvo:
The minimum time required for a DS18B20 temperature measurement (at 9-bit resolution) is 94ms. By default, the DallasTemperature blocks for this long while waiting. You can change that behavior as I described in Reply #9.
94mS = 100mS, I did not know that. But really, unless the OP adds in code to measure the actual time of execution, the rest is just speculation, right?
I do not believe that the code is taking 100mS to execute, until I see an actual number and the code used to calculate execution time...
Also, OP. Get a better sensor. Try a BME280, SPI. for faster transfers.
gfvalvo:
It looks to me like the two biggest problems are that you're calling for a temperature measurement on EVERY iteration of the loop() function and you're not using the non-blocking techniques the library provides.A DS18B20 temperature measurement can take up to 750ms (depending on resolution). Why are you asking for one on every pass through loop()? If you really think the temperature you're measuring will change that quickly, then you're using the wrong type of sensor.
So, the first thing to do is implement a millis()-based timer to take a measurement no more often than every few seconds instead. Also, in your setup() function, set the library's waitForConversion flag to false using the setWaitForConversion() function (see the source code in DallasTemperature.h and DallasTemperature.cpp).
When it's time for a measurement, call the requestTemperatures() function. It will now return immediately after requesting the measurement but not wait for it to finish. Then, use another millis()-based timer to determine when the measurement has finished (see the library's millisToWaitForConversion() function). When that timer expires, you can use the getTempFByIndex() function. This should all be done using non-blocking techniques.
A final optimization would be to use getTempF() instead of getTempFByIndex(). It's significantly faster because it doesn't have to scan the OneWire bus for the correct address first. You must supply getTempF() with your sensor's address. You only need to determine this once, in your setup() function. The library's examples show how to do this.
I think there are also problem with the way you're handling button presses. But, I'd fix the DS18B20 problems first.
so i should code it so it only reads once every 100 loops or smtn?
i only need it to read about once per second
please note that im very new to ardunio and im beautifully oblivious to a large amount of things
confusedpotato34:
so i should code it so it only reads once every 100 loops or smtn?
Depends on your coding knowledge and skill. No way of really knowing until you try.
ok my code is doing what i want it to do now that i made it only check the temperature once every 1000 loops
whats wrong with my button handling? i would really like to know because i kinda concocted it myself and im not even sure how what i did works
Post your current complete code.