How do I solve the delay and button that doesn't work in my Project?

Microcontroller : Arduino Uno
Connectivity : HC - 05 Bluetooth Module

Hello, i want to ask about my problem. How to solve delay when i push the physical buttons, and button on app that didn't do the job, in this case is to switch between physical button or app button and switch a heater on/off.

Here is the code:

#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "HX711.h" // Berat tabung pemanas = 205 ml
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>

#define SwMode 9
#define HeatBtn 8
#define HeaterLamp 7
#define LOADCELL_SCK_PIN2  6
#define LOADCELL_DOUT_PIN2  5
#define LOADCELL_SCK_PIN1  4
#define LOADCELL_DOUT_PIN1  3
#define Heater 2
#define ONE_WIRE_BUS A3

SoftwareSerial BT(A1, A2); // Rx, Tx

HX711 produk;
HX711 pemanas;

RTC_DS3231 rtc;

File myFile;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

LiquidCrystal_I2C lcd(0x27, 20, 4); //0x3F/0x27

//DS18B20 MAC Address
DeviceAddress sH = {0x28, 0x59, 0x0B, 0x07, 0xD6, 0x01, 0x3C, 0x41};
DeviceAddress sS = {0x28, 0x40, 0x00, 0x94, 0x97, 0x09, 0x03, 0x86};
DeviceAddress sC = {0x28, 0x51, 0x57, 0x08, 0x59, 0x20, 0x01, 0xB5};

char data;
bool Mode;
bool modeButton;
float sHT;
float sCT;
float sST;
unsigned long menit;
unsigned long detik;
float calibration_factor1 = 513.10;
float calibration_factor2 = 468.50;

unsigned long previousTime = 0;
const long interval = 1000;

byte Degree [] {
  B00111,
  B00101,
  B00111,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
};

void changeMode() {
  if (digitalRead(SwMode) == HIGH) {
    Mode = 1;
  } else {
    Mode = 0;
  }
}

void mainControl() {
  if (Mode == 0) { // Manual
    if (BT.available() > 0) {
      data = BT.read(); // reading the data received from the bluetooth module
      if (data == '0') { //Phys Btn
        if (digitalRead(HeatBtn) == HIGH) {
          digitalWrite(Heater, LOW);
        } else {
          digitalWrite(Heater, HIGH);
        }
      } else if (data == '1') { //App Btn
        if (data == 'y') { //App Heater ON Btn
          digitalWrite(Heater, LOW);
        }
        if (data == 'n') { //App Heater OFF Btn
          digitalWrite(Heater, HIGH);
        }
      }
    }
    if (digitalRead(Heater) == HIGH) {
      BT.print("heatOFF");
      BT.print("/");
    } else if (digitalRead(Heater) == LOW) {
      BT.print("heatON");
      BT.print("/");
    }
    BT.print("Manual Mode");
    BT.println("/");
  }
  if (Mode == 1) { // Auto
    if (sHT >= 95) {
      digitalWrite(Heater, HIGH);
      BT.print("heatOFF");
      BT.print("/");
    } else {
      digitalWrite(Heater, LOW);
      BT.print("heatON");
      BT.print("/");
    }
    BT.print("Auto Mode");
    BT.println("/");
  }
}

void sendSensor()
{
  //  unsigned long currentTime =  millis();
  //  if (currentTime ; previousTime >= interval) {
  sensors.requestTemperatures();
  sensors.setResolution(12);

  sHT = (sensors.getTempC(sH) + 1.5);
  sST = (sensors.getTempC(sS) + 0.5);
  sCT = (sensors.getTempC(sC) + 0.5);

  produk.set_scale(calibration_factor1); //Adjust to this calibration factor
  pemanas.set_scale(calibration_factor2); //Adjust to this calibration factor

  // Sensors Reading send to MIT App
  BT.print(sHT, 1);
  BT.print("/");
  BT.print(sST, 1);
  BT.print("/");
  BT.print(sCT, 1);
  BT.print("/");
  BT.print(produk.get_units(), 1);
  BT.print("/");
  BT.print(pemanas.get_units(), 1);
  BT.print("/");
  //    previousTime = currentTime;
  //  }
}

void printDisplay() {
  unsigned long currentTime =  millis();
  if (currentTime - previousTime >= interval) {
    lcd.setCursor(0, 0);
    lcd.print("Pemanas:");
    lcd.setCursor(13, 0);
    lcd.print(sHT, 1);
    lcd.write(0);
    lcd.print("C");
    lcd.setCursor(0, 1);
    lcd.print("Uap Air:");
    lcd.setCursor(13, 1);
    lcd.print(sST, 1);
    lcd.write(0);
    lcd.print("C");
    lcd.setCursor(0, 2);
    lcd.print("Kondensator:");
    lcd.setCursor(13, 2);
    lcd.print(sCT, 1);
    lcd.write(0);
    lcd.print("C");

    lcd.setCursor(0, 3);
    lcd.print("Pro:");
    lcd.setCursor(4, 3);
    lcd.print(produk.get_units(), 1);
    lcd.print("ml");
    lcd.setCursor(10, 3);
    lcd.print("Pem:");
    lcd.setCursor(14, 3);
    lcd.print(pemanas.get_units(), 1);
    lcd.print("ml");
    previousTime = currentTime;
  }
}

void HeatLamp() {
  if (sHT >= 80) {
    digitalWrite(HeaterLamp, LOW);
  } else {
    digitalWrite(HeaterLamp, HIGH);
  }
}

void DataLog() {
  unsigned long currentTime =  millis();
  if (currentTime - previousTime >= interval) {
    DateTime now = rtc.now();
    menit = (now.minute() + 3);
    if (menit >= 60) {
      menit = (menit - 60);
    }
    detik = now.second() + 20;
    if (detik >= 60) {
      menit = (menit + 1);
      detik = (detik - 60);
    }

    int HeatStr = digitalRead(Heater);

    myFile = SD.open("Databases.csv", FILE_WRITE);
    if (myFile) {
      myFile.print(now.day(), DEC);
      myFile.print('/');
      myFile.print(now.month(), DEC);
      myFile.print('/');
      myFile.print(now.year(), DEC);
      myFile.print(',');
      myFile.print(now.hour(), DEC);
      myFile.print(':');
      myFile.print(now.minute(), DEC);
      myFile.print(':');
      myFile.print(now.second(), DEC);
      myFile.print(",");
      if (HeatStr == LOW) {
        myFile.print("ON");
        myFile.print(",");
      } else {
        myFile.print("ON");
        myFile.print(",");
      }
      myFile.print(sHT, 1);
      myFile.print(" ");
      myFile.print("°C");
      myFile.print(",");
      myFile.print(sST, 1);
      myFile.print(" ");
      myFile.print("°C");
      myFile.print(",");
      myFile.print(sCT, 1);
      myFile.print(" ");
      myFile.print("°C");
      myFile.print(",");
      myFile.print(pemanas.get_units(), 1);
      myFile.print(" ");
      myFile.print("ml");
      myFile.print(",");
      myFile.print(produk.get_units(), 1);
      myFile.print(" ");
      myFile.print("ml");
      myFile.print(",");
    }
    myFile.close();
    previousTime = currentTime;
  }
}

void setup()
{
  // Debug console
  Serial.begin(9600);
  BT.begin(9600);
  sensors.begin();
  rtc.begin();
  SD.begin(10);

  if (rtc.lostPower()) {
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

  myFile = SD.open("Databases.csv", FILE_WRITE);
  if (myFile) {
    // print the headings for our data
    myFile.println("Date,Time,Heater,Heater Temp,Steam Temp,Condensator Temp,Heater Volume,Product Volume");
  }
  myFile.close();

  pinMode(SwMode, INPUT);
  pinMode(Heater, OUTPUT);
  digitalWrite(Heater, HIGH);

  produk.begin(LOADCELL_DOUT_PIN1, LOADCELL_SCK_PIN1);
  produk.set_scale();
  produk.tare();
  pemanas.begin(LOADCELL_DOUT_PIN2, LOADCELL_SCK_PIN2);
  pemanas.set_scale();
  pemanas.tare();

  long zero_factor1 = produk.read_average(); //Get a baseline reading
  long zero_factor2 = pemanas.read_average(); //Get a baseline reading

  lcd.init();
  // Nyalakan backlight
  lcd.backlight();

  lcd.createChar(0, Degree);

  lcd.setCursor(1, 0);
  lcd.print("Haidar Amir Faruqi");
  lcd.setCursor(0, 1);
  lcd.print("DIII Teknik Elektro");
  lcd.setCursor(3, 2);
  lcd.print("Sekolah Vokasi");
  lcd.setCursor(3, 3);
  lcd.print("UNDIP Semarang");
  delay(2000);
  lcd.clear();

  lcd.setCursor(4, 0);
  lcd.print("Tugas Akhir");
  lcd.setCursor(2, 1);
  lcd.print("Prototipe Sistem");
  lcd.setCursor(4, 2);
  lcd.print("Kontrol Suhu");
  lcd.setCursor(4, 3);
  lcd.print("Berbasis IoT");
  delay(2000);
  lcd.clear();
}

void loop()
{
  sendSensor();
  mainControl();
  changeMode();
  printDisplay();
  HeatLamp();
  DataLog();
}

And here is the App:


TA_Haidar_copy_Heater_Button.aia (120.5 KB)

And the Blocks:

You are not taking advantage of AI2's BlueTooth message Delimiter facilities.
Here is a reworked Timer event that cover's the AI2 side in one place, at a slight inefficiency:

For an explanation, see this stanndard Delimiter advice:

Please see the Delimiter article in FAQ

Be sure to use println() at the end of each message to send from the sending device, to signal end of message. Do not rely on timing for this, which is unreliable.

In the AI2 Designer, set the Delimiter attribute of the BlueTooth Client component to 10 to recognize the End of Line character.
BlueToothClient1_Properties
Also, return data is not immediately available after sending a request,
you have to start a Clock Timer repeating and watch for its arrival in the Clock Timer event. The repeat rate of the Clock Timer should be faster than the transmission rate in the sending device, to not flood the AI2 buffers.

In your Clock Timer, you should check

  Is the BlueTooth Client still Connected?
  Is Bytes Available > 0?
     IF Bytes Available > 0 THEN
       set message var  to BT.ReceiveText(-1) 

This takes advantage of a special case in the ReceiveText block:

ReceiveText(numberOfBytes)
Receive text from the connected Bluetooth device. If numberOfBytes is less than 0, read until a delimiter byte value is received.

If you are sending multiple data values per message separated by | or comma, have your message split into a local or global variable for inspection before trying to select list items from it. Test if (length of list(split list result) >= expected list length) before doing any select list item operations, to avoid taking a long walk on a short pier. This bulletproofing is necessary in case your sending device sneaks in some commentary messages with the data values.

P.S. These blocks can be dragged directly into your Blocks Editor workspace.

See A way to group projects by theme - #10 by ABG
for a demo.

Be sure to use println() at the end of each message to send from the sending device, to signal end of message. Do not rely on timing for this, which is unreliable.

What you mean by this is BT.println in each sensor reading in my case or each global data sends?
And if i have set the bluetooth DelimiterByte in Designer, is it necessary to add the delimiter block or not?

The Designer setting is good.
I did it in the run time blocks because it was easy to package for this board.

Do your println operations in such a way that your AI2 code can recognize what it receives, either by included markup (labelling) or by counting commas (or whatever you use in your split block).

I just debugging my project, and found out that the problem was with the bluetooth connection. The bluetooth need around 40sec+ to settle, then it can send the messages and Arduino do the job. How to solve this?


From your terminal logs, I see two things ...

  • Your AI2 Clock component running the Timer was left at 1000 ms, way too slow. Speed it up to 29 ms.
  • Y
    o
    u

a
r
e

s
e
n
d
i
n
g

t
o
o

m
a
n
y

l
i
n
e

f
e
e
d
s
.