#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;
}
}
}