Moving ps2x.config_gamepad(); to loop will endlessly configure controller in result massive delays. I have tested it.
I have spent some time trying to understand PS2X library and, I think, author predicted connection loss but for my Arduino Mega, for some reason, could not keep up.
I have managed to kill two receivers trying to hook up to green LED and from there create function to pick up connection status of the controller. Eventually I gave up on this.
Then I have started playing with multimeter and pins on the receiver.
One of the pins (CMD?) when controller ON or OFF was giving fairly consistent readings but...
When ON - 1018 to 1023 ( when no buttons pressed)
When OFF - 1021 - 1022 ( occasionally 1020 -1022)
Unfortunately when ON, spikes were to far apart to safely determine when actually was ON.
On average it was 3-4 seconds but at some point even 7-8 seconds.
analogRead(ps2x.read_gamepad(X, X)); X= true/false
finally gave me consistency and I could start playing with it.
The most optimal reading time to determine for controller when ON is 3500ms to count spikes for x>1022 and x<1021 by sampleCount I could see when controller was ON or OFF.
void ccc() {
int analogValue = analogRead(!ps2x.read_gamepad(true, true)); // read analog data from the controller
int isDeviceOn = (analogValue > 1022 || analogValue < 1021); // check if device is ON
Serial.println(analogValue);
}
Unfortunately ps2x library has a "bug" when PS2 controller is on and Arduino restarted or code uploaded, library think that controller is still connected and return " Controller found" even when controller in fact was switched OFF or cannot connect after restart.
By sampleCount I now can safely halt all other functions until connection is established. This method works for sleep mode. Controller sleep mode activate after 3 minutes.
Code:
When controller is OFF for more than specified time it goes to safety mode to slow down/ reduce functionality and if additional time passes then go to full stop.
const int SAMPLE_TIME = 3500; // 3 seconds in milliseconds
const int SLOW_MODE_TIME = 1500;
const int EMERGENCY_MODE_TIME = 1000;
unsigned long sampleStartTime = 0;
unsigned long slowModeStartTime = 0;
unsigned long emergencyModeStartTime = 0;
int sampleCount = 0;
bool prevDeviceState = false;
bool slowModeFlag = false;
bool emergencyModeFlag = false;
void ccc() {
int analogValue = analogRead(!ps2x.read_gamepad(true, true)); // read analog data from the controller
int isDeviceOn = (analogValue > 1022 || analogValue < 1021); // check if device is ON
// update sample count if necessary
if (millis() - sampleStartTime >= SAMPLE_TIME) {
Serial.print("Sample count: ");
Serial.println(sampleCount);
if (sampleCount > 0) {
slowModeFlag = false;
emergencyModeFlag = false;
} else {
slowModeFlag = true;
slowModeStartTime = millis();
}
sampleCount = 0;
sampleStartTime = millis();
} else {
if (isDeviceOn) {
sampleCount++;
}
}
// enter slow mode if necessary
if (slowModeFlag && (millis() - slowModeStartTime >= SLOW_MODE_TIME)) {
if (!emergencyModeFlag) {
Serial.println("Entering slow mode");
// call slow mode function here
slowModeFlag = false;
emergencyModeFlag = true;
emergencyModeStartTime = millis();
} else if (emergencyModeFlag && slowModeFlag) {
Serial.println("Device did not recover, emergency stop");
// call emergency stop function here
}
}
// check if device has recovered from emergency mode
if (emergencyModeFlag && (millis() - emergencyModeStartTime >= EMERGENCY_MODE_TIME)) {
if (sampleCount > 0) {
Serial.println("Device has recovered from emergency mode");
// call function to exit emergency mode here
slowModeFlag = false;
emergencyModeFlag = false;
} else {
emergencyModeStartTime = millis();
}
}
}
Based on my knowledge and experience I might be wrong or not fully understand many aspects but at least know my approach works for me