// sampling the cells voltage and current
//===============================================================================================================================================

    tempw:=0;
    ADCON0:=0x81;
    delay_us(5);
    for i:=0 to 63 do
      begin
        ADCON0.2:=1;
        repeat until ADCON0.2=0;
        tempw:=tempw+ADRESL;
        tempw:=tempw+(ADRESH shl 8);
      end;
    fast_voltage:=tempw;                                                        //voltage and current @16bits
    acc_voltage:=acc_voltage+tempw;

    tempw:=0;
    ADCON0:=0x89;
    delay_us(5);
    for i:=0 to 63 do
      begin
        ADCON0.2:=1;
        repeat until ADCON0.2=0;
        tempw:=tempw+ADRESL;
        tempw:=tempw+(ADRESH shl 8);
      end;
    fast_current:=tempw;                                                        //voltage and current @16bits
    acc_current:=acc_current+tempw;

    inc(count_slow);
    if (count_slow=0) then
      begin
        slow_voltage:=acc_voltage shr 8;                                        //voltage and current @16bits "high precision"
        slow_current:=acc_current shr 8;                                        //voltage and current @16bits "high precision"
        acc_voltage:=0;
        acc_current:=0;
      end;

    case (action) of                                                            //choice for different operating modes
    
//===============================================================================================================================================
// Discharge at constant current (all the batteries)
//===============================================================================================================================================

    discharge_cc:begin                                                          //discharge control loop
        tempi:=fast_current-zero_current;
        if (tempi<0) then tempi:=0;
        mah:=mah+tempi;
        if (tempi>target_current) then                                          //modulate the PWM following the discharge current changes
          begin
            dec(duty_pwm_discharge);
            if (duty_pwm_discharge<0) then duty_pwm_discharge:=0;
          end
        else
          begin
            inc(duty_pwm_discharge);
            if (duty_pwm_discharge>1023) then
              begin
                duty_pwm_discharge:=1023;
                pwm_err:=1;                                                     //if the PWM is at the maximum value, there is an error
              end;

          end;
      end;
      
//===============================================================================================================================================
// Charge at constant current (NiMh and NiCd all the time, LiPo and SLA only the first period)
//===============================================================================================================================================

    charge_cc:begin                                                             //charge cc control loop
        tempi:=zero_current-fast_current;
        if (tempi>0) then mah:=mah+tempi;
        if (tempi>target_current) then                                          //modulate the PWM following the charge current changes
          begin
            dec(duty_pwm_charge);
            if (duty_pwm_charge<0) then duty_pwm_charge:=0;
          end
        else
          begin
            inc(duty_pwm_charge);
            if (duty_pwm_charge>1023) then
              begin
                duty_pwm_charge:=1023;
                pwm_err:=1;                                                     //if the PWM is at the maximum value, there is an error
              end;
          end;
      end;