#include <Arduino.h>
#include <Wire.h>
#include <WiFi.h>
#include <ThingsBoard.h>
#include <Arduino_MQTT_Client.h>
// Pin tanımlamaları
#define desarjPin 35 // ADC1
#define sarjPin 26 // ADC1
#define balMosfet1 27 // ADC1
#define balMosfet2 14 // ADC1
#define balMosfet3 12 // ADC1
#define akimPin 36 // ADC1
#define NTCPin 39 // ADC1
#define bat1volt 25 // ADC1
#define bat2volt 33 // ADC1
#define bat3volt 32 // ADC1
#define desarjLed 16
#define sarjLed 0
#define standbyLed 17
#define I2C_ADDRESS 0x08
#define MSG_BUFFER_SIZE (50)
unsigned long lastMsg = 0;
char msg[MSG_BUFFER_SIZE];
int value = 0;
int seriModu = 0; // 0: Alıcı, 1: Verici
float topAkim = 0;
float akimRaw = 0;
float h1_v = 0;
float h2_v = 0;
float h3_v = 0;
float sicaklik = 0;
float v1 = 0;
float v1_yuzde=0;
float v2 = 0;
float v2_yuzde=0;
float v3 = 0;
float v3_yuzde=0;
float vTop = 0;
bool sarjDurumu = 0;
bool desarjDurumu = 0;
const float BETA = 3950; // Termistörün Beta Katsayısı
int state=0;
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASS ""
#define TB_SERVER "thingsboard.cloud"
#define TOKEN "exlv4ummkinduco5gxug"
constexpr uint16_t MAX_MESSAGE_SIZE = 256U;
WiFiClient espClient;
Arduino_MQTT_Client mqttClient(espClient);
ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE);
void connectToWiFi() {
Serial.println("Connecting to WiFi...");
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
WiFi.begin(WIFI_SSID, WIFI_PASS);
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("\nFailed to connect to WiFi.");
} else {
Serial.println("\nConnected to WiFi");
}
}
void connectToThingsBoard() {
if (!tb.connected()) {
Serial.println("Connecting to ThingsBoard server");
if (!tb.connect(TB_SERVER, TOKEN)) {
Serial.println("Failed to connect to ThingsBoard");
} else {
Serial.println("Connected to ThingsBoard");
}
}
}
void tbVeriGonder(int seriModu, float topAkim, float v1,float v1_yuzde, float v2,float v2_yuzde, float v3,float v3_yuzde, float vTop, bool sarjDurumu, bool desarjDurumu, float sicaklikCelcius) {
String jsonData = "{";
jsonData += "\"seriModu\":" + String(seriModu) + ", ";
jsonData += "\"topAkim\":" + String(topAkim) + ", ";
jsonData += "\"v1\":" + String(v1) + ", ";
jsonData += "\"v1_yuzde\":" + String(v1_yuzde) + ", ";
jsonData += "\"v2\":" + String(v2) + ", ";
jsonData += "\"v2_yuzde\":" + String(v1_yuzde) + ", ";
jsonData += "\"v3\":" + String(v3) + ", ";
jsonData += "\"v3\":" + String(v3_yuzde) + ", ";
jsonData += "\"vTop\":" + String(vTop) + ", ";
jsonData += "\"sarjDurumu\":" + String(sarjDurumu) + ", ";
jsonData += "\"desarjDurumu\":" + String(desarjDurumu) + ", ";
jsonData += "\"sicaklik\":" + String(sicaklikCelcius);
jsonData += "}";
tb.sendTelemetryJson(jsonData.c_str());
Serial.println("Data sent: " + jsonData);
}
void durumLedi() {
if (sarjDurumu) {
digitalWrite(sarjLed, HIGH);
digitalWrite(desarjLed, LOW);
digitalWrite(standbyLed, LOW);
} else if (desarjDurumu) {
digitalWrite(sarjLed, LOW);
digitalWrite(desarjLed, HIGH);
digitalWrite(standbyLed, LOW);
} else {
digitalWrite(sarjLed, LOW);
digitalWrite(desarjLed, LOW);
digitalWrite(standbyLed, HIGH);
}
}
void setup_wifi() {
delay(10);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
void reconnect() {
// Loop until we're reconnected
while (!mqttClient.connected()) {
// Attempt to connect
if (mqttClient.connect("ESP8266Client", TOKEN, NULL)) {
} else {
delay(1000);
}
}
}
void pinDefine(){
pinMode(desarjPin, OUTPUT);
pinMode(sarjPin, OUTPUT);
pinMode(balMosfet1, OUTPUT);
pinMode(balMosfet2, OUTPUT);
pinMode(balMosfet3, OUTPUT);
pinMode(sarjLed, OUTPUT);
pinMode(desarjLed, OUTPUT);
pinMode(standbyLed, OUTPUT);
pinMode(NTCPin, INPUT) ;
pinMode(akimPin, INPUT) ;
pinMode(bat1volt, INPUT) ;
pinMode(bat2volt, INPUT) ;
pinMode(bat3volt, INPUT) ;
}
void balans() {
float v1 = analogRead(bat1volt);
float v2 = analogRead(bat2volt);
float v3 = analogRead(bat3volt);
// MOSFET'leri başlangıçta kapalı duruma getir
digitalWrite(balMosfet1, LOW);
digitalWrite(balMosfet2, LOW);
digitalWrite(balMosfet3, LOW);
// En yüksek voltajı bul ve ilgili MOSFET'i aç
if (v1 > v2 && v1 > v3) {
digitalWrite(balMosfet1, HIGH);
if (v1 == v2 || v1 == v3) {
digitalWrite(balMosfet1, LOW);
}
} else if (v2 > v1 && v2 > v3) {
digitalWrite(balMosfet2, HIGH);
if (v2 == v1 || v2 == v3) {
digitalWrite(balMosfet2, LOW);
}
} else if (v3 > v1 && v3 > v2) {
digitalWrite(balMosfet3, HIGH);
if (v3 == v1 || v3 == v2) {
digitalWrite(balMosfet3, LOW);
}
}
}
void i2cVeriGonder(float topAkim, float sicaklik, float v1, float v2, float v3, float vTop, bool sarjDurumu, bool desarjDurumu) {
Wire.beginTransmission(I2C_ADDRESS);
Wire.write((byte*)&topAkim, sizeof(topAkim));
Wire.write((byte*)&sicaklik, sizeof(sicaklik));
Wire.write((byte*)&v1, sizeof(v1));
Wire.write((byte*)&v2, sizeof(v2));
Wire.write((byte*)&v3, sizeof(v3));
Wire.write((byte*)&vTop, sizeof(vTop));
Wire.write(sarjDurumu);
Wire.write(desarjDurumu);
Wire.endTransmission();
}
void i2cVeriOku() {
Wire.requestFrom(I2C_ADDRESS, 26);
if (Wire.available() == 26) {
float topAkim, sicaklik, v1, v2, v3, vTop;
bool sarjDurumu, desarjDurumu;
Wire.readBytes((char*)&topAkim, sizeof(topAkim));
Wire.readBytes((char*)&sicaklik, sizeof(sicaklik));
Wire.readBytes((char*)&v1, sizeof(v1));
Wire.readBytes((char*)&v2, sizeof(v2));
Wire.readBytes((char*)&v3, sizeof(v3));
Wire.readBytes((char*)&vTop, sizeof(vTop));
sarjDurumu = Wire.read();
desarjDurumu = Wire.read();
}
}
void verialisveris() {
akimRaw = analogRead(akimPin);
sicaklik = analogRead(NTCPin);
h1_v = analogRead(bat1volt);
h2_v = analogRead(bat2volt);
h3_v = analogRead(bat3volt);
sarjDurumu = digitalRead(sarjPin);
desarjDurumu = digitalRead(desarjPin);
topAkim = map(analogRead(akimPin),0, 4095, 0, 50.0);
v1 = map(h1_v, 0, 4095, 0, 4.2);
v1_yuzde=map(h1_v, 0, 4095, 0, 100);
v2 = map(h2_v, 0, 4095, 0, 4.2);
v2_yuzde=map(h2_v, 0, 4095, 0, 100);
v3 = map(h3_v, 0, 4095, 0, 4.2);
v3_yuzde=map(h3_v, 0, 4095, 0, 100);
vTop = v1 + v2 + v3;
float sicaklikCelcius = map(sicaklik, 3813, 462, -24, 80);
// Corrected function call with all required arguments
tbVeriGonder(seriModu, topAkim, v1, v1_yuzde, v2, v2_yuzde, v3, v3_yuzde, vTop, sarjDurumu, desarjDurumu, sicaklikCelcius);
}
void seriModKontrolu(){
switch (seriModu) {
case 0: // Master modu
i2cVeriOku();
break;
case 1: // Slave modu
i2cVeriGonder(topAkim, sicaklik, v1, v2, v3, vTop, sarjDurumu, desarjDurumu);
break;
default:
Serial.println("Geçersiz seriModu değeri.");
break;
}
}
void setState() {
switch (state) {
case 0:
if (sicaklik < 70 && topAkim <= 30 && vTop <= 12 && vTop >= 9) {
// Deşarj durumu
desarjDurumu = true;
sarjDurumu = false;
digitalWrite(desarjLed, HIGH);
digitalWrite(sarjLed, LOW);
digitalWrite(desarjPin, HIGH);
digitalWrite(sarjPin, LOW);
state = 1;
}
else if (sicaklik < 70 && topAkim <= 30 && vTop <= 9) {
// Şarj durumu
desarjDurumu = false;
sarjDurumu = true;
digitalWrite(desarjLed, LOW);
digitalWrite(sarjLed, HIGH);
digitalWrite(desarjPin, LOW);
digitalWrite(sarjPin, HIGH);
state = 2;
}
else if (sicaklik < 70 && topAkim <= 30 && vTop <= 12 && vTop >= 9) {
if (topAkim < 1.0) {
delay(3000); // 3 saniye bekle
if (topAkim < 1.0) {
// Balans durumu
balans();
desarjDurumu = false;
sarjDurumu = false;
digitalWrite(desarjLed, LOW);
digitalWrite(sarjLed, LOW);
digitalWrite(desarjPin, LOW);
digitalWrite(sarjPin, LOW);
state = 3;
}
}
}
else {
// Hata durumu
desarjDurumu = false;
sarjDurumu = false;
digitalWrite(desarjLed, LOW);
digitalWrite(sarjLed, LOW);
digitalWrite(standbyLed, HIGH);
digitalWrite(desarjPin, LOW);
digitalWrite(sarjPin, LOW);
state = 4;
}
break;
case 1:
if (!(sicaklik < 70 && topAkim <= 30 && vTop <= 12 && vTop >= 9)) {
state = 0; // Başka bir duruma geçiş yapacak
}
break;
case 2:
if (!(sicaklik < 70 && topAkim <= 30 && vTop <= 9)) {
state = 0; // Başka bir duruma geçiş yapacak
}
break;
case 3:
if (!(sicaklik < 70 && topAkim <= 30 && vTop <= 12 && vTop >= 9 && topAkim < 1.0)) {
state = 0; // Başka bir duruma geçiş yapacak
}
break;
case 4:
if (sicaklik < 70 && topAkim <= 30 && (vTop <= 12 && vTop >= 9) && (topAkim < 1.0)) {
state = 0; // Hata durumu giderildiğinde normal duruma geçiş
}
break;
default:
state = 0; // Herhangi bir durumda state 0'a geçiş yap
break;
}
}
void setup() {
Serial.begin(115200);
Wire.begin(); // I2C başlat
connectToWiFi();
connectToThingsBoard();
pinDefine();
digitalWrite(balMosfet1, LOW);
digitalWrite(balMosfet2, LOW);
digitalWrite(balMosfet3, LOW);
}
void loop() {
verialisveris();
balans();
durumLedi();
seriModKontrolu();
setState();
if (!tb.connected()) {
connectToThingsBoard();
}
tb.loop();
}