View previous topic :: View next topic |
Author |
Message |
hssn601
Joined: 31 Jan 2014 Posts: 20
|
Communicating with energy meter on MODBUS with P24FJ64GA004 |
Posted: Tue Apr 22, 2014 7:28 am |
|
|
I am trying to communicate with
http://www.powerlogic.com/literature/63230-501-209.pdf
What i want to achieve is to read register values of energy meter.
I want some help from where i should start.
I have seen CCS modbus master example but here i only find the following functions:
Code: |
read_all_coils();
read_all_inputs();
read_all_holding();
read_all_input_reg();
|
Ii just want to read some register values of energy meter.
I know nobody have time to give me a code i just want to know from where should i start as i am new to modbus protocol.
Thanks..
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Tue Apr 22, 2014 7:54 am |
|
|
I've never used Modbus but I believe 'coils' is their term for 'registers'.
I downloaded your meter spec sheet and in the 'register' lists there are several 'registers'. I'm of the opinion that if you specify and read those 'addresses', you'll get the data back(some are 1 byte, some 2 bytes).
This is only a quick reply, I'm sure those that use Modbus on a daily basis can explain in better details.
hth
jay |
|
|
notbad
Joined: 10 Jan 2013 Posts: 68
|
|
Posted: Tue Apr 22, 2014 8:56 am |
|
|
It's easy. Use function "modbus_read_holding_registers". To make it simple, read only one register.
modbus_read_holding_registers(unsigned int8 address, unsigned int16 start_address, unsigned int16 quantity)
"address" is your station address. "start_address" is the address of the register you want to read. For "quantity" enter 1.
Response value will be in array "modbus_rx.data". |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Tue Apr 22, 2014 12:56 pm |
|
|
One other critical thing to remember.
Floating point numbers from this will be in IEEE format. IEEEFLOAT.C contains the code to convert these.
Best Wishes |
|
|
hssn601
Joined: 31 Jan 2014 Posts: 20
|
|
Posted: Tue Apr 22, 2014 11:52 pm |
|
|
notbad wrote: | It's easy. Use function "modbus_read_holding_registers". To make it simple, read only one register.
modbus_read_holding_registers(unsigned int8 address, unsigned int16 start_address, unsigned int16 quantity)
"address" is your station address. "start_address" is the address of the register you want to read. For "quantity" enter 1.
Response value will be in array "modbus_rx.data". |
ok let suppose i want to read value of register 4000
device address is 0x08
then some thing like this will work?
modbus_read_holding_registers(0x08, 4000, 1)
? |
|
|
notbad
Joined: 10 Jan 2013 Posts: 68
|
|
Posted: Wed Apr 23, 2014 4:46 am |
|
|
hssn601 wrote: |
then some thing like this will work?
modbus_read_holding_registers(0x08, 4000, 1)
|
Yes. But make sure the register address' base is correct. You may have to use 0x4000. Your spec sheet didn't mention the decimal/hex. Or I didn't see it. |
|
|
hssn601
Joined: 31 Jan 2014 Posts: 20
|
My code |
Posted: Wed Apr 23, 2014 4:46 am |
|
|
I have made the following code to read register values but i am getting
Warnings:
[img]s15.postimg.org/5w5m878a3/screenshot_21.png[/img]
http://s15.postimg.org/5w5m878a3/screenshot_21.png
Here is my code:
Main:
Code: | #include <24FJ64GA004.h>
#include "system.h"
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#build(stack =512)
#ZERO_RAM
int i;
static int1 send;
int8 swap_bits(int8 c)
{
return ((c&1)?128:0)|((c&2)?64:0)|((c&4)?32:0)|((c&8)?16:0)|((c&16)?8:0)
|((c&32)?4:0)|((c&64)?2:0)|((c&128)?1:0);
}
void Boot_MSG()
{
fprintf( SERIAL1, "\r\nUART1: OK");
fprintf( MODBUS_SERIAL, "\r\nUART3 OK!:) ");
fprintf( SERIAL2, "\r\nUART2 OK!:) ");
}
void main()
{
Boot_MSG();
enable_interrupts(INT_RDA2);
setup_adc_ports(NO_ANALOGS);
fprintf( SERIAL2, "\r\nInitializing...");
modbus_init();
modbus_init();
delay_ms(200);
fprintf( SERIAL2, "...ready\r\n");
while(true){
if(send){
send=0;
fprintf( SERIAL2, "...Sending\r\n");
if(!(modbus_read_holding_registers(MODBUS_SLAVE_ADDRESS,10,1)))
{
fprintf( SERIAL2, "Data: ");
for(i=1; i < (modbus_rx.len); ++i){
fprintf( SERIAL2, "%X ", modbus_rx.data[i]);
}
fprintf( SERIAL2, "\r\n\r\n");
}
else{fprintf( SERIAL2, "\r\n No Data Rcvd");}
}
}
}
#int_RDA2
void RDA2_isr(void)
{
if(fgetc(SERIAL2)=='1'){send=1;fprintf( SERIAL2, "\r\n Valid Command");}
}
|
System.h:
Code: | #FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOCKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES PR //Primary Oscillator
#FUSES PROTECT //Code protected from reads
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES ICSP1 //ICD uses PGC1/PGD1 pins
#FUSES WINDIS //Watch Dog Timer in non-Window mode
#FUSES WDT128 //Watch Dog Timer PreScalar 1:128 > 128
#FUSES WPOSTS10 //Watch Dog Timer PostScalar 1:32768 > 512
#FUSES NOWDT //Watchdog time=2.11 Sec
#use delay(clock=20000000)
#byte RCSTA1 = 0x222
#byte RCSTA2 = 0x232
#byte U1MODE = 0x220
#byte U2MODE = 0x230
#byte U1RXREG = 0x226
#byte U2RXREG = 0x236
#bit OERR1 = RCSTA1.1
#bit OERR2 = RCSTA2.1
#bit UART1EN = U1MODE.15
#bit UART2EN = U2MODE.15
#bit FERR1 = RCSTA1.2
#bit FERR2 = RCSTA2.2
#bit RC1IF = RCSTA1.0
#bit RC2IF = RCSTA2.0
//#define DIR_485 PIN_B12
#define RXD2 PIN_C0
#define TXD2 PIN_C1
#define CTS_FROM_UC PIN_C4
#define CTS_FROM_MCW PIN_C5
#define CS_MMC PIN_C6
#pin_select U1TX=PIN_C3
#pin_select U1RX=PIN_C2
#pin_select U2TX=PIN_C1
#pin_select U2RX=PIN_C0
#use standard_io(B)
#use standard_io(C)
#define DIR_485_IN() output_bit( DIR_485, 0)
#define DIR_485_OUT() output_bit( DIR_485, 1)
#use rs232(UART1,baud=19200,parity=N,bits=8,stream=SERIAL1,errors)
#use rs232(UART2,baud=19200,parity=N,bits=8,stream=SERIAL2,errors)
#use i2c(Master,Fast,sda=PIN_B5,scl=PIN_B6,restart_wdt)
#define MODBUS_TYPE MODBUS_TYPE_MASTER
#define MODBUS_SERIAL_TYPE MODBUS_RTU //use MODBUS_ASCII for ASCII mode
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_SERIAL_TX_PIN PIN_A10 // Data transmit pin
#define MODBUS_SERIAL_RX_PIN PIN_B13
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_EXT
#define MODBUS_SERIAL_ENABLE_PIN PIN_B12 // Controls DE pin for RS485
#define MODBUS_SERIAL_RX_ENABLE PIN_B12
//#define MODBUS_SERIAL_INT_SOURCE MODBUS_int_RDA
#include <modbus.c>
#define MODBUS_SLAVE_ADDRESS 0x01 |
Last edited by hssn601 on Thu Apr 24, 2014 1:41 am; edited 3 times in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Wed Apr 23, 2014 4:54 am |
|
|
Even though I don't use Modbus, I'd suggest you code a complete program, using the CCS supplied example as a 'template'.
While your incomplete code 'snippet' might look OK to some,unless a complete, small program is shown, no one can really test it.
As you're new ..we have no way of knowing IF your hardware(PIC,rs-485 I/F, etc. ) is built and wired correctly.
It is very,very difficult to debug in a forum without knowing the hardware works! Usually you code the simple '1Hz LED type program' first,get it 100% working, then code the 'Hello PC' program, then the 'Hello LCD' program.These 3 simple programs can quickly confirm both your hardware and software are working right.Only then should you proceed with the 'real' program.Taken in steps, the project will go fast,usually in less than a week.
hth
jay |
|
|
notbad
Joined: 10 Jan 2013 Posts: 68
|
|
Posted: Wed Apr 23, 2014 4:57 am |
|
|
I get those warning too. I don't know exactly what problems they might cause, but my circuit works.
BTW, I use hardware UART and ASCII mode. I don't know if that makes a difference.
Last edited by notbad on Wed Apr 23, 2014 5:03 am; edited 1 time in total |
|
|
hssn601
Joined: 31 Jan 2014 Posts: 20
|
|
Posted: Wed Apr 23, 2014 5:00 am |
|
|
temtronic wrote: | Even though I don't use Modbus, I'd suggest you code a complete program, using the CCS supplied example as a 'template'.
While your incomplete code 'snippet' might look OK to some,unless a complete, small program is shown, no one can really test it.
As you're new ..we have no way of knowing IF your hardware(PIC,rs-485 I/F, etc. ) is built and wired correctly.
It is very,very difficult to debug in a forum without knowing the hardware works! Usually you code the simple '1Hz LED type program' first,get it 100% working, then code the 'Hello PC' program, then the 'Hello LCD' program.These 3 simple programs can quickly confirm both your hardware and software are working right.Only then should you proceed with the 'real' program.Taken in steps, the project will go fast,usually in less than a week.
hth
jay |
the hardware i am using works fine as i have to integrate mod bus in existing firmware so i have just erased the rest of things to make mod bus work.
basically i have a device which collects data from sensors and then transmit over WiFi now i have to add that energy meter with existing program and read values from register and then transmit over WiFi..
what i want to achevie is to communicate with energy meter .
Last edited by hssn601 on Wed Apr 23, 2014 6:18 am; edited 1 time in total |
|
|
hssn601
Joined: 31 Jan 2014 Posts: 20
|
|
Posted: Wed Apr 23, 2014 5:02 am |
|
|
notbad wrote: | I get those warning too. I don't know exactly what problems they might cause, but my circuit works.
BTW, I use hardware UART and I don't know if that makes a difference. |
hmm ok i'll try it on real hardware.
i am using mod bus protocol first time that's why i am worried. |
|
|
hssn601
Joined: 31 Jan 2014 Posts: 20
|
|
Posted: Wed Apr 23, 2014 6:10 am |
|
|
i am using MAX3843 to use 485
here is schematic
and in code i have defined in this way
Code: | #define MODBUS_SERIAL_ENABLE_PIN PIN_B12 // Controls DE pin for RS485
#define MODBUS_SERIAL_RX_ENABLE PIN_B12 |
|
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Wed Apr 23, 2014 8:14 am |
|
|
temtronic wrote: | I've never used Modbus but I believe 'coils' is their term for 'registers'. |
A modbus coil is a BIT value and the term is a leftover from the days of relay logic where energizing a coil meant turning on a relay. Coils can be read and written to. A coil might also map to a bit position in a modbus register. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
notbad
Joined: 10 Jan 2013 Posts: 68
|
|
Posted: Wed Apr 23, 2014 2:25 pm |
|
|
hssn601 wrote: | i am using MAX3843 to use 485
here is schematic
...
and in code i have defined in this way
Code: | #define MODBUS_SERIAL_ENABLE_PIN PIN_B12 // Controls DE pin for RS485
#define MODBUS_SERIAL_RX_ENABLE PIN_B12 |
|
What's the question?
Code is good.
Circuit is correct although I think you can test in your workbench with a short wire without those diodes and resistor.
Don't forget to add a pull-up on RX. |
|
|
hssn601
Joined: 31 Jan 2014 Posts: 20
|
|
Posted: Thu Apr 24, 2014 1:50 am |
|
|
notbad wrote: | hssn601 wrote: | i am using MAX3843 to use 485
here is schematic
...
and in code i have defined in this way
Code: | #define MODBUS_SERIAL_ENABLE_PIN PIN_B12 // Controls DE pin for RS485
#define MODBUS_SERIAL_RX_ENABLE PIN_B12 |
|
What's the question?
Code is good.
Circuit is correct although I think you can test in your workbench with a short wire without those diodes and resistor.
Don't forget to add a pull-up on RX. |
see my updated code every thing seems fine but i am unable to communicate with device.
if i run this code then it transmits the following HEX packet
[01 03 00 0A 00 01 A4 08 ] on software serial port
which i think is fine but i am getting no response from device.
Last edited by hssn601 on Thu Apr 24, 2014 2:01 am; edited 1 time in total |
|
|
|