34 Comments

  1. Wonder if there would be a way to Cycle the readings for individual batteries (Cells) on a 48v 13S E bike Battery? Could be handy to see if the battery needs to be balanced.

  2. Hello Julian over all what do you think of the fuel Gauge? Because i have a few on the way i need for a project and Want to get more input on it? I know this is a older video so i was just wondering.

  3. Hey julian please help or anyone..

    I keep getting dtostrf was not declared in this scope
    anyone know how i can fix this
    please!!!! :'(

  4. Hi Julian, I'd like to try this with my ESP8266 that requires 3.3v from the TP4056, can I use a AM1117 regulator on the out of the TP4056 still get accurate readings?

  5. @Julian Ilett I did the same mistake as you did by connecting the MAX17043 directly to the lipo. So I had to change it over so that its in the protection circuit. But I have a problem. I pulled the solder pads off the SDA and SCL connections. Do you have any idea where the traces go so I can solder directly to maybe a transistor?

  6. is there a Library for the 18650 Li-ion cell as I see some people are getting false readings with this Lipo designated Library? (i.e. gives a reading of 5v and state of charge 256%)

  7. Did anyone ever figure out the 5v and state of charge 256% issue? I'm having the same problem at the moment :S

  8. Hi Julian,
    I have the charger and the fuel gauge. My battery is an 18650 2500mAh Li-ion. It's charged to 4.2v. The fuel gauge / library gives a reading of 5v and state of charge 256%. Any idea why this is happening? Also, thank you for the video. You've done a great job. ++

  9. on about line 26 of the sketch you have "for (int i=0; i<5; i++) oledWriteData(ASCII[character – 0x20][i]);"

    When I try to verify this code, I get "error: 'ASCII was not declared in this scope"

    and despite all my googling, I can't figure out how to include ASCII.
    Any thoughts (other than I don't know much) ?

  10. Hi Julian, 

    I have exactly the same board eqipped with MAX17043 and I'm trying to use it to monitor a single LiFePo4 cell. However, as the typical voltage of this chemistry is lower than the common Lipo/Lion chemistries, the SOC value seems to be wrong (Around 0.1% whatever the real SOC). Do you know if there is any access to Config register that can allow a kind of calibration ? The only statement I can find in the datasheet is like "Please contact us for ajustments". I didn't carried full charging cycles yet, do you think I have to (Just in case there a self-learning feature ?). Thanks for your help.

    Benoît

  11. I have a problem with different code for a big battery(5500mah), it can't "reset", i tried different library, codes but it's everytime the same thing, it does not go further than Serial.begin, have you get this problem ?(I don't have a smaller battery so i can't know if it's a battery problem or not)

  12. Hi to bother you is there a chance to read 3s or 4s lipo with arduino if it is what harware required thanks.Regards

  13. Julian,

    Maybe you know this already?  Just  wanted to mention that I have experienced some burn-in issues with these OLED displays. After using a similar display that has been displaying status of the B3603  buck converter controlled by an Aduino Mega for a while, I filled the display with 0xff for some reverse display info and was really surprised that I could see where I had displayed the previous info.

    When using these displays from now on will consider to have a "Screen Saver" function implemented that turns off the display while not in use for some minutes.

    Best Regards,
    Bjorn Erik

  14. Dear Julian, I wonder if you can help me, I have a lot of experience in Electronics, from the analogue days, I'm a bit of an old school wiz, I built a large Lithium ion battery using 168 cells, like most people I started out with little knowledge on lithium ion, then discovered the dangers, to cut a long story short, I had the batteries given to me they are second hand laptop batteries. I have almost finished checking them all now for safety fully charging them on my IMAX B6, and then discharging them to the base minimum voltage of 3 volt per cell for safety while assembling them into 3s arrays to give me 11.1 volt banks of cells, grouped into blocks of 24 configured as 3s.  My problem is I need a suitable built in Battery Management system to auto balance charge them from my solar panel, as it happens I also received stacks of battery management safety boards (one problem) I did not realize at the time when disconnecting these boards that many of them would lose their programming 🙁 so now I need a way to re-program them to suit my new 100 AH (approx) battery assembly

    I really needed to write more but seem to be on contact lock can you allow me to PM you please ? Michelle

  15. Hi
    You make a very interesting projects.
    Do you share out the schematics and source code? I am interested but your site does not work.
    Currently most curious to me MPPT.

  16. so the charging Ic gets a little confused if theres a load while charging?

    eek that could be a bit of an issue for some designs.  sat here with my morning brew trying to think how to get round that, nothing so far…

    I just got 6 of them, maybe i can rig something up to see whats going on, but only thing i have to log battery voltage over time is a camera and a multimeter so if i get time to set that up may be handy to see what is happening if i just drop say 300 or 600 ohms across the battery to give some moderate load.

    as the charge Ic seems to look at batter voltage you would think the circuit drain would just delay the charging time instead of it failing to complete.

    need more brew..
    and a biscuit

  17. Haha UKIP won euro-elections. It is very good, isn`t it? Finally, in Europe wakes up right wing. The only right-wing party in Poland exceeded the electoral threshold but does that mean that,it's in the European Parliament.

  18. Concerning your underscore/dash problem.
    When you clone and download a zip file containing the project on Github's website, the zip file will also contain the name of the branch of the project.
    In this case, you cloned the master branch.
    That means that the original project folder name was not supposed to contain "master" at all.

  19. Could you not have just used an analogue input on the arduino to calculate SOC?

  20. On the lucadentella page, you could have also clicked on the "English" link below "Lingua" (right hand side) and have gotten all the pages in proper english 😉

  21. Will be interesting to see how accurate the MAX17043 is under vary loads – I would think they've put alot of effort in to their algorithm.

    Incidenetally, ADAFRUIT have a library for that OLED display.

  22. Thanks much Julian. It would be nice if there were a 'monolithic' (multi-cell) solar charger and monitor chip combined – maybe there is.

  23. Just got my 10 pack of tp4056's. I wonder why they didn't add a fuel gauge when they redesigned it with the protection IC. Have you encountered a cheap lipo charger with a Max16043 built in?

  24. Font header file:

    #include <Arduino.h>

    static const byte ASCII[][5] =
    {
     {0x00, 0x00, 0x00, 0x00, 0x00} // 20  
    ,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
    ,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
    ,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
    ,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
    ,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
    ,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
    ,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
    ,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
    ,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
    ,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
    ,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
    ,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
    ,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d –
    ,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
    ,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
    ,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
    ,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
    ,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
    ,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
    ,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
    ,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
    ,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
    ,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
    ,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
    ,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
    ,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
    ,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
    ,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
    ,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
    ,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
    ,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
    ,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
    ,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
    ,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
    ,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
    ,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
    ,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
    ,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
    ,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
    ,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
    ,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
    ,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
    ,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
    ,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
    ,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
    ,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
    ,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
    ,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
    ,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
    ,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
    ,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
    ,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
    ,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
    ,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
    ,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
    ,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
    ,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
    ,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
    ,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
    ,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
    ,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
    ,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
    ,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
    ,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
    ,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
    ,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
    ,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
    ,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
    ,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
    ,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
    ,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
    ,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
    ,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
    ,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j 
    ,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
    ,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
    ,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
    ,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
    ,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
    ,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
    ,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
    ,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
    ,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
    ,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
    ,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
    ,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
    ,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
    ,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
    ,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
    ,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
    ,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
    ,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
    ,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
    ,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
    ,{0x78, 0x46, 0x41, 0x46, 0x78} // 7f →
    };

  25. Arduino Sketch

    #define PIN_RESET 8
    #define PIN_CS    9
    #define PIN_DC    10
    #define PIN_SDIN  11
    #define PIN_SCLK  12

    #include "font.h";
    #include "MAX17043.h";
    #include "Wire.h";

    float soc;
    float voltage;
    char tmp[8];

    MAX17043 batteryMonitor;

    void oledWriteString(char *characters)
    {
      while (*characters) oledWriteCharacter(*characters++);
    }

    void oledWriteCharacter(char character)
    {
      for (int i=0; i<5; i++) oledWriteData(ASCII[character – 0x20][i]);
      oledWriteData(0x00);
    }

    void oledWriteData(byte data)
    {
      digitalWrite(PIN_DC, HIGH);
      digitalWrite(PIN_CS, LOW);
      shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
      digitalWrite(PIN_CS, HIGH);
    }

    void oledWriteCmd(byte command)
    {
      digitalWrite(PIN_DC, LOW);
      digitalWrite(PIN_CS, LOW);
      shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, command);
      digitalWrite(PIN_CS, HIGH);
    }

    void setup()
    {
      Wire.begin();
      batteryMonitor.reset();
      batteryMonitor.quickStart();

      pinMode(PIN_RESET, OUTPUT);
      pinMode(PIN_CS, OUTPUT);
      pinMode(PIN_DC, OUTPUT);
      pinMode(PIN_SDIN, OUTPUT);
      pinMode(PIN_SCLK, OUTPUT);
      digitalWrite(PIN_RESET, LOW);
      digitalWrite(PIN_RESET, HIGH);
      
    //  oledWriteCmd(0xa8); //set MUX ratio
    //  oledWriteCmd(0x3f);
    //  oledWriteCmd(0xd3); //set display offset
    //  oledWriteCmd(0x00);
    //  oledWriteCmd(0x40); //set display start line
    ////  oledWriteCmd(0xa1); //set segment re-map
    ////  oledWriteCmd(0xc8); //set COM output scan direction
    ////  oledWriteCmd(0xda); //set COM pins hardware configuration
    ////  oledWriteCmd(0x12);
    //  oledWriteCmd(0x81); //set contrast
    //  oledWriteCmd(0x7f);
    //  oledWriteCmd(0xa4); //disable entire display on
    //  oledWriteCmd(0xa6); //set normal display
    //  oledWriteCmd(0xd5); //set oscillator frequency
    //  oledWriteCmd(0x80);
    //  oledWriteCmd(0xdb); //vcomh deselect level (brightness)
    //  oledWriteCmd(0x10);

    //  oledWriteCmd(0x8d); //enable charge pump
    //  oledWriteCmd(0x14);
      
      oledWriteCmd(0xaf); //set display on
      
      oledWriteCmd(0x20); //set horizontal addressing mode
      oledWriteCmd(0x00);
      
      for (int i=0; i<1024; i++) oledWriteData(0x00); // clear oled
      
      //oledWriteString("The quick brown fox jumps over the lazy dog");
      //oledWriteString("THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG");
      //oledWriteString("The quick brown fox jumps over the lazy dog");
      
      
      //oledWriteCmd(0x27); //set right horizontal scroll
      //oledWriteCmd(0x0);  //dummy byte
      //oledWriteCmd(0x0);  //page start address
      //oledWriteCmd(0x7);  //scroll speed
      //oledWriteCmd(0x7);  //page end address
      //oledWriteCmd(0x0);  //dummy byte
      //oledWriteCmd(0xff); //dummy byte
      
      //oledWriteCmd(0x2f); //start scrolling
    }

    void loop()
    {
      soc = batteryMonitor.getSoC();
      voltage = batteryMonitor.getVCell();
      oledWriteCmd(0x21); //
      oledWriteCmd(0x00);
      oledWriteCmd(0x7f);
      oledWriteCmd(0x22); //
      oledWriteCmd(0x07);
      oledWriteCmd(0x07);
      oledWriteString("LiPo: ");
      oledWriteString(dtostrf(soc,4,1,tmp));
      oledWriteString("% ");
      oledWriteString(dtostrf(voltage,5,2,tmp));
      oledWriteString("V ");
      delay(500);
    }

Leave a Reply

Your email address will not be published. Required fields are marked *