vI have this functions in my loop() and it publishes temperature reading to Ubidots(an IoT cloud service) using the #include library but it seems it returns a boolean and so the loop is delayed until a true or false value is return and this takes a while there by slowing down my loop() function and other functions in it. Is there a way I can call this function without it having to slow the loop?
#include <math.h>
#include <Wire.h>
#include <Servo.h>
#include <WiFi.h>
#include <Ubidots.h>
#include "rgb_lcd.h"
#include "Timer.h"
//#include <SoftwareSerial.h>
//SoftwareSerial mySerial(11, 10); // RX, TX
char ssid[] = "ROSTALECOM_6916"; //your network SSID (name)
char pass[] = "6PTDFYJD"; //your network password (use for WPA, or use as key for WEP)
String api = "875c4a17d995ce4977bdfc1ace55233fd0591c7ce"; //your API Key number
String idvari = "567d623a762542205cbc517f"; //the number of the Ubidots variable
String ctext = "{\"color\":\"blue\",\"status\":\"active\"}";
Ubidots ubiclient(api); //with that you call the api with the prefix ubiclient
byte p5[8] = {
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F,
0x1F
};
int a;
int temperature;
int B=3975; //B value of the thermistor
float resistance;
String readString;
int val;
int hum = 70.35;
unsigned char base = 10;
//Temperature Limits
int maxTemp = 29;
int minTemp = 28.5;
//Declarations
rgb_lcd lcd;
Servo winServo;
//Ubidots timer
Timer t;
void setup()
{
//Loading character
lcd.createChar(0, p5);
Serial1.begin(9600);
Serial.begin(9600);
winServo.attach(3);
lcd.begin(16, 2);
//mySerial.begin(9600);
//Start Screen
lcd.print("--SmartGarden--");
for (int i = 0; i < 16; i++)
{
// scroll one position left:
lcd.setCursor(i, 1);
lcd.write((uint8_t)0);
delay(400);
}
lcd.clear();
lcd.print("Connecting...");
//connect to wifi network
boolean response;
int status = WL_IDLE_STATUS;
response = ubiclient.WifiCon(ssid, pass, status, api);
Serial.println(response);
//
t.every(1000, sendToUbi);
}
void readTemp()
{
a=analogRead(0);
resistance=(float)(1023-a)*10000/a;
temperature=1/(log(resistance/10000)/B+1/298.15)-273.15;
//Send temperature via Bluetooth
Serial.print(temperature);
//print temperature to LCD
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Tmp:");
lcd.print(temperature);
//print humidity to LCD
lcd.setCursor(8,0);
lcd.print("Hm:");
lcd.print("50");
delay(1000);
}
void writeServo()
{
if (val != 0)
{
//val = map(val, 0, 1023, 0, 180);
winServo.write(val);
delay(100);
}
}
void sendToUbi()
{
ubiclient.save_value(idvari, String(temperature)); //this function is to post to ubidots and return True or False depending on the connection status
Serial.println("The sensor value " + String(temperature) + " was sent to Ubidots"); //print the sensor value
}
void timerMax()
{
for (int i = 0; i < 60; i++)
{
}
winServo.write(180);
}
void loop()
{
//read temperature
readTemp();
//Update ubidots timer
t.update();
while (Serial1.available()) {
delay(3);
char c = Serial1.read();
readString += c;
}
if (readString.length() >0)
{
Serial.println(readString);
delay(15);
val = readString.toInt();
if (val != 0)
{
//val = map(val, 0, 1023, 0, 180);
winServo.write(val);
delay(100);
readString = "";
}
//writeServo();
if (readString == "1")
{
digitalWrite(13, HIGH);
}
if (readString == "0")
{
digitalWrite(13, LOW);
}
readString = "";
}
if (temperature >= maxTemp)
{
timerMax();
}
}
2 Answers 2
How to avoid delays in the loop() function?
The question is why all the delays? Is there some logic missing? What are you trying to design?
Using delays is often a sign of an attempt to synchronize with external events. Wait for additional input, etc.
Let us walk through some of them:
void readTemp()
{
...
delay(1000);
}
What is this about? The function does read an analog input BUT then there is a lot of output to Serial and LCD and last this delay. Why?
void writeServo()
{
...
delay(100);
}
Again the same pattern. Now for your question "delays in the loop()".
void loop()
{
readTemp(); // hidden 1000 ms delay
while (Serial1.available()) {
delay(3);
...
}
if (readString.length() >0)
{
...
delay(15);
...
if (val != 0)
{
winServo.write(val); // Possible hidden 100 ms delay
delay(100);
...
}
...
}
Consider using some logic instead of the delays. There seem to be a common pattern you are using.
As short reply and a general note, there is the millis() function that will be faster than a delay()
. It returns the number of milliseconds since the Arduino board began running the current program. You use maths to check if you've waited long enough.
Like this:
// check to see if it's time to do something; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// do something after the waiting interval here
}
Edit: One should also be aware of Interrupts, but be warned they must be used correctly.
Explore related questions
See similar questions with these tags.
Ctrl+K
to have your browser do this for you.