alduxvm / pyMultiWii

MultiWii Serial Protocol (MSP) API to send and receive data from firmware using MSP
GNU General Public License v3.0
154 stars 85 forks source link

Variable types in getData() #1

Closed conkerkh closed 8 years ago

conkerkh commented 8 years ago

Hi first of all great work nice class you've made it saved me some time. However you have few issues, mainly in getData. You are not doing crc checking thats one. Second when you are unpacking string to temp you assume it's signed short which is correct however not for everything. For example RC Channels are send as UInt16 which is unsigned short.

Another thing is you can batch send like 5 requests and then recieve 5 of them processing whole buffer. The idea is to get liek 5 infos updated every loop rather than 5 infos updated every 5 loops.

alduxvm commented 8 years ago

Oh that is nice!! Would you like to contribute at it and we can add it like a patch?

How can you batch 5 requests? care to place some examples?

conkerkh commented 8 years ago

Sure man sorry I didn't update at first place. As far as I understand for example on clmeanflight the way the whole thing works is by reading incoming serial buffer. So lets say at the beginning of the loop MCU has total of 5 requests on serial port 1. Then basically it sends 5 different responses in the same loop. Based on this you send 5 concurrent requests then you have to read the whole incoming buffer from the beginning till the end I would suggest not to flush it till you read the whole thing. As for the logic used to read it there are two options one is what you are using. However there is second one used in multiwii to interpret requests which is maybe slightly more elegant:

bool read_message (MSP_PAYLOAD* payload, MSP_FC_STATUS* x) {
  bool result = 0;
  int pos = 0;
  byte countr=0;
  int int_pos = 0;
  payload->length_received = 0;
  payload->state = 0;
  //read some into buffer
  while (defSerial.available() > 0) {
      payload->message_buffer[pos] = defSerial.read();
      pos++;
  }
  for (int i = 0; i < pos; i++) {
            switch (payload->state) {
                case 0: // sync char 1
                    if (payload->message_buffer[i] == 36) { // $
                          payload->state++;
                    }
                    break;
                case 1: // sync char 2
                    if (payload->message_buffer[i] == 77) { // M
                        payload->state++;
                    } else { // restart and try again
                        payload->state = 0;
                    }
                    break;
                case 2: // direction (should be >)
                    if (payload->message_buffer[i] == 62) { // >
                        payload->message_direction = 1;
                    } else { // <
                        payload->message_direction = 0;
                    }
                    //defSerial.write(payload->message_direction);
                    payload->state++;
                    break;
                case 3:
                    payload->length_expected = payload->message_buffer[i];
                    payload->message_checksum = payload->message_buffer[i];
                    payload->state++;
                    break;
                case 4:
                    payload->code = payload->message_buffer[i];
                    payload->message_checksum ^= payload->message_buffer[i];
                    if (payload->length_expected > 0) {
                        // process payload
                        payload->state++;
                    } else {
                        // no payload
                        payload->state += 2;
                    }
                    break;
                case 5: // payload data
                    payload->message_data[payload->length_received] = payload->message_buffer[i];
                    payload->message_checksum ^= payload->message_buffer[i];
                    payload->length_received++;
                    if (payload->length_received >= payload->length_expected) {
                        payload->state++;
                    }
                    break;
                case 6:
                    if (payload->message_checksum == payload->message_buffer[i]) {
                        // message received, process
                        process_data(payload, payload->message_data, payload->length_expected, x);
                        result=1;
                    }
                    // Reset variables
                    payload->length_received = 0;
                    payload->state = 0;
                    break;
                 default:
                    defSerial.println("SUM ERROR OCCURED");
                    break;
            }
  }
  return result;
}

This would be my code based on some other code to interpret the whole buffer (t's messy btw) there is additional function that assigns data in each response from micro controller to global variables (process_data). I hope it will let you understand concept.

What would I do is to read the whole Serial buffer to byte array or rather struct tuple because it's easier to use apparently. Then basically analyze it using logic in the function I attached.

I'm gonna do some modifications and send you to accept in next few days, but right now I'm a bit busy. Also my XBee for some reason is pretty stubborn to cooperate...