• Steel Soldiers now has a few new forums, read more about it at: New Munitions Forums!

  • Microsoft MSN, Live, Hotmail, Outlook email users may not be receiving emails. We are working to resolve this issue. Please add support@steelsoldiers.com to your trusted contacts.

AMMPS Generator Series Remote Data

kloppk

Well-known member
Steel Soldiers Supporter
2,135
3,506
113
Location
Pepperell, Massachusetts
Your "Z" issue may be due to a noise or signal level issue on the 485 data. I ran into an issue with the 485 levels being too low causing issues. Once the levels were corrected data became consistant.

Is your Pyserial interface using a hadware UART or is it a bit basher serial port emulator?
 

Icesythe7

Active member
147
223
43
Location
Indiana, USA
Depending on how decent you are at bitwise operators or coding style I find something like

C++:
// Bus Frequency Row 12
int Pval = (DCSParams[12][5] << 24) | (DCSParams[12][4] << 16) | (DCSParams[12][3] << 8) | DCSParams[12][2];
float PvalFloat = static_cast<float>(Pval) / 1000.0;
Serial.print("Row 12 Bus Frequency: ");
Serial.print(PvalFloat);
Serial.println(" Hz");
delay(5);
to be more concise or even better use a variable for loop since data length is known like so

C++:
// Bus Frequency Row 12
int Pval = 0;
for (int i = 5; i >= 2; --i) {
    Pval = (Pval << 8) | DCSParams[12][i];
}

float PvalFloat = static_cast<float>(Pval) / 1000.0;
Serial.print("Row 12 Bus Frequency: ");
Serial.print(PvalFloat);
Serial.println(" Hz");
delay(5);
Obviously all this is up to the coder just thought I'd toss in my 2 cents haha
 

kloppk

Well-known member
Steel Soldiers Supporter
2,135
3,506
113
Location
Pepperell, Massachusetts
I agree the code can be more concise. It was the first pass at decoding the data to get it to work. I was simply evolving the code to get it to work. I was going for "function over form" initially. Now that it's working it could certainly be made more concise.
Back when I started doing some programming in my career we had to use IBM punch cards. Editing involved shuffling the cards and dropping them into the optical card reader again and again.
Once done the deck was marked with a marker making a diagonal stripe on the side of the deck just in case you dropped the deck. That gave one a fighting chance to get the deck back in the right order. The program decks were stored in long cardboard boxes.
:LOL:
 
Last edited:

Icesythe7

Active member
147
223
43
Location
Indiana, USA
I agree the code can be more concise. It was the first pass at decoding the data to get it to work. I was simply evolving the code to get it to work. I was going for "function over form" initially. Now that it's working it could certainly be made more concise.
Back when I started doing some programming in my career we had to use IBM punch cards. Editing involved shuffling the cards and dropping them into the optical card reader again and again.
Once done the deck was marked with a marker making a diagonal stripe on the side of the deck just in case you dropped the deck. That gave one a fighting chance to get the deck back in the right order. The program decks were stored in long cardboard boxes.
:LOL:
Oh yes for sure I wasn't meaning your code specifically just to future readers really...your code was just handy to use as an example, for the others reading this and the sir/madam that asked about the math it is basically just this (again using kloppk's code as an example haha


C++:
uint8_t DCSParams[] = {
    0x93, 0x02, 0xCC, 0x07, 0x5A
};

uint8_t calcChecksum(const uint8_t* data) {
    uint8_t checksum = data[0];
    const uint8_t data_size = data[1] + 3;
    for (std::size_t index = 1; index < data_size - 1; ++index)
        checksum ^= data[index];
    return checksum;
}

uint32_t decodeResponse(const uint8_t* data) {
    uint32_t result = 0;
    const uint8_t response_size = data[1] + 3;
    const uint8_t current_checksum = data[response_size - 1];
    const uint8_t expected_checksum = calcChecksum(data);

    if (expected_checksum == current_checksum) {
        for (int i = response_size - 1; i >= response_size - data[1]; --i) {
            result = (result << 8) | data[i - 1];
        }
        return result;
    }

    printf("Invalid checksum, expected 0x%.2X got 0x%.2X\n", expected_checksum, current_checksum);
    return result;
}

void printData(const char* name, const char* units, const uint8_t* data, const float factor = 1.0f) {
    printf("%s %.2f%s\n", name, static_cast<float>(decodeResponse(data)) / factor, units);
}

int main() {
    printData("Battery Voltage:", "V", DCSParams, 100.0f);
    return 0;
}
this should be a baseline of the math in a simple method format, I'm not any good at python but should be something like this

Python:
DCSParams = [0x93, 0x02, 0xCC, 0x07, 0x5A]

def calc_checksum(data):
    checksum = data[0]
    data_size = data[1] + 3
    for index in range(1, data_size - 1):
        checksum ^= data[index]
    return checksum

def decode_response(data):
    result = 0
    response_size = data[1] + 3
    current_checksum = data[response_size - 1]
    expected_checksum = calc_checksum(data)

    if expected_checksum == current_checksum:
        for i in range(response_size - 1, response_size - data[1] - 1, -1):
            result = (result << 8) | data[i - 1]
        return result

    print(f"Invalid checksum, expected 0x{expected_checksum:02X} got 0x{current_checksum:02X}")
    return result

def print_data(name, units, data, factor=1.0):
    decoded_value = decode_response(data)
    print(f"{name} {decoded_value / factor:.2f}{units}")

if __name__ == "__main__":
    print_data("Battery Voltage:", "V", DCSParams, 100.0)
 
Last edited:

Light in the Dark

Well-known member
Steel Soldiers Supporter
3,813
5,889
113
Location
MA
I agree the code can be more concise. It was the first pass at decoding the data to get it to work. I was simply evolving the code to get it to work. I was going for "function over form" initially. Now that it's working it could certainly be made more concise.
Back when I started doing some programming in my career we had to use IBM punch cards. Editing involved shuffling the cards and dropping them into the optical card reader again and again.
Once done the deck was marked with a marker making a diagonal stripe on the side of the deck just in case you dropped the deck. That gave one a fighting chance to get the deck back in the right order. The program decks were stored in long cardboard boxes.
:LOL:
You mean the kids up and coming today couldn't just summon Siri to aid in that?
 

kloppk

Well-known member
Steel Soldiers Supporter
2,135
3,506
113
Location
Pepperell, Massachusetts
Nope, the internet was just in its infancy when I graduated. Back then it was only used for connecting a few scientific facility together.
Voice recognition was just in its beginnings too. It took an 18" rack full of stuff to understand a dozen words. We had to train it by speaking the same word over and over into a mic to train it. No Siri then!
 
Last edited:

MLCap

New member
2
0
1
Location
Los Angeles
Hello @R1ckyb0nd and @kloppk !

I have read through the thread about getting data from the AMMPS generator via the remote port on the DCS and I have been struggling to replicate the work that has been completed. I am using the "LOCAL CABLE" (30554-04-21227) along with the RS-232 to RS-485 adapter and am connecting that into a USB RS-232 Serial to DB9 Male into my PC. I have not been able to get the handshake or the 44 requests to return any form of valid data. If either of you would be willing to share your code or some more insight into getting the 44 requests to actually return data that would be greatly appreciated.

Thanks!
 

kerosene

New member
1
1
3
Location
Wyoming
Hello everyone, thanks for the work on the Remote serial protocol, it has been very helpful. Forgive me if this has already been sent previously in this thread, but I did not see mention of the "Advanced DCS Operator’s Manual", which details control of the DCS via the "Front Face CAN" (Network) connector. I have been using this for remote start, closing the contactor, etc with multiple paralleled units, along with data from the remote port since the CAN protocol does not support much in the way of statistics. I have attached a copy that I found online for reference.
 

Attachments

Top