Using two 16-bit output to get one 32 bit integer

Hello all,

Could anyone give me an example of how to convert a 32-bit integer into two 16bits? I am trying to send a negative value through Modbus TCP input register. My code works great just the input register won't show a negative value, instead shows some really big value when the Arduino updates a negative value.

I know this is not an Arduino issue, but was hoping someone could help me with this. This is the library I used.

Thank you

Gijo

My code works great

What code?

#include <ModbusIP.h>
#include <Modbus.h>
#include <Ethernet.h>
#include <SPI.h>

int PULC = 7; //define Pulse pin
int DIRC = 6; //define Direction pin
int ENAC = 5; //define Enable pin
float nC = 0;     
float pC = 0;    // variable for pot in center

int PULP = 2; //define Pulse pin
int DIRP = 3; //define Direction pin
int ENAP = 4; //define Enable pin
float nP = 0;
float pP = 0;   // variable for pot in power

int power;
int power_zero;

int center;
int center_zero;

int potC = A0;                    // set analog pin A0 for pot for center
int valC = 0;                     // variable to read from pot 
int potP = A1;                     // same for power
int valP = 0;         

const int power_hr = 100;       // makeing a holding register at 30101 for power value
const int center_hr = 105;      // making a holding register at 30106 for center values

const int valC_ir = 110;        // making a input register for pot pin center
const int valP_ir = 115;        // making a input register for pot pin power

ModbusIP mb;                    // Modbus IP object

void setup() 
{
  Serial.begin(9600);

  pinMode (PULC, OUTPUT);           // set all pins as output pins
  pinMode (DIRC, OUTPUT);
  pinMode (ENAC, OUTPUT);
  pinMode (PULP, OUTPUT);
  pinMode (DIRP, OUTPUT);
  pinMode (ENAP, OUTPUT);
  
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  byte ip[]  = {192, 168, 1, 120};

  mb.config(mac, ip);  // config MODBUS IP

  mb.addHreg(power_hr);             // adding the holding register for power
  mb.addHreg(center_hr);            //      same for center
  mb.addIreg(valC_ir);              // input register for center
  mb.addIreg(valP_ir);               // input register for power
  
  power_zero = 5;                 // Hard coding the zero power value
  power = 5;

  center_zero = 0;                // Hard coding the zero center value
  center = 0;
  potC = 0;

  mb.Hreg(power_hr, power);
  mb.Hreg(center_hr, center);
  mb.Ireg(valC_ir, potC); 
  mb.Ireg(valP_ir, valP);
  
}

void loop() 
{
  mb.task();
  power = mb.Hreg(power_hr);
  center = mb.Hreg(center_hr);
  
  if (power != power_zero)
  {
    moveinpower();
  }
  if (center != center_zero)
  {
    moveincenter();
  }
  delay(1000);
  valC = analogRead(potC);          // read the center pot pin
  valP = analogRead(potP);          // read the power pot pin

  pC = map(valC, 0, 1023, -75,75);
  pP = map(valP, 0, 1023, -75, 75);
  
  mb.Ireg(valC_ir, pC);
  mb.Ireg(valP_ir, pP);
  /*Serial.print("Center Pot value: ");
  Serial.println(pC);                              // for debugging
  Serial.print("Power Pot value: ");
  Serial.println(pP);                              // for debugging   */
}

void moveincenter()
{
       
}
 
 void moveinpower()
{
  
}

I am trying to get a negative value to output in the input registry.

The Arduino sends the correct value but since a negative value uses 32bits, can I maybe send two 16bit values into Modbus and maybe it can output a negative value?

There are two generally accepted ways of splitting integers.

  1. Shifting

uint32_t big_number = something;
uint16_t low_order_byte = big_number & 0xFFFF;
uint16_t high_order_byte = big_number >> 16;

  1. Union

union
{
uint32_t big_number;
struct
{
uint16_t low_order_byte;
uint16_t high_order_byte;
};
} new_name;

Assign new_name.big_number = something;
Then new_name.low_order_byte is the low order byte and new_name.high_order_byte is the high order byte.

The main difference being is that the shift operation has to be done explicitly while the union can be used repeatedly.