/*
thanks to
PowerCartel for smart battery routines - https://github.com/PowerCartel/PackProbe
Alain Aeropic - for BatMan inspiration - https://www.thingiverse.com/thing:4235767
Mavic Mini
Baterry info
Modified by Branislav Chovanec
*/
#define VERSION "v2.0"
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <TFT_eSPI.h>
#include <Wire.h>
#include <SPI.h>
#include "dji_logo-48x48.h"
byte deviceAddress = 11;
const char* ssid = "Wokwi-GUEST";
const char* password = "";
#define BTN_PIN 5
#define TFT_DC 2
#define TFT_CS 15
// Standard and common non-standard Smart Battery commands
#define BATTERY_MODE 0x03
#define TEMPERATURE 0x08
#define VOLTAGE 0x09
#define CURRENT 0x0A
#define RELATIVE_SOC 0x0D
#define ABSOLUTE_SOC 0x0E
#define REMAINING_CAPACITY 0x0F
#define FULL_CHARGE_CAPACITY 0x10
#define TIME_TO_FULL 0x13
#define CHARGING_CURRENT 0x14
#define CHARGING_VOLTAGE 0x15
#define BATTERY_STATUS 0x16
#define CYCLE_COUNT 0x17
#define DESIGN_CAPACITY 0x18
#define DESIGN_VOLTAGE 0x19
#define SPEC_INFO 0x1A
#define MFG_DATE 0x1B
#define SERIAL_NUM 0x1C
#define MFG_NAME 0x20 // String
#define DEV_NAME 0x21 // String
#define CELL_CHEM 0x22 // String
#define MFG_DATA 0x23 // String
#define CELL4_VOLTAGE 0x3C
#define CELL3_VOLTAGE 0x3D
#define CELL2_VOLTAGE 0x3E
#define CELL1_VOLTAGE 0x3F
#define STATE_OF_HEALTH 0x4F
#define DJI_SERIAL 0xD8 // String
#define bufferLen 32
uint8_t i2cBuffer[bufferLen];
//#include "dji_logo-48x48.h"
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
void setup() {
pinMode(BTN_PIN, INPUT_PULLUP);
Serial.begin(115200);
Wire.begin();
Wire.setClock(100000);
WiFi.begin(ssid, password, 6);
tft.begin();
tft.setRotation(0); //portrait
tft.setTextColor(ILI9341_DARKGREEN);
tft.setTextSize(1);
tft.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(100);
tft.print(".");
}
tft.print("\nOK! IP=");
tft.println(WiFi.localIP());
tft.drawXBitmap(85, 40, dji_logo, 64, 64, 0xBDF7);
tft.setTextSize(2);
tft.setTextColor(ILI9341_WHITE);
tft.setCursor(25, 150);
tft.println("DJI Mini 2");
tft.setCursor(25, 175);
tft.println("battery info");
tft.setCursor(25, 200);
tft.println(VERSION);
tft.setCursor(25, 225);
tft.println("github.com/czipis");
tft.setTextSize(1);
tft.setCursor(25, 250);
tft.println("Mod-Branislav Chovanec");
delay(3000);
tft.fillScreen(ILI9341_DARKGREEN);
}
uint8_t read_byte()
{
while (1)
{
if (Wire.available())
{
return Wire.read();
}
}
}
int fetchWord(byte func)
{
Wire.beginTransmission(deviceAddress);
Wire.write(func);
Wire.endTransmission(false);
delay(1);// FIX wire bug
Wire.requestFrom(deviceAddress, 2, true);
uint8_t b1 = read_byte();
uint8_t b2 = read_byte();
Wire.endTransmission();
return (int)b1 | ((( int)b2) << 8);
}
uint8_t i2c_smbus_read_block ( uint8_t command, uint8_t* blockBuffer, uint8_t blockBufferLen )
{
uint8_t x, num_bytes;
Wire.beginTransmission(deviceAddress);
Wire.write(command);
Wire.endTransmission(false);
delay(1);
Wire.requestFrom(deviceAddress, blockBufferLen, true);
num_bytes = read_byte();
num_bytes = constrain(num_bytes, 0, blockBufferLen - 2);
for (x = 0; x < num_bytes - 1; x++) { // -1 because x=num_bytes-1 if x<y; last byte needs to be "nack"'d, x<y-1
blockBuffer[x] = read_byte();
}
blockBuffer[x++] = read_byte(); // this will nack the last byte and store it in x's num_bytes-1 address.
blockBuffer[x] = 0; // and null it at last_byte+1
Wire.endTransmission();
return num_bytes;
}
#define BUFF_SIZE 64
void drawIcon(const unsigned short* icon, int16_t x, int16_t y, int8_t width, int8_t height) {
uint16_t pix_buffer[BUFF_SIZE]; // Pixel buffer (16 bits per pixel)
// Set up a window the right size to stream pixels into
tft.setAddrWindow(x, y, x + width - 1, y + height - 1);
// Work out the number whole buffers to send
uint16_t nb = ((uint16_t)height * width) / BUFF_SIZE;
// Fill and send "nb" buffers to TFT
for (int i = 0; i < nb; i++) {
for (int j = 0; j < BUFF_SIZE; j++) {
pix_buffer[j] = pgm_read_word(&icon[i * BUFF_SIZE + j]);
}
//tft.pushColors(pix_buffer, BUFF_SIZE);
}
// Work out number of pixels not yet sent
uint16_t np = ((uint16_t)height * width) % BUFF_SIZE;
// Send any partial buffer left over
if (np) {
for (int i = 0; i < np; i++) pix_buffer[i] = pgm_read_word(&icon[nb * BUFF_SIZE + i]);
//tft.pushColors(pix_buffer, np);
}
}
void loop()
{
}