Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
flavios
Published © GPL3+

QI wireless charger / tester for a Li-Ion battery

LiPo battery "test & charge". A useful COMPONENT to insert in any of your miniaturized projects.

IntermediateWork in progress3,003
QI wireless charger / tester for a Li-Ion battery

Things used in this project

Hardware components

Microcontroller PRO Mini w/Atmel AVR ATMEGA328P, 3.3V 8MHz
×1
Arduino UNO
Arduino UNO
Used for breadboard testing "in vitro"... sketch attached...
×1
FT232RL USB to serial TTL (3.3V - 5V) (AZDelivery)
×1
OLED I2C SSD1306 0.96 pollici Display 128 x 64 Pixel (AZDelivery)
×1
TP4056 Micro USB 5V 1A Li - Ion Battery Charger Module (AZDelivery)
×1
QI wireless 5W Coil Circuit Board Module
×1
Li-Ion 3.7V 250mAh battery
×1
Through Hole Resistor, 680 kohm
Through Hole Resistor, 680 kohm
×1
Through Hole Resistor, 220 kohm
Through Hole Resistor, 220 kohm
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Solder Paste, Tack Flux
Solder Paste, Tack Flux

Story

Read more

Schematics

Testing + Charging Li-Ion battery with a QI wireless receiver

This is the circuit as I use it in my projects

TEST battery and display charge - breadboard sketch

This is a version of the "voltmeter" that uses an Arduino UNO and a simple bradboard set-up..

Code

TEST Sketch on Arduino UNO

C/C++
Breadboard and Arduino UNO test
// Charger Wireless QI "snippet" by F.Stella 20220314

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
// #include <Fonts/FreeMonoBold24pt7b.h>	

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define debug0      //attiva stampa DEBUG base e SERIAL
#define debug1      //attiva stampa DEBUG sezione1

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


// 'BatteryLevels_bitmap_12x22', 22x12px
const unsigned char BatteryLevelFULL [] PROGMEM = {
	0x1f, 0xff, 0xfc, 0x1f, 0xff, 0xfc, 0x18, 0x00, 0x0c, 0xfb, 0xff, 0xec, 0xfb, 0xff, 0xec, 0xfb, 
	0xff, 0xec, 0xfb, 0xff, 0xec, 0xfb, 0xff, 0xec, 0xfb, 0xff, 0xec, 0x18, 0x00, 0x0c, 0x1f, 0xff, 
	0xfc, 0x1f, 0xff, 0xfc
};

const unsigned char BatteryLevelMID [] PROGMEM = {
	0x1f, 0xff, 0xfc, 0x1f, 0xff, 0xfc, 0x18, 0x00, 0x0c, 0xf8, 0x3f, 0xec, 0xf8, 0x3f, 0xec, 0xf8, 
	0x3f, 0xec, 0xf8, 0x3f, 0xec, 0xf8, 0x3f, 0xec, 0xf8, 0x3f, 0xec, 0x18, 0x00, 0x0c, 0x1f, 0xff, 
	0xfc, 0x1f, 0xff, 0xfc
};

const unsigned char BatteryLevelEMPTY [] PROGMEM = {
	0x1f, 0xff, 0xfc, 0x1f, 0xff, 0xfc, 0x18, 0x00, 0x0c, 0xf8, 0x00, 0xcc, 0xf8, 0x00, 0xcc, 0xf8, 
	0x00, 0xcc, 0xf8, 0x00, 0xcc, 0xf8, 0x00, 0x0c, 0xf8, 0x00, 0xcc, 0x18, 0x00, 0x0c, 0x1f, 0xff, 
	0xfc, 0x1f, 0xff, 0xfc
};

byte pin_A     = 2;
byte button_A  = 0;

int offset18_x = -2;
int offset18_y = 22;
int offset12_x = -2;
int offset12_y = 14;
int offset9_x = -1;
int offset9_y = 12;        

unsigned long button_delay_t = 0;

int analoginput = 0;            // Battery CHECK analog pin
int analogamount = 0;           // stores incoming value
float percAREF = 0;
float percBatt = 0;             // used to store our BATTERY percentage charge value
float voltBatt = 0;       
float voltage = 0;              // used to store voltage value
float V_out = 0; 
float V_source = 0; 
float referenceVoltage = 0;
int voltageError = 0;
// float resist1 = 4604;        // 4604 tester value 4.7 kOhm nominal - TEST on ARDUINOuno 5V
// float resist2 = 1000;        //                   1 kOhm nominal  - TEST on ARDUINOuno 5V
float resist1 = 982000;         //   1 MOhm  680 kOhm nominal
float resist2 = 306000;         // 300 kOhm  220 kOhm nominal

void setup() {

#ifdef debug0
  Serial.begin(19200);
  Serial.println(F(""));
  Serial.print(F("Serial START - press button!"));
  Serial.println(F(""));
#endif

  analogReference(INTERNAL); // use INTERNAL (1.1V) for reference voltage

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setFont(&FreeMono9pt7b);                        // PLAIN font

  display.setCursor(1, 10);
  display.print("Display on.");
  display.setCursor(25, 30);
  display.print("press"); 
  display.setCursor(15, 50);
  display.print("to test");
  display.display();

  pinMode(pin_A, INPUT_PULLUP);   //button
}

void loop() {
  do {
      button_A = digitalRead(pin_A);
  } while ((button_A == 1) || ((millis()-button_delay_t) < 500));

  button_delay_t = millis();

  #ifdef debug1
    Serial.print(F("Button A ("));
    Serial.print(pin_A); 
    Serial.print(F(") = ")); 
    Serial.println(button_A); 
  #endif
  batteryCheck();
  showSCREEN();
}

void showSCREEN() {
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setCursor(10+offset18_x, 20+offset18_y);
  display.setFont(&FreeMonoBold18pt7b);                        // PLAIN font
  display.print(voltBatt,1);
  display.setCursor(85+offset18_x, 20+offset18_y);
  display.print("V");

  // display footer ***
  display.setCursor(47+offset9_x, 51+offset9_y);
  display.setFont(&FreeMono9pt7b);                        // PLAIN font
  display.print(percBatt,1);
  display.print("%");

  if (percBatt > 76 ) {                               // Battery level graphic display
    display.drawBitmap(0, 53, BatteryLevelFULL, 22, 12, WHITE);
  } else if (percBatt > 65 ) { 
      display.drawBitmap(0, 53, BatteryLevelMID, 22, 12, WHITE);
  } else { 
      display.drawBitmap(0, 53, BatteryLevelEMPTY, 22, 12, WHITE);
  }  
  display.display();          //Send buffer to display
  delay(3000);

}

void batteryCheck() {
  referenceVoltage = 1100;    // 1100 internal;
  V_source = 4.2;            // LiPo Vmax 4.2V - UNO R3 5.056 - Vs from the divider calculation
  // using the REAL resistor values makes it more "precise" - one can also set a fixed value
  V_out =  V_source*(resist2)/((resist1)+(resist2));              // UNO 0.889 - LiPo 1.05      - VOut from the divider calculation
  voltageError = 0;          // to empirically adjust ;-)

  analogamount = analogRead(analoginput);
  percAREF=(analogamount/1024.00)*100;

  voltage=(analogamount/1024.00)*referenceVoltage+voltageError;       // in millivolts
  voltBatt=(voltage*((resist1)+(resist2))/(resist2))/1000;            // V_s = V_out * (R1+R2) / R2
  percBatt=(voltBatt/V_source)*100;

  #ifdef debug1
    Serial.print("V_out: ");
    Serial.println(V_out,3);  
    Serial.print("Lettura analog (0-1023): ");
    Serial.print(analogamount);
    Serial.print(" --------       % of AREF: ");
    Serial.print(percAREF,2);
    Serial.print(" --------       A0 (mV): ");   // compare with result of Voltage Divider calculation Vout
    // for 5.056 (that I checked on Arduino1) and resistors 1K 4.7K is 0.889
    Serial.print(voltage,2);

    Serial.print(" --------       % of battery nominal: ");
    Serial.print(percBatt,2);
    Serial.print(" --------     Real - no divider (V): "); // if you check Arduino voltage should be 5.0x
    Serial.println(voltBatt,2);
    Serial.println("");
  #endif
}

Credits

flavios
0 projects • 1 follower
Contact

Comments

Please log in or sign up to comment.