Word operation in Arduino

Dear all.

I have attached my code below . I have few question here.
http://arduino.cc/en/Reference/WordCast
question are:

  1. I have value latitude 13.08. Here 13 should put in lower byte of word and 08 into higher order of byte address. How to assign it
    2)i have analog sensor which read analog voltage 0-5v . that being converted from +75 deg to -75 degree.
    from 0-75 degree i can read value properly on QMODBUS, But 0 to -75 master varying with 65561 value.How to covert it to -ve value.
  2. IS it possible to assign our own slave address in below code

main code

#define ID   1



Modbus slave(ID, 0, 0);
boolean led;
int8_t state = 0;
unsigned long tempus;
// data array for modbus network sharing
uint16_t au16data[9];

float latitude=13.08;
static int Sensor_Value;
float Yvoltage;
static float ARDUINO_ANALOG_SCALING = 0.00488758;
static float Ydegree;


void setup() {
  // define i/o
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(13, OUTPUT);

  digitalWrite(6, LOW );
  digitalWrite(7, LOW );
  digitalWrite(8, LOW );
  digitalWrite(9, LOW );
  digitalWrite(13, HIGH );
  

  // start communication
  slave.begin( 9600 );

  tempus = millis() + 100;
  digitalWrite(13, HIGH );
}


void loop() {
  // poll messages
  // blink led pin on each valid message
  state = slave.poll( au16data, 9 );
  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > tempus) digitalWrite(13, LOW );

  
  // read analog inputs
  
   Sensor_Value=analogRead(A0); 
  Yvoltage = Sensor_Value * ARDUINO_ANALOG_SCALING;
   Ydegree=(30*Yvoltage)-75;
/*  mySerial.println(Ydegree);
  delay(1000);*/
  au16data[0] = Ydegree;
 //  au16data[1]=latitude;
word(au16data[1],latitude);
//word(au16data[1]);
  // diagnose communication
  au16data[6] = slave.getInCnt();
  au16data[7] = slave.getOutCnt();
  au16data[8] = slave.getErrCnt();
}

modbus1.rar (5.69 KB)

  1. Use simple arithmetic
  2. Use signed data types.

But 0 to -75 master varying with 65561 value

sp. "65461"

I have added these senntense for reading floating value. But i cant read 08, But i can read 13.

#define ID   1
#include<math.h>


Modbus slave(ID, 0, 0);
boolean led;
int8_t state = 0;
unsigned long tempus;
// data array for modbus network sharing
uint16_t au16data[9];

double  latitude=13.08;
static int Sensor_Value;
float Yvoltage;
static float ARDUINO_ANALOG_SCALING = 0.00488758;
static float Ydegree;


void setup() {
  // define i/o
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(13, OUTPUT);

  digitalWrite(6, LOW );
  digitalWrite(7, LOW );
  digitalWrite(8, LOW );
  digitalWrite(9, LOW );
  digitalWrite(13, HIGH );
  

  // start communication
  slave.begin( 9600 );

  tempus = millis() + 100;
  digitalWrite(13, HIGH );
}


void loop() {
  // poll messages
  // blink led pin on each valid message
  state = slave.poll( au16data, 9 );
  if (state > 4) {
    tempus = millis() + 50;
    digitalWrite(13, HIGH);
  }
  if (millis() > tempus) digitalWrite(13, LOW );

  
  // read analog inputs
  
   Sensor_Value=analogRead(A3); 
  Yvoltage = Sensor_Value * ARDUINO_ANALOG_SCALING;
   Ydegree=(30*Yvoltage)-75;
/*  mySerial.println(Ydegree);
  delay(1000);*/
  au16data[0] = Sensor_Value;
  int lat_int=(int)latitude;
  float lat_float=(latitude-lat_int)*1000;
  //Serial.print((lat_float));
  int value=(int)lat_int;
 au16data[1]=lowByte(lat_int);
 au16data[1]=highByte(value);
//   Serial.println( au16data[1]);
  

  au16data[6] = slave.getInCnt();
  au16data[7] = slave.getOutCnt();
  au16data[8] = slave.getErrCnt();
}
#include<math.h>

Isyourspacekeybroken?

static float ARDUINO_ANALOG_SCALING = 0.00488758;
static float Ydegree;

Why are your global variables also static?

  int lat_int=(int)latitude;

The cast is not necessary.

  int value=(int)lat_int;

Casting an int to an int so you can store it in an int is not only not necessary, it’s stupid.

 au16data[1]=lowByte(lat_int);
 au16data[1]=highByte(value);

Storing the byte of one int and the low byte of a copy of the same int is going to result in the whole portion of latitude being stored. The fractional part is discarded.

What are you really trying to do? A float is FOUR bytes.

I wanted to store floating value into The slave address . WHen i call from qmodbus master i should see value in particular register.

au16data[1]=lowByte(lat_int);
 au16data[1]=highByte(value);

As you said how can save in the array buffer, I tried to assign value directly it print only 13 not 08 . i.e 08 is discarded.

As you said how can save in the array buffer

First, define what you want to save. A 4 byte float can not be saved in a 2 byte buffer.

You could, in theory, split the float into two parts, truncate each part to a byte, and store those two bytes, but that is not the direction you are going.

int lat_int=(int)latitude;
  float lat_float=(latitude-lat_int)*1000;
  //Serial.print((lat_float));
  int value=(int)lat_int;
 au16data[1]=lowByte(lat_int);
 au16data[1]=highByte(value);

This piece of code looks like nonsense. What are you trying to do ?

lat_int is the integer part of the floating point number you started with.
lat_float is presumably supposed to be the fractional part, multiplied by 1000

You then make another int copy of lat_int for no obvious reason, and put two copies of it into your byte array. And then you do nothing at all with the fractional part of the number which you calculated.