I have a APC SMC1000-2UC UPS device that has a serial port to connection. The serial port protocol seems that is based on microlink protocol which has not documented. I monitored the communication of the UPC and PC witch UPS deriver has been initialed. I want to detect command of UPS such as shutdown command by a microcontroller-based device. Some information of "https://sites.google.com/site/klaasdc/apc-smartups-decode" site is compatible with things I observed. but calculation of frame checksum and Challenge string calculation don't pass.
Data length of protocol has been set to 32 bytes, So each frame has 35 bytes.
[Msg ID | 32 byte data | 2 byte checksum]
Regarding calculation of challenge frame, the UPS send 0x65 frame ID then 0x68 frame ID, after that the PC response with 0x65 frame ID and UPS send confirmed frame by 0x65 frame ID. based on presented calculation, I think format or Position of Password_1, Header data and two bytes of that has been changed as the protocol has been configured to 32 bytes data. The following frame are a sample of this challenge:
Header frame: 0x00 0a206903fa27090001004000f802fe04fe0940fc1042fc1044fc20f80416fc10 32a6
UPS : 0x65 ffff00010000a0e80000 c0bbb4e1 000001040000001000000004000000000020 7350
UPS : 0x68 000000000000000000000008004c2943000000000966039a063b675601f30000 864f
PC : 0x65 0a 04 8afb65f1 bdf0
UPS : 0x65 ffff000100000eaf62d8 8afb65f1 000001040000001000000004000000000020 6227
How can I satisfy the challenge and checksum type? I try many type of checksum for that data but they not correct.
It may be a bit late, but have you looked at this:
https://github.com/klaasdc/apcups-serial-test
This looks like somebody got pretty far reverse engineering the MicroLink protocol, including the checksum part. The GitHub repo also contains a link to a web page with a protocol description.
Related
I'm trying to write a loader for a file type I have. It's basically a binary file that has a bunch of bootloader ROM data in it(multiple bootloaders). I can parse the file and load all the BLs into the database just fine. My problem is that each bootloader sometimes loads data from inside its address range. So for example, if I load the 3rd bootloader into the database and then examine its code I might see it try to access some data at 0x10 into its own range. When I hover over that 0x10 and or double click it I am taken to 0x10 at the start of the database and not the start of that specific bootloader. Is there any way I can get it to show me what is at 0x10 in its own memory range?
I have each BL in its own code segment.
So I'd basically like each BL segment to act like its own database.
To help explain it better, lets say I have BL1 from 0 - 0x1000, BL2 from 0x1000 - 0x2000 and BL3 from 0x2000 - 0x3000 in the database.
I am using Docklight Scripting to put together a VBScript that communicates with a device via RS232. All the commands are sent in Hex.
When I want to read from the device, I send a 32-bit address, a 16-bit read length, and an 8-bit checksum.
When I want to write to the device, I send a 16-bit data length, the data, followed by an 8-bit checksum.
In Hex, the data that is sent to the device is the following:
AA0001110200060013F81800104D
AA 00 01 11 02 0006 0013F818 0010 4D
(spaced for ease of reading)
AA000111020006 is the protocol header, where:
AA is the Protocol Byte
00 is the Source ID
01 is the Dest ID
11 is the Message Type
02 is the Command Byte
0006 is the Length Byte(s)
The remainder of the string is broken down as follows:
0013F818 is the 32-bit address
0010 is the 16 bit read length
4D is the 8-bit checksum
If the string is not correct, or the checksum is invalid the device replies back with an error string. However, I am not getting an error. The device replies back with the following hex string:
AA0100120200100001000000000100000000000001000029
AA 01 00 12 02 0010 00010000000001000000000000010000 29
(spaced for ease of reading)
Again, the first part of the string (AA00011102) is a part of the protocol header, where:
AA is the Protocol Byte
01 is the Source ID
00 is the Dest ID
12 is the Message Type
02 is the Command Byte
The difference between what is sent to the device, and what the device replies back with is that the length bytes is not a "static" part of the protocol header, and will change based of the request. The remainder of the string is broken down as follows:
0010 is the Length Byte(s)
00010000000001000000000000010000 is the data
29 is the 8-bit Check Sum
The goal is to read a timer that is stored in the NVM. The timer is stored in the upper halves of 60 4-byte NVM words.
The instructions specify that I need to read the first two bytes of each word, and then sum the results.
Verbatim, the instructions say:
Read the NVM elapsed timer. The timer is stored in the upper halves of 60 4-byte words.
Read the first two bytes of each word of the timer. Read the 16 bit values of these locations:
13F800H, 13F804H, 13808H, and continue to 13F8ECH.
Sum the results. Multiply the sum by 409.6 seconds, then divide by 3600 to get the results in hours.
My knowledge of bits, and bytes, and all other things is a bit cloudy. The first thing I need to confirm is that I am understanding the read protocol correctly.
I am assuming that when I specify 0010 as the 16 bit read length, that translates to the 16-bit values that the instructions want me to read.
The second thing I need to understand a little better is that when it tells me to read the first two bytes of each word, what exactly constitutes the first two bytes of each word?
I think what confuses me a little more is that the instructions say the timer is stored in the upper half of the 4 byte word (which to me seems like the first half).
I've sat with another colleague of mine for a day trying to figure out how to make this all work, and we haven't had any consistent results with our trials.
I have looked on the internet to find something that would explain this better in the context being used.
Another worry is that the technical data I am using to accomplish this project isn't 100% accurate in their instructions, and they have conflicting information or skipping information throughout their publication (which is probably close to 1000 pages long).
What I would really appreciate is someone who has a much better understanding of hex / binary to review the instructions I've posted, and provide some feedback on my interpretation of the instructions provided, and provide any information.
I want to measure current fuel level inside my car's fuel tank using OBD2 bluetooth/USB adapter.
When i try to query that PID i got following data as "NO DATA" while at the same time i can check other PIDS like RPM and all data comes fine.
I have small python program which reads its but i am unable to get it.
import serial
#ser = serial.Serial('COM12',38400,timeout=1)
#ser.write("01 2F \r")
#speed_hex = ser.readline().split(' ')
#print speed_hex
#convert hex to decprint ("SpeedHex",speed_hex)
#speed = float(int('0x'+speed_hex[3],0))
#print ('Speed',speed,'Km/h')
ser1 = serial.Serial("COM12",38400,timeout=1)
#ser1.write("ATZ \r")
#ser1.write("ATE0 \r")
#ser1.write("ATL0 \r")
#ser1.write("ATH1 \r")
#ser1.write("ATSP 5 \r")
ser1.write("01 0C \r")
fuel_hex= ser1.readline()
print fuel_hex
#convert to hex to decprint ("FuelHex",fuel_hex)
#fuel = float(int('0x'+fuel_hex[3],0))
#print ("Fuel in Per",fuel)
Can any one suggest here how to get fuel level which is their inside in car at this current time. As i can see in my panel with bar sign.
In order to get all the available PIDs in a vehicle, you have to request the following PIDs at first exactly like you ask the rpm of the vehicle:
0x00, 0x20, 0x40, ....0x80 and so on.
For instance when you request PID 0x00 the ECU will return you 4 bytes which means if it supports PIDs from 0x01 - 0x20. Each byte has 8 bits in total of 32 bits which is exactly from PID 0x01 to PID 0x20. Now it is time to parse the data. If each bit is 1 it means the ECU will support and 0 no support. It is your duty to do some bitwise operations to translate these bits:
Also you can look out this Wikipedia link which shows in graphics!
byte 1 bit 1 : availability of PID 0x01
byte 1 bit 2 : availability of PID 0x02
byte 1 bit 3 : availability of PID ox03
....
byte 4 bit 7 : availability of PID 0x1F
byte 4 bit 8 : availability of PID 0x20 --> Here the ECU tells you if support any PIDs in next 32 PIDs. If it is 0, you do not need to check anymore!
After parsing and gathering all the supported PIDs, then you can have a roadmap to calculate or check each PIDs you want. Do not forget many of conversion rates a formulas in wikipedia is wrong due to the complexity of calculations. You have to read the ISO 15031 part 5 and do NOT forget ECU only gives you the emissions-related diagnostics and not all the data.
I'am new in read binary files, sorry for mistakes. I have a problem with read ELF header with bless editor. First I read first 4 bytes and I do this. First 4 bytes tells it's ELF file or not
and this is ok for me. Next I want read 0x04 address wikipedia says about this address This byte is set to either 1 or 2 to signify 32- or 64-bit format, respectively. and where can I find this address on my screen?
I Have a project using a 240 bit Octal data format that will be coming in the serial port of Arduino uno at 2.4K RS232 converted to TTL.
The 240 bits along with other things has range, azimuth and elevation words, which is what I need to display.
The frame starts with a frame sync code wich is an alternating binary 7 bit code which is:
1110010 for frame 1 and
0001101 for frame 2 and so on.
I was thinking that I might use something like val = serial.read command like
if (val = 1110010 or 0001101) { data++val; }`
that will let me validate the start of my sting.
The rest of the 240 bit octal frame (all numbers) can be serial read to a string of which only parts will be needed to be printed to the screen.
Past the frame sync, all octal data is serial with no Nulls or delimiters so I am thinking
printf("%.Xs",stringname[xx]);
will let me off set the characters as needed so they can be parsed out.
How do I tell the program that the frame sync its looking for is binary or that the data that needs to go into the string is octal, or that it may need to be converted to be read on the screen?