EKM-Omnimeter RS-485 Data

For more advanced meter data users. Learn from others and ask questions about how to read meters, how to use the EKM Push Data, and how to display the meter data in useful ways.
Jameson
Posts: 860
Joined: Fri Nov 04, 2011 7:42 pm
Location: Santa Cruz, CA
Contact:

Re: EKM-Omnimeter RS-485 Data

Post by Jameson »

Hello Daniel,

Yes, I think using a MAX485 should work (you will want to make sure you play with the terminating and biasing resistor values). If you can get the data to look like the data in your "Mon Jan 25, 2016 10:37 am" post, then you will be on the right track.

Do you have a USB port? If so, I would recommend our USB converter, then once you get your Arduino talking to the meter via the USB converter you can switch the code to talk over the UART TTL to MAX485 transceiver. This way you are only tackling one issue at a time.

Best,
Jameson
EKM METERING
http://www.ekmmetering.com
831.425.7371
Daniel_Ch
Posts: 6
Joined: Mon Jan 11, 2016 12:02 pm

Re: EKM-Omnimeter RS-485 Data

Post by Daniel_Ch »

Good evening Jameson,

This is my serial monitor reading (ASCII),

¯?0000000±39±9!�

‚�0000000±39±9066´5²±²03995²²·0²6´99¸5000000000000000000003±²90000±¸300000±²990000000000000000±±¸·±±¸¸00000²¸´0030²´00000003±±¸03±²00006²00²0²0000·0±6±¸56±²´0000000000000000000000000000000!
6�B0 õ�

and this is HEX conversion, (I'm still working on HEX printing), my meter is 13919, as you can see the address is wrong by b1,
Static ?

af 3f 30 30 30 30 30 30 30 b1 33 39 b1 39 21 fffd
0a
fffd
0a
201a fffd 17 14 30 30 30 30 30 30 30 b1 33 39 b1 39
30 36 36 b4 35 b2 b1 b2 30 33 39 39 35 b2 b2 b7
30 b2 36 b4 39 39 b8 35 30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30 30 30 30 30 33 b1 b2 39
30 30 30 30 b1 b8 33 30 30 30 30 30 b1 b2 39 39
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
b1 b1 b8 b7 b1 b1 b8 b8 30 30 30 30 30 b2 b8 b4
30 30 33 30 b2 b4 30 30 30 30 30 30 30 33 b1 b1
b8 30 33 b1 b2 30 30 30 30 36 b2 30 30 b2 30 b2
30 30 30 30 b7 30 b1 36 b1 b8 35 36 b1 b2 b4 30
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30 30 30 30 30 30 30 21
0a
36 fffd 42 30 20 f5 fffd

Remember that I'm getting data from meter and push system, I think that my reading is
*request
*data
*close string,

My data are only about 191 bytes, is this possible ?, I mean any configuration ? (I didn't install the ommimeter)
Daniel_Ch
Posts: 6
Joined: Mon Jan 11, 2016 12:02 pm

Re: EKM-Omnimeter RS-485 Data

Post by Daniel_Ch »

I think arduino is reading 8 Bits data because of the b1 (+-), it is not 7 bits symbol.
Jameson
Posts: 860
Joined: Fri Nov 04, 2011 7:42 pm
Location: Santa Cruz, CA
Contact:

Re: EKM-Omnimeter RS-485 Data

Post by Jameson »

Thanks for the Hex return. I would either suspect bad Serial Settings or bad terminating resistor and biasing resistor values. Your data looks garbled.

Are you still reading through your UART port? I would still suggest you read through a USB port if you have one.

I dont know what you mean by : "b1 (+-), it is not 7 bits symbol."
Jameson
EKM METERING
http://www.ekmmetering.com
831.425.7371
nielo
Posts: 10
Joined: Wed Aug 27, 2014 7:45 pm

Re: EKM-Omnimeter RS-485 Data

Post by nielo »

The crc calculation for EKM meters is pretty confusing so I thought I'd post a routine for Arduino to help anyone who needs it.
You should be able to copy what's below and paste it into your sketch without modification.
The only thing you'll need to add is a global character array declared as "char crcCalculated[2]".

One last thought that is unrelated:
If you need to print (om maybe save it to an SD card) the data passed to this
routine (or any other HEX data) with 2 characters per byte ("0A" as opposed to "A")
the easiest way is something like this:

for (int i = 0; i < sizeof(WhateverArray); i++) {
if (WhateverArray <= 15) Serial.write('0'); // Leading "0"
Serial.print(WhateverArray, HEX);
Serial.write(' ');
}


/******************** copy and paste below stuff ************************/

/*
Arduino version of building a CRC for EKM meters. (ModBus 16bit CRC).
This will fill in the global array "char crcCalculated[2]" with the CRC calculated from the passed
information.
if the calculated CRC matches the CRC in the passed array this routine returns TRUE, else
Returns FALSE.

Finally, because this was designed to check the CRC contained in a message received from an EKM meter,
the first byte of the message (0x02, Ascii STX = "Start Of Text") is not included in the CRC calculation.
Also, the last two bytes of the message are the CRC calculated by the meter and are not
included in the calculation, but they should match the crc calculated by this routine.

SOOO, if you need to calculate a CRC from something other than a message received from an
EKM meter you should pass an array with the first byte and the last 2 bytes as dummies.
For instance, if you want to send a message to an EKM meter with the correct crs, add a byte to the beginning
of the message and add two bytes to the end, then send the result to this routine. After this routine executes
the calculated crc will be contained in the crcCalculated array.

Finally, just for clarity, with the Arduino compiler arrays are always 0 based so, an array of 255 characters runs
from 0 to 254.

*/
boolean generateCRC(char ar[], int x) {
// "ar" is an array and should (for an EKM meter) contain 255 characters.
// The received character count is passed in x (and should be 255 for an EKM meter).
// crcCalculated is a global array used to save the CRC calculated by this routine so it may be
// used elsewhere (if necessary).

char crcCheck[2];// Used to hold the passed crc
unsigned int b;
unsigned int crc = 0xFFFF; // Eventuall holds calculated crc

// Save passed crc
crcCheck[0] = ar[x - 2];
crcCheck[1] = ar[x - 1];

// Calculate crc
for (int i = 1; i < (x - 2); i++) {
b = ar;
crc ^= b;
for (int c = 8; c != 0; c--) {
if ((crc & 0x0001) != 0) {
crc >>= 1;
crc ^= 0xA001;
} else {
crc >>= 1;
}
}
}

// Keep just the lowest 7 bits of both bytes
crcCalculated[0] = crc & 0x7F;
crcCalculated[1] = (crc >> 8) & 0x7F;

// If everything is ok return true, else return false
if ((crcCalculated[0] == crcCheck[0]) && (crcCalculated[1] == crcCheck[1])) {
return true;
} else {
return false;
}
} //End of routine
Post Reply