Problem making PID library controller "see" setpoint and input data

I am making a solar PV power system PID PWM diversion controller. The charge controller used is a midnite classic 150. I can extract the data needed from the Classic using an arduino uno via rs232 connection. The data is the charge controller mode, battery volts, battery voltage setpoint. I calculate the diversion control setpoint from the battery voltage setpoint. These 4 values I display on a 4X20 lcd. This I have working - mostly due to dgd on the Midnite forum whose initial sketch it was that I have modified.
Now I am trying to get the PID control to work. I have put in the basic PID library ( br3ttb arduino pid library) into the sketch and am using the PID Basic sketch in my sketch. I am trying to modify that sketch to read the values for battery voltage as the PID input and diversion control setpoint as the PID setpoint. I was hoping when I got this working then I would put in timer1 and slow the PWM down to a slower speed to allow for the relay to work correctly. I am not being successful in getting the PID to see the input and or the setpoint. I think this because I am testing the system by connecting it to the relay that I will be using. It has leds that light up when it gets a signal to close. The PID is reverse acting. It increases output to reduce the voltage and decreases to increase the voltage. The relay leds are always on regardless of if the battery voltage is above the setpoint or below it. Ideally the relay would only close when the voltage is above the setpoint.
I have tried many things. I suspected tuning and gave the pid setpoints a long way from desired process to try to effect a change. Nothing happened. I have prowled the web downloading code and trying to find something that works. I have probably 20 interations of sketchs but so far I have not been successful in getting the relay led to turn off when the battery voltage is below setpoint. I gave 0 values of the integral and derivative components to try to eliminate them from the equation but was still not successful. I built functions and tried to use them for the setpoint and input but all I got was lots of error messages that I could not(mostly) understand. The good thing about all this is that I am learning lots however I am beginning to run out of things to try.
I am not a very experienced coder and suspect that I am making a basic error that I am not picking up on. Possibly someone with experience will be able to spot my error relatively quickly. I have put lots of comments into the sketch to make it easy to see what is going on (or not).

Thanks

Will

      #include <LiquidCrystal_I2C.h>  //lcd
      #include <Wire.h>               //lcd
      #include <SimpleModbusMaster.h> //rs232
      #include <PID_v1.h>             //pid
      #define PIN_OUTPUT 6            //pwm pin

      double div_spt;        //pid declare diversion setpoint for pid`setpoint
      double batt_volts;     //pid  declare battery volts for pid input

                            //pid Define Variables we'll be connecting to
      double Setpoint;
      double Input;
      double Output;

                            //pid Specify the links and initial tuning parameters
      double Kp=2, Ki=0, Kd=0;
      PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, REVERSE);



                         //rs232 Port information 
      #define baud 19200
      #define timeout 1000
      #define polling 200 // the scan rate
      #define retry_count 10
      #define TxEnablePin 2 // used to toggle the receive/transmit pin on the driver
      #define LED 9


      enum
{
      PACKET1,
      PACKET2,
      TOTAL_NO_OF_PACKETS // leave this last entry
};

      Packet packets[TOTAL_NO_OF_PACKETS]; // Create an array of Packets to be configured
      packetPointer packet1 = &packets[PACKET1];
      packetPointer packet2 = &packets[PACKET2];// Create a packetPointer to access each packet
      unsigned int readRegsa[21];
      unsigned int readRegsb[3];
      LiquidCrystal_I2C lcd(0X20,20,4); // set the LCD address to 0X20 for a 20 chars and 4 line display
 
 

void setup()
{
      lcd.init ();// lcd setup LCD display
      lcd.backlight ();
      
                  // rs 232 read 20 register starting at address 4114  
      modbus_construct(packet1, 10, READ_HOLDING_REGISTERS, 4114, 20, readRegsa);
      modbus_construct(packet2, 10, READ_HOLDING_REGISTERS, 4243, 2, readRegsb);
  
 
  
                  // Initialize communication settings:
       
       modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS);
  
 {
                  //pid initialize the variables we're linked to
                  
      Input = (batt_volts);
      Setpoint = (div_spt) ;

                 //pid turn the PID on
      myPID.SetMode(AUTOMATIC);
}

}


      void loop()

{  
      int state ;
      double bat_v_spt;

                     // read the Classic's modbus registers
      modbus_update();
  
  
                     // make Classic register values ready for LCD
      batt_volts = readRegsa[0];
      batt_volts /=10;
      state = (unsigned int)readRegsa[5] >> 8;  // high byte contains charge state code
      bat_v_spt = readRegsb[0];
      bat_v_spt /=10;
      div_spt = readRegsb[0];
      div_spt /=10;
      div_spt -=.3;
 
                  // top line of lcd
      lcd.setCursor(0,0);
     
      switch (state)
  {
       case 0:
          lcd.print ("Resting  ");
          break;
       case 3:
          lcd.print ("Absorb   ");
          break;
       case 4:
          lcd.print ("BulkMppt ");
         break;
       case 5:
          lcd.print ("Float    ");
          break;
       case 6:
          lcd.print ("FloatMppt");
          break;
       case 7:
          lcd.print ("Equalize ");
          break;
       case 10:
          lcd.print ("HyperVoc ");
          break;
       case 18:
          lcd.print ("EqMppt   ");
          break;
   }

      lcd.setCursor (0,1);
      lcd.print("Batt Volts    ") ; 
      lcd.print(batt_volts);  
      lcd.setCursor(0,2);
      lcd.print("Batt V SetPt  ");
      lcd.print(bat_v_spt);
      lcd.setCursor(0,3);
      lcd.print("Divt V SetPt  ");
      lcd.print(div_spt);
      
      delay (300);          // delay to stop LCD flickering, refreshes display 300ms
      
  
      Input = (batt_volts);
      myPID.Compute();
      analogWrite(PIN_OUTPUT, Output);
 
      
 }

Try pid.setControllerDirection(REVERSE) in setup().

Thanks for your reply. I have tried this but it did not work for me. In the variables the direction is declared at the start of the sketch with the line - PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);. I think if the direction was the problem ( direction set for DIRECT rather than REVERSE) then the relay led would be on when the battery voltage PV is below the diversion setpoint SP and off when the PV is above the SP. In my case the leds are on when the PV is both above and below the SP. I have tried turning the PID off by putting it to manual ( myPID.SetMode(MANUAL); ) and this works well- the leds stay off however when the pid is turned on (myPID.SetMode( AUTOMATIC); regardless of what I do the relay stays closed / leds on.

Might this be some kind of curly brackets error?

Or possibly I am not defining the battery voltage (batt_volts) and diversion setpoint (div_spt) correctly?

Thanks again

Will

Does your Setpoint never change after setup()? I see you setting it in setup() but not in loop().

For driving a relay there is an example:
File->Examples->PID_v1->Examples->PID_RelayOutput
It sets the Output range to 0-5000 and uses that as the portion of each 5000 millisecond (5 second) interval to activate the relay. The default Output range is 0-255.

Hi John,

Thanks for your reply. The SP will change as the charge controller changes modes. I suspect that i would have run into the problem of the SP not following the mode when I started using the controller.

I have managed to get the controller using the calculations for Input and Setpoint. It looks like I also have Timer1 working and am turning the Mode on or off as the Charge controller mode changes also. Yay.

Thanks for all your help. The first reply stimulated new thought for me and the second reply suggests that the setpoint calculation should be loop() instead of setup().

Thanks for your help.

Will