Arduino Code – ESP-32

#include <Wire.h>

#define DEVICE_ADDR 0x09   // I²C address of the DiSEqC module
#define CONTROL_REG 0x01   // Register to which commands are sent
#define STATUS_REG  0x02   // Register from which responses are read

// Structure that defines a DiSEqC test command.
struct DiseqcCommand {
  const char* description; // Short description of the command
  uint8_t bytes[6];        // Command bytes (up to 6 bytes; adjust size if needed)
  uint8_t length;          // Actual number of bytes in the command
};

/*
  Comprehensive list of known DiSEqC commands from the specification.
  Many devices support only a subset; this program tests them all.
*/
DiseqcCommand commands[] = {
  { "Reset ALL devices",                 { 0xE0, 0x00, 0x00 },        3 },
  { "Reset polar/azimuth positioner",      { 0xE0, 0x31, 0x00 },        3 },
  { "Select Input Port A (Switch A)",      { 0xE0, 0x10, 0x38 },        3 },
  { "Select Input Port B (Switch B)",      { 0xE0, 0x10, 0x39 },        3 },
  { "Select Input Port C (Switch C)",      { 0xE0, 0x10, 0x3A },        3 },
  { "Select Input Port D (Switch D)",      { 0xE0, 0x10, 0x3B },        3 },
  { "Stop polar/azimuth movement",         { 0xE0, 0x31, 0x60 },        3 },
  { "Disable limits",                      { 0xE0, 0x31, 0x63 },        3 },
  { "Set CW limit to current pos",         { 0xE0, 0x31, 0x66 },        3 },
  { "Set CCW limit to current pos",        { 0xE0, 0x31, 0x67 },        3 },
  { "Drive to stored position #1",         { 0xE0, 0x31, 0x6B, 0x01 },  4 },
  { "Drive to stored position #2",         { 0xE0, 0x31, 0x6B, 0x02 },  4 },
  { "Relative movement east (5 steps)",    { 0xE0, 0x31, 0x40, 0x05 },  4 },
  { "Relative movement west (5 steps)",    { 0xE0, 0x31, 0x41, 0x05 },  4 },
  { "Absolute position: 10° CW from zero", { 0xE0, 0x31, 0x6E, 0xE0, 0xA0 }, 5 },
  { "Absolute position: 10° CCW from zero", { 0xE0, 0x31, 0x6E, 0xD0, 0xA0 }, 5 }
};

const int numCommands = sizeof(commands) / sizeof(commands[0]);

// Function prototypes
void runAllTests();
void runTest(const DiseqcCommand &cmd, int testNumber);
void printBytes(const uint8_t *data, uint8_t length);
void interpretResponse(uint8_t response);

void setup() {
  Serial.begin(115200);
  while (!Serial); // Wait for Serial Monitor, if needed

  // Initialize I²C (for ESP32 use GPIO21 as SDA, GPIO22 as SCL)
  Wire.begin(21, 22);
  
  Serial.println("====================================================");
  Serial.println(" Comprehensive DiSEqC Commands Test Program");
  Serial.println("====================================================");
  Serial.println("This program will issue ALL known DiSEqC commands one by one.");
  Serial.println("Since we don't yet know which commands are implemented on the chip,");
  Serial.println("each command is tested and its response is logged.");
  Serial.println("Press any key to begin the tests...");

  // Wait for a keystroke from the Serial Monitor
  while (Serial.available() == 0) {}
  while (Serial.available() > 0) { Serial.read(); } // Flush input
  
  runAllTests();
}

void loop() {
  // All tests are executed in setup(); loop remains idle.
}

//----------------------------------------------------------------
// runAllTests()
//  Iterates through the commands array and executes each test.
//----------------------------------------------------------------
void runAllTests() {
  Serial.println("\n--- Starting DiSEqC Command Tests ---\n");
  for (int i = 0; i < numCommands; i++) {
    runTest(commands[i], i + 1);
    
    Serial.println("\n>> Press any key when ready for the next test...");
    while (Serial.available() == 0) {}         // Wait for user to hit a key
    while (Serial.available() > 0) { Serial.read(); } // Flush input
    Serial.println("----------------------------------------------------\n");
  }
  Serial.println("\n=== All DiSEqC Tests Completed ===");
}

//----------------------------------------------------------------
// runTest()
//  Sends a DiSEqC command, retrieves the response, and prints the result.
//----------------------------------------------------------------
void runTest(const DiseqcCommand &cmd, int testNumber) {
  Serial.print("Test ");
  Serial.print(testNumber);
  Serial.print(": ");
  Serial.println(cmd.description);
  
  Serial.print("Sending Command Bytes: ");
  printBytes(cmd.bytes, cmd.length);

  // Send the command over I²C (using CONTROL_REG as a command header)
  Wire.beginTransmission(DEVICE_ADDR);
  Wire.write(CONTROL_REG);
  for (uint8_t i = 0; i < cmd.length; i++) {
    Wire.write(cmd.bytes[i]);
  }
  uint8_t i2cResult = Wire.endTransmission();
  
  if (i2cResult == 0) {
    Serial.println("[INFO] I²C Transmission successful.");
  } else {
    Serial.print("[ERROR] I²C Transmission failed with code: ");
    Serial.println(i2cResult);
    return;  // Skip response reading if transmission failed.
  }
  
  // Allow the module time to process the command
  delay(200);
  
  // Request a response from the STATUS_REG (expecting one status byte)
  Wire.beginTransmission(DEVICE_ADDR);
  Wire.write(STATUS_REG);
  Wire.endTransmission();
  Wire.requestFrom(DEVICE_ADDR, 1);

  if (Wire.available()) {
    uint8_t ack = Wire.read();
    Serial.print("Received Acknowledgment: 0x");
    Serial.print(ack, HEX);
    Serial.print(" (Binary: ");
    Serial.print(ack, BIN);
    Serial.println(")");
    interpretResponse(ack);
  } else {
    Serial.println("[ERROR] No response received from device.");
  }
}

//----------------------------------------------------------------
// printBytes()
//  Helper function to print an array of bytes in hexadecimal format.
//----------------------------------------------------------------
void printBytes(const uint8_t *data, uint8_t length) {
  for (uint8_t i = 0; i < length; i++) {
    Serial.print("0x");
    if (data[i] < 0x10)
      Serial.print("0");  // For neat alignment of single-digit values
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

//----------------------------------------------------------------
// interpretResponse()
//  Extends the response interpretation to handle the ubiquitous 0x21 code.
//----------------------------------------------------------------
void interpretResponse(uint8_t response) {
  if (response == 0x21) {
    Serial.println("[RESULT] Response 0x21: This value is returned for every command.");
    Serial.println("           It may indicate a default acknowledgement (e.g., with internal flags set).");
    Serial.println("           Consult the datasheet or further test with additional registers/commands.");
  }
  else {
    switch (response) {
      case 0x00:
        Serial.println("[RESULT] Response 0x00: Undefined or no response.");
        break;
      case 0x01:
        Serial.println("[RESULT] Success: Command executed successfully.");
        break;
      case 0x02:
        Serial.println("[RESULT] Warning: Device busy; try again later.");
        break;
      case 0x03:
        Serial.println("[RESULT] Error: Command not recognized by device.");
        break;
      default:
        Serial.print("[RESULT] Unknown response code: 0x");
        Serial.print(response, HEX);
        Serial.println(".");
        break;
    }
  }
}