Nissan Leaf 48v Off-Grid Solar Project


ALL NEW - Battery Finder Search for 12/24/36/48v or by capacity www.batteryfinder.net
New & used Batteries, Solar, accessories, LifePo4 cells & more 5% Coupon "Powerwalls" www.batteryhookup.com
I needed to make custom solar mounting brackets for my Japanese tile roof. You might be able to buy them if your roof allows it, but in my case the rise between my roof decking and the space between the tiles is too small. Here's an example of some of the ones you can buy:

View attachment 33707View attachment 33706
Also, they're expensive (at least here). ($13-16 usd each) I need 20 so I put on my Macgyver hat and bought a bunch of these standard 90deg brackets (bottom of this picture below) and figured out how to bend them without an expensive brake press.

View attachment 33708
The top metal strapping is the template I made by pulling off a tile and bending it to the dimensions I need. Then I made a bulky, poorly designed bender (🫣 which I'm not too proud of, but it worked for bending the 4 brackets I needed for my orginal 2 solar panels.)

Here's my new and improved diy brake press build... 🥳

1st, I repurposed a bench press adjustable safety catcher.

View attachment 33709

Then off to the hardware store for < $6 usd in metal parts and screws. Using some scrap wood I built this guillotine looking contraption. The flat metal is sandwiched and bolted between two pieces of scrap angle iron I had. I ran the side pieces of wood through a table saw to make cuts to act as guides. I made the bottom piece of wood with two 45degree cuts on the table saw and fitted the 90degree metal piece and screwed it in.


View attachment 33711

I added two guides and a spacer to hold the bracket for the first bend.

View attachment 33712

View attachment 33713

Then a 5Ton bottle jack does all the work.

View attachment 33714

I can turn the bracket around and do the second bend from the opposite side.
Really a great idea! 😊 And maybe simpler than my method with angle brackets and screws and nuts.

Is it possible for you to make a video of this process?
 
Really a great idea! 😊 And maybe simpler than my method with angle brackets and screws and nuts.

Is it possible for you to make a video of this process?
Actually, I would have preferred using your method; however, I couldn't find the correct size that would work with my tiles/roof.

Sorry, I did all the bending already, and have the bottle-jack somewhere else now. But, I'll toss in a few more pictures:

1773576121737.png


1773576176115.png


1773576192116.png
 
  • Like
Reactions: kje
It's also possible to use treated lumber (wood/plank/barge) as mounting rails for solar panels on the roof like I did.

I made a thread about it for some time ago:
Hi kje,

I initially looked into using pressure treated wood, but found it isn't often used on roofs in Japan. It is used for ground based panels where it can be monitored more closely.

It won't meet various codes/regulations (for wind, fire and earthquake) in many regions of Japan.

Wood will expand and contract with humidity and can warp. Fasteners can loosten for the same reason.

If the pressure treated wood uses copper azole, it is reactive with aluminum used for solar panel frames. It requires some barrier between the two.

I really wanted to use wood because it is so much cheaper, lighter and easier to work with. I even considered switching to ground-mounted panels, but I don't want to give up the space, or have longer cable runs.
 
  • Like
Reactions: kje
Hey folks - since the general topic (metal vs wood) came up it reminded me I used pressure treated 2x4s for part of the mounting of a couple of panels on my pergola. Here's what it looks like after 8 yrs (we live in Zone 4 weather). Not bad shape / not seeing structural issues but of course the 2x4s are well protected by the panels.
1773673063058.png
1773673089944.png


Not pushing any particular solution, just sharing that on my roof I went aluminum rails. I have cement tiles... so between tile 50yr est life and metal rails (?yrs life) and 30yrs? panel life - I'm hoping never to go up there again.
1773673612469.png


I notice @Korishan went metal for his ground array as well :)
 
Last edited:
I notice @Korishan went metal for his ground array as well :)
Yeah, mine was made from basically "scrap" metal. Good thing is that I didn't pay for any of it, just had to buy the nuts/bolts to put everything together.
 
Brackets & rails painting time!

If anyone is in Japan, this paint is really good for metal... (from Handsman - may need to use some thinner... it's really thick. )

1774060446496.png
1774060480377.png
1774060504255.png


Needs one more coat and some touchups.. (y)
 
*** Check out this post by Korishan *** I decided it will be a good idea to add a H2 sensor to trigger the temperature controlled vent fans.

Working on the battery box...

1778158570131.png
1778158603327.png

Cut two holes in the box... one down low, and the other high up, kitty-corner. The upper one will have a temperature controlled fan.
It should provide good cross-ventilation.

1778158742893.png
1778158824243.png

But foam tape around the vent, basically to hold the silicon sealant in place while it dries.
1778158875466.png

I used aluminum tape to seal the insulation, then a ring of brown duct tape to protect the aluminum when the vents are inserted.
The walls are 4.5cm thick, so I had to MacGyver the mounts by cutting the 3 tabs and bending them so they can screw into the aluminum
wall panel. Not pretty (from the inside) but functional. I'll appy some foam sealer in the gaps later on.
1778159147727.png

Cleaned the floor, and used pre-primered/sealed plywood layed upside-down and made cutouts for the corner drains.
I figure the primered side will do more good facing down in case there's ever any condensation.

The plywood will help distribute the weight of the batteries. I also added extra spacers/supports under the box. You can see
three of them under the front of the door. (There's around 20 of them in total.)

1778159644899.png

I wired up a 12v car halogen bulb to discharge any of the modules that are too high a voltage, so they can all be paralleled together before making the final battery configuration. (7 stacks of 20 modules) It's an easy/cheap way to do it, if you don't have a charger/discharger; but it would take way to long if the voltages are too far apart.

The first 91 modules (from 2 leaf batteries) have already been paralleled together, and have stayed within .01v of each other after sitting for more than a year. However, I need to verify the last 49 modules are close enough before parallel balancing everything.
 
After reviewing my battery bank plans, I decided to split it into two banks; I ordered another BMS (JIKONG V19 JK-PB2A16S15P V19).
I'll still stack the modules in 7 stacks of 20, just wire them in groups of 10 to made two banks.

A couple reasons for this:
1. If I have a problem with one of the battery banks, I'll still have power from the other one.
2. It will be gentler on the BMSs. I think I figured the BMS could see ~115amps--both charge & load under the original plan. (1 big battery bank). It is rated for 150A, but 60ish amps (with 2 BMSs will be super-gentle on them.)
3. Balancing will be more efficient.

---

Decided to paint the sides and top of the plywood in the battery box. (Bottom is already primered/sealed) It's the right thing to do for protecting the wood. (y)

---

Made a arduino powered hydrogen detector. 💡 Tested it, and works.

Parts used: Arduino Uno R3
MQ8 sensor
2 line LCD screen (which will eventually be inside my house... using shielded cat5, doubling wires to handle voltage drop and pull-up resistors to keep the signal reliable. I'll update on how I'm doing later.)
I'll toss the code I'm using at the bottom. I hafta tweak it to trigger the Fan Relay (SSR) Also need to go through it to understand the callibration settings.

Waiting on: SSR-25DD solid state relay to trigger fans using Arduino (Hydrogen Detector)
Buck Module 10-80V to 5V 1A to power the Arduino
Buck Module 48V60V to 12V 1A To power the fans. (2 computer case fans)
(*** need to use fuses for the power into the Buck Modules)

Already have the temperature controller and sensor. (Something like the XH-W1209, but in a case)

---------------------
Arduino Code: (Sensor part from here, LCD screen speed has been slowed to allow for running it several meters, you don't need to do this if you've got the screen close to the arduino. 😉)

Code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
/************************Hardware Related Macros************************************/
#define         MQ_PIN                       (0)     //define which analog input channel you are going to use
#define         RL_VALUE                     (10)    //define the load resistance on the board, in kilo ohms
#define         RO_CLEAN_AIR_FACTOR          (9.21)  //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,
                                                     //which is derived from the chart in datasheet
 
/***********************Software Related Macros************************************/
#define         CALIBARAION_SAMPLE_TIMES     (50)    //define how many samples you are going to take in the calibration phase
#define         CALIBRATION_SAMPLE_INTERVAL  (500)   //define the time interal(in milisecond) between each samples in the
                                                     //cablibration phase
#define         READ_SAMPLE_INTERVAL         (50)    //define how many samples you are going to take in normal operation
#define         READ_SAMPLE_TIMES            (5)     //define the time interal(in milisecond) between each samples in
                                                     //normal operation
 
/**********************Application Related Macros**********************************/
#define         GAS_H2                      (0)
 
/*****************************Globals***********************************************/
float           H2Curve[3]  =  {2.3, 0.93,-1.44};    //two points are taken from the curve in datasheet.
                                                     //with these two points, a line is formed which is "approximately equivalent"
                                                     //to the original curve.
                                                     //data format:{ x, y, slope}; point1: (lg200, lg8.5), point2: (lg10000, lg0.03)
 
float           Ro           =  10;                  //Ro is initialized to 10 kilo ohms
// Initialize Youmile LCD (PCF8574T Chip Address: 0x27, 16 characters wide, 2 lines high)
LiquidCrystal_I2C lcd(0x27, 16, 2);
 
void setup() {
  Serial.begin(9600);                                //UART setup, baudrate = 9600bps
  // Initialize the I2C LCD hardware interface
  lcd.init();
  lcd.backlight();
  // Force Hardware I2C clock down to 100 kHz Standard Mode for 5-meter path reliability
  Wire.setClock(100000);
  // Print start message to the remote LCD display
  lcd.setCursor(0, 0);
  lcd.print("Calibrating...");
  lcd.setCursor(0, 1);
  lcd.print("Please wait... ");
  Serial.print("Calibrating...\n");              
  Ro = MQCalibration(MQ_PIN);                        //Calibrating the sensor. Please make sure the sensor is in clean air
                                                     //when you perform the calibration                  
  Serial.print("Calibration is done...\n");
  Serial.print("Ro=");
  Serial.print(Ro);
  Serial.print("kohm");
  Serial.print("\n");
  // Confirm calibration completeness on the display screen
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Calib. Complete");
  lcd.setCursor(0, 1);
  lcd.print("Ro: ");
  lcd.print(Ro, 1);
  lcd.print(" kohm");
  delay(3000); // Hold calibration values on screen briefly before runtime loops
  lcd.clear();
}
 
void loop() {
   // Calculate current gas density concentrations
   int ppmValue = MQGetGasPercentage(MQRead(MQ_PIN)/Ro, GAS_H2);
   // Output telemetry data package to local hardware Serial terminal
   Serial.print("H2 Concentration:");
   Serial.print(ppmValue);
   Serial.print( "ppm" );
   Serial.print("\n");
   // Update remote LCD over the 5-meter connection link
   lcd.setCursor(0, 0);
   lcd.print("H2 Concentration");
 
   lcd.setCursor(0, 1);
   lcd.print(ppmValue);
   lcd.print(" ppm        "); // Trailing padding spaces clean up residual numeric remnants
 
   delay(200);
}
 
/****************** MQResistanceCalculation ****************************************
Input:   raw_adc - raw value read from adc, which represents the voltage
Output:  the calculated sensor resistance
Remarks: The sensor and the load resistor forms a voltage divider. Given the voltage
         across the load resistor and its resistance, the resistance of the sensor
         could be derived.
************************************************************************************/
float MQResistanceCalculation(int raw_adc) {
  return ( ((float)RL_VALUE*(1023-raw_adc)/raw_adc));
}
 
/***************************** MQCalibration ****************************************
Input:   mq_pin - analog channel
Output:  Ro of the sensor
Remarks: This function assumes that the sensor is in clean air. It use
         MQResistanceCalculation to calculates the sensor resistance in clean air
         and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
         10, which differs slightly between different sensors.
************************************************************************************/
float MQCalibration(int mq_pin) {
  int i;
  float val=0;
 
  for (i=0;i<CALIBARAION_SAMPLE_TIMES;i++) {            //take multiple samples
    val += MQResistanceCalculation(analogRead(mq_pin));
    delay(CALIBRATION_SAMPLE_INTERVAL);
  }
  val = val/CALIBARAION_SAMPLE_TIMES;                   //calculate the average value
 
  val = val/RO_CLEAN_AIR_FACTOR;                        //divided by RO_CLEAN_AIR_FACTOR yields the Ro
                                                        //according to the chart in the datasheet
 
  return val;
}
/*****************************  MQRead *********************************************
Input:   mq_pin - analog channel
Output:  Rs of the sensor
Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
         The Rs changes as the sensor is in the different consentration of the target
         gas. The sample times and the time interval between samples could be configured
         by changing the definition of the macros.
************************************************************************************/
float MQRead(int mq_pin) {
  int i;
  float rs=0;
 
  for (i=0;i<READ_SAMPLE_TIMES;i++) {
    rs += MQResistanceCalculation(analogRead(mq_pin));
    delay(READ_SAMPLE_INTERVAL);
  }
 
  rs = rs/READ_SAMPLE_TIMES;
 
  return rs;
}
 
/*****************************  MQGetGasPercentage **********************************
Input:   rs_ro_ratio - Rs divided by Ro
         gas_id      - target gas type
Output:  ppm of the target gas
Remarks: This function passes different curves to the MQGetPercentage function which
         calculates the ppm (parts per million) of the target gas.
************************************************************************************/
int MQGetGasPercentage(float rs_ro_ratio, int gas_id) {
  if ( gas_id == GAS_H2) {
     return MQGetPercentage(rs_ro_ratio,H2Curve);
  }
  return 0;
}
 
/*****************************  MQGetPercentage **********************************
Input:   rs_ro_ratio - Rs divided by Ro
         pcurve      - pointer to the curve of the target gas
Output:  ppm of the target gas
Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
         of the line could be derived if y(rs_ro_ratio) is provided. As it is a
         logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
         value.
************************************************************************************/
int  MQGetPercentage(float rs_ro_ratio, float *pcurve) {
  return (pow(10,( ((log(rs_ro_ratio)-pcurve[1])/pcurve[2]) + pcurve[0])));
}
[ /code ]
 
Last edited:
After reviewing my battery bank plans, I decided to split it into two banks; I ordered another BMS (JIKONG V19 JK-PB2A16S15P V19).
I'll still stack the modules in 7 stacks of 20, just wire them in groups of 10 to made two banks.

A couple reasons for this:
1. If I have a problem with one of the battery banks, I'll still have power from the other one.
2. It will be gentler on the BMSs. I think I figured the BMS could see ~115amps--both charge & load under the original plan. (1 big battery bank). It is rated for 150A, but 60ish amps (with 2 BMSs will be super-gentle on them.)
3. Balancing will be more efficient.
No right/wrong but I'll be interested to see how you operate and how balance works in the long run. Here's what I'm thinking about.....

I need to balance once every 6 months or so to tighten the max pack difference. Things diverge an extra 30mv or so over 6-9months and I believe my cells to be healthy. In my case, I can use Batrium's Auto-Balance which works thru the charge/discharge voltage range so I don't need to 'top balance'. I can just toggle this on for a couple of weeks, regardless of where I am in the year and don't have to manage reaching top charge to encourage balancing.

My packs (that I balance) are 260ah each and in you're case, with 7 stacks of 10 in parallel it will be something like 10 x 30ah = 300ah 'parallel units' in series?. That's a reasonably hefty set of parallel units in series to balance.

If you post you're operational experiences - e.g. do you balance all the time, what kind of drift (max difference) do you run into, etc... I'll be interested to follow along :)
 
Last edited:
No right/wrong but I'll be interested to see how you operate and how balance works in the long run. Here's what I'm thinking about.....

I need to balance once every 6 months or so to tighten the max pack difference. Things diverge an extra 30mv or so over 6-9months and I believe my cells to be healthy. In my case, I can use Batrium's Auto-Balance which works thru the charge/discharge voltage range so I don't need to 'top balance'. I can just toggle this on for a couple of weeks, regardless of where I am in the year and don't have to manage reaching top charge to encourage balancing.

My packs (that I balance) are 260ah each and in you're case, with 7 stacks of 10 in parallel it will be something like 10 x 30ah = 300ah 'parallel units' in series?. That's a reasonably hefty set of parallel units in series to balance.

If you post you're operational experiences - e.g. do you balance all the time, what kind of drift (max difference) do you run into, etc... I'll be interested to follow along :)
I'm looking forward to getting things up and running too. 😊. I'll be reading your past comments, and probably/hopefully be in a similar operation as you in terms of balancing. Our setups are similar, and your posts/comments are much appreciated.
 
Hydrogen detector in action... using a lighter (unlit) to test. I guess it can detect propane, methane and other gases too.
Recommend checking this comment by Korishan for a better way to control things.

1778989499961.png
1778989510388.png


Picked up this double RJ45 board for ~$3.50 usd:

1778989585346.png
1778993587198.png

Cut it in half using a hacksaw... the green terminals helped keep the blade aligned and running parallel to the surface. Then checked the connections to make sure we're still good. I'll use the screw terminals for the connections to the Arduino on one end and the LCD on the other. Note: I'm useless at soldering. 🔥 😞



I'm following this AI recommendation:

Recommended Wiring Strategy (I2C)
Using standard I2C backpacks (like the PCF8574), you only need four pins: Ground, VCC (5V), SDA (Data), and SCL (Clock). Since CAT5 cable has four twisted pairs, pairing them correctly is critical for signal integrity.

CAT5 PairCAT5 Wire ColorLCD Pin ConnectionPurpose
Pair 1Blue / White-BlueGNDCommon Ground
Pair 2Orange / White-Orange5V / VCCPower Supply
Pair 3Green / White-GreenSDAI2C Data Line
Pair 4Brown / White-BrownSCLI2C Clock Line
Tip: Connect both wires of the twisted pair together for VCC and GND to reduce resistance and prevent voltage drops over longer distances.


1778990429997.png
 

Attachments

  • 1778993549886.png
    1778993549886.png
    441.7 KB · Views: 45
Last edited:
  • Like
Reactions: kje
My new JK-PB2A16S15P V19 arrived, and I will use it as a Master, with my older (which I think is a V15) as the slave.

They are compatible, but there are a few configuration hacks/tricks to get them to work together efficiently. I'll probably post about these setup issues later when/or after I do them. (If you need to know now, do a search comparing using the two boards together.)

One importand note I need to be careful about is that the PowMr hybrid inverter connection to the BMS (only the master connection is required) needs a special cable for the RJ45 ports. Each device uses a slightly different pinout, and connecting a standard cat5 cable can destroy the port(s).
Instead of buying, or making it myself, I'll buy another of the RJ45 8P8C wiring connectors ($3.50) and do the cross-over connections on it, then I can then use 2 standard cat5 cables from the BMS and PowMr.
 
I need to be careful about is that the PowMr hybrid inverter connection to the BMS (only the master connection is required)
Good luck with that, I never got mine to talk to each other. And yeah, I did the pinout change over. I have a patch panel with punches and that didn't work.
That 8P8C connector is pretty neat, tbh. Nice way to make the jumpers
 
, I never got mine to talk to each other.
Curious if you only connected the ground and 2 data lines, or all of them? I read that connecting the other lines even though they aren't used can add noise/interference.
 
I did both. I never could figure out which protocol to use either. I think I just ended up with dud units, both Inverters, that is. They both don't output pure sine wave, either. There's quite a bit of noise as the wave comes back up. If zoomed in, the frequency at that section is >130HZ
 
Yuck! 😲 I hope I can get mine working. I know you've done a lot of trouble-shooting on yours and no doubt have gone through this; I'm putting the following info for my reference when I set my system up :):

Use Pylontech/Pylon9600 or SRNE protocol. (both JK-PB2A16S15P V19 & v15 contain an emulation feature for this)
(The V19 is faster so it should be the master)
Setting 05 to LI2 (lithium Battery with Closed-Loop RS485 BMS Communication.)
Setting 36 to L01 (Pylontech RS485 comm protocol at 9600bps)
Handshaking: Have both inverter and BMSs off, then turn the the BMSs on 1st, after they boot turn on the inverter.

Use STP cable, keeping it away from other voltage.
Check that the voltage at the inverter and the voltage at the BMS are not causing a stalled data loop (i.e. inverter reading higher voltage than BMS so stopping charging early and BMS continuing to communicate it wants voltage.) -- results in handshake timeout.
False overloading - When inverter turns on it can suck massive power from the battery, which the BMS thinks is a short circuit and shuts off.
(Use a pre-charge resistor)
Make sure the battery groups have unique ID's (dip switch settings are correct)
 
I'll check those settings and revisit it. Would definitely be nice to have the BMS actually tell the chargers when to ramp up/down instead of them being blind.
 
Arduino screen is now working over the 5m cat5 cable. :)
Everything works without the pull up resistors (for now ;)), but I'll still add them later, when they arrive.

1779429098827.png


Here's the wiring config for this setup:

Double up power, and isolate I2C lines using jumpers across the terminals of both (split in half) RJ45 boards like this:

Terminals Wire Colors* Connnects to
[1]--[2] (Orange Pair) --> 5V
[3]--[6] (Green Pair) --> SDA (<-edit: for the observant, I have SCL here in the pic)
[4]--[5] (Blue Pair) --> GND
[7]--[8] (Brown Pair) --> SCL (<-edit: I have SDA here in the pic)
[SH] Shielding (STP) --> only to the Arduino's GND to avoid a ground loop. (not at LCD end)
*Note: The twisted pairs provide protection against electrical noise, so it's important to use these wire combinations.

How to Install the two 2.2kohm Resistors into the Terminals
  1. SDA Pull-Up Resistor: Insert one leg of the 1st resistor into Terminal 1 (5V) and the other leg into Terminal 3 (SDA).
  2. SCL Pull-Up Resistor: Insert one leg of the 2nd resistor into Terminal 2 (5V) and the other leg into Terminal 7 (SCL).
    (Note: Because Terminals 1 & 2 are already jumpered together for 5V,putting one resistor on Pin 1 and the other on Pin 2 keeps the terminal holes from getting too crowded.)
I will clean up the wiring and put things in cases. (***I am probably using the wrong wire coloring for this testing; so you should look up the standards for your area to keep things compliant. (y))
 
Last edited:
Back
Top