| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 
 |  
#define externalDevice Serial1
 
enum t_state : uint8_t {WAITING_00, WAITING_30, WAITING_LENGTH, WAITING_COMMAND} state = WAITING_00;
 
const uint32_t maxCommandLength = 4;
 
struct t_command {
  uint8_t length;
  uint8_t bytes[maxCommandLength];
};
 
const t_command commandList[] = {   // don't forget to pad with 0x00 to the left
  {0x03, {0x00, 0x21, 0xc0, 0x05}}, // command Comm_0
  {0x03, {0x00, 0x21, 0xc0, 0x06}}, // command Comm_1
  {0x02, {0x00, 0x00, 0x00, 0x00}}, // command Comm_2
  {0x02, {0x00, 0x00, 0x00, 0x01}}, // command Comm_3
  {0x03, {0x00, 0x20, 0x10, 0x09}}, // command Comm_4
  {0x03, {0x00, 0x20, 0x11, 0x0d}}, // command Comm_5
  {0x03, {0x00, 0x20, 0x11, 0x20}}, // command Comm_6
  {0x03, {0x00, 0x10, 0x1b, 0x0d}}, // command Comm_7
  {0x03, {0x00, 0x0a, 0x1b, 0x0d}}, // command Comm_8
  {0x03, {0x00, 0x0c, 0x1b, 0x0d}}, // command Comm_9
  {0x03, {0x00, 0x20, 0x10, 0x19}}, // command Comm_10
};
const uint8_t numberOfCommands = sizeof commandList / sizeof commandList[0];
 
// we assign symbolic names to the indexes to make it easier to read the code
enum : uint8_t {Comm_0 = 0, Comm_1, Comm_2, Comm_3, Comm_4, Comm_5, Comm_6, Comm_7, Comm_8, Comm_9, Comm_10, Comm_Unknown = 0xFF};
 
// define static answers if you know them
const uint8_t answerComm_2[] = {0x03, 0x00, 0x80, 0x92}; // hardwire answer to Comm_2
const uint8_t answerComm_3[] = {0x03, 0x00, 0x81, 0x17}; // hardwire answer to Comm_3
const uint8_t answerComm_4[] = {0x04, 0x20, 0x90, 0x09, 0x01}; // hardwire answer to Comm_4
const uint8_t answerComm_5[] = {0x04, 0x20, 0x91, 0x0d, 0x01}; // hardwire answer to Comm_5
const uint8_t answerComm_6[] = {0x04, 0x20, 0x91, 0x20, 0x00}; // hardwire answer to Comm_6
const uint8_t answerComm_7[] = {0x04, 0x10, 0x9b, 0x0d, 0x00}; // hardwire answer to Comm_7
const uint8_t answerComm_8[] = {0x04, 0x0a, 0x9b, 0x0d, 0x00}; // hardwire answer to Comm_8
const uint8_t answerComm_9[] = {0x04, 0x0c, 0x9b, 0x0d, 0x00}; // hardwire answer to Comm_9
const uint8_t answerComm_10[] = {0x05, 0x20, 0x90, 0x19, 0x00, 0x07}; // hardwire answer to Comm_10
 
bool receiveCommand(t_command& aCommand)
{
  bool commandComplete = false;
  int r = externalDevice.read();
  if (r == -1) return false;
 
  uint8_t byteReceived = (uint8_t) r;
  static uint8_t bytePosition;
 
  switch (state) {
    case WAITING_00: // handle ping
      if (r == 0x00) state = WAITING_30;
      break;
 
    case WAITING_30:
      if (r == 0x30) {
          Serial.println(F("Got PING"));
        // got ping, provide answer
        externalDevice.write(0x84);
        externalDevice.write(0x84);
        state = WAITING_LENGTH;
      } else if (r != 0x00) state = WAITING_00; // handle 00 00 30 ... by recognizing the 2 last bytes
      break;
 
    case WAITING_LENGTH:
      if (byteReceived == 0x00) { // length can't be 0. Handle possible ping
        state = WAITING_30;
      } else {
        if (byteReceived <= maxCommandLength) {
          aCommand.length = byteReceived;
          bytePosition = byteReceived;
          memset(aCommand.bytes, 0x00, maxCommandLength); // empty the previous command cf https://en.cppreference.com/w/cpp/string/byte/memset
          state = WAITING_COMMAND;
        } else {
          // handle error, this can't be a command.
          Serial.println(F("error: Command length too long"));
          externalDevice.end();                     // close the connection
          delay(100);                               // wait a bit
          externalDevice.begin(38400, SERIAL_8N1);  // open a fresh connection
          state = WAITING_00;                       //  wait for a new ping
        }
      }
      break;
 
    case WAITING_COMMAND:
      aCommand.bytes[--bytePosition] = byteReceived;
      Serial.println(byteReceived, HEX);
      if (bytePosition == 0) {
        commandComplete = true;
        state = WAITING_COMMAND;
      }
      break;
  }
 
  return commandComplete;
}
 
bool handleCommand(t_command& aCommand)
{
  uint8_t commandIndex = Comm_Unknown;
 
  // Do we know this command?
  for (uint8_t i = 0; i < numberOfCommands; i++) {
 
 
    // check if we have the right length and matching bytes for the command
    if ((aCommand.length == commandList[i].length) && (!memcmp(aCommand.bytes, commandList[i].bytes, maxCommandLength))) { // cf memcmp() doc: https://en.cppreference.com/w/cpp/string/byte/memcmp
      Serial.print("commands: ");
      Serial.println(i);
      commandIndex = i; // found our command
      break;
    }
  }
 
  // did we find our command?
  if (commandIndex == Comm_Unknown) return false;
 
  // we have a known command
  switch (commandIndex) {
    case Comm_0: Serial.println(F("Command 0")); /* send answer */; break;
    case Comm_1: Serial.println(F("Command 1")); /* send answer */; break;
    case Comm_2: Serial.println(F("Command 2")); externalDevice.write(answerComm_2, sizeof answerComm_2); break;
    case Comm_3: Serial.println(F("Command 3")); externalDevice.write(answerComm_3, sizeof answerComm_3); break;
    case Comm_4: Serial.println(F("Command 4")); externalDevice.write(answerComm_4, sizeof answerComm_4); break;
    case Comm_5: Serial.println(F("Command 5")); externalDevice.write(answerComm_5, sizeof answerComm_5); break;
    case Comm_6: Serial.println(F("Command 6")); externalDevice.write(answerComm_6, sizeof answerComm_6); break;
    case Comm_7: Serial.println(F("Command 7")); externalDevice.write(answerComm_7, sizeof answerComm_7); break;
    case Comm_8: Serial.println(F("Command 8")); externalDevice.write(answerComm_8, sizeof answerComm_8); break;
    case Comm_9: Serial.println(F("Command 9")); externalDevice.write(answerComm_9, sizeof answerComm_9); break;
    case Comm_10: Serial.println(F("Command 10")); externalDevice.write(answerComm_10, sizeof answerComm_10); break;
  }
  return true;
}
 
void setup() {
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  Serial.begin(115200);
  externalDevice.begin(38400, SERIAL_8N1);
}
 
void loop() {
  t_command aCommand;
  if (receiveCommand(aCommand)) handleCommand(aCommand);
} | 
Partager