Hi,
I have a automatic project that involve two fuzzy logics, one for controlling pH (with two inputs and two outputs, with 10 rules) and the other for controlling TDS (with two inputs and one output, with 6 rules). Both of them are sharing one sensor which is water height (ketinggian air). the problem is none of them are showing output, always zero. anybody can help me what's wrong with my program?
here is the code:
//by M Akmal
//write the code carefully!!!
//urutan data:
//<pH, TDS, suhu air, tinggi air>
//=============Oneshot Timer =====================
class OneShotTimer {
public:
OneShotTimer(uint8_t pin, const char* lbl):
m_pin(pin), m_label(lbl)
{
pinMode(m_pin, OUTPUT);
}
void start(float a, float b){
m_x = a;
m_y = b;
}
void pour(float ml) {
digitalWrite(m_pin, HIGH);
m_startTime = millis();
m_setTime = calcDelay(m_x, m_y, ml);
Serial.print("Start: ");
Serial.print(m_label);
Serial.print(", amount: ");
Serial.print(int(ml));
Serial.print(", duration: ");
Serial.print(m_setTime);
Serial.println(" ms.");
m_running = 1;
}
void run() {
if (millis() - m_startTime >= m_setTime && m_running) {
digitalWrite(m_pin, LOW);
Serial.print("Stop: ");
Serial.println(m_label);
m_running = 0;
}
}
uint32_t calcDelay(float a, float b, int ml) {
double val = a * (ml^2) + b * ml;
return (uint32_t) val;
}
private:
const char* m_label;
uint8_t m_pin;
uint8_t m_running;
uint32_t m_startTime;
uint32_t m_setTime;
uint8_t m_x;
uint8_t m_y;
};
//=============Software Serial====================
#include <SoftwareSerial.h>
SoftwareSerial Serial2(A4, A5); // RX, TX
//===============universal variable===============
float w_temp = 25;
float pH_value;
unsigned long tds_value;
int height_value;
uint64_t elapsedSprint;
uint64_t elapsedLoop;
uint64_t elapsedLogic;
int spinterval = 3000; //interval serial print
int loopinterval = 3000; //interval pembacaan sensor
int logicInterval = 3000; //interval fuzzy logic
bool pH_up = false;
bool pH_down = false;
bool tds_up = false;
#define A_liq 7
#define B_liq 8
#define pHup_liq 9
#define pHdown_liq 10
//===================pH Sensor=====================
int pHSense = A0;
int samples = 100;
float adc_resolution = 1024.0;
//===============DS18B2 Temp sensor================
#include <OneWire.h>
#include <DallasTemperature.h>
#include <NonBlockingDallas.h> //Include the NonBlockingDallas library
#define ONE_WIRE_BUS 6 //PIN of the Maxim DS18B20 temperature sensor
#define TIME_INTERVAL 3000 //Time interval among sensor readings [milliseconds]
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature dallasTemp(&oneWire);
NonBlockingDallas temperatureSensors(&dallasTemp); //Create a new instance of the NonBlockingDallas class
//==================TDS Sensor=====================
#include <EEPROM.h>
#include "GravityTDS.h"
#define TdsSensorPin A1
GravityTDS gravityTds;
//=============water-height sensor=================
#include <NewPing.h>
#define TRIGGER_PIN 4 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 5 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 400 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
int height = 10;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
//===================pompa==========================
#define pompa_a 7
#define pompa_b 8
#define pompa_c 9
#define pompa_d 10
OneShotTimer pumpA(pompa_a, "PUMP A");
OneShotTimer pumpB(pompa_b, "PUMP B");
OneShotTimer pumpC(pompa_c, "PUMP C");
OneShotTimer pumpD(pompa_d, "PUMP D");
//==================fuzzy logic======================
#include <Fuzzy.h>
// #include "fuzzySetupAndRule.h"
Fuzzy *fuzzy_pH = new Fuzzy();
Fuzzy *fuzzy_TDS = new Fuzzy();
FuzzySet *pH_VeryLow = new FuzzySet(0, 0, 4.5, 5.5);
FuzzySet *pH_Low = new FuzzySet(5, 5.5, 5.5, 6.25);
FuzzySet *pH_Normal = new FuzzySet(5.5, 6.5, 6.5, 7.5);
FuzzySet *pH_High = new FuzzySet(6.75, 7.5, 7.5, 8);
FuzzySet *pH_VeryHigh = new FuzzySet(7.5, 8, 14,14);
FuzzySet *TDS_VeryLow = new FuzzySet(0, 0, 300, 500);
FuzzySet *TDS_Normal = new FuzzySet(600, 800, 1000, 1000);
FuzzySet *TDS_Low = new FuzzySet(400, 550, 550, 700);
FuzzySet *tinggiAir_Low = new FuzzySet(0, 0, 15, 25);
FuzzySet *tinggiAir_High = new FuzzySet(15, 25, 35, 35);
FuzzySet *pompa_phup_small = new FuzzySet(-10, -10, 0, 50 );
FuzzySet *pompa_phup_medium = new FuzzySet(25, 50, 50, 75);
FuzzySet *pompa_phup_high = new FuzzySet(50, 100, 150, 150);
FuzzySet *pompa_phdown_small = new FuzzySet(-10, -10, 0, 50 );
FuzzySet *pompa_phdown_medium = new FuzzySet(25, 50, 50, 75);
FuzzySet *pompa_phdown_high = new FuzzySet(50, 100, 150, 150);
FuzzySet *pompa_tds_small = new FuzzySet(-10, -10, 0, 50 );
FuzzySet *pompa_tds_medium = new FuzzySet(25, 50, 50, 75);
FuzzySet *pompa_tds_high = new FuzzySet(50, 100, 150, 150);
//===================================================
void setup() {
Serial.begin(9600);
Serial2.begin(115200);
randomSeed(analogRead(0));
//DS18B2======================
temperatureSensors.begin(NonBlockingDallas::resolution_12, TIME_INTERVAL);
temperatureSensors.onTemperatureChange(handleTemperatureChange);
temperatureSensors.requestTemperature();
//TDS Sensor===================
gravityTds.setPin(TdsSensorPin);
gravityTds.setAref(5.0); //reference voltage on ADC, default 5.0V on Arduino UNO
gravityTds.setAdcRange(1024); //1024 for 10bit ADC;4096 for 12bit ADC
gravityTds.begin(); //initialization
//pompa========================
pumpA.start(-0.0568, 66.154);
pumpB.start(-0.0268, 53.651);
pumpC.start(-0.0223, 49.775);
pumpD.start(-0.0505, 64.876);
// fuzzyVariables();
//fuzzy initial variable
//input pH
FuzzyInput *pH_Fuzzy = new FuzzyInput(1);
pH_Fuzzy->addFuzzySet(pH_VeryLow);
pH_Fuzzy->addFuzzySet(pH_Low);
pH_Fuzzy->addFuzzySet(pH_Normal);
pH_Fuzzy->addFuzzySet(pH_High);
pH_Fuzzy->addFuzzySet(pH_VeryHigh);
fuzzy_pH->addFuzzyInput(pH_Fuzzy);
//input TDS
FuzzyInput *TDS_Fuzzy = new FuzzyInput(2);
TDS_Fuzzy->addFuzzySet(TDS_VeryLow);
TDS_Fuzzy->addFuzzySet(TDS_Low);
TDS_Fuzzy->addFuzzySet(TDS_Normal);
fuzzy_TDS->addFuzzyInput(TDS_Fuzzy);
//input Tinggi air
FuzzyInput *tinggiAir_Fuzzy = new FuzzyInput(3);
tinggiAir_Fuzzy->addFuzzySet(tinggiAir_Low);
tinggiAir_Fuzzy->addFuzzySet(tinggiAir_High);
fuzzy_pH->addFuzzyInput(tinggiAir_Fuzzy);
fuzzy_TDS->addFuzzyInput(tinggiAir_Fuzzy);
//output pompa pH
FuzzyOutput *pH_pompaUp = new FuzzyOutput(1);
pH_pompaUp->addFuzzySet(pompa_phup_small);
pH_pompaUp->addFuzzySet(pompa_phup_medium);
pH_pompaUp->addFuzzySet(pompa_phup_high);
FuzzyOutput *pH_pompaDown = new FuzzyOutput(2);
pH_pompaDown->addFuzzySet(pompa_phdown_small);
pH_pompaDown->addFuzzySet(pompa_phdown_medium);
pH_pompaDown->addFuzzySet(pompa_phdown_high);
fuzzy_pH->addFuzzyOutput(pH_pompaUp);
fuzzy_pH->addFuzzyOutput(pH_pompaDown);
//output pompa TDS
FuzzyOutput *TDS_pompa = new FuzzyOutput(3);
TDS_pompa->addFuzzySet(pompa_tds_small);
TDS_pompa->addFuzzySet(pompa_tds_medium);
TDS_pompa->addFuzzySet(pompa_tds_high);
fuzzy_TDS->addFuzzyOutput(TDS_pompa);
//building fuzzy rule pH Normal Tinggi air low pompa small (1)
FuzzyRuleAntecedent *pHNormal_tinggiAirLow = new FuzzyRuleAntecedent();
pHNormal_tinggiAirLow->joinWithAND(pH_Normal, tinggiAir_Low);
FuzzyRuleConsequent *thenPompaPHOFF1 = new FuzzyRuleConsequent();
thenPompaPHOFF1->addOutput(pompa_phup_small);
thenPompaPHOFF1->addOutput(pompa_phdown_small);
FuzzyRule *pHRule1 = new FuzzyRule(1, pHNormal_tinggiAirLow, thenPompaPHOFF1);
fuzzy_pH->addFuzzyRule(pHRule1);
//building fuzzy rule pH Normal Tinggi air high pompa small (2)
FuzzyRuleAntecedent *pHNormal_tinggiAirHigh = new FuzzyRuleAntecedent();
pHNormal_tinggiAirHigh->joinWithAND(pH_Normal, tinggiAir_High);
FuzzyRuleConsequent *thenPompaPHOFF2 = new FuzzyRuleConsequent();
thenPompaPHOFF2->addOutput(pompa_phup_small);
thenPompaPHOFF2->addOutput(pompa_phdown_small);
FuzzyRule *pHRule2 = new FuzzyRule(2, pHNormal_tinggiAirHigh, thenPompaPHOFF2);
fuzzy_pH->addFuzzyRule(pHRule2);
//building fuzzy rule pH verylow Tinggi air low pompa phup high (3)
FuzzyRuleAntecedent *pHVeryLow_tinggiAirLow = new FuzzyRuleAntecedent();
pHVeryLow_tinggiAirLow->joinWithAND(pH_VeryLow, tinggiAir_Low);
FuzzyRuleConsequent *thenPompaPHupHigh1 = new FuzzyRuleConsequent();
thenPompaPHupHigh1->addOutput(pompa_phup_high);
thenPompaPHupHigh1->addOutput(pompa_phdown_small);
FuzzyRule *pHRule3 = new FuzzyRule(3, pHVeryLow_tinggiAirLow, thenPompaPHupHigh1);
fuzzy_pH->addFuzzyRule(pHRule3);
//building fuzzy rule pH verylow Tinggi air high pompa phup high (4)
FuzzyRuleAntecedent *pHVeryLow_tinggiAirHigh = new FuzzyRuleAntecedent();
pHVeryLow_tinggiAirHigh->joinWithAND(pH_VeryLow, tinggiAir_High);
FuzzyRuleConsequent *thenPompaPHupHigh2 = new FuzzyRuleConsequent();
thenPompaPHupHigh2->addOutput(pompa_phup_high);
thenPompaPHupHigh2->addOutput(pompa_phdown_small);
FuzzyRule *pHRule4 = new FuzzyRule(4, pHVeryLow_tinggiAirHigh, thenPompaPHupHigh2);
fuzzy_pH->addFuzzyRule(pHRule4);
//building fuzzy rule pH Low Tinggi air low pompa phup medium (5)
FuzzyRuleAntecedent *pHLow_tinggiAirLow = new FuzzyRuleAntecedent();
pHLow_tinggiAirLow->joinWithAND(pH_Low, tinggiAir_Low);
FuzzyRuleConsequent *thenPompaPHupMedium = new FuzzyRuleConsequent();
thenPompaPHupMedium->addOutput(pompa_phup_medium);
thenPompaPHupMedium->addOutput(pompa_phdown_small);
FuzzyRule *pHRule5 = new FuzzyRule(5, pHLow_tinggiAirLow, thenPompaPHupMedium);
fuzzy_pH->addFuzzyRule(pHRule5);
//building fuzzy rule pH Low Tinggi air high pompa phup high (6)
FuzzyRuleAntecedent *pHLow_tinggiAirHigh = new FuzzyRuleAntecedent();
pHLow_tinggiAirHigh->joinWithAND(pH_Low, tinggiAir_High);
FuzzyRuleConsequent *thenPompaPHupHigh3 = new FuzzyRuleConsequent();
thenPompaPHupHigh3->addOutput(pompa_phup_high);
thenPompaPHupHigh3->addOutput(pompa_phdown_small);
FuzzyRule *pHRule6 = new FuzzyRule(6, pHLow_tinggiAirHigh, thenPompaPHupMedium);
fuzzy_pH->addFuzzyRule(pHRule6);
//building fuzzy rule pH very high Tinggi air low pompa pdown high (7)
FuzzyRuleAntecedent *pHVeryHigh_tinggiAirLow = new FuzzyRuleAntecedent();
pHVeryHigh_tinggiAirLow->joinWithAND(pH_VeryHigh, tinggiAir_Low);
FuzzyRuleConsequent *thenPompaPHdownHigh1 = new FuzzyRuleConsequent();
thenPompaPHdownHigh1->addOutput(pompa_phup_small);
thenPompaPHdownHigh1->addOutput(pompa_phdown_high);
FuzzyRule *pHRule7 = new FuzzyRule(7, pHVeryHigh_tinggiAirLow, thenPompaPHdownHigh1);
fuzzy_pH->addFuzzyRule(pHRule7);
//building fuzzy rule pH very high Tinggi air high pompa pdown high (8)
FuzzyRuleAntecedent *pHVeryHigh_tinggiAirHigh = new FuzzyRuleAntecedent();
pHVeryHigh_tinggiAirHigh->joinWithAND(pH_VeryHigh, tinggiAir_High);
FuzzyRuleConsequent *thenPompaPHdownHigh2 = new FuzzyRuleConsequent();
thenPompaPHdownHigh2->addOutput(pompa_phup_small);
thenPompaPHdownHigh2->addOutput(pompa_phdown_high);
FuzzyRule *pHRule8 = new FuzzyRule(8, pHVeryHigh_tinggiAirHigh, thenPompaPHdownHigh2);
fuzzy_pH->addFuzzyRule(pHRule8);
//building fuzzy rule pH high Tinggi air low pompa phdown medium (9)
FuzzyRuleAntecedent *pHHigh_tinggiAirLow = new FuzzyRuleAntecedent();
pHHigh_tinggiAirLow->joinWithAND(pH_High, tinggiAir_Low);
FuzzyRuleConsequent *thenPompaPHdownMedium = new FuzzyRuleConsequent();
thenPompaPHdownMedium->addOutput(pompa_phup_small);
thenPompaPHdownMedium->addOutput(pompa_phdown_medium);
FuzzyRule *pHRule9 = new FuzzyRule(9, pHHigh_tinggiAirLow, thenPompaPHdownMedium);
fuzzy_pH->addFuzzyRule(pHRule9);
//building fuzzy rule pH high Tinggi air high pompa phdown high (10)
FuzzyRuleAntecedent *pHHigh_tinggiAirHigh = new FuzzyRuleAntecedent();
pHHigh_tinggiAirHigh->joinWithAND(pH_High, tinggiAir_High);
FuzzyRuleConsequent *thenPompaPHdownHigh3 = new FuzzyRuleConsequent();
thenPompaPHdownHigh3->addOutput(pompa_phup_small);
thenPompaPHdownHigh3->addOutput(pompa_phdown_high);
FuzzyRule *pHRule10 = new FuzzyRule(10, pHHigh_tinggiAirHigh, thenPompaPHdownHigh3);
fuzzy_pH->addFuzzyRule(pHRule10);
//building fuzzy rule TDS normal Tinggi air low pompa tds small (1)
FuzzyRuleAntecedent *TDSNormal_tinggiAirLow = new FuzzyRuleAntecedent();
TDSNormal_tinggiAirLow->joinWithAND(TDS_Normal, tinggiAir_Low);
FuzzyRuleConsequent *thenPompaTDSSmall1 = new FuzzyRuleConsequent();
thenPompaTDSSmall1->addOutput(pompa_tds_small);
FuzzyRule *TDSRule1 = new FuzzyRule (1, TDSNormal_tinggiAirLow, thenPompaTDSSmall1);
fuzzy_TDS->addFuzzyRule(TDSRule1);
//building fuzzy rule TDS normal Tinggi air high pompa tds small (2)
FuzzyRuleAntecedent *TDSNormal_tinggiAirHigh = new FuzzyRuleAntecedent();
TDSNormal_tinggiAirHigh->joinWithAND(TDS_Normal, tinggiAir_High);
FuzzyRuleConsequent *thenPompaTDSSmall2 = new FuzzyRuleConsequent();
thenPompaTDSSmall2->addOutput(pompa_tds_small);
FuzzyRule *TDSRule2 = new FuzzyRule (2, TDSNormal_tinggiAirHigh, thenPompaTDSSmall2);
fuzzy_TDS->addFuzzyRule(TDSRule2);
//building fuzzy rule TDS very low Tinggi air low pompa tds high (3)
FuzzyRuleAntecedent *TDSVeryLow_tinggiAirLow = new FuzzyRuleAntecedent();
TDSVeryLow_tinggiAirLow->joinWithAND(TDS_VeryLow, tinggiAir_Low);
FuzzyRuleConsequent *thenPompaTDSHigh1 = new FuzzyRuleConsequent();
thenPompaTDSHigh1->addOutput(pompa_tds_high);
FuzzyRule *TDSRule3 = new FuzzyRule (3, TDSVeryLow_tinggiAirLow, thenPompaTDSHigh1);
fuzzy_TDS->addFuzzyRule(TDSRule3);
//building fuzzy rule TDS very low Tinggi air high pompa tds high (4)
FuzzyRuleAntecedent *TDSVeryLow_tinggiAirHigh = new FuzzyRuleAntecedent();
TDSVeryLow_tinggiAirHigh->joinWithAND(TDS_VeryLow, tinggiAir_High);
FuzzyRuleConsequent *thenPompaTDSHigh2 = new FuzzyRuleConsequent();
thenPompaTDSHigh2->addOutput(pompa_tds_high);
FuzzyRule *TDSRule4 = new FuzzyRule (4, TDSVeryLow_tinggiAirHigh, thenPompaTDSHigh2);
fuzzy_TDS->addFuzzyRule(TDSRule4);
//building fuzzy rule TDS low Tinggi air low pompa tds medium (5)
FuzzyRuleAntecedent *TDSLow_tinggiAirLow = new FuzzyRuleAntecedent();
TDSLow_tinggiAirLow->joinWithAND(TDS_Low, tinggiAir_Low);
FuzzyRuleConsequent *thenPompaTDSMedium = new FuzzyRuleConsequent();
thenPompaTDSMedium->addOutput(pompa_tds_medium);
FuzzyRule *TDSRule5 = new FuzzyRule (5, TDSLow_tinggiAirLow, thenPompaTDSMedium);
fuzzy_TDS->addFuzzyRule(TDSRule5);
//building fuzzy rule TDS low Tinggi air high pompa tds High (6)
FuzzyRuleAntecedent *TDSLow_tinggiAirHigh = new FuzzyRuleAntecedent();
TDSLow_tinggiAirHigh->joinWithAND(TDS_Low, tinggiAir_High);
FuzzyRuleConsequent *thenPompaTDSHigh3 = new FuzzyRuleConsequent();
thenPompaTDSHigh3->addOutput(pompa_tds_high);
FuzzyRule *TDSRule6 = new FuzzyRule (6, TDSLow_tinggiAirHigh, thenPompaTDSHigh3);
fuzzy_TDS->addFuzzyRule(TDSRule6);
}
void loop() {
//pompa
pumpA.run();
pumpB.run();
pumpC.run();
pumpD.run();
//TDS
temperatureSensors.update();
if (millis() - elapsedLoop >= loopinterval){
elapsedLoop = millis();
pHMeasure();
TDSMeasure();
heightMeasure();
// pH_value = random(1,1400) / 100;
// tds_value = random(0,800);
// height_value = random(10,30);
// pH_value = 8.3;
// // tds_value = 755;
// height_value = 25;
}
//fuzzy logic dan aktuator
if (millis() - elapsedLogic >= logicInterval){
elapsedLogic = millis();
fuzzy_pH->setInput(1,pH_value);
fuzzy_pH->setInput(2,float(height_value));
fuzzy_pH->fuzzify();
fuzzy_TDS->setInput(3,tds_value);
fuzzy_TDS->setInput(2,float(height_value));
fuzzy_TDS->fuzzify();
Serial.println("\n\n\nInput pH");
Serial.print("\tVeryLow->");
Serial.print(pH_VeryLow->getPertinence());
Serial.print(", low->");
Serial.print(pH_Low->getPertinence());
Serial.print(", Normal->");
Serial.print(pH_Normal->getPertinence());
Serial.print(", High->");
Serial.print(pH_High->getPertinence());
Serial.print(", VeryHigh->");
Serial.println(pH_VeryLow->getPertinence());
Serial.println("Input Ketinggian Air");
Serial.print("\t Low->");
Serial.print(tinggiAir_Low->getPertinence());
Serial.print(", High->");
Serial.println(tinggiAir_High->getPertinence());
Serial.println("Input TDS");
Serial.print("\t Very Low->");
Serial.print(TDS_VeryLow->getPertinence());
Serial.print(", low->");
Serial.print(TDS_Low->getPertinence());
Serial.print(", Normal->");
Serial.println(TDS_Normal->getPertinence());
int output_pHup = int(fuzzy_pH->defuzzify(1));
int output_pHdown = int(fuzzy_pH->defuzzify(2));
Serial.print("pH up:");
Serial.print(output_pHup);
Serial.print(", pH down:");
Serial.println(output_pHdown);
int output_tds = int(fuzzy_TDS->defuzzify(3));
Serial.print("pompa TDS:");
Serial.println(output_tds);
// logic_pH();
// logic_tds();
}
//pastikan serial print yang keluar hanya ini
//urutan data:
//<pH, TDS, suhu air, tinggi air>
if (millis() - elapsedSprint >= spinterval){
elapsedSprint = millis();
Serial2.print("<");
Serial2.print(pH_value);
Serial2.print(", ");
Serial2.print(tds_value);
Serial2.print(", ");
Serial2.print(w_temp);
Serial2.print(", ");
Serial2.print(height_value);
Serial2.print(">");
Serial.print("<");
Serial.print(pH_value);
Serial.print(", ");
Serial.print(tds_value);
Serial.print(", ");
Serial.print(w_temp);
Serial.print(", ");
Serial.print(height_value);
Serial.println(">");
// Serial2.print(buffer);
// Serial.println(buffer);
}
}
//logic pH
void logic_pH(){
}
//logic tds
void logic_tds(){
}
//pengukuran pH
void pHMeasure(){
unsigned long measurings=0;
for (int i = 0; i < samples; i++)
{
measurings += analogRead(pHSense);
delay(10);
}
float voltage = (5.0 / 1023.0) * (measurings/samples);
// pH_value = voltage;
pH_value = -10.449 * voltage + 43.88;
}
//pengukuran TDS
void TDSMeasure() {
gravityTds.setTemperature(w_temp); // set the temperature and execute temperature compensation
gravityTds.update(); //sample and calculate
int tds = gravityTds.getTdsValue(); // then get the value
// tds_value = tds;
// tds_value = 0.0017 * tds*tds + 0.7685 * tds;
tds_value = 0,8488 * tds;
}
//parameter tambahan sensor suhu
void handleTemperatureChange(int deviceIndex, int32_t temperatureRAW)
{
w_temp = temperatureSensors.rawToCelsius(temperatureRAW) * 0.9979;
// w_temp = 25;
}
//pengukuran ketinggian
void heightMeasure() {
int h_temporary= sonar.ping_cm();
height_value = height - h_temporary;
// height_value = h_temporary;
}
And here is the schematic for additional help:
Thank you!

