#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 v2 = 0;
float v3 = 0;
float vTop = 0;
bool sarjDurumu = 0;
bool desarjDurumu = 0;
const float BETA = 3950; // Termistörün Beta Katsayısı
#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 v2, float v3, float vTop, bool sarjDurumu, bool desarjDurumu, float sicaklikCelcius) {
String jsonData = "{";
jsonData += "\"seriModu\":" + String(seriModu) + ", ";
jsonData += "\"topAkim\":" + String(topAkim) + ", ";
jsonData += "\"v1\":" + String(v1) + ", ";
jsonData += "\"v2\":" + String(v2) + ", ";
jsonData += "\"v3\":" + String(v3) + ", ";
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 setup() {
Serial.begin(115200);
Wire.begin(); // I2C başlat
connectToWiFi();
connectToThingsBoard();
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) ;
digitalWrite(balMosfet1, LOW);
digitalWrite(balMosfet2, LOW);
digitalWrite(balMosfet3, LOW);
}
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 veriOkuma() {
akimRaw = analogRead(akimPin);
sicaklik = analogRead(NTCPin);
h1_v = analogRead(bat1volt);
h2_v = analogRead(bat2volt);
h3_v = analogRead(bat3volt);
sarjDurumu = digitalRead(sarjPin);
desarjDurumu = digitalRead(desarjPin);
}
void veriDonusturGonder() {
veriOkuma();
topAkim = map(akimRaw,0, 4095, 0, 50.0);
v1 = map(h1_v, 0, 4095, 0, 4.2);
v2 = map(h2_v, 0, 4095, 0, 4.2);
v3 = map(h3_v, 0, 4095, 0, 4.2);
vTop = v1 + v2 + v3;
float sicaklikCelcius = map(sicaklik, 3813, 462, -24, 80);
tbVeriGonder(seriModu, topAkim, v1, v2, v3, vTop, sarjDurumu, desarjDurumu, sicaklikCelcius);
}
void loop() {
veriDonusturGonder();
balans();
durumLedi();
if (!tb.connected()) {
connectToThingsBoard();
}
delay(1000);
tb.loop();
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;
}
}