I am trying to build a car which can be 1) controlled manually (through remote as well as bluetooth), 2) put to obstacle avoiding mode,
3) put to line following mode.
All the modes are working fine.
The Problem:
In function fetchSensorData(),
if I put the code for fetching DTH11 sensor data
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);
if (isnan(h) || isnan(t) || isnan(f))
Serial.println(F("Failed to read from DHT sensor!"));
double hif = dht.computeHeatIndex(f, h);
Serial.println("Humidity: " + String(h));
Serial.println("Temperature: " + String(t) + "°C ");
Serial.println("Heat index: " + String(hif) + "°F ");
dht11_value = "Humidity: " + String(h) + "%" + " Temperature: " + String(t) + " C " + " Heat index: " + String(hif) + " F ";
BTSerial.println(dht11_value);
Serial.println(dht11_value);
or if I put the code for fetching BMP280 sensor data
sensors_event_t temp_event, pressure_event;
bmp_temp->getEvent(&temp_event);
bmp_pressure->getEvent(&pressure_event);
Serial.print(F("Temperature = "));
Serial.print(temp_event.temperature);
Serial.println(" *C");
Serial.print(F("Pressure = "));
Serial.print(pressure_event.pressure);
Serial.println(" hPa");
Serial.print(F("Temperature = "));
Serial.print(bmp.readTemperature());
Serial.println(" *C");
Serial.print(F("Pressure = "));
Serial.print(bmp.readPressure());
Serial.println(" Pa");
Serial.print(F("Approx altitude = "));
Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */
Serial.println(" m");
If either of the code is present in that function then it works (the total code then occupies almost 89% of the total available space on the board)
If both of the codes are present in that function then it shows (the total code then occupies almost 105% of the total available space on the board).
My tries:
I tried to use the F macro for the strings but then it reduced to 103%.
But still that error. How to reduce the size of my code?
Please help. Thanks a lot.
Schematic (very rough diagram, I have tried my best, I am new to all this):
Full Code:
#include <IRremote.h>
#include <SoftwareSerial.h>
#include <Servo.h> //Servo motor library. This is standard library
#include <NewPing.h> //Ultrasonic sensor function library. You must install this library
#include "DHT.h"
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>
//==============================================
// Data Definitions
//==============================================
#define ttp223 8
#define buzzer 12
unsigned long lastDebounceTime = 0; // the last time the output pin was toggled
unsigned long debounceDelay = 500; // the debounce time; increase if the output flickers
#define DHTPIN A0 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
Adafruit_BMP280 bmp; // use I2C interface
Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();
unsigned status;
//==============================================
// Manual Control Definitions
//==============================================
SoftwareSerial BTSerial(10, 11); // pin10->TX of BT, pin11->RX of BT
#define irPin 9
IRrecv irrecv(irPin);
decode_results rslts;
//==============================================
// Line Follower Definitions
//==============================================
#define R_S A6 //ir sensor Right
#define L_S A7 //ir sensor Left
//==============================================
// Obstacle Avoiding Definitions
//==============================================
#define trig_pin A2 //analog input 1
#define echo_pin A1 //analog input 2
#define maximum_distance 200
NewPing sonar(trig_pin, echo_pin, maximum_distance); //sensor function
Servo servo_motor; //our servo name
boolean goesForward = false;
int distance = 100;
//==============================================
// Motor Definitions
//==============================================
// Motor A
#define enA 6
#define in1 7
#define in2 4
// Motor B
#define enB 5
#define in3 3
#define in4 2
//PWM 3, 5, 6, 9, 10, 11
//==============================================
// General Definitions
//==============================================
//IR
String irNum;
//Loop
bool send = true;
int mode = 3, ttpData;
String data = "";
//Data
String dht11_value = "";
//BTSerial
String btNum = "o";
int d = -1, prev_d = -1;
bool running = false;
char incomingByte;
//Obstacle
int distanceRight, distanceLeft, cm;
void BTControl();
void IRControl();
void ObstacleControl();
void LineControl();
void Forward();
void Back();
void Left();
void Right();
void Stop();
void fetchSensorData();
void (*functionModePointers[4])(){
BTControl, IRControl, ObstacleControl, LineControl
};
void (*functionMovesPointers[7])(){
Forward, Back, Left, Right, Stop, fetchSensorData, show
};
void setup() {
pinMode(buzzer, OUTPUT);
//==============================================
// Motor Setup
//==============================================
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
//==============================================
// Manual Control Setup
//==============================================
Serial.begin(9600);
BTSerial.begin(9600);
pinMode(ttp223, INPUT);
irrecv.enableIRIn();
//==============================================
// Data Setup
//==============================================
dht.begin();
status = bmp.begin();
bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
bmp_temp->printSensorDetails();
//==============================================
// Line Follower Setup
//==============================================
pinMode(R_S, INPUT);
pinMode(L_S, INPUT);
//==============================================
// Obstacle Avoiding Setup
//==============================================
servo_motor.attach(13); //our servo pin
servo_motor.write(95);
delay(2000);
distance = readPing();
delay(100);
}
void loop() {
ttpData = digitalRead(ttp223);
if (ttpData == HIGH && (millis() - lastDebounceTime) > debounceDelay) {
lastDebounceTime = millis();
mode = (mode + 1) % 4;
Serial.println(mode);
send = true;
}
if (send == true) {
data = "mode after d is entered= " + String(mode);
Serial.println(data);
BTSerial.println(data);
send = false;
}
functionModePointers[mode]();
}
int decode(String data) {
if (data == "T" || data == "44")
return 0;
else if (data == "B" || data == "1d")
return 1;
else if (data == "L" || data == "1c")
return 2;
else if (data == "R" || data == "48")
return 3;
else if (data == "OK" || data == "O" || data == "K" || data == "5c")
return 4;
else if (data == "d" || data == "D")
return 5;
else if (data == "s" || data == "S") {
return 6;
} else
return -1;
}
void BTControl() {
while (BTSerial.available()) {
// Serial.write(BTSerial.read()); //writes full words to serial monitor
incomingByte = BTSerial.read();
if (incomingByte >= 97 && incomingByte <= 122) {
btNum = incomingByte;
BTSerial.println(btNum);
Serial.println(btNum);
running = false;
}
}
d = decode(btNum);
if (d > 0 && running == false) {
functionMovesPointers[d]();
running = true;
}
}
void show() {
BTSerial.println("Hello");
}
void IRControl() {
if (irrecv.decode()) {
Serial.println(rslts.value);
String irNum = String(irrecv.decodedIRData.command, HEX);
Serial.println(irrecv.decodedIRData.command, HEX);
Serial.println(irNum);
irrecv.resume();
}
// Add a small delay to avoid overwhelming the serial buffer
// delay(50);
functionMovesPointers[decode(irNum)]();
}
void ObstacleControl() {
distanceRight = 0;
distanceLeft = 0;
delay(50);
if (distance <= 20) {
moveStop();
delay(300);
moveBackward();
delay(400);
moveStop();
delay(300);
distanceLeft = lookLeft();
delay(300);
distanceRight = lookRight();
delay(300);
if (distance >= distanceLeft) {
turnRight();
moveStop();
} else {
turnLeft();
moveStop();
}
} else {
moveForward();
}
distance = readPing();
}
void LineControl() {
if ((analogRead(R_S) <= 500) && (analogRead(L_S) <= 500)) {
Serial.println(F("Forward"));
Forward();
} //if Right Sensor and Left Sensor are at White color then it will call forword function
if ((analogRead(R_S) >= 500) && (analogRead(L_S) <= 500)) {
// Right();
Serial.println(F("Right"));
} //if Right Sensor is Black and Left Sensor is White then it will call turn Right function
if ((analogRead(R_S) <= 500) && (analogRead(L_S) >= 500)) {
Left();
Serial.println(F("Left"));
} //if Right Sensor is White and Left Sensor is Black then it will call turn Left function
if ((analogRead(R_S) >= 500) && (analogRead(L_S) >= 500)) {
Stop();
Serial.println(F("Stop"));
} //if Right Sensor and Left Sensor are at Black color then it will call Stop function
}
void fetchSensorData() {
delay(2000);
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);
if (isnan(h) || isnan(t) || isnan(f))
Serial.println(F("Failed to read from DHT sensor!"));
double hif = dht.computeHeatIndex(f, h);
Serial.println("Humidity: " + String(h));
Serial.println("Temperature: " + String(t) + "°C ");
Serial.println("Heat index: " + String(hif) + "°F ");
dht11_value = "Humidity: " + String(h) + "%" + " Temperature: " + String(t) + " C " + " Heat index: " + String(hif) + " F ";
BTSerial.println(dht11_value);
Serial.println(dht11_value);
sensors_event_t temp_event, pressure_event;
bmp_temp->getEvent(&temp_event);
bmp_pressure->getEvent(&pressure_event);
Serial.print(F("Temperature = "));
Serial.print(temp_event.temperature);
Serial.println(" *C");
Serial.print(F("Pressure = "));
Serial.print(pressure_event.pressure);
Serial.println(" hPa");
Serial.print(F("Temperature = "));
Serial.print(bmp.readTemperature());
Serial.println(" *C");
Serial.print(F("Pressure = "));
Serial.print(bmp.readPressure());
Serial.println(" Pa");
Serial.print(F("Approx altitude = "));
Serial.print(bmp.readAltitude(1013.25)); /* Adjusted to local forecast! */
Serial.println(" m");
// Serial.println();
// delay(2000);
}
//==============================================
// Manual Control Functions
//==============================================
void Forward() {
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, 150);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 150);
}
void Back() {
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 150);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enB, 150);
}
void Right() {
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
analogWrite(enA, 150);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 150);
}
void Left() {
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, 150);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
analogWrite(enB, 150);
}
void Stop() {
analogWrite(enA, 0);
analogWrite(enB, 0);
}
//==============================================
// Obstacle Avoiding Functions
//==============================================
int lookRight() {
servo_motor.write(20);
delay(500);
int distance = readPing();
delay(100);
servo_motor.write(95);
return distance;
delay(100);
}
int lookLeft() {
servo_motor.write(170);
delay(500);
int distance = readPing();
delay(100);
servo_motor.write(95);
return distance;
delay(100);
}
int readPing() {
delay(70);
cm = sonar.ping_cm();
if (cm == 0) {
cm = 250;
}
return cm;
}
void moveStop() {
digitalWrite(in3, LOW);
digitalWrite(in1, LOW);
digitalWrite(in4, LOW);
digitalWrite(in2, LOW);
}
void moveForward() {
if (!goesForward) {
goesForward = true;
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, 150);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 150);
}
}
void moveBackward() {
goesForward = false;
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 150);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enB, 150);
}
void turnRight() {
//turning right little
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
analogWrite(enA, 150);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 150);
delay(500);
//moving backward little
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 150);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enB, 150);
}
void turnLeft() {
//turning left little
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, 150);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
analogWrite(enB, 150);
delay(500);
//moving backward little
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 150);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
analogWrite(enB, 150);
}