ElectricMotorcycleForum.com

  • November 23, 2024, 05:33:14 PM
  • Welcome, Guest
Please login or register.

Login with username, password and session length
Advanced search  

News:

Electric Motorcycle Forum is live!

Pages: 1 2 3 [4] 5 6 ... 23

Author Topic: My homemade 'Supercharger' for a ZERO Version 2  (Read 37576 times)

Skidz

  • Sr. Member
  • ****
  • Posts: 319
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #45 on: February 23, 2017, 04:25:44 PM »

A howto would be much appreciated ;) When I can source two 1800w-units I'll try this one myself, to minimise on-the-road charging. The units Remmie pointed out are 1000w units, and are a bit expensive for what you'll get. I'll have to keep my eyes open for some 1800w units...
Logged

Fred

  • Sr. Member
  • ****
  • Posts: 486
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #46 on: February 23, 2017, 04:49:23 PM »

I'm also just getting started on building a 2 x Flatpack2 HE quick charger from the excellent work remmie and others have done.

The differences I'm hoping to incorporate are using solid copper contacts in place of worryingly thin PCB traces and using isolated CAN transceivers so that both packs can be monitored and controlled. I'll obviously share anything I do. Progress may be slow - I'm not in a great hurry as I'm still a week away from getting my Zero.
Logged
Zero SR/F
Ducati Hypermotard 950

remmie

  • Sr. Member
  • ****
  • Posts: 318
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #47 on: February 23, 2017, 08:24:27 PM »

A howto would be much appreciated ;) When I can source two 1800w-units I'll try this one myself, to minimise on-the-road charging. The units Remmie pointed out are 1000w units, and are a bit expensive for what you'll get. I'll have to keep my eyes open for some 1800w units...

OOPS, good catch Skidz (was so eager to share the availability I overlooked the fact they are 'only' 1000 W instead of the ones I have that are 1800 Watt. My apologies.  :-[
I've edited my previous post accordingly
Logged
Current : Red Premium Zero SR/F (ordered May 25, delivered August 23 2019) with Rapid charger for 12kW charging
Former : White Zero SR 2018 ZF14.4 kWh (17.500 km)
Former : Black Zero SR 2014 ZF11.4 kWh (25.000 km)
SR's outfitted with Homemade "Supercharger" 6x eltek Flatpack S (12 kW)

remmie

  • Sr. Member
  • ****
  • Posts: 318
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #48 on: February 27, 2017, 01:15:03 AM »

Had some time this weekend to play around with the fastcharger and work some more on the code of the arduino.

The charger still consists of a 2S2P configuration without the center connection. So more like 2 flatpack in series connected in parallel to a second set of flatpacks in series.
Previously i had only connected 1 of the 4 flatpacks to the CANbus of the arduino, just to get some data from it and later for some current control.
It would obviously only control the current of one of the 2 strings of flatpacks in series. The other set would just charge full power.

So this weekend i connected the canbus connections of the 2 "bottom" flatpacks together to be able to read-out and control the current of both sets of flatpacks.
The good news is that it is no problem connecting those 2 canbusses without blowing anything up (so far)  8)
This way i can read out both "bottom"  flatpacks and show the data on the tiny oled screen in one of them.

In the attached photo the display shows :
top row : mains voltage of FP1 in VAC + output power into the battery in watts (including the onboard charger!) + mains voltage of FP2
2nd row : in- and outlet temperature of FP1 and FP2 in Celcius
3rd row : Output voltage of FP1 and FP2 in volts
4th row : Output current of FP1 and FP2 in amps
5th row : Current setpoint (this setpoint can be changed with a small pushbutton.

Again a warning not to connect the canbus of a top and bottom flatpack together as the canbus references to the - output of the flatpack. !!! There would be a 57 volt difference between them.

I have added code to implement 2 independent PID controllers, 1 for each set of flatpacks. Unfortunately that cannot work. This is because the message to control the output current and voltage is a broadcast to all connected flatpacks. a message to a single flatpack does not work. The flatpacks are usually only connected in parallel (not in series) so this makes sort of sense for their intended purpose. 

I chose to see what would happen if i just use a single PID controller which would control the current of one of the two sets and see what the other set would do.
The very good news is that the second set of flatpacks very closely follows the current of the first (controlled) set of flatpacks. It is at most about 0,5 to 1 amp less and often exactly the same.

This obviously saves a PID controller or even a completely new arduino. For the above to work it is very important that the 2 "top" flatpacks are set to the same voltage, otherwise this doesn't work properly. The 2 "top" flatpacks are not monitored and are set to 57.0 Volts with a short walkin (after powerup the unit reaches this 57.0 volt in about 5 seconds).

I also built in a small SMS module to send all data and the estimated SOC and Time to go to my iphone/apple watch. Very nice to sit in the restaurant/terras and to be able to still keep an eye on the charging process without getting up every 5 minutes to see whether the bike is still charging and how long it takes. Other attached picture is a screenshot of the apple watch message

I'll post the entire code once i've cleaned it up a bit and put some more commentary in it.

 
Logged
Current : Red Premium Zero SR/F (ordered May 25, delivered August 23 2019) with Rapid charger for 12kW charging
Former : White Zero SR 2018 ZF14.4 kWh (17.500 km)
Former : Black Zero SR 2014 ZF11.4 kWh (25.000 km)
SR's outfitted with Homemade "Supercharger" 6x eltek Flatpack S (12 kW)

Erasmo

  • Hero Member
  • *****
  • Posts: 1116
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #49 on: February 27, 2017, 01:31:05 AM »

I think those look tiny enough to be tucked away below the tail?
Logged

remmie

  • Sr. Member
  • ****
  • Posts: 318
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #50 on: February 27, 2017, 01:31:54 AM »

one more picture at full power at 50% SOC

a calculated power input of 8919 watts into the battery (top of the display). It is probably a bit lower because in the code right now it is assumed the the top flatpack is at 57 volts which it will not be at full power.

the calculation is :

(57 + 52.8 volts) * 34.6 Amps + (57 + 52.88 volts) * 34.6 amps + (57 + 52.8 volts)*12 amps for the onboard (total 8919)

Because the flatpacks have a constant power regulation of 1800 watt it would never output more than 1800 watt (well 1822 is what i've seen)
if the current is at 34.60 amps, the top flatpack would be at 1822/34.6 = 52.7 volts rather than 57 and i therefore think the top flatpack is at the exact same voltage as the bottom one.

so the total power output would then be
(52.8 volts * 2)*34.6*2 + (52.8 volts*2) *12A = 8574 Watt so still quite nice.
Logged
Current : Red Premium Zero SR/F (ordered May 25, delivered August 23 2019) with Rapid charger for 12kW charging
Former : White Zero SR 2018 ZF14.4 kWh (17.500 km)
Former : Black Zero SR 2014 ZF11.4 kWh (25.000 km)
SR's outfitted with Homemade "Supercharger" 6x eltek Flatpack S (12 kW)

remmie

  • Sr. Member
  • ****
  • Posts: 318
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #51 on: February 27, 2017, 01:35:25 AM »

I think those look tiny enough to be tucked away below the tail?

I think you COULD but it would catch a lot of dirt and moisture there and they are IP20 so not weatherproof by any means.
I just put them in the "frunk"  where they fit nicely, even together with a motorcycle chain lock.

Logged
Current : Red Premium Zero SR/F (ordered May 25, delivered August 23 2019) with Rapid charger for 12kW charging
Former : White Zero SR 2018 ZF14.4 kWh (17.500 km)
Former : Black Zero SR 2014 ZF11.4 kWh (25.000 km)
SR's outfitted with Homemade "Supercharger" 6x eltek Flatpack S (12 kW)

remmie

  • Sr. Member
  • ****
  • Posts: 318
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #52 on: February 27, 2017, 02:00:49 AM »

Here's the first half of the code i have now due to a 20000 character limit of the forum

Code: [Select]
// from rectifier : (requests for logins)
// 05014400 + ser nr + 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 + ser nr + 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 + ser nr + 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)
// PID settings of 0.5 , 0.5 and 0.0 work excellent. Nice and slow buildup of voltage and current

#include <mcp_can.h>                                                                // library for CANBUS
#include <mcp_can_dfs.h>                                                            // library for CANBUS
#include <SPI.h>               
#include <Wire.h>
#include <HT_SSD1306.h>                                                             // library for oled display
#include <SoftwareSerial.h>                                                         // library for SMS module
#include <PID_v1.h>                                                                 // library for PID controller(s)

#define PIN_RESET 9                                                                 // Connect RST of oled display to pin 9
#define PIN_DC    10                                                                // Connect DC of oled display to pin 8
#define PIN_CS    11                                                                // Connect CS of oled display to pin 10
#define SIM800_TX_PIN 4                                                             // Connect TX pin of SMS module to pin 4
#define SIM800_RX_PIN 5                                                             // Connect RX pin of SMS module to pin 5
#define currentstep 50                                                             // each press on the button is 10 amps more (divide by 10)
#define amphours 91                                                                 // amphours of my Zero SR 2014 (adjust accordingly)
#define onboardamps 12                                                              // amount of amps the onboard cherger delivers (normally 12)
#define SPI_CS_PIN 17                                                               // set the input pin for the CANBUS receiver (on the leonardoboard = 17)
#define buttonup 8                                                                  // inputpin for the pushbutton to step through the current steps
#define SMSinterval 300000                                                          // interval in msec to send an SMS (300 sec = 5 minutes)

word currentsetpoint = 0;                                                         // set initial currentsetpoint (divide by 10)
word outputvoltage1 = 4350;                                                         // set output voltage of the first flatpack to 43.50 Volt (divide by 100)
word outputvoltage2 = 4350;                                                         // set output voltage of the second flatpack to 43.50 Volt (divide by 100)
word overvoltage = 5950;                                                            // set the overvoltage protection limit at 59.50 Volt (divide by 100)
double PIDSetpoint1, PIDInput1, PIDOutput1;                                         // parameters for the first PID controller
double PIDSetpoint2, PIDInput2, PIDOutput2;                                         // parameters for the second PID controller                                                         
unsigned char len = 0;                                                              // this variable holds the length of the CANBUS message received
unsigned char serialnr1[8] = {0x14,0x14,0x71,0x11,0x08,0x20,0x00,0x00};             // this variable holds the serialnumber of the first Flatpack
unsigned char serialnr2[8] = {0x16,0x02,0x71,0x12,0x76,0x44,0x00,0x00};             // this variable holds the serialnumber of the second Flatpack
int msgreceived1;                                                                   // this variable holds the number of messages received from flatpack 1
int msgreceived2;                                                                   // this variable holds the number of messages received from flatpack 2
int led = 23;                                                                       // LED output pin for the leonardo CAN board= 23
long counter;                                                                       // counter to determine when no new messages are available
unsigned long previousMillis = 0;                                                   // variable for the SMS function
int Ti1 = 0;                                                                        // Temperature in from flatpack 1
int Ti2 = 0;                                                                        // Temperature in from flatpack 2
int To1 = 0;                                                                        // Temperature out from flatpack 1
int To2 = 0;                                                                        // Temperature out from flatpack 2
int Vi1 = 0;                                                                        // input voltage from flatpack 1
int Vi2 = 0;                                                                        // input voltage from flatpack 2
float Vo1 = 0.0;                                                                    // output voltage from flatpack 1
float Vo2 = 0.0;                                                                    // output voltage from flatpack 2
float Io1 = 0.0;                                                                    // output current from flatpack 1
float Io2 = 0.0;                                                                    // output current from flatpack 1
int Po = 0;                                                                         // output power variable
int SOC = 0;                                                                        // State Of Charge variable
int TTG = 0;                                                                        // Time To Go variable
int flatpackamount= 0;                                                              // amount of flatpacks used (only if serialnr is determined automatically)

SoftwareSerial serialSIM800(SIM800_TX_PIN,SIM800_RX_PIN);                           // initialise the SMS module
SSD1306 oled(PIN_RESET, PIN_DC, PIN_CS);                                            // initialise the oled display
MCP_CAN CAN(SPI_CS_PIN);                                                            // Set CS pin for CANBUS shield
PID myPID1(&PIDInput1, &PIDOutput1, &PIDSetpoint1, 0.5,0.5,0,DIRECT);               // PID controller settings
PID myPID2(&PIDInput2, &PIDOutput2, &PIDSetpoint2, 0.5,0.5,0,DIRECT);               // PID controller settings

/********************
 * SETUP
 ********************/
 
void setup()                                                                        // Initialisation routine
{
  pinMode(buttonup, INPUT);                                                         // Set pin 11 to input (pushbutton for up)
  digitalWrite(buttonup, HIGH);                                                     // activate pull-up on A0
  pinMode(led, OUTPUT);                                                             // pin 23 is the output pin for the LED on the LEONARDO CANBUS board
  digitalWrite(led, LOW);                                                           // turn the LED of
  oled.begin();                                                                     // initialise the oled display       
  oled.clear(ALL);                                                                  // clear the oled display
  oled.clear(PAGE);                                                                 // set the cursor to home
  oled.setFontType(1);                                                              // set the font size of the oled display
  oled.flipHorizontal(1);                                                           // flip the display (because the way i mounted it)
  oled.flipVertical(1);                                                             // flip the display (because the way i mounted it)
//  delay(100);                                                                       // delay to show the splash screen (do not use a long delay as the current may spike due to lack of communication with the flatpack
  PIDInput1 = 0;                                                                    // Initial input of the first PID controller
  PIDInput2 = 0;                                                                    // Initial input of the second PID controller
  PIDSetpoint1 = currentsetpoint;                                                   // Initial Setpoint of the first PID controller
  PIDSetpoint2 = currentsetpoint;                                                   // Initial Setpoint of the second PID controller
  serialSIM800.begin(9600);                                                         // initialise the communication with the SMS module
  Serial.begin(115200);
 
START_INIT:
  if(CAN_OK == CAN.begin(CAN_125KBPS))                                              // init can bus : baudrate = 125k !!
    {
      oled.clear(PAGE);                                                             // clear the oled display
      oled.setCursor(0,0);                                                          // set the cursor to home
      oled.print("CAN OK");                                                         // let the oled display show that the canbus initialised properly
      oled.display();                                                               // command to actually show on the oled display what has been printed just before
//      delay(100);                                                                   // delay to show the information for a short while
      myPID1.SetMode(AUTOMATIC);                                                    // Start the first PID controller after the CANbus has initialised properly
      myPID2.SetMode(AUTOMATIC);                                                    // Start the second PID controller after the CANbus has initialised properly
    }
    else
    {
      oled.clear(PAGE);                                                             // clear the oled display
      oled.setCursor(0,0);                                                          // set the cursor to home
      oled.print("CAN Fail");                                                       // let the oled display that the canbus did not initialise properly
      goto START_INIT;                                                              // return to the start of the canbus initialisation
    }
          digitalWrite(led,HIGH);                                                   // turn the LED on (indicating a message transmission)
          CAN.sendMsgBuf(0x05004804, 1, 8, serialnr1);                              // send message to log in to the first flatpack and assign ID1 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
          CAN.sendMsgBuf(0x05004808, 1, 8, serialnr2);                              // send message to log in to the second flatpack and assign ID2 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc         
          digitalWrite(led,LOW);                                                    // turn the LED off

}

/********************
 * MAIN PROGRAM
 ********************/


void loop()                                                                         // MAIN PROGRAM (LOOP)
{
  unsigned char buf[8] ;
  if(CAN_MSGAVAIL == CAN.checkReceive())                                            // if data is available then :
    {
      unsigned char buf[8]={0,0,0,0,0,0,0,0};
      counter=0;                                                                    // reset the counter for non received messages
      digitalWrite(led,HIGH);                                                       // turn the LED on (indicating a message reception)
      CAN.readMsgBuf(&len, buf);                                                    // read data,  len: data length, buf: data buf
      INT32U canId = CAN.getCanId();                                                // read the CAN Id
      digitalWrite(led,LOW);                                                        // turn the LED off

         Serial.print(millis()*0.001);
          Serial.print("\t");
          Serial.print("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
        }
       Serial.println();

   switch (canId)
{

       case 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 (ID1 or ID2)
       case 0x05024400:
        {                                                                           // the message itself consists of the (decimal) serial number of the flatpack unit in HEX format !! the sernr is 6 bytes. the remaining 2 bytes are not used (0x00)
          digitalWrite(led,HIGH);                                                   // turn the LED on (indicating a message transmission)
          CAN.sendMsgBuf(0x05004804, 1, 8, serialnr1);                              // send message to log in to the first flatpack and assign ID1 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
          CAN.sendMsgBuf(0x05004808, 1, 8, serialnr2);                              // send message to log in to the second flatpack and assign ID2 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc         
          digitalWrite(led,LOW);                                                    // turn the LED off
          msgreceived1++;                                                           // increase the variable "msgreceived" for flatpack 1
        }
        break;

     
    case 0x05000820:                                                                // if CANID = 0500xxyy where xxyy the last 2 digits of the serial nr
    {
      digitalWrite(led,HIGH);                                                       // turn the LED on (indicating a message reception/transmission)
      CAN.sendMsgBuf(0x05004804, 1, 8, serialnr1);                                  // send message to log in to the first flatpack and assign ID1 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc
      digitalWrite(led,LOW);                                                        // turn the LED off
      msgreceived1=0;                                                               // reset the variable "msgreceived" because we just logged in         
    }
    break;

  case 0x05003644:                                                                  // if CANID = 0500xxyy where xxyy the last 2 digits of the serial nr
    {
      digitalWrite(led,HIGH);                                                       // turn the LED on (indicating a message reception/transmission)
      CAN.sendMsgBuf(0x05004808, 1, 8, serialnr2);                                  // send message to log in to the second flatpack and assign ID2 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc         
      digitalWrite(led,LOW);                                                        // turn the LED off
      msgreceived1=0;                                                               // reset the variable "msgreceived" because we just logged in         
    }
    break;
Logged
Current : Red Premium Zero SR/F (ordered May 25, delivered August 23 2019) with Rapid charger for 12kW charging
Former : White Zero SR 2018 ZF14.4 kWh (17.500 km)
Former : Black Zero SR 2014 ZF11.4 kWh (25.000 km)
SR's outfitted with Homemade "Supercharger" 6x eltek Flatpack S (12 kW)

remmie

  • Sr. Member
  • ****
  • Posts: 318
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #53 on: February 27, 2017, 02:02:11 AM »

and the second part of the code

Code: [Select]
case 0x05014004:
  case 0x05014008:
  case 0x05014010:
  case 0x0501400C:
        {
          msgreceived1++;                                                           // increase number of messages received
          if(msgreceived1>40)                                                       // if more that 40 messages received then :                                                                                   
            {
              msgreceived1=0;                                                       // reset the number of messages received
              digitalWrite(led,HIGH);                                               // turn the LED on (indicating a message reception/transmission)
              CAN.sendMsgBuf(0x05004804, 1, 8, serialnr1);                          //send message to log in to the first flatpack 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);                                                // turn the LED off
            }
          Ti1=buf[0];                                                               // Inlet temperature is byte 0 in the status message
          To1=buf[7];                                                               // Outlet temperature is byte 7 in the status message
          Vi1=256*buf[6]+buf[5];                                                    // Input voltage is byte 6 (highbyte) and byte 5 (lowbyte) in the status message
          Vo1=(0.01*(256*buf[4]+buf[3]));                                           // Output voltage is byte 4 (highbyte) and 3 (lowbyte) in the status message / added with 57.6 because of the flatpack in series
          Io1=(0.1*(256*buf[2]+buf[1]));                                            // Output current is byte 2 (highbyte) and 1 (lowbyte) in the status message
          PIDSetpoint1 = currentsetpoint*0.1;                                       // The PID setpoint is the maxcurrent (division by 10 due to deciamps in the code)
          PIDInput1 = Io1;                                                          // The PID input is the actual current measured by the Flatpack
          myPID1.Compute();                                                         // calculate a new output value for the PID controller
          outputvoltage1 = 4350 + PIDOutput1*(5760-4350)/255;                       // Scale the PID output (0-255) to the Flatpack output (43.50 to 57.60 Volt)
          if(outputvoltage1 > 5760)                                                 // limit the voltout in case the PID goes beyond 255 (which normally won't happen)
            {   
              outputvoltage1 = 5760;                                                // never output a voltage above 57.6 volts
            }
            goto DISPLAYDATA;
        }
        break;
  case 0x05024004:
  case 0x05024008:
  case 0x05024010:
  case 0x0502400C:
       
        {
          msgreceived2++;                                                           // increase number of messages received
          if(msgreceived2>40)                                                       // if more that 40 messages received then :                                                                                   
            {
              msgreceived2=0;                                                       // reset the number of messages received
              digitalWrite(led,HIGH);                                               // turn the LED on (indicating a message reception/transmission)
              CAN.sendMsgBuf(0x05004808, 1, 8, serialnr2);                          // send message to log in to the second flatpack and assign ID2 (DO NOT use an ID in the header, use 00, the third last number of the CANID determines ID of the flatpack (4=0, 8=1 C=2 etc) so 0x5004404 is ID0, 0x5004804 is ID1, 0x5004C04 is ID3 etc         
              digitalWrite(led,LOW);                                                // turn the LED off
            }
          Ti2=buf[0];                                                               // Inlet temperature is byte 0 in the status message
          To2=buf[7];                                                               // Outlet temperature is byte 7 in the status message
          Vi2=256*buf[6]+buf[5];                                                    // Input voltage is byte 6 (highbyte) and byte 5 (lowbyte) in the status message
          Vo2=(0.01*(256*buf[4]+buf[3]));                                           // Output voltage is byte 4 (highbyte) and 3 (lowbyte) in the status message / multiplied by 2 due to 2 rectifiers in series
          Io2=(0.1*(256*buf[2]+buf[1]));                                            // Output current is byte 2 (highbyte) and 1 (lowbyte) in the status message / the onboardamps value is added for the onboard charger / multiplied by 2 due to a quadpack (2S2P)
          PIDSetpoint2 = currentsetpoint*0.1;                                       // The PID setpoint is the maxcurrent (division by 10 due to deciamps in the code)
          PIDInput2 = Io2;                                                          // The PID input is the actual current measured by the Flatpack
          myPID2.Compute();                                                         // calculate a new output value for the PID controller
          outputvoltage2 = 4350 + PIDOutput2*(5760-4350)/255;                       // Scale the PID output (0-255) to the Flatpack output (43.50 to 57.60 Volt)
          outputvoltage2 = constrain (outputvoltage2, 4350,5760);
          if(outputvoltage2 > 5760)                                                 // limit the voltout in case the PID goes beyond 255 (which normally won't happen)
            {   
              outputvoltage2 = 5760;                                                // never output a voltage above 57.6 volts
            }
 
        DISPLAYDATA:
        Po=round((57+Vo1)*Io1+(57+Vo2)*Io2+(57+Vo1)*12);                            // Output power is output voltage times output current  + onboard
        SOC=-0.2177*(Vo1+57)*(Vo1+57)+51.437*(Vo1+57)-2940.1;                       // State of charge (in percentage) is calculated using a curve (this is an approximate value !!)
        TTG=(100-SOC)*0.6*amphours/(Io1+Io2+12);                                    // 91 = total amp hours
        SOC = constrain(SOC,0,100);                                                 // limit the State of Charge to between 0 and 100%
        oled.setCursor(0, 0);                                                       // set the cursor on the first line to show data on the LCD screen 0x050140yy 0xAA 0xBB 0xCC 0xDD 0xEE 0xFF 0xGG 0xHH
        oled.print("V ");                                                           // input voltage
        oled.print(Vi1);                                                            // 0xFF = Voltage in Low byte, 0xGG = Voltage in High byte. Voltage in Volts (because voltage is below 255 Volts, high byte is always 0)
        oled.print(" ");                                                           
        oled.print(Po);                                                             // output power
        oled.print(" ");                                                             
        oled.print(Vi2);                                                            // Input voltage of FP2
        oled.print("   ");
 
        oled.setCursor(0,13);                                                       // set the cursor on the second line       
        oled.print("T ");                                                           // temperatures
        oled.print(Ti1);                                                            // 0xAA (byte 0) = Temperature in (celcius)
        oled.print("/");                                                           
        oled.print(To1);                                                            // 0xHH (byte 7) = Temperature out (celcius)
        oled.print("  ");                                                         
        oled.print(Ti2);                                                            // 0xAA (byte 0) = Temperature in (celcius)
        oled.print("/");                                                           
        oled.print(To2);                                                            // 0xHH (byte 7) = Temperature out (celcius)

        oled.setCursor(0,26);                                                       // set the cursor on the third line
        oled.print("V ");                                                           // Voltage out
        oled.print(Vo1);                                                            // Voltage out of flatpack 1
        oled.print("  ");                                                           
        oled.print(Vo2);                                                            // Voltage out of flatpack 2
 
        oled.setCursor(0,39);                                                       // set the cursor on the 4th line
        oled.print("I ");                                                           // current
        if(Io1<10)
        {
         oled.print(" ");                                                           // if current is below zero add a space to align the values on the display better
        }
        oled.print(Io1);                                                            // Current out from flatpack 1
        oled.print("  ");
        if(Io2<10)                                                                  // if current is below zero add a space to align the values on the display better
        {
         oled.print(" ");
        }
        oled.print(Io2);                                                            // Current out from flatpack 2

        oled.setCursor(0,52);                                                       // Set the cursor to the 5th line
        oled.print("I set to ");                                                    // Current setpoint
         if(currentsetpoint<100)
        {
         oled.print(" ");
        }
        oled.print(currentsetpoint*0.1);                                            // display the current current setting       
        oled.display();                                                             // actually display the content printed above

        digitalWrite(led,HIGH);                                                     // turn the LED on (indicating a message reception/transmission)
        unsigned char stmp1[8] = {lowByte(450), highByte(450), lowByte(outputvoltage1), highByte(outputvoltage1), lowByte(outputvoltage1), highByte(outputvoltage1), lowByte(overvoltage), highByte(overvoltage)};     // set all rectifiers maxcurrent, outputvoltage and OVP and long walk-in 4005 or short walk in 4004
        CAN.sendMsgBuf(0x05FF4004, 1, 8, stmp1);                                    //(last 4 in header is for 5 sec walkin, 5 is for 60 second walkin)
//        unsigned char stmp2[8] = {lowByte(450), highByte(450), lowByte(outputvoltage2), highByte(outputvoltage2), lowByte(outputvoltage2), highByte(outputvoltage2), lowByte(overvoltage), highByte(overvoltage)};     // set rectifiers maxcurrent, outputvoltage and OVP and long walk-in 4005 or short walk in 4004
//        CAN.sendMsgBuf(0x05024004, 1, 8, stmp2);                                    //This does NOT work so it is deleted, only a broadcast to all rectifiers can be called
        digitalWrite(led,LOW);                                                      // turn the LED off
      }
      break;

    default:                                                                        // If the CANID is not any of the above then :
      {
        oled.clear(PAGE);                                                           // clear the oled display
        oled.setCursor(0,0);                                                        // set the cursor on the first line
        oled.print(canId,HEX);                                                      // show the unknown can Id on the oled display
        oled.setCursor(0,16);                                               
        for(int i = 0; i<len; i++)                                                  // cycle through all the bytes
          {
          if( buf[i] < 0x10){ oled.print("0");} oled.print(buf[i],HEX);             // send a leading zero if only one digit
          }
        delay(1000);                                                                // show the message for 1 second and then continue
      }

    break; 
    }
    }
    else                                                                            // if no can message available do :
    {
      counter++;                                                                    // increase the counter
      if(counter > 20000)                                                           // 20000 loops without a CAN message means no data available (approx 2 seconnds)
        {
          oled.clear(PAGE);                                                         // clear the oled display
          oled.setCursor(0,0);                                                      // set the cursor on the first line
          oled.print("NO DATA");                                                    // show "No DATA"  on the oled display
          oled.display();                                                           // display the actual content printed above
        }
      if((digitalRead(buttonup)==0))                                                // read digital pin for button up and if it is low (pushbutton is pressed)
        {
          currentsetpoint = currentsetpoint + currentstep;                                    // raise maxcurrent with the amount specified in the currentstep constant (10 A)
          if(currentsetpoint > 400)                                                      // to be able to lower the current with one button, if the maxcurrent > 40 the current is reset to 10
            {
              currentsetpoint =50;                                                      // rest the current to 10 A
            }
//          oled.setCursor(0,52);                                                     // Set the cursor to the fourth line
//          oled.print("I set to ");                                                  // send to display
//          oled.print(currentsetpoint*0.1);                                               // display the current current setting
//          oled.display();                                                           // display the actual content printed above
          delay(200);
        }
             
Logged
Current : Red Premium Zero SR/F (ordered May 25, delivered August 23 2019) with Rapid charger for 12kW charging
Former : White Zero SR 2018 ZF14.4 kWh (17.500 km)
Former : Black Zero SR 2014 ZF11.4 kWh (25.000 km)
SR's outfitted with Homemade "Supercharger" 6x eltek Flatpack S (12 kW)

remmie

  • Sr. Member
  • ****
  • Posts: 318
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #54 on: February 27, 2017, 02:03:07 AM »

and the final part 3

Code: [Select]
unsigned long currentMillis = millis();                                           // take the actual time in milliseconds from the start of the arduino (overflows in 55 days so no worries there)
  if (currentMillis - previousMillis >= SMSinterval)                                // if the current time exceeds the SMS interval time (5 min)
    {     
      previousMillis = currentMillis;                                               // save the current time
      serialSIM800.write("AT+CMGF=1\r\n");                                          // write the command " send a SMS message to the SMS module
      delay(100);                                                                   // wait a bit to let the module handle the command
      serialSIM800.write("AT+CMGS=\"+31612345678\"\r\n");                           // send the receiving telephone number to the SMS module
      delay(1000);                                                                  // wait a bit to let the module handle the command
      digitalWrite(led,HIGH);                                                       // turn the LED on to indicate message reception / transmission
      serialSIM800.print("Time=");                                                  // send the current time since the start of the uC to the SMS module
      serialSIM800.print(millis()/60000);                                           // send the time in minutes
      serialSIM800.print((char)10);                                                 // new line command
      serialSIM800.print("Ti=");                                                    // inlet temperature
      serialSIM800.print(Ti1);                                                      // inlet temperature
      serialSIM800.print("/");
      serialSIM800.print(Ti2);                                                      // inlet temperature
      serialSIM800.print((char)10);                                                 // new line command
      serialSIM800.print("To=");                                                    // outlet temperature
      serialSIM800.print(To1);                                                      // outlet temperature
      serialSIM800.print("/");
      serialSIM800.print(To2);                                                      // outlet temperature
      serialSIM800.print((char)10);                                                 // new line command
      serialSIM800.print("Vi=");                                                    // input voltage
      serialSIM800.print(Vi1);                                                      // input voltage
      serialSIM800.print("/");
      serialSIM800.print(Vi2);                                                      // input voltage
      serialSIM800.print((char)10);                                                 // new line command
      serialSIM800.print("Vo=");                                                    // output voltage
      serialSIM800.print(Vo1);                                                      // output voltage
      serialSIM800.print("/");
      serialSIM800.print(Vo2);                                                      // output voltage
      serialSIM800.print((char)10);                                                 // new line command
      serialSIM800.print("Io=");                                                    // output current
      serialSIM800.print(Io1);                                                      // output current
      serialSIM800.print("/");
      serialSIM800.print(Io2);                                                      // output current
      serialSIM800.print((char)10);                                                 // new line command
      serialSIM800.print("Po=");                                                    // output power
      serialSIM800.print(Po);                                                       // output power 
      serialSIM800.print(" SOC=");                                                  // State of Charge
      serialSIM800.print(int(SOC));                                                 // State of Charge
      serialSIM800.print("%");                                                      // State of Charge
      serialSIM800.print((char)10);                                                 // new line command
      serialSIM800.print("Iset=");                                                  // Current setpoint
      serialSIM800.print(int(currentsetpoint*0.1));                                 // Current setpoint
      serialSIM800.print(" TTG=");                                                  // Time To Go
      serialSIM800.print(TTG);                                                      // Time To Go
      serialSIM800.print((char)26);                                                 // end of message command
      delay(100);                                                                   // wait a bit to let the SMS module handle the command
      digitalWrite(led,LOW);                                                        // turn the LED off

    }
   }
  }
Logged
Current : Red Premium Zero SR/F (ordered May 25, delivered August 23 2019) with Rapid charger for 12kW charging
Former : White Zero SR 2018 ZF14.4 kWh (17.500 km)
Former : Black Zero SR 2014 ZF11.4 kWh (25.000 km)
SR's outfitted with Homemade "Supercharger" 6x eltek Flatpack S (12 kW)

MrDude_1

  • Hero Member
  • *****
  • Posts: 1146
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #55 on: February 27, 2017, 10:23:15 AM »

 since you're doing all this work anyway, you might as well talk to the higher power supplies as well. All you need to do is use a can bus opto isolator.
Logged

remmie

  • Sr. Member
  • ****
  • Posts: 318
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #56 on: February 27, 2017, 01:12:54 PM »

since you're doing all this work anyway, you might as well talk to the higher power supplies as well. All you need to do is use a can bus opto isolator.

That would be the easiest for sure but I've looked into that but it's not as easy as it seems. I can't seem to find a simple and small CAN to CAN optoisolated converter which would fit into the flatpack S.
Logged
Current : Red Premium Zero SR/F (ordered May 25, delivered August 23 2019) with Rapid charger for 12kW charging
Former : White Zero SR 2018 ZF14.4 kWh (17.500 km)
Former : Black Zero SR 2014 ZF11.4 kWh (25.000 km)
SR's outfitted with Homemade "Supercharger" 6x eltek Flatpack S (12 kW)

Skidz

  • Sr. Member
  • ****
  • Posts: 319
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #57 on: February 27, 2017, 01:58:55 PM »

Nice work! Using the 8.5kW of the flatpacks with 1.3kW of the onboard and 2.5kW of a charge tank you'd get awfully close to 1C charging at 12.3kW.... If only there would be more flatpacks available at an affordable price...
Logged

Fred

  • Sr. Member
  • ****
  • Posts: 486
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #58 on: February 27, 2017, 03:02:30 PM »

since you're doing all this work anyway, you might as well talk to the higher power supplies as well. All you need to do is use a can bus opto isolator.

That would be the easiest for sure but I've looked into that but it's not as easy as it seems. I can't seem to find a simple and small CAN to CAN optoisolated converter which would fit into the flatpack S.
I'm not sure there are any CAN to CAN isolators. I've only seen isolated transceivers such as TI's ISO1050. The irony there is that CAN is supposed to be a shared bus now your microcontroller needs two separate CAN controllers. Still worth trying to monitor all the flatpacks IMHO even though they should have the same current passing through them.
Logged
Zero SR/F
Ducati Hypermotard 950

MrDude_1

  • Hero Member
  • *****
  • Posts: 1146
    • View Profile
Re: My homemade 'Supercharger' for a ZERO Version 2
« Reply #59 on: February 27, 2017, 07:31:08 PM »

since you're doing all this work anyway, you might as well talk to the higher power supplies as well. All you need to do is use a can bus opto isolator.

That would be the easiest for sure but I've looked into that but it's not as easy as it seems. I can't seem to find a simple and small CAN to CAN optoisolated converter which would fit into the flatpack S.
I'm not sure there are any CAN to CAN isolators. I've only seen isolated transceivers such as TI's ISO1050. The irony there is that CAN is supposed to be a shared bus now your microcontroller needs two separate CAN controllers. Still worth trying to monitor all the flatpacks IMHO even though they should have the same current passing through them.

I know there are a ton of Bi-directional I²C Isolator chips... I might be assuming too much, but I would think they would work perfectly for this too.
Logged
Pages: 1 2 3 [4] 5 6 ... 23