Hysterical MPPT - Solar Charger

So i killed my display, now its even simplier :confused:
The sleep functions works how it should.
Faster cycle less then 10ms.
Ye, i should look if the IR_safe resistor is working how it should. Btw it should be done with every new build if all is working lik in the simulator spice. I charge 2x 100Ah batteries. Or they had 100Ah the old charger was not doing a great job.. sometimes he only charged up 13.2 and on good day sometimes 13.8V.. no wonder the batteries loved it. :frowning:

NB. Find a good coil for Stepers is the most tricky part. A friend tested a trafo ferrit ring and cut about 1mm out of it (like tis "C") now it has 40x less "ur" and satures at 20A with 14 windings, it has about 10uH, and keeps absolutly cool. Thos ferrit rings are everywhere too find (choke coils).

So heres the code witout TFT now:

// THIS MPPT SLOPECLIMBER ALGORITH WORKS FINE! EFFICIENCY 90% @  Solarpanel = 180W 22V 36Cells
// It sleeps for 8s then wake up some ms too check if there is sun
// In SLEEP MODE consumes only 5mA with TFT ON, thx too a little step-downer that makes the 5V for arduino and TFT.
// NB my wiring is bad and long, i lose a lot of power on the lines. my gain is 10% compared too normal regulator.

#define MinStartV 18.5           // Min solarpanel volt value for ON Charger
#define LOW_SOL_WATTS 5          //value of solar watts // this is 5.00 watts -> PWM_START
#define MIN_SOL_WATTS 1          //value of solar watts // this is 1.00 watts -> OFF      
#define MAX_BAT_VOLTS 14.7       // upper hysteresis -> OFF
#define BATT_HYS 13.6            // low   hysteresis -> ON
#define MAX_TEMP 70
#define OK_TEMP  40
#define SOL_AMPS_SCALE  0.012734          //LM324 680k 10k -> Gain = 68 with 5mOhm shunt placed ground side withou a bridge
#define SOL_VOLTS_SCALE 0.027107422       // the scaling value for raw adc reading to get solar volts  // (5/1024)*(R1+R2)/R2 // R1=100k and R2=20k max. +30V -> +5V arduino
#define BAT_VOLTS_SCALE 0.0261            // the scaling value for raw adc reading to get battery volts 
#define TEMP_SCALE 0.13125                // the scaling value for raw adc reading to get temperatur 

#define PWM_MAX 254                  // 254 60ns off; 1= 60ns coz of 16Mhz     
#define PWM_START 240                // max dutycycle tat maks sense with an irfz44
#define PWM_MIN 170                  // 68% min duty cyle NB. My normal avarage dutycycle is 210 normaly 16,5V solar and batt at 13,5V. rarely goes under 200.
#define AVG_NUM 55

#include <avr/sleep.h>
#include <avr/wdt.h>

// watchdog interrupt
ISR (WDT_vect) 
{
   wdt_disable();  // disable watchdog
}  // end of WDT_vect

// global variables
float old_sol_watts,sol_watts,sol_volts,sol_amps,bat_volts,celsius;
int pwm, old_pwm,delta=-1;
unsigned int rzz,charger_state,old_charger_state,k; //65.535max

 //PINS
#define SOL_VOLTS_CHAN 0            // defining the adc channel to read solar volts 
#define SOL_AMPS_CHAN 1             // Defining the adc channel to read solar amps
#define BAT_VOLTS_CHAN 2            // defining the adc channel to read battery volts
#define CELSIUS_CHAN 3              // defining the adc channel to read temperatur of mosfett
#define PWM_PIN 5                   // the output pin for the pwm (only pin 5 or 6 at 63kHz)
#define PWM_ENABLE_PIN 6            // pin used to control shutoff function of the IR2104 MOSFET driver (hight the mosfet driver is on)

#define TURN_ON_MOSFETS analogWrite(PWM_ENABLE_PIN, 255)      // enable MOSFET driver
#define TURN_OFF_MOSFETS analogWrite(PWM_ENABLE_PIN, 0)      // disable MOSFET driver
#define LON digitalWrite(13, HIGH)
#define LOF digitalWrite(13, LOW)
#define TOG digitalWrite(13,!digitalRead(13))


void setup() {
  pinMode(SOL_AMPS_CHAN, INPUT);
  pinMode(SOL_VOLTS_CHAN, INPUT);
  pinMode(BAT_VOLTS_CHAN, INPUT);
  pinMode(CELSIUS_CHAN, INPUT);
  pinMode(13,OUTPUT);
  
    //For Fast PWM of 62.500 kHz (prescale factor of 1) pins 5 and 6
    //Use these two lines in the setup function: (16Mhz/253 steps):
    TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);  //(16Mhz/255 steps)
    TCCR0B = _BV(CS00); 
    
  TURN_OFF_MOSFETS;
  charger_state = 0;
  pwm = PWM_START;
  set_pwm_duty(); 
}

void loop() {
  read_adc();                      
  run_charger();
}

//------------------------------------------------------------------------------------------------------
// This reads and average, temperatur, solar volts, solar amps and battery volts. 
//------------------------------------------------------------------------------------------------------
void read_adc(void){
  celsius  += (28+TEMP_SCALE* (1024-analogRead(CELSIUS_CHAN) - 460)); celsius=celsius/2; //460 bei 28°C
  for (k=0; k<AVG_NUM; k++) {//NB: 55x3x(100us+16us) = 165x116u = 19ms
    sol_amps  += (analogRead(SOL_AMPS_CHAN)-19)  * SOL_AMPS_SCALE  ;      //input of solar amps, 100us read time
    sol_volts += analogRead(SOL_VOLTS_CHAN) * SOL_VOLTS_SCALE;       //input of solar volts
    bat_volts += analogRead(BAT_VOLTS_CHAN) * BAT_VOLTS_SCALE;       //input of battery volts
     delay(5);//wait some ms. -> delay(10000); super! <
    }
    sol_volts = sol_volts  /(AVG_NUM+1);
    bat_volts = bat_volts  /(AVG_NUM+1);
    sol_amps  = sol_amps   /(AVG_NUM+1);
    sol_watts = sol_amps * sol_volts;  //calculations of solar watts                       
  }         

//------------------------------------------------------------------------------------------------------
// Set the pwm duty cycle.
//------------------------------------------------------------------------------------------------------
void set_pwm_duty(void) {
  if (pwm > PWM_START) {             // check limits of PWM duty cyle and set to PWM_START
    pwm = PWM_START;    
  }
  else if (pwm < PWM_MIN) {          // if pwm is less than PWM_MIN then set it to PWM_MIN
    pwm = PWM_MIN;
  }
analogWrite(PWM_PIN,pwm);                     
} 

//------------------------------------------------------------------------------------------------------
// Hysterischer-MPPT Charger
//------------------------------------------------------------------------------------------------------
void run_charger(void){
  switch (charger_state) {

case 0://Charger Off
      if ((bat_volts < BATT_HYS) & (sol_volts>MinStartV) ) {                // hysteresis: on
        charger_state = 1; //ON
        rzz=0;
        pwm = PWM_START;
        set_pwm_duty();
        TURN_ON_MOSFETS;
      }
    else {rzz++; if(rzz>12)sleep8s();else {LON;sleep0dot5s();LOF;sleep0dot5s();}} //test
break;
    
case 1://Charger On                                        
      if (bat_volts > (MAX_BAT_VOLTS)) {                                   //  hysteresis max: off
        TURN_OFF_MOSFETS;
        charger_state = 0; //OFF
        pwm = PWM_START;
        set_pwm_duty();
 break;}

      else if (celsius > (MAX_TEMP)) {                                  //  hysteresis max_temp: off
        TURN_OFF_MOSFETS;
        charger_state = 2; //OVERHEATED
        pwm = PWM_START;
        set_pwm_duty();for(k=0; k<10; k++){TOG;sleep0dot5s();}
break;}
      else if (sol_watts < MIN_SOL_WATTS) {                              // no sun -> off
        TURN_OFF_MOSFETS;
        charger_state = 0; //OFF
        pwm = PWM_START;       
        set_pwm_duty();digitalWrite(13,LOW);sleep1s();
break;}  
       else if (sol_watts < LOW_SOL_WATTS) {                           // very low watts -> max duty
        pwm = PWM_START;        
        set_pwm_duty();digitalWrite(13,LOW);
break;}
       else if (old_sol_watts > sol_watts)  {                       // MPPT against flat tops: ">"                                      
          delta = -delta;                       
      }
        pwm += delta;                        
        old_sol_watts = sol_watts;                       
        set_pwm_duty();                                   
break;
    
case 2://Charger Overheated
      if (celsius < (OK_TEMP) ) {                                  // Temp ok -> go off
        charger_state = 0; //OFF
      }
      else {
              for(k=0; k<10; k++){TOG;sleep0dot5s();}
break;}

default: //never happens
        TURN_OFF_MOSFETS;
        charger_state = 0;
        pwm = PWM_START;set_pwm_duty();     
        sleep8s();
break;
      }//END of switch()
}//END of run_charger()


// SLEEP..