Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Program by: RANDY N. CAÑADA, DEC. 2025
- ESP32 wiring (VSPI example)
- MOSI -> GPIO23
- MISO -> GPIO19
- SCK -> GPIO18
- CSN -> GPIO5
- CE -> GPIO17
- ESP32 (Transmitter + Feedback Receiver)
- OLED 1306 CONNECTIONS:
- -can be operated in 3.3vdc / 5 vdc
- sda=21,scl=22
- */
- #include <SPI.h>
- #include <nRF24L01.h>
- #include <RF24.h>
- #include <Wire.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_SSD1306.h>
- // --- RF24 setup ---
- RF24 radio(17, 5); // CE, CSN
- const byte address[][6] = {"00001", "00002"}; // ESP32->Arduino, Arduino->ESP32
- int buttonPin = 13;
- // --- OLED setup ---
- #define SCREEN_WIDTH 128
- #define SCREEN_HEIGHT 64
- Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
- // --- Battery thresholds ---
- const float VBAT_MIN = 7.0; // cutoff for 2S Li-ion
- const float VBAT_MAX = 8.4; // full charge for 2S Li-ion
- void setup() {
- Serial.begin(9600);
- pinMode(buttonPin, INPUT_PULLUP);
- // --- Radio init ---
- radio.begin();
- radio.setPALevel(RF24_PA_MIN);
- radio.openWritingPipe(address[0]); // Send commands to Arduino
- radio.openReadingPipe(1, address[1]); // Listen for feedback
- // --- OLED init ---
- if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
- Serial.println("SSD1306 allocation failed");
- while (1);
- }
- display.clearDisplay();
- display.setTextSize(3);
- display.setTextColor(SSD1306_WHITE);
- display.setCursor(20,0);
- display.println("Remote");
- display.setCursor(20,35);
- display.println("Ready!");
- display.display();
- delay(1500);
- }
- void loop() {
- // --- Send command ---
- radio.stopListening();
- if (digitalRead(buttonPin) == LOW) {
- const char text[] = "LED ON";
- radio.write(&text, sizeof(text));
- Serial.println("Sent: LED ON");
- } else {
- const char text[] = "LED OFF";
- radio.write(&text, sizeof(text));
- Serial.println("Sent: LED OFF");
- }
- // --- Switch to RX mode and wait for feedback ---
- radio.startListening();
- unsigned long start_time = millis();
- while (!radio.available()) {
- if (millis() - start_time > 500) {
- Serial.println("No feedback received.");
- display.clearDisplay();
- display.setTextSize(2);
- display.setCursor(0,0);
- display.println("OFFLINE!");
- display.display();
- return;
- }
- }
- char feedback[32] = "";
- radio.read(&feedback, sizeof(feedback));
- Serial.print("Battery feedback: ");
- Serial.println(feedback);
- // --- Parse feedback (format: "V=1.45V I=1.4mA") ---
- float busVoltage = 0.0, current_mA = 0.0;
- sscanf(feedback, "V=%fV I=%fmA", &busVoltage, ¤t_mA);
- // Calculate power and battery percentage
- float power_W = busVoltage * (current_mA / 1000.0);
- int pct = batteryPercent(busVoltage);
- // --- Serial Monitor output ---
- Serial.print("V: "); Serial.print(busVoltage, 2); Serial.println("V");
- Serial.print("I: "); Serial.print(current_mA, 1); Serial.println(" mA");
- Serial.print("P: "); Serial.print(power_W, 1); Serial.println(" W");
- Serial.print("Batt: "); Serial.print(pct); Serial.println("%");
- Serial.println("-----------------------------");
- // --- OLED output ---
- display.clearDisplay();
- display.setCursor(0,0);
- display.setTextSize(2);
- display.print("V: "); display.print(busVoltage, 2); display.println("V");
- display.print("I: "); display.print(current_mA, 1); display.println(" mA");
- display.print("P: "); display.print(power_W, 1); display.println(" W");
- // --- Graphical Battery Bar ---
- int barX = 0;
- int barY = 48;
- int barWidth = 100;
- int barHeight = 12;
- // Outline
- display.drawRect(barX, barY, barWidth, barHeight, SSD1306_WHITE);
- // Fill based on pct
- int fillWidth = map(pct, 0, 100, 0, barWidth - 2);
- display.fillRect(barX + 1, barY + 1, fillWidth, barHeight - 2, SSD1306_WHITE);
- // Percentage text
- display.setCursor(104, 48);
- display.setTextSize(1);
- display.print(pct);
- display.print("%");
- // --- Battery warnings ---
- if (pct >= 15 && pct <= 20) {
- display.clearDisplay();
- display.setTextSize(2);
- display.setCursor(28,0);
- display.print("Charge");
- display.setCursor(42,20);
- display.print("Your");
- display.setCursor(28,40);
- display.print("Battery");
- Serial.println("⚠️ Battery Low!");
- }
- else if (pct <= 5) {
- display.clearDisplay();
- display.setTextSize(2);
- display.setCursor(52,1);
- display.print("LOW");
- display.setCursor(28,32);
- display.print("BATTERY!");
- Serial.println("❌ Battery Depleted!");
- }
- display.display();
- delay(1000);
- }
- // ------------------------------------------------------
- // REALISTIC NON-LINEAR BATTERY PERCENTAGE FUNCTION
- // For 2S Li-ion (7.0V empty, 8.4V full)
- // ------------------------------------------------------
- int batteryPercent(float v) {
- if (v >= 8.40) return 100;
- if (v >= 8.30) return 90;
- if (v >= 8.20) return 80;
- if (v >= 8.10) return 70;
- if (v >= 8.00) return 60;
- if (v >= 7.90) return 50;
- if (v >= 7.80) return 40;
- if (v >= 7.60) return 30;
- if (v >= 7.40) return 20;
- if (v >= 7.20) return 10;
- if (v >= 7.00) return 5;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment