BBK1AVW.ino、BBK1AVWCom.ino
控制代码:BBK1AVW.ino
//===============================================================
#include <SoftwareSerial.h>
SoftwareSerial myAvw(A5,A3);//RX,TX
long AVWTime = millis(), AVWTimeKey = 1000;
//===============================================================
int Volt = 10,Watt = 20;
float Amps = 0.1,Kwhs = 40.5,Pfss = 1,Cabn = 1;
//===============================================================
int retval,data[10],tt[30]; //int changed to unsigned int
//===============================================================
void AVW_Setup(){
Serial.print("AVW_Setup......");
myAvw.begin(4800);
delay(2000);
Serial.println("OK!");
}
//===============================================================
void AVW_Loop(bool showkey) {
//-------------------------------------------------------------
if( millis() - AVWTime < AVWTimeKey) return;
AVWTime = millis();
//-------------------------------------------------------------
Serial.print("AVW_Read_ON.....");
retval = read_holding_registers(1, 0x49, 6, tt, 1);
Serial.println("OFF");
//-------------------------------------------------------------
Volt = tt[0];
Volt = Volt / 100;
Amps = tt[1];
Amps = Amps / 1000;
Watt = tt[2];
unsigned int Kwhh = (unsigned int)tt[3];
unsigned int Kwhl = (unsigned int)tt[4];
unsigned long kwhA = (unsigned long) Kwhh *65536 + Kwhl;
Kwhs = kwhA;
Kwhs = Kwhs / 3200;
Pfss = tt[5];
Pfss = Pfss / 1000;
Cabn = tt[5];
Cabn = Cabn / 1000;
//-------------------------------------------------------------
if(showkey){
Serial.print("Volt = ");Serial.println(Volt);
Serial.print("Amps = ");Serial.println(Amps);
Serial.print("Watt = ");Serial.println(Watt);
Serial.print("Kwhs = ");Serial.println(Kwhs);
Serial.print("Pfss = ");Serial.println(Pfss);
Serial.print("Cabn = ");Serial.println(Cabn);
}
//-------------------------------------------------------------
}
//===============================================================
读取代码:BBK1AVWCom.ino
/* Modbus para */
//int retval;
//int data[10];
//int tt[30]; //int changed to unsigned int
/****************************************************************************
* BEGIN MODBUS RTU MASTER FUNCTIONS
****************************************************************************/
//#define TIMEOUT 1000 /* 1 second */
#define TIMEOUT 10000 /* 10 second */
#define MAX_READ_REGS 125
#define MAX_WRITE_REGS 125
#define MAX_RESPONSE_LENGTH 256
#define PRESET_QUERY_SIZE 256
/* errors */
#define PORT_ERROR -5
/*
CRC
INPUTS:
buf -> Array containing message to be sent to controller.
start -> Start of loop in crc counter, usually 0.
cnt -> Amount of bytes in message being sent to controller/
OUTPUTS:
temp -> Returns crc byte for message.
COMMENTS:
This routine calculates the crc high and low byte of a message.
Note that this crc is only used for Modbus, not Modbus+ etc.
****************************************************************************/
unsigned int crc(unsigned char *buf, int start, int cnt)
{
int i, j;
unsigned temp, temp2, flag;
temp = 0xFFFF;
for (i = start; i < cnt; i++) {
temp = temp ^ buf[i];
for (j = 1; j <= 8; j++) {
flag = temp & 0x0001;
temp = temp >> 1;
if (flag)
temp = temp ^ 0xA001;
}
}
/* Reverse byte order. */
temp2 = temp >> 8;
temp = (temp << 8) | temp2;
temp &= 0xFFFF;
return (temp);
}
/***********************************************************************
*
* The following functions construct the required query into
* a modbus query packet.
*
***********************************************************************/
#define REQUEST_QUERY_SIZE 6 /* the following packets require */
#define CHECKSUM_SIZE 2 /* 6 unsigned chars for the packet plus */
/* 2 for the checksum. */
void build_request_packet(int slave, int function, int start_addr,
int count, unsigned char *packet)
{
packet[0] = slave;
packet[1] = function;
start_addr -= 1;
packet[2] = start_addr >> 8;
packet[3] = start_addr & 0x00ff;
packet[4] = count >> 8;
packet[5] = count & 0x00ff;
//below test only
// packet[0] =0x01;
// packet[1] = 0x03;
// packet[2] = 0;
// packet[3] = 0x48;
// packet[4] = 0;
// packet[5] = 0x02;
}
/*************************************************************************
*
* modbus_query( packet, length)
*
* Function to add a checksum to the end of a packet.
* Please note that the packet array must be at least 2 fields longer than
* string_length.
**************************************************************************/
void modbus_query(unsigned char *packet, size_t string_length)
{
int temp_crc;
temp_crc = crc(packet, 0, string_length);
packet[string_length++] = temp_crc >> 8;
packet[string_length++] = temp_crc & 0x00FF;
packet[string_length] = 0;
}
/***********************************************************************
*
* send_query(query_string, query_length )
*
* Function to send a query out to a modbus slave.
************************************************************************/
int send_query(unsigned char *query, size_t string_length)
{
int i;
modbus_query(query, string_length);
string_length += 2;
for (i = 0; i < string_length; i++) {
myAvw.write(query[i]); //JingLi
}
/* without the following delay, the reading of the response might be wrong
* apparently, */
delay(200); /* FIXME: value to use? */
return i; /* it does not mean that the write was succesful, though */
}
/***********************************************************************
*
* receive_response( array_for_data )
*
* Function to monitor for the reply from the modbus slave.
* This function blocks for timeout seconds if there is no reply.
*
* Returns: Total number of characters received.
***********************************************************************/
int receive_response(unsigned char *received_string)
{
int bytes_received = 0;
int i = 0;
/* wait for a response; this will block! */
while(myAvw.available() == 0) {
delay(1);
if (i++ > TIMEOUT)
return bytes_received;
}
delay(200);
/* FIXME: does myAvw.available wait 1.5T or 3.5T before exiting the loop? */
while(myAvw.available()) {
received_string[bytes_received] = myAvw.read();
bytes_received++;
if (bytes_received >= MAX_RESPONSE_LENGTH)
return PORT_ERROR;
}
return (bytes_received);
}
/*********************************************************************
*
* modbus_response( response_data_array, query_array )
*
* Function to the correct response is returned and that the checksum
* is correct.
*
* Returns: string_length if OK
* 0 if failed
* Less than 0 for exception errors
*
* Note: All functions used for sending or receiving data via
* modbus return these return values.
*
**********************************************************************/
int modbus_response(unsigned char *data, unsigned char *query)
{
int response_length;
int i;
unsigned int crc_calc = 0;
unsigned int crc_received = 0;
unsigned char recv_crc_hi;
unsigned char recv_crc_lo;
do { // repeat if unexpected slave replied
response_length = receive_response(data);
}
while ((response_length > 0) && (data[0] != query[0]));
if (response_length) {
crc_calc = crc(data, 0, response_length - 2);
recv_crc_hi = (unsigned) data[response_length - 2];
recv_crc_lo = (unsigned) data[response_length - 1];
crc_received = data[response_length - 2];
crc_received = (unsigned) crc_received << 8;
crc_received =
crc_received | (unsigned) data[response_length - 1];
/*********** check CRC of response ************/
if (crc_calc != crc_received) {
response_length = 0;
}
/********** check for exception response *****/
if (response_length && data[1] != query[1]) {
response_length = 0 - data[2];
}
}
return (response_length);
}
/************************************************************************
*
* read_reg_response
*
* reads the response data from a slave and puts the data into an
* array.
*
************************************************************************/
int read_reg_response(int *dest, int dest_size, unsigned char *query)
{
unsigned char data[MAX_RESPONSE_LENGTH];
int raw_response_length;
int temp, i;
raw_response_length = modbus_response(data, query);
if (raw_response_length > 0)
raw_response_length -= 2;
if (raw_response_length > 0) {
/* FIXME: data[2] * 2 ???!!! data[2] isn't already the byte count (number of registers * 2)?! */
for (i = 0;
i < (data[2] * 2) && i < (raw_response_length / 2);
i++) {
/* shift reg hi_byte to temp */
temp = data[3 + i * 2] << 8;
/* OR with lo_byte */
temp = temp | data[4 + i * 2];
dest[i] = temp;
}
}
return (raw_response_length);
}
/***********************************************************************
*
* preset_response
*
* Gets the raw data from the input stream.
*
***********************************************************************/
int preset_response(unsigned char *query)
{
unsigned char data[MAX_RESPONSE_LENGTH];
int raw_response_length;
raw_response_length = modbus_response(data, query);
return (raw_response_length);
}
/************************************************************************
*
* read_holding_registers
*
* Read the holding registers in a slave and put the data into
* an array.
*
*************************************************************************/
int read_holding_registers(int slave, int start_addr, int count,
int *dest, int dest_size)
{
int function = 0x03; /* Function: Read Holding Registers */
int ret;
unsigned char packet[REQUEST_QUERY_SIZE + CHECKSUM_SIZE];
if (count > MAX_READ_REGS) {
count = MAX_READ_REGS;
}
build_request_packet(slave, function, start_addr, count, packet);
if (send_query(packet, REQUEST_QUERY_SIZE) > -1) {
ret = read_reg_response(dest, dest_size, packet);
}
else {
ret = -1;
}
return (ret);
}
/************************************************************************
*
* preset_multiple_registers
*
* Write the data from an array into the holding registers of a
* slave.
*
*************************************************************************/
int preset_multiple_registers(int slave, int start_addr,
int reg_count, int *data)
{
int function = 0x10; /* Function 16: Write Multiple Registers */
int byte_count, i, packet_size = 6;
int ret;
unsigned char packet[PRESET_QUERY_SIZE];
if (reg_count > MAX_WRITE_REGS) {
reg_count = MAX_WRITE_REGS;
}
build_request_packet(slave, function, start_addr, reg_count, packet);
byte_count = reg_count * 2;
packet[6] = (unsigned char)byte_count;
for (i = 0; i < reg_count; i++) {
packet_size++;
packet[packet_size] = data[i] >> 8;
packet_size++;
packet[packet_size] = data[i] & 0x00FF;
}
packet_size++;
if (send_query(packet, packet_size) > -1) {
ret = preset_response(packet);
}
else {
ret = -1;
}
return (ret);
}
更新日期: 2014-11-05 10:56:47
文章标签:
文章链接: BBK1AVW.ino、BBK1AVWCom.ino
站方声明: 除特别标注, 本站所有文章均为原创, 互联分享, 尊重版权, 转载请注明.
文章标签:
文章链接: BBK1AVW.ino、BBK1AVWCom.ino
站方声明: 除特别标注, 本站所有文章均为原创, 互联分享, 尊重版权, 转载请注明.