Arduino keeps resetting if pwm is enable

Thread Starter

Ðeejay Kital

Joined Mar 24, 2016
27
hi
i am trying to build an mppt charger using arduino nano and right now i am having a problem with my mppt.
i already test all the components and working fine. the current sensor is okay and also the voltage sensor is okay.
but when the mppt start pwm then the arduino keeps resetting every seconds.

Code:
#include <LiquidCrystal_PCF8574.h>
#include <Wire.h>
LiquidCrystal_PCF8574 lcd(0x27); // set the LCD address to 0x27 for a 16 chars and 2 line display
int show = -1;

uint16_t PWM_MIN = 96;
uint16_t PWM_MAX = 150;
uint16_t PWM_DUTY = 120;
#define PWM_INC 1 //the value the increment to the pwm value for the ppt algorithm
#define AVG_NUM 20
#define SOL_AMPS_PIN A0
#define SOL_VOLTS_PIN A3
#define BAT_AMPS_PIN A1
#define BAT_VOLTS_PIN A2

#define SENSOR_SCALE 0.05 // 50mv per amper

double VOLTAGE_DIVIDER = 0.04912836767; //(r2/(r1+r2))
double VOLTAGE_REFERENCE = 4.096;       //external Vref
double SOL_AMPS = 0.0;
double SOL_VOLTS = 0.0;
double BAT_AMPS = 0.0;
double BAT_VOLTS = 0.0;
double SOL_WATTS = 0.0;
double OLD_SOL_WATTS = 0.0;
double OLD_SOL_VOLT = 0.0;

double OFFSET_SOLAR = 0.0;
double OFFSET_BATTERY = 0.0;
void setup() {
  // put your setup code here, to run once:
  TCCR1A = 0xB2;
  TCCR1B = 0x11;
  ICR1 = 160;
  DDRB = 0x06;
  OCR1A = 0; // pin 9
  OCR1B = 0; // pin 10
  int error;
  analogReference(EXTERNAL);
  analogRead(A0);
  analogRead(A1);
  analogRead(A2);
  analogRead(A3);
  Serial.begin(115200);

  Serial.println("Dose: check for LCD");
  Wire.begin();
  Wire.beginTransmission(0x27);
  error = Wire.endTransmission();
  Serial.print("Error: ");
  Serial.print(error);
  if (error == 0) {
    Serial.println(": LCD found.");
    show = 0;
    lcd.begin(16, 2); // initialize the lcd
  } else {
    Serial.println(": LCD not found.");
  }
  lcd.setBacklight(255);


  OFFSET_SOLAR = read_adc(SOL_AMPS_PIN);
  OFFSET_BATTERY = read_adc(BAT_VOLTS_PIN);
}

void loop() {
  read_data();
  if (SOL_WATTS > OLD_SOL_WATTS) {
    if (SOL_VOLTS > OLD_SOL_VOLT)
    {
      PWM_DUTY += PWM_INC;
    }
    else
    {
      PWM_DUTY -= PWM_INC;
    }
  }
  else {
    if (SOL_VOLTS > OLD_SOL_VOLT)
    {
      PWM_DUTY -= PWM_INC;
    }
    else
    {
      PWM_DUTY += PWM_INC;
    }
  }

  if (PWM_DUTY < PWM_MIN) {
    PWM_DUTY = 96;
  }
  if (PWM_DUTY > PWM_MAX) {
    PWM_DUTY = 150;
  }
  OLD_SOL_VOLT = SOL_VOLTS;
  OLD_SOL_WATTS = SOL_WATTS; // load old_watts with current watts value for next time

  OCR1A = PWM_DUTY - 10;
  OCR1B = PWM_DUTY;

  delay(100);
  lcd.setCursor(0, 0);
  lcd.print(SOL_WATTS);

  lcd.setCursor(8, 0);
  lcd.print(SOL_VOLTS);

  lcd.setCursor(0, 1);
  lcd.print(BAT_VOLTS);

  lcd.setCursor(8, 1);
  lcd.print(SOL_AMPS);

}


void read_data(void)
{
  int temp_sol_amps = read_adc(SOL_AMPS_PIN);
  int temp_sol_offset = temp_sol_amps - OFFSET_SOLAR;
  if (temp_sol_offset < 0)
  {
    temp_sol_offset = 0;
  }

  int temp_bat_amps = read_adc(BAT_AMPS_PIN);
  int temp_bat_offset = temp_bat_amps - OFFSET_BATTERY;
  if (temp_bat_offset < 0)
  {
    temp_bat_offset = 0;
  }

  SOL_AMPS = (temp_sol_offset * (VOLTAGE_REFERENCE / 1023.0)) / 0.05; //input of solar amps
  //SOL_AMPS = read_adc(SOL_AMPS_PIN);                      //input of solar amps
  SOL_VOLTS = (read_adc(SOL_VOLTS_PIN) * (VOLTAGE_REFERENCE / 1023.0)) / VOLTAGE_DIVIDER; //input of solar volts
  BAT_AMPS = (temp_bat_offset * (VOLTAGE_REFERENCE / 1023.0)) / 0.05;                     //output of battery amps
  //BAT_AMPS = read_adc(BAT_AMPS_PIN);                       //output of battery amps
  BAT_VOLTS = (read_adc(BAT_VOLTS_PIN) * (VOLTAGE_REFERENCE / 1023.0)) / VOLTAGE_DIVIDER; //calculations of solar watts
  SOL_WATTS = SOL_AMPS * SOL_VOLTS;
}

int read_adc(int channel)
{
  int sum = 0;
  int temp;
  int i;
  for (i = 0; i < AVG_NUM; i++)
  { // loop through reading raw adc values AVG_NUM number of times
    temp = analogRead(channel); // read the input pin
    sum += temp;                // store sum for averaging
    delayMicroseconds(100);     // pauses for 50 microseconds
  }
  return (sum / AVG_NUM); // divide sum by AVG_NUM to get average and return it
}

Schematic_for-all-about-circuit_SCHEM-copy-copy_20191208121018.png
 

Alec_t

Joined Sep 17, 2013
11,398
Welcome to AAC!
I see no decoupling capacitor next to the Arduino supply pins. It's possible that interference from the PWM switching is affecting the Arduino.
Do you have a star ground system to prevent heavy currents causing 'ground bounce' on the Arduino's ground rail?
 

jpanhalt

Joined Jan 18, 2008
9,699
Decoupling caps was my first thought too, but then doesn't the Arduino nano have decoupling caps on the board already? I agree grounding may be the culprit.
 

Thread Starter

Ðeejay Kital

Joined Mar 24, 2016
27
hi everyone i have ceramic capacitor 10 uf 16v beside 5v pin of arduino. not shown in schematic since i just place it in pcb layout.
still cant figure out the problem. here the pcb below.

top.PNG
bot.PNG
 

pmd34

Joined Feb 22, 2014
507
Do you have the correct frequency for the inductor you are using? (Avoid too small inductor or too low frequency). This is very useful actually:
http://www.ti.com/tool/POWERSTAGE-DESIGNER

If you have a scope, see if there are any glitches on the supply for the micro-controller.
Try supplying VCC externally.
Does the PWM routine work on the arduino board itself, when not plugged into the charger? (Sometimes coding errors can cause the microcontroller to reset - though i couldn't spot any obvious ones).
Check Q4 is not damaged or switched on all the time. These type of FET driver ICs can be very sensitive to negative voltage spikes which you can get during the switching cycles.
One thing I notice, if there is no power coming from the solar cell, the battery will charge up the capacitor bank, and then every pulse try and send power back into the solar cell - will the cause problems?
 

Thread Starter

Ðeejay Kital

Joined Mar 24, 2016
27
what i have found is that the power reset also if the the pwm for low side mosfet is enable. so i dont think that the psu for microcontroller is the problem since it is stable when not using pwm at low side mosfet.
OCR1A = PWM_DUTY - 10; i comment this line in the code then the problem solve but then it wont operate as synchronous converter and also not working as buck converter since when i tried to check in the oscilloscope at high side mosfet while lowside mosfet is 0 duty cycle and always getting high signal almost 10v at high side no changes in pwm. i already check the pwm before the mosfet driver and the pwm is working fine. i also check the two pwm without putting into the charger it works fine also in the oscilloscope. i then to groun the signal of mosfet driver then power on the board to check again if the power supply has a problem but then it is also working fine.
 

jpanhalt

Joined Jan 18, 2008
9,699
Can you show that part of your code? Can you simulate the chip and watch what happens at that step? Does your simulator allow you to monitor the stack?

Is it possible there is a call and no return or a return and no call (i.e., anything that will cause stack over-or underflow)? That will cause a reset on the devices I use.
 

Sensacell

Joined Jun 19, 2012
2,568
I have a feeling you will find that it's stable when no high currents are flowing, this will be the dead giveaway that you have ground or power decoupling problems.

Try to run it with the load or power to the half-bridge disconnected, or at a reduced voltage to see if it crashes.
 

Thread Starter

Ðeejay Kital

Joined Mar 24, 2016
27
I have a feeling you will find that it's stable when no high currents are flowing, this will be the dead giveaway that you have ground or power decoupling problems.

Try to run it with the load or power to the half-bridge disconnected, or at a reduced voltage to see if it crashes.

hello
the prblem occurs when this line of code is not commented
OCR1A = PWM_DUTY - 10;
the arduino restart after putting battery since the power is from the battery.

but when i remove that code the arduino works fine and the rest of power is stable.
it only works when the low side mosfet have zero duty cycle.
 

jpanhalt

Joined Jan 18, 2008
9,699
If I understand correctly, it works without that code being commented out, but only when duty cycle for low side is 0%.

Since the mosfet driver is separate from the MCU, like @Sensacell said, that points to high currents being the source of problems.
 

Alec_t

Joined Sep 17, 2013
11,398
I can't tell from the pcb pics: are the Gnd and Reset pins of the Arduino actually floating?
You are misusing the +5V output pin of the Arduino nano as its supply input. I understand this bypasses the on-board regulator, and can damage the Arduino.
What is the purpose of FET Q6? Its body diode allows the capacitor group to charge from the SOl_Volt input whether or not the FET is switched on.
 
Last edited:

djsfantasi

Joined Apr 11, 2010
6,504
I can't tell from the pcb pics: are the Gnd and Reset pins of the Arduino actually floating?
What do you mean by “is the Gnd pin actually floating” I would think that by definition a Gnd pin is at Gnd and can’t be floating.

I’ve developed systems that use the Gnd pin as ground and they all work fine.

As far as the Reset pin, an actual Arduino board has a pull up resistor on the PCB. Hence, in that case it is not floating.
 

Alec_t

Joined Sep 17, 2013
11,398
What do you mean by “is the Gnd pin actually floating”
The Nano has two Gnd pins. I can't tell if either actually connects to the ground-pour copper of the pcb.
Edit: Got the magnifier out. I think I now see the lower Gnd pin does have a connection to the pcb copper.
As far as the Reset pin, an actual Arduino board has a pull up resistor on the PCB. Hence, in that case it is not floating.
That's ok then.
 
Last edited:

djsfantasi

Joined Apr 11, 2010
6,504
The Nano has two Gnd pins. I can't tell if either actually connects to the ground-pour copper of the pcb.
Edit: Got the magnifier out. I think I now see the lower Gnd pin does have a connection to the pcb copper.

That's ok then.
All Gnd pins on legitimate Arduinos connect to the ground plane.
 

dendad

Joined Feb 20, 2016
3,564
Can you hook up an external supply for the Arduino to test if your 5V is failing?
A large cap on the 5V may help. Or use the Vin pin and have the Arduino use its own reg.
 

pmd34

Joined Feb 22, 2014
507
hello
the prblem occurs when this line of code is not commented
OCR1A = PWM_DUTY - 10;
the arduino restart after putting battery since the power is from the battery.

but when i remove that code the arduino works fine and the rest of power is stable.
it only works when the low side mosfet have zero duty cycle.
Can you confirm that this change in duty cycle is not making both fets switch on at the same time. Its a bit hard to follow what counter mode your arduino is running in (as I am used to using C programming in atmel studio). Confirmation with a scope on the gates of both fets would be very useful.
 

Thread Starter

Ðeejay Kital

Joined Mar 24, 2016
27
Can you confirm that this change in duty cycle is not making both fets switch on at the same time. Its a bit hard to follow what counter mode your arduino is running in (as I am used to using C programming in atmel studio). Confirmation with a scope on the gates of both fets would be very useful.

hi
before putting the arduino nano to my pcb i already test put it in oscilloscope i have about 300 ns deadtime.
i already tried putting external power supply for arduino alone but same thing happen.
 
Top