ULtra Compact 1800W charger + Eltek programming

Batteries, Chargers, and Battery Management Systems.
remmie1972
10 mW
10 mW
Posts: 26
Joined: Aug 06, 2015 5:00 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by remmie1972 » May 13, 2017 7:48 am

Kin wrote:Is this the right thread for 2000W Flatpack2 HE programming as well? I am familiar with basics of C++/Arduino programming, but know very little about communication protocols. I can whip together libraries and expand on basic preliminary sketches though. I'm just trying to get up to speed on what people have already done, to see if I can reprogram my Flatpack 2000W HE that I scored off ebay for a project of mine.

Or is this thread only focused on the Flatpack S 1800W? I personally haven't been able to find many of them yet for aprice I can afford.
The programming works for both the flatpack 2HE 2000W (and probably 3000W) and the flatpack S 1800W (and probably the 1000W)

User avatar
danielrlee
1 kW
1 kW
Posts: 433
Joined: Mar 29, 2013 8:30 am
Location: Wiltshire, UK

Re: ULtra Compact 1800W charger + Eltek programming

Post by danielrlee » May 13, 2017 10:35 am

remmie1972 wrote:
Kin wrote:Is this the right thread for 2000W Flatpack2 HE programming as well? I am familiar with basics of C++/Arduino programming, but know very little about communication protocols. I can whip together libraries and expand on basic preliminary sketches though. I'm just trying to get up to speed on what people have already done, to see if I can reprogram my Flatpack 2000W HE that I scored off ebay for a project of mine.

Or is this thread only focused on the Flatpack S 1800W? I personally haven't been able to find many of them yet for aprice I can afford.
The programming works for both the flatpack 2HE 2000W (and probably 3000W) and the flatpack S 1800W (and probably the 1000W)
I can confirm that a 3000W HE Flatpack2 is programmable via CANBUS having successfully done so.

Jibeji
10 µW
10 µW
Posts: 5
Joined: Mar 25, 2017 6:05 pm

Re: ULtra Compact 1800W charger

Post by Jibeji » May 17, 2017 3:30 pm

remmie1972 wrote: OLED display version to follow :)
Hi,
Did you manage to make this running with an OLED display?
I tried with U8GLIB but the display is blinking each time a CAN message is received.

Here is the code:

Code: Select all

// from rectifier : (requests for logins)
// 05014400 + SN + 00 00 from rectifier  : HELLOOW where are you ! rectifier sends 05014400 and 6 bytes serial number and followed by 00 00 (login request)
// 0500xxyy + 1B + SN + 00 is send during normal voltage every second. xxyy is the last 2 bytes from the serial number
// after either of these send 05004804 every 5 seconds ! to keep logged in. rectifier does not send login requests so after 10 second the numbers stop until 05014400 is sent
// from rectifier : (status messages)
// 0501400C + status data : walkin and below 43 volts (error) and during walk-out (input voltage low)
// 05014010 + status data : walkin busy 
// 05014004 + status data : normal voltage reached
// 05014008 + status data : current-limiting active

// send TO rectifier (act as controller)
// 05004804 + SN + 00 00 from controller : send 05004804 and 6 bytes ser number followed by 00 00 
// 05FF4004 controller sends current and voltage limits (last 4 is 5 sec walk-in, for 60 second walk-in use 05FF4005)
// 05FF4005 controller sends current and voltage limits (last 5 is 60 sec walk-in, for 5 second walk-in use 05FF4004)

#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include <SPI.h>
#include <U8glib.h>

word maxcurrent = 370;                    // set initial maxcurrent (divide by 10)
word outputvoltage = 5300;                // set output voltage to 57.50 Volt (divide by 100)
word overvoltage = 5500;                  // set the overvoltage protection limit at 59.50 Volt (divide by 100)

const int SPI_CS_PIN = 17;                 // set the input pin for the CANBUS receiver (on the leonardoboard = 17)
unsigned char len = 0;                     // this variable holds the length of the CANBUS message received
unsigned char serialnr[8];                 // this variable holds the serialnumber of the Flatpack
int msgreceived;                           // this variable holds the number of messages received
int led = 23;                              // LED output pin for the leonardo CAN board= 23

MCP_CAN CAN(SPI_CS_PIN);                   // Set CS pin for CANBUS shield

/* OLED connections
 *   CLK = Pin 12 
 *   MOSI = Pin 11 
 *   CS = Pin 8 
 *   DC = Pin 9
 *   RST = Pin 10
 */
U8GLIB_SSD1306_128X64 u8g(12, 11, 8, 9, 10);

void setup() {                              // Initialisation routine
   pinMode(led, OUTPUT);                      // pin 23 is the output pin for the LEONARDO CANBUS board
   digitalWrite(led, LOW);                    // turn the LED of

   Serial.begin(115200);                      // Set the baudrate for the seial connection to the PC at 115200
   Serial.println("Starting...");

   START_INIT:
   if (CAN_OK == CAN.begin(CAN_125KBPS)) {   // init can bus : baudrate = 125k !!
      Serial.println("CAN BUS Shield init ok!");
   } else {
      Serial.println("CAN BUS Shield init fail");
      Serial.println("Init CAN BUS Shield again");
      goto START_INIT;
   }
}

void can_bus(void) {
   unsigned char buf[8] ;
   if (CAN_MSGAVAIL == CAN.checkReceive()) {  // check if data coming
      digitalWrite(led,HIGH);                 // turn the LED on
      CAN.readMsgBuf(&len, buf);              // read data,  len: data length, buf: data buf
      unsigned long canId = CAN.getCanId();   // read the CAN Id
      Serial.println();                       // start on a new line
      Serial.print("Received : 0");           // leading zero 
      Serial.print(canId,HEX);                // output CAN Id to serial monitor
      Serial.print("\t");                     // send Tab
      for (int i = 0; i<len; i++) {           // print the data
         if ( buf[i] < 0x10) {
            Serial.print("0");
         }
         Serial.print(buf[i],HEX);            // send a leading zero if only one digit
         Serial.print(" ");                   // space to seperate bytes
      }

      digitalWrite(led,LOW);                  // turn the LED off

      if (canId==0x05014400) {
         //this is the request from the Flatpack rectifier during walk-in (start-up) or normal operation when no log-in response has been received for a while
         for (int i = 0; i<8; i++) {
            serialnr[i]=buf[i];                  // transfer the message buffer to the serial number variable
         } 
         Serial.print("\tSerial Number is : ");
         for (int i = 0; i<6; i++) {             // print the data
            if ( serialnr[i] < 0x10) {
               Serial.print("0");
            }
            Serial.print(serialnr[i],HEX);       // send a leading zero if only one digit
         }
         digitalWrite(led,HIGH);
         CAN.sendMsgBuf(0x05004804, 1, 8, serialnr);   //send message to log in (DO NOT ASSIGN AN ID use 00)
         digitalWrite(led,LOW);
         Serial.println();
         Serial.print("TRANSMIT : 05004804");
         Serial.print("\t");
         for (int i = 0; i<len; i++) {           // print the data
            if (serialnr[i] < 0x10) {
               Serial.print("0");
            }
            Serial.print(serialnr[i],HEX);      // send a leading zero if only one digit
            Serial.print(" ");                  // space to seperate bytes
         }
         Serial.print("\tLog in with SrNr : ");
         for(int i = 0; i<6; i++) {             // print the data
            if (serialnr[i] < 0x10) {
               Serial.print("0");
            }
            Serial.print(serialnr[i],HEX);      // send a leading zero if only one digit
         }
            
         msgreceived++;                         // increase the variable "msgreceived" 
         unsigned char stmp7[8] = {
            lowByte(maxcurrent), highByte(maxcurrent), lowByte(outputvoltage), highByte(outputvoltage), lowByte(outputvoltage), highByte(outputvoltage), lowByte(overvoltage), highByte(overvoltage)
         };
         // set rectifier to maxcurrent 57,0V (16 44) and OVP to 59.5V (17 3E) qnd long walk-in 4005 or short walk in 4004

         digitalWrite(led,HIGH);
         CAN.sendMsgBuf(0x05FF4004, 1, 8, stmp7);//(last 4 in header is for 5 sec walkin, 5 is for 60 second walkin)
         digitalWrite(led,LOW);
         Serial.println();
         Serial.print("TRANSMIT : 05FF4004");
         Serial.print("\t");
         for (int i = 0; i<len; i++) {            // print the data
            if (stmp7[i] < 0x10) {
               Serial.print("0");
            }
            Serial.print(stmp7[i],HEX);           // send a leading zero if only one digit
            Serial.print(" ");                    // space to seperate bytes
         }

         Serial.print("\tImax set to : ");
         Serial.print(0.1*(stmp7[0]+stmp7[1]*256));
         Serial.print(" A\t");
         Serial.print("Vout set to : ");
         Serial.print(0.01*(stmp7[2]+stmp7[3]*256));
         Serial.print(" V\t");
         Serial.print("OVP set to : ");
         Serial.print(0.01*(stmp7[6]+stmp7[7]*256));
         Serial.print(" V\tWalkin : ");
         Serial.print("5 seconds");         
      }

      else if (canId==(0x05000000+buf[6])) {
         //if CANID = 0500xxyy where xxyy the last 2 digits of the serial nr
         for (int i = 0;i<6; i++) {
            serialnr[i] = buf[i+1];  
         }
         // unsigned char serialnr[8] = {buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], 0x00, 0x00};                     //this is the serial number of the unit which is covered in the request (unit announces its serial number)
         Serial.print("\tSerial Number is : ");
         for (int i = 0; i<6; i++) {             // print the data
            if (serialnr[i] < 0x10) {
               Serial.print("0");
            }
            Serial.print(serialnr[i],HEX);       // send a leading zero if only one digit
         }
         msgreceived++;
         digitalWrite(led,HIGH);
         CAN.sendMsgBuf(0x05004804, 1, 8, serialnr); //(last 4 in header is for 5 sec walkin, 5 is for 60 second walkin)
         digitalWrite(led,LOW);
         msgreceived=0;
         Serial.println();
         Serial.print("TRANSMIT : 05004804");
         Serial.print("\t");
         for (int i = 0; i<8; i++) {             // print the data
            if (serialnr[i] < 0x10) {
               Serial.print("0");
            }
            Serial.print(serialnr[i],HEX);       // send a leading zero if only one digit
            Serial.print(" ");                   // space to seperate bytes
         }
         Serial.print("\tLog in with SrNr : ");
         for (int i = 0; i<6; i++) {             // print the data
            if (serialnr[i] < 0x10) {
               Serial.print("0");
            }
            Serial.print(serialnr[i],HEX);       // send a leading zero if only one digit
         }
                
         unsigned char stmp7[8] = {
            lowByte(maxcurrent), highByte(maxcurrent), lowByte(outputvoltage), highByte(outputvoltage), lowByte(outputvoltage), highByte(outputvoltage), lowByte(overvoltage), highByte(overvoltage)}; 
         // set rectifiers maxcurrent, outputvoltage and OVP and long walk-in 4005 or short walk in 4004
         digitalWrite(led,HIGH);
         CAN.sendMsgBuf(0x05FF4004, 1, 8, stmp7);//(last 4 in header is for 5 sec walkin, 5 is for 60 second walkin)
         digitalWrite(led,LOW);
         Serial.println();
         Serial.print("TRANSMIT : 05FF4004");
         Serial.print("\t");
         for (int i = 0; i<len; i++) { // print the data
            if (stmp7[i] < 0x10) {
               Serial.print("0");
            }
            Serial.print(stmp7[i],HEX);      // send a leading zero if only one digit
            Serial.print(" ");       // space to seperate bytes
         }

         Serial.print("\tImax set to : ");
         Serial.print(0.1*(stmp7[0]+stmp7[1]*256));
         Serial.print(" A\t");
         Serial.print("Vout set to : ");
         Serial.print(0.01*(stmp7[2]+stmp7[3]*256));
         Serial.print(" V\t");
         Serial.print("OVP set to : ");
         Serial.print(0.01*(stmp7[6]+stmp7[7]*256));
         Serial.print(" V\tWalkin : ");
         Serial.print("5 seconds");
      }

      else if ((canId==0x05014004) or (canId==0x05014008) or (canId==0x05014010) or (canId=0x0501400C)) {
      // these are the status messages (05014004 is not current-limiting, 05014008 is current limiting 05014010 = busy with walkin, 0501400C in input voltage low)
    
         Serial.print("\t");
         Serial.print("Tin = ");
         Serial.print(buf[0]);          //first byte is temperature in (celcius)
         Serial.print(" C\t");

         Serial.print("Tout = ");
         Serial.print(buf[7]);          //last byte is temperature out (celcius)
         Serial.print(" C\t");

         Serial.print("Vin = ");          
         Serial.print(buf[5]);          // sixth byte is input voltage in volts ac/dc
         Serial.print(" V\t");

         Serial.print("Iout = ");
         Serial.print(buf[2]*256*0.1+buf[1]*0.1);              // third (msb) and second byte are current in 0.1A (deciamp) calculated to show directly in Amps
         Serial.print(" A\t");

         Serial.print("Vout = ");
         Serial.print(buf[4]*256*0.01+buf[3]*0.01);            // fifth (msb) and fourth byte are voltage in 0.01V (centivolt) calculated to show directly in Volts dc
         Serial.print(" V\t");

         Serial.print("Pout = ");
         Serial.print((2*buf[4]*256*0.01+2*buf[3]*0.01)*(buf[2]*256*0.1+buf[1]*0.1));     // Power is calculated from output voltage and current. Output is in Watts
         Serial.print(" W\t");
         
 

         msgreceived++; // record number of messages received
         
         if (msgreceived>40) {
            msgreceived=0;
            digitalWrite(led,HIGH);
            CAN.sendMsgBuf(0x05004804, 1, 8, serialnr);    //send message to log in every 40 messages (DO NOT USE ID NR, USE 00) this because during walk-in the 0500xxyy is not send and the rectifier "logs out" because of no received log-in messages from controller
            digitalWrite(led,LOW);
            Serial.println();
            Serial.print("TRANSMIT : 05004804");
            Serial.print("\t");
            for (int i = 0; i<8; i++) { // print the data
               if (serialnr[i] < 0x10) {
                  Serial.print("0");
               }
               Serial.print(serialnr[i],HEX);      // send a leading zero if only one digit
               Serial.print(" ");       // space to seperate bytes
            }
            Serial.print("\tover 40 messages : Log in with SrNr : ");
            for (int i = 0; i<6; i++) { // print the data
               if (serialnr[i] < 0x10) {
                  Serial.print("0");
               }
               Serial.print(serialnr[i],HEX);      // send a leading zero if only one digit
            }
            msgreceived++;
         }
      }
         
      else {
         Serial.println("\tUNKNOWN COMMAND");
      }
      
      /* Display the data */
      u8g.setFont(u8g_font_fub17);
      u8g.setPrintPos(5, 24);         // x pos, y pos
      u8g.print(buf[4]*256*0.01+buf[3]*0.01);   // V out

      u8g.setFont(u8g_font_fub17);
      u8g.setPrintPos(5, 47); 
      u8g.print(buf[2]*256*0.1+buf[1]*0.1);     // I out

      u8g.setFont(u8g_font_7x14);
      u8g.setPrintPos(8, 64);
      u8g.print("Vin");
      u8g.setFont(u8g_font_7x14);
      u8g.setPrintPos(34, 64); 	
      u8g.print(buf[5]);
      
      u8g.setFont(u8g_font_7x14);
      u8g.setPrintPos(84, 25);
      u8g.print("Temp");

      u8g.setFont(u8g_font_7x14);
      u8g.setPrintPos(84, 40);
      u8g.print(buf[0]);u8g.print((char)176);   
      u8g.setFont(u8g_font_6x12);
      u8g.setPrintPos(106, 40);
      u8g.print("in");  
      
      u8g.setFont(u8g_font_7x14);
      u8g.setPrintPos(84, 55);
      u8g.print(buf[7]);u8g.print((char)176); 
      u8g.setFont(u8g_font_6x12);
      u8g.setPrintPos(106, 55);
      u8g.print("out");
   }
}

void loop(void) {
   u8g.firstPage(); 
   do {
      can_bus();
   } while (u8g.nextPage());
}

Jibeji
10 µW
10 µW
Posts: 5
Joined: Mar 25, 2017 6:05 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by Jibeji » May 18, 2017 2:32 pm

This instruction reset the OLED display, it works fine (but of course no data) when commented...

Code: Select all

CAN.readMsgBuf(&len, buf);              // read data,  len: data length, buf: data buf

markz
10 GW
10 GW
Posts: 4727
Joined: Jan 09, 2014 11:38 pm
Location: Alberta Canada

Re: ULtra Compact 1800W charger + Eltek programming

Post by markz » May 18, 2017 3:54 pm

I must say I am impressed with the size, but underwhelmed with the 120V 1000W ~20A output for guerilla charging. My current Meanwell can do 16A with pot for voltage. It works for my needs.

winem
10 µW
10 µW
Posts: 6
Joined: Apr 01, 2017 6:38 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by winem » May 29, 2017 5:50 am

Hey,

I just wanted to say: THANK YOU!!!!
I read this thread a couple of weeks ago and was able to score a really cheap Flatpack2. I started out using a raspberry pi and Controlling it, because the modified ESP8266-01 wasnt working with the MCP2515 CAN-board. Until last week or so I always had to wait until the Rapsberry Pi booted and sent the CAN-signals untilI was able to Charge my electric scooter. Then I tried the Node MCU (wich is a board based on the EPS8266-12) and was able to use it with the CAN-shield. Now im able to control the Flatpack and use the integrated WiFi of the ESP8266-12 to send the data from the CAN Bus to a cloud.
So I can always check the current state of the charging and also do a Little statistics. I also included a relay to shut the main power of, when the current drops below 500 mA. For the usability I also added an smal OLED so I could see all the data on the charger itself.

Without your knowlegde I wouldn't have been able to get it done - so thank you again for all the great work and for sharing it.

The battery that im charing is a liion 14s10p battery of an unu scooter and is based on 140 LG 18650 cells adding up to about 28,5 Ah (about 1,5 kWh ).

winem
10 µW
10 µW
Posts: 6
Joined: Apr 01, 2017 6:38 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by winem » May 30, 2017 3:03 am

Hey, because I got the question, if I could share a couple of Infos on my build; here are the schematics:

Image

So the NodeMCU is controlling the Flatpack2 over the Can MCP2515 Chip and also receiving all the data from it.
The latest data is then displayed in the OLED and also transfered via wifi to the cloud (in this case Im using thinkgspeak).
If the current drops below 500mA, the NodeMCU will open the relays (I had to use a two-step setup, because the NodeMCU can not deliver enough current for the main relay).
With the rotary Switch you can select the current preset in den CC phase, so if Im not in a hurry, Ill dial it down to charge the batterys slowly and dont stress them so much-

If you have any questions just let me know!

winem
10 µW
10 µW
Posts: 6
Joined: Apr 01, 2017 6:38 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by winem » Jun 02, 2017 4:21 am

So to give some use-case data to the Setup, here is the first charge I tracked with this setup: https://thingspeak.com/channels/252264

The battery was a eScooter battery of the company unu, which is build with 140 LD MG1 18650 cells in a 12s14p setup.
The overchargevoltage of the BMS is set to about 57.4 V and the normal charger would deliver up to 5.7 A.
With the new charger ist goes up to 30 A, but I only tried 15 A this far.

mekaz
1 µW
1 µW
Posts: 1
Joined: Jun 02, 2017 6:00 am

Re: ULtra Compact 1800W charger + Eltek programming

Post by mekaz » Jun 02, 2017 7:47 am

Hello,

I am a newbie with a newbie question.

For my e bike I would like to build a quick charger with two from these Eltek rectifier.
Therefore I need 96V.
How do I can do this?

Can I do this with normal serial connection of the rectifier DC out.
Or do I need some special things like a diode ?

winem
10 µW
10 µW
Posts: 6
Joined: Apr 01, 2017 6:38 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by winem » Jun 18, 2017 7:24 pm

Here is the Code I used for the arduino ide with the nodeMCU.
Im no pro, so its bad, really bad, but it works for me :-D

Keep in mind this Code is based on a lot of diffrent soucres so do not use it in any way for a comercial product!
If there is any Problem with it just let me know.

If you have some questions, just ask me - ill try to help.

EDIT:
Here is the Pin usage:

- I2C for the OLED: D1(SCL), D2(SDA), 3.3V & GND

- Current selection: D3, D9, D10 & GND (only D9 can stay switched on GND during boot, otherwise the NodeMCU will not start)

- SPI for the CAN Shield (MCP2515 with modification): D4(INT), D5(SCK), D6(MISO), D7(MOSI), D8(CS) + 5V for the Tranceiver, 3.3V for the SPI chip of the CAN & GND
==> Modification for the MCP2515: external Link

Code: Select all

#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include <SPI.h>
#include <ESP8266WiFi.h>
#include "OLED.h"
#include <Wire.h>

//pins:
#define CAN_INT 2    // Set INT to pin 2
MCP_CAN CAN(15);    // Set CS to pin 4 (D2)
OLED display(4, 5);

//Wifi and thingspeak setup:
String apiKey = "XXXXXXXXXXXXXXXXXX";    //thinkspeak api write key of you chanle goes here
const char* ssid = "XXXXXXXX";    //wifi name goes here
const char* password = "XXXXXXXX";    //wifi psk goes here
const char* server = "api.thingspeak.com";

//variables:
unsigned char payload2[8] = {0x16, 0x00, 0x6C, 0x16, 0x6C, 0x16, 0xF8, 0x16};    //setup data with max current & voltage 
int T = 0;
int I = 0;
int Ubat = 0;
int P = 0;
int Uac = 0;
int E = 0;
int l = 0;
int relay=0;
int counter = 1;
long unsigned int canID;
unsigned char datalength = 0;
unsigned char reData[8];

WiFiClient client;

void setup()
{
  Serial.begin(115200);
  delay(100);
  pinMode(2, INPUT);    //Setting pin 2 for /INT input
  pinMode(16, OUTPUT);    //Setting pin 16 for relay out
  digitalWrite(16, HIGH);
  display.begin();
  display.print("Select AMP:",1);
  delay(2000);
  WiFi.begin(ssid, password);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
  }
  display.clear();

START_INIT:
  if(CAN_OK == CAN.begin(MCP_ANY, CAN_125KBPS, MCP_8MHZ))    //test can module
  {
    delay(100);
  }
  else
  {
    delay(1000);
    goto START_INIT;
  }
  CAN.setMode(MCP_NORMAL);    //set operation mode to normal so the MCP2515 sends and receives
  unsigned char payload1[8] = {0x11, 0x29, 0x71, 0x14, 0x55, 0x80, 0x00, 0x00};    //login data with serial number
  CAN.sendMsgBuf(0x05004804, 1, 8, payload1);    //send login data
  delay(500);
  CAN.sendMsgBuf(0x05FF4005, 1, 8, payload2);    //send setup data

//rotary switch setup and read:
  pinMode(D3, INPUT);
  pinMode(D9, INPUT);
  pinMode(D10, INPUT);
  int state5 = digitalRead(D3);
  int state10 = digitalRead(D9);
  int state15 = digitalRead(D10);
  
  if (state5==0)
  {
    display.print("-> 5 A",1);
    payload2[0]=0x32;    //changes first part of setup data (max current = 5 A)
   }
  if (state10==0)
  {
    display.print("-> 10 A",1);
    payload2[0]=0x64;    //changes first part of setup data (max current = 10 A)
  }
  if (state15==0)
  {
    display.print("-> 15 A",1);
    payload2[0]=0x96;    //changes first part of setup data (max current = 15 A)
  }
  delay(2000);

//relay charge setup:
  digitalWrite(16, LOW);    //close relay
  relay=1;
  delay(5000);
}

void loop()
{
  unsigned char payload1[8] = {0x11, 0x29, 0x71, 0x14, 0x55, 0x80, 0x00, 0x00};    //login data with serial number
  CAN.sendMsgBuf(0x05004804, 1, 8, payload1);    //send login data
  delay(500);
  CAN.sendMsgBuf(0x05FF4005, 1, 8, payload2);    //send setup data
  delay(500);
  if(!digitalRead(2))    //if pin 2 is low, read receive data
  {
//fetch data from flatpack:
    CAN.readMsgBuf(&canID, &datalength, reData);
    if(canID == 2231451652)    //ID check, only use state messages
    {
//analyze data from flatpack:
      T = reData[0];
      I = ((reData[2]*255+reData[1])*100);
      Ubat = ((reData[4]*255*0.1+reData[3]*0.1)*100);
      P = Ubat * I;
      Uac = (reData[5]);
      P = P / 1000;
      char energie[5];
      itoa (E, energie, 10);      
      char current[5];
      itoa (I, current, 10);
      char voltage[5];
      itoa (Ubat, voltage, 10);
      char power[5];
      itoa (P, power, 10);
      char temp[4];
      itoa (T, temp, 10);
      char state[4];
      itoa (relay, state, 10);
//display data:
      display.print("T [C]:",1);
      display.print(temp,1,10);
      display.print("I [mA]:",2);
      display.print(current,2,10);
      display.print("U [mV]:",3);
      display.print(voltage,3,10);
      display.print("P [mW]:",4);
      display.print(power,4,10);
      display.print("E [mWh]:",5);
      display.print(energie,5,10);
      display.print("Relay:",6);
      display.print(state,6,10);
    }
  }

  if (l > 18)    //roughly every 30 s: check relay state & upload data to thinkspeak,
  {
    if (client.connect(server,80))
    {
//relay control:
      if (I < 500)    //open relay if current is unter 500 mA
      {
        digitalWrite(16, HIGH);
        relay=0;
      }
      if (I > 20000)    //open relay if current is over 20 A
      {
        digitalWrite(16, HIGH);
        relay=0;
      }
//upload data to thinkspeak:
      E = E + (P / 120);    //energy calc for upload every 30s
      String postStr = apiKey;
      postStr +="&field1=";
      postStr += String(T);
      postStr +="&field2=";
      postStr += String(I);
      postStr +="&field3=";
      postStr += String(Ubat);
      postStr +="&field4=";
      postStr += String(P);
      postStr +="&field5=";
      postStr += String(E);   
      postStr += "\r\n\r\n";
      client.print("POST /update HTTP/1.1\n");
      client.print("Host: api.thingspeak.com\n");
      client.print("Connection: close\n");
      client.print("X-THINGSPEAKAPIKEY: "+apiKey+"\n");
      client.print("Content-Type: application/x-www-form-urdatalengthcoded\n");
      client.print("Content-datalengthgth: ");
      client.print(postStr.length());
      client.print("\n\n");
      client.print(postStr);
      l = 0;
    }
  }
  l = (l + 1);
}

nunux59
1 µW
1 µW
Posts: 4
Joined: Aug 06, 2017 11:55 am

Re: ULtra Compact 1800W charger + Eltek programming

Post by nunux59 » Sep 06, 2017 2:49 am

Hello power supply Gurus :D

Do you think that I can series 7 or 8 server power supplies that can deliver 80+Amps at 13.3V with ONE Eltek 24V 2000W (75Amps) to make a 75 Amps battery charger with constant current ? I have the server power supply for free (HP DPS-800GB), would one Eltek Flatpak2 24V for the regulation be enough?

Thank you !

User avatar
cycborg
1 kW
1 kW
Posts: 432
Joined: Jul 05, 2014 4:45 pm
Location: Boston metro, US

Re: ULtra Compact 1800W charger + Eltek programming

Post by cycborg » Sep 07, 2017 9:46 am

nunux59 wrote:would one Eltek Flatpak2 24V for the regulation be enough?
It would regulate the current fine, but it wouldn't have nearly enough voltage range. This sounds like ~30s, so you'd need a range of at least 30*(4.2-2.5) = 51 V. A single 24 V Flatpack would have about 1/5 of that range.

You could probably come up with a charging plan that involves leaving out some of the server PSUs, and switching them in one by one whenever the Flatpack hits CV, but that's tedious and error-prone.

jimbo83
1 µW
1 µW
Posts: 2
Joined: Nov 07, 2017 8:36 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by jimbo83 » Nov 08, 2017 3:04 pm

winem wrote:So to give some use-case data to the Setup, here is the first charge I tracked with this setup: https://thingspeak.com/channels/252264

The battery was a eScooter battery of the company unu, which is build with 140 LD MG1 18650 cells in a 12s14p setup.
The overchargevoltage of the BMS is set to about 57.4 V and the normal charger would deliver up to 5.7 A.
With the new charger ist goes up to 30 A, but I only tried 15 A this far.
Hi winem, thanks for sharing your modification and automation of the flatpack--

what I've understood is that you've been able to successfully set up the flatpak2 to do a proper CC / CV charging to this scooter battery? So you're able to make sure it's at 15A (or so) until it reaches 57.4V (or your value), then it's watching until the current dropped until 500mA, and the relay you mentioned is turning off the flatpak? It looks like you're logging (printing to screen) a little bit of that information, too?

Thanks for sharing!

User avatar
zzoing
10 kW
10 kW
Posts: 659
Joined: Feb 01, 2008 12:26 am
Location: Fr SE

Re: ULtra Compact 1800W charger + Eltek programming

Post by zzoing » Nov 13, 2017 7:56 pm

We can get a kilo of boron nitride and a kilo of aluminium oxide, two super thermal non conducive materials, and mix it with silicone, and pot any current chargers in a small blobs of thermal compound. that would be even more compact.

Also check the new chip I posted previously, it's aimed to reduce laptop power supplies volume by 50 percent, so laptop bricks can reduced, and so can chargers too hopefully.

winem
10 µW
10 µW
Posts: 6
Joined: Apr 01, 2017 6:38 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by winem » Nov 14, 2017 1:15 am

Yeah, thats about right. With the integration of the NodeMcu its a CC/CV charger witch is able to terminate the charging at a certain mA level.
Because of my new job, new city ad new apartment I wasn't really able to put in some work. But two days ago I started on the housing of the charger. Super easy design - nothing fancy. Just a plain 2mm aluminum sheet and a little bending...
If I remember ill put a picture here, once Im finished.

MaxE
1 µW
1 µW
Posts: 4
Joined: Feb 09, 2016 11:57 am

Re: ULtra Compact 1800W charger + Eltek programming

Post by MaxE » Nov 14, 2017 10:55 am

Has anybody thought of connecting eltek flatpacks in series? what to look for especially for the communication part? I am interested in the CAN communication, so a isolation is needed.
Would it be possible with an ISO SPI chip like this:
http://cds.linear.com/docs/en/datasheet/6820fb.pdf
to connect lets say 3 in series with a MCP2515 and control them together with one arduino with can bus shield as master?


MaxE
1 µW
1 µW
Posts: 4
Joined: Feb 09, 2016 11:57 am

Re: ULtra Compact 1800W charger + Eltek programming

Post by MaxE » Nov 15, 2017 12:45 pm

i did, but a few questions arised.
planetaire wrote:In my projet I have connected several elteck flatpack 48v serialy, needing more then 57.5v dc.

So i am sure that the can bus is not isolated from the output.
Unlike the 110vdc and 220vdc versions of the flatpack 2.

So be carefull.
dgh853 wrote:Be aware that the CAN Hi and Lo are not isolated so don't just wire the CAN connections directly when running in series otherwise you'll be sending 48V+ through the CAN wires.
pm_dawn wrote:HI !

@dgh853: Yes I read that in this thread, so I'm staying away. But If the PSUs are connected in series It would only need one to thottle the current right.
So that way one can have a leonardo for example conencted to only one of the PSUs in a stack.

Regards
/Per
dgh853 wrote:If users are happy to make the permanent settings such as default voltage and walk-in for each rectifier before wiring them in series all good.

There are other messages people may want to use than just current control so even if you're right about one rectifier controlling the flow in series some people may still want to connect multiple rectifiers via CAN.

Using an Arduino board with an isolated CANBUS can circumvent the problem.
So this means the CAN of the Flatpack2 2000 and 3000 Watt versions are isolated, but not the Flatpack S 1800 Watt? Has someone managed to connect multiple PSUs in series and communicate and control MORE than one at the same time? I think this is needed as otherwise the delta voltage is to low for my planned purpose. I also would want to use the isolated UART to CAN communication to be completely isolated between 12V and high voltage part, any thoughts? Would it work to connect flatpack2 2000 watt all with CAN via arduino and standard arduino can shield, which is powered from 12V board net?
I am quite a noob and just want to clarify things before something stupid happens and money smokes away ;)
okashira wrote:
Doctorbass wrote:
okashira wrote:Let's say you have 10 flatpacks in series programmed for 50v 30A
So, the whole string will go to 500V 30A.

If you limit one to 5A. Once that ONE flat pack sees 50V it will try to taper current. Only one, though.

Let's say battery is at 300V. All flat packs will provide 50V and 30A max except the one programmed for 5A. Just 6 flat packs can provide 300V and 30A.
Each supply will push 30A until it's individual 30A limit is reached, until 300V.

Once 300V and 30A is reached, that one "5A" flat pack will reach its current limit. But there are 9 other flatpacks setup for 30A and 50V. The other nine, ignoring the current limited one, can do 450V and 30A. So even if the limited power supply went to 0v, the other nine would force current through it.
So 6 PSU can do 300V 30A. The other 4 must have 30A going thru them per Kirchoff's current law. So... This supplys may end up with a negative voltage!

Thus, current limit must be applied to all PSU in series or bad things will happen!

Voltage limit can be applied so only some PSU to achieve desired limit ( ie 50+50+50+30 = 180)

Conclusion, current must be applied to all psu in series. On the other hand, voltage limit can be defined by all psu in series added.
B careful with this though. All it takes is for one PSU out of 10 to malfunction and produce higher then 50v and damage your battery without a BMS.

Total summary, use a well designed BMS! Lol.
As i said many times, the thumb rule for serie psu for charging is :
The only thing you need is to have ONE of the psu in serie that have enough voltage range to take all the delta V of the 0-100% battery SOC and that is also the psu with the lowest current limit ( in fact it only need to have let say 1 less amp than others)
For a typical 400v system of 96s. this means you may need 4 "50V" flatpack's configured.

Min voltage of 96s: 240V
Max voltage: 403.2V
Difference: 163V.

So one flatpack is not enough. For a higher voltage system, one might need a way to ensure the flatpacks are all communicating in some way so they properly share voltage.
flatpacks might work great up to systems of 3s ~150V or so, but higher you risk funny things happening, unless you want to babysit them all.

At this level it's looking more like just using an 400V salvage EV charger setup (with a custom micro or even a CANBUS hack) makes more sense.
my dream setup would be a 3s2p PSU configuration, as i am currently charging with 3 HP PSUs which only delivers 65 A and the HP are inefficient ( arround 85 %) and bulky. I did not found anything in the thread regarding multiple PSUs in series and parallel, and i am as mentioned not sure about the CAN communication part.

Regards

User avatar
Merlin
1 MW
1 MW
Posts: 1535
Joined: Jan 29, 2013 10:00 am
Location: europe

Re: ULtra Compact 1800W charger + Eltek programming

Post by Merlin » Nov 15, 2017 1:05 pm

the ZERO Motorcycle guys do it with the Flatpack "S" i sold...

https://endless-sphere.com/forums/viewt ... 2#p1283122


i think it was a bit lost since doc bass merged the 2 topics :D

https://endless-sphere.com/forums/viewt ... 6#p1204986

user remmie was one of the first using flatpacks in series.


MaxE
1 µW
1 µW
Posts: 4
Joined: Feb 09, 2016 11:57 am

Re: ULtra Compact 1800W charger + Eltek programming

Post by MaxE » Nov 16, 2017 6:25 am

remmie really did amazing work, or better, he is doing really amazing work ;)
Thank you for guiding me to the "supercharger version 2" ;)

The 2 flatpack S 1800 in series with 2 leonardos for controll is a good starting point for me, which is shown here:
http://electricmotorcycleforum.com/boar ... c=6405.270

but what is still unclear, and i just need this for clarification:
- Is the CAN bus from Flatpack S and Flatpack2 different regarding CAN isolation? Specific: Is the flatpack2 can bus isolated instead of the Flatpack S as mentioned or thought, or is it exaclty the same?

pm_dawn
100 W
100 W
Posts: 132
Joined: Jan 17, 2009 3:36 pm
Location: Östersund, Sweden

Re: ULtra Compact 1800W charger + Eltek programming

Post by pm_dawn » Nov 16, 2017 7:56 am

The distinction is not between the FP2 HE and FP S.
Take a look at the datasheet.
for the FP2 HE there are differences between the output levels. 48V versions seems to not have isolated CAN, but the higher output voltages (110v, 220v and 380v) all have CAN isolation stated in the datasheet.

So most of us has asumed that the 48v versions are non isolated CAN.

Best Regards
/Per

MaxE
1 µW
1 µW
Posts: 4
Joined: Feb 09, 2016 11:57 am

Re: ULtra Compact 1800W charger + Eltek programming

Post by MaxE » Nov 16, 2017 10:45 am

Thank you! It was not clear to me and i thought maybe that the flatpack2 and flatpack2He would have the isolation integrated.
So i think best would be to change the hardware of the flatpacks to have an isolated CAN bus, this should be doable and is maybe the most elegant solution in terms of needed hardware and overall package.

Has anybody thought of changing the CAN pcb or part of it ( tranceiver, isolated DC/DC ) to have an isolated CAN Bus? in that way the MCU (arduino for example) could be wired to the 12V board net and directly to all Flatpack2, correct? Are there pictures of the CAN pcb board?

Camon
1 µW
1 µW
Posts: 2
Joined: Nov 18, 2017 6:31 pm

Re: ULtra Compact 1800W charger + Eltek programming

Post by Camon » Dec 11, 2017 2:58 pm

Hi anyone can help me to program the 2 eltks flatpack 2HE 48/2000.
I have purchased two with the serial voltage of 53.5V. and I would like to program them once only at 57V to get 114V to load the zero DS 2015.
I've been reading for a few hours and I think I found the code but I can not find it if I need something other than the arduino one.

Code: Select all

#include <mcp_can.h>
#include <mcp_can_dfs.h>
#include <SPI.h>

const int SPI_CS_PIN = 10;                                                          // Set CS pin to pin 10 (could be 9 for other CANshields)
MCP_CAN CAN(SPI_CS_PIN);                                                            // Set CS pin for CANBUS shield

void setup()                                                                        // Initialisation routine
{

START_INIT:

    if(CAN_OK == CAN.begin(CAN_125KBPS))                                            // init can bus : baudrate = 125k !!
    {
    }
    else
    {
    delay(100);
    goto START_INIT;
    }
    unsigned char login[8] = {0x14, 0x14, 0x71, 0x11, 0x08, 0x20, 0x00, 0x00};     //this is the serial number of the unit + 2 added bytes of 00 each, sernr on the unit reads 141471110820)
    CAN.sendMsgBuf(0x05004804, 1, 8, login);                                       //send message to log in and assign ID=1 (last 04 means ID=1, for ID=2 use 05004808 ) 

    unsigned char setdefaultvolt[5] = {0x29, 0x15, 0x00, 0x80, 0x16};              //this is the command for setting the default output voltage (Last two bytes, LSB first). 16 80 is the maximum voltage of 57.6 V
    CAN.sendMsgBuf(0x05019C00, 1, 5, setdefaultvolt);                              //send message to set ouput voltage to all chargers connected to the CAN-bus
}

void loop()                                                                        // main program (LOOP)
{                                                                                  // nothing to do :)
}

/*********************************************************************************************************
  END FILE
  Voltage settings 
  80 16 => 1680 HEX = 57,60 Volt (= highest possible voltage
  E6 14 => 14E6 HEX = 53,50 Volt (= factory set voltage)
  FE 10 => 10FE HEX = 43,50 Volt (= lowest possible voltage)
*********************************************************************************************************/
thanks a lot

Post Reply